Build Your Own Digital Compass with XinaBox

Build Your Own Digital Compass with XinaBox

Learn how to build a digital compass that displays the heading of your device with respect to magnetic north.

XinaBox produces a range of 80+ modular xChips, which include cores/CPUs, sensors, power, communication, output, and storage, using a connectivity standard without wires, soldering, breadboards or hardware knowledge

xChip CW01 (ESP82666 Core) is a microprocessor and Wi-Fi module, that enables users to send/receive data from XinaBox's modular xChips to/from the cloud.

xChip SI01 (LSM9DS1) is an IMU 9DoF module that comprises of 3 sensors, an accelerometer that measures acceleration of the X, Y and Z axes, a magnometer that computes orientation to magnetic north, on the X, Y and Z axes, therefore we can calculate which direction we are facing as well as the angle at which we are leaning. The last sensor is the gyroscope that measures our orientation to the center of the earth.

xChip OD01 is a display module that forms part of the output modules and is equipped with an OLED display unit that is capable of displaying any graphics or text.

A Magnetic field moves away from Magnetic South and moves towards Magnetic North. The magnetometer in SI01 senses the magnetic field direction using its 3D magnetometer that senses magnetic fields at its X, Y and Z axes.

Using the sensor value of X and Y of the Magnetic field, we can determine the heading by simply calculating atan2(MX, MY). In this guide we will show you how to build a Digital compass using XinaBox xChips CW01 and SI01.


  • 1x CW01 - Wi-Fi Core (ESP8266/ESP-12F)
  • 1x IP01/IP02 –Simple/Advanced USB Programming Interface (FT232R)
  • 1x OD01 - OLED Display 128x64 (SSD1306)
  • 1x SI01 - IMU 9DoF( LSM9DS1)
  • 1x XC10 - 10-Pack xBus Connectors
  • Arduino IDE


  1. Hardware Setup
  2. Installing Arduino Libraries
  3. Code
  4. Result
  5. Summary

1. Hardware Setup

1. Connect xChips CW01, SI01 and IP01/IP02 together using XC10 xBus connectors. You may connect it as shown in the diagram below. Please see this guide on how to assemble xChips generally.

2. Then connect IP01/IP02 to the USB port of PC.

3. Select “XinaBox CW01” Board in Arduino IDE for uploading code, after installing required Arduino cores/libraries.

2. Installing Arduino Libraries

1. Install Arduino IDE 1.8.8

2. Install these cores/libraries into Arduino IDE:

NOTE: If you are not familiar with how to install libraries, please refer to the links: Installing Arduino libraries and Installing cores

3. Code

Digital Compass C/C++
The compass displays heading of the sensor with respect to Magnetic North.

#include <xCore.h>
#include <xSI01.h>
#include <xOD01.h>

//Sensor Object
xSI01 SI01;
xOD01 OD01;

//Calibration and Sesnor variables
float mX, mY, mZ;
float mx_min, my_min, mz_min;
float mx_max, my_max, mz_max;
float mx_offset, my_offset, mz_offset;
float mx_calibrated, my_calibrated, mz_calibrated;
float mx_scale, my_scale, mz_scale;
static unsigned long startTime;
float avg_scale;

String dir; //Direction String

void setup() {

  mx_max = 0; my_max = 0; mz_max = 0;
  mx_min = 0; my_min = 0; mz_min = 0;

  startTime = millis();

  // Start the Serial Monitor at 115200 BAUD

  // Set the I2C Pins for CW01
#ifdef ESP8266
  Wire.pins(2, 14);


  if (!SI01.begin()) {
    Serial.println("Failed to communicate with SI01.");
    Serial.println("Check the Connector");
  } else {
    Serial.println("start successful");

  // get min/max values by taking readings
  // from magnetometer of your choice

  OD01.println("Move the device");
  OD01.println("in figure 8");
  OD01.println("pattern for 10s");
  //Calculating calibration parameters

  while (true)

    mX = SI01.getMX(); mY = SI01.getMY(); mZ = SI01.getMZ();

    if (mX > mx_max) mx_max = mX; if (mY > my_max) my_max = mY; if (mZ > mz_max) mz_max = mZ;
    if (mX < mx_min) mx_min = mX; if (mY < my_min) my_min = mY; if (mZ < mz_min) mz_min = mZ;

    mx_offset = (mx_min + mx_max) / 2;
    my_offset = (my_min + my_max) / 2;
    mz_offset = (mz_min + mz_max) / 2;

    mx_scale = (mx_max - mx_min) / 2;
    my_scale = (my_max - my_min) / 2;
    mz_scale = (mz_max - mz_min) / 2;

    avg_scale = (mx_scale + my_scale + mz_scale) / 3;


    if (millis() - startTime > 10000) break;

  OD01.println("Calibration done!");


void loop() {


  mX = SI01.getMX(); mY = SI01.getMY(); mZ = SI01.getMZ();
  //Calculates calibrated magnetic field
  mx_calibrated = avg_scale / (mX - mx_offset);
  my_calibrated = avg_scale / (mY - my_offset);
  mz_calibrated = avg_scale / (mZ - mz_offset);

  //Calculates heading
  float heading;
  if (-my_calibrated == 0)
    heading = (-mx_calibrated < 0) ? PI : 0;
    heading = atan2(-mx_calibrated, -my_calibrated);
  heading += 1.15* PI / 180;

  if (heading > PI) heading -= (2 * PI);

  else if (heading < -PI) heading += (2 * PI);

  Serial.print("MX: ");
  Serial.print("MY: ");

  heading *= 180.0 / PI;

  //Adjusting heading value
  if ((heading >= -90) && (heading) <=0) heading += 180;
  if ((heading >= -180) && (heading <= -90)) heading += 360;
  if((heading>90)&&(heading<=182)&&(mx_calibrated<0)) heading+=180;

  if(heading>315 || heading<=45)dir="North";
  if(heading>45 && heading<=135)dir="East";
  if(heading>135 && heading<=225)dir="South";
  if(heading>225 && heading<=315)dir="West";




4. Result

5. Summary

In this project we have shown you how to make a Digital compass using XinaBox xChips CW01 and SI01. This guide can be very useful in a Robotics project and can help the robot navigate indoors/outdoors. This project is simple and requires little or no hardware knowledge.

Previous article Build a Weather Station with XinaBox and Okdo IoT Cloud
Next article 3D Magnetic Field Sensing with XinaBox