Reading Sensors on the MXChip AZ3166 IoT Device

Recently I have been playing around with the MXChip IoT DevKit device (AZ3166, you can purchase one here) and I’ve noticed that while there are great code samples designed to get you started with the MXChip DevKit, there aren’t any basic examples showing you how to use the different sensors built into the device. This article aims to go through each of the available on-board sensors (temperature & humidity, pressure, accelerometer & gyroscope, and magnetometer) and give examples on how to use them.

I am assuming you already went through the steps to update to the latest firmware and connect to your WiFi network (steps are here; ignore the sections regarding connecting to Azure IoT Hub as we do not need that for this article). Also make sure your VSCode environment has the Azure IoT Tools extension installed.

There are 4 on-board sensors that come with the MXChip IoT DevKit device:

  • Temperature & Humidity
  • Pressure
  • Accelerometer & Gyroscope
  • Magnetometer

The MXChip IoT DevKit device is Arduino-compatible, and there is support for this hardware via the Microsoft Azure IoT Developer Kit in VSCode (via Arduino Board Manager). Once you’ve connected your MXChip device to your WiFi you can start creating Arduino sketches to upload the code for.

Setup

First off, you will want to create a new project in VSCode. Open VSCode and press F1 and type in Azure IoT Device Workbench in the textbox that appears.

Figure 1: Creating a New Project

Find the entry labeled Azure IoT Device Workbench: Create Project… and click on it. Enter a descriptive name for your project.

Figure 2: Project Name

Once you press Enter you will see another selection dropdown asking for the platform for this project. Choose Arduino as our project will be based on the Arduino platform.

Figure 3: Platform Selection

Pressing Enter will bring you to the next selection choice: the project template. This is where the different boards and service functionality are listed for the project being created. Since we are using the MXChip we want to select the choices that are available for the MXChip. You will notice that there are a couple of entries that have support for Azure IoT Hub or Azure Functions. For this article, we only need the base device support so select MXChip IoT DevKit selection.

Figure 4: Project Templates

At this point VSCode will create a new workspace with the project name you provided and create a device.ino file for your Arduino sketch.

If you look under the .vscode directory in your project (under Device) you will see 4 JSON files that were automatically created as part of this project. These files define what board the project is using along with other information such as the sketch name and the serial port being used.

Figure 5: Project Configuration

General Information

Since we are coding an Arduino sketch for our device, I thought I’d briefly go through some of the general code and setup that is needed before we delve into the sensor code specifics.

First off, there are the setup() and loop() methods, which need to be coded first. The setup() method is for code that is executed once when the sketch is run, while the loop() method runs on a continuous loop (after setup is complete).

There are a few initializations we need to perform when the code first runs. These are as follows:

  • Initialize the OLED display
  • Start the serial support
  • Initialize WiFi

First thing is to initialize the OLED display on the board so we can display text. Fortunately, the Microsoft Azure IoT Developer Kit library provides a Screen object that we can use (this is defined in the Arduino.cpp file):

Figure 6: Initializing Screen object

Also shown is the Screen.print() method which allows us to display text on the OLED display.

Next is to enable the serial port support for the board. This is done by another class in the Microsoft Azure IoT Developer Kit library called Serial. We want to utilize 115200 baud so we pass that number as the parameter to the Serial.begin() method to start our serial port.

Figure 7: Serial Support

We also want to make sure our WiFi connectivity is working properly. Even though our example in this article doesn’t explicitly use WiFi, it is a good practice to enable this and verify connectivity since we would need this for any communication with the cloud or over-the-air (OTA) updates, such as firmware updates.

Again, the Microsoft Azure IoT Developer Kit library files have support for WiFi for the AZ3166 chipset (see the AZ3166WiFi.cpp file) so all we have to do is utilize the WiFi class in our InitWiFi() method. This method enables WiFi for the board and checks if it connects successfully. If it does, it sets the hasWiFi flag to true and prints the IP address the device is using to the screen. The setup() method will return if the WiFi is not connected.

Figure 8: WiFi Initialization

The final initialization we need to perform is the individual sensors we are utilizing. We need to initialize the temperature & humidity sensor, the pressure sensor and finally the magnetometer sensor. In order to do this, we need to instantiate a helper class of type DevI2C which will handle the details of I2C peripherals. We also need to pass 2 parameters to the instantiation of this helper class which correspond to GPIO pins 18 and 17 respectively (D14=GPIO_18, D15=GPIO_17).

Figure 9: I2C Helper Class Instantiation

There is also the main loop() method which runs on a continuous basis (after setup() finishes executing). This method will repeat indefinitely and here is where we want the code to do our work. Please note that I have a line of code that calls a delay so the loop doesn’t continuously run over and over again without a pause. We use this delay to give some time for the device to perform any background tasks it hasn’t yet finished.

Figure 10: Main Program Loop

Temperature & Humidity Sensor

In order to read from the temperature and humidity sensor we need to initialize this sensor in the setup() method. This is done by instantiating a new class of type HTS221Sensor (which is part of the Microsoft Azure IoT Developer Kit library). This class takes a parameter of type DevI2C so we pass the pointer to the DevI2C variable we created earlier. We then call the init() method to initialize the sensor.

Figure 11: Initializing the Temperature & Humidity Sensor

Once we have initialized this sensor we can now use it in the main loop() method. There are a number of supported methods for this sensor (located here). We are reading the temperature and humidity sensor readings by calling getTemperature() and getHumidity(), respectively. These methods read the sensor and place the results into a float variable which we pass as a pointer to the methods. Please also note that we enable the sensor when using it and disable the sensor when finished.

Figure 12: Reading Temperature, Humidity Sensor

Pressure Sensor

In order to read from the pressure sensor we need to initialize this sensor in the setup() method. This is done by instantiating a new class of type LPS22HBSensor (which is part of the Microsoft Azure IoT Developer Kit library). This class takes a parameter of type DevI2C so we pass the pointer to the DevI2C variable we created earlier. We then call the init() method to initialize the sensor.

Figure 13: Initializing the Pressure Sensor

Once we have initialized this sensor we can now use it in the main loop() method. There are a number of supported methods for this sensor (located here). We are reading the pressure sensor reading by calling getPressure(). This method reads the sensor and places the results into a float variable which we pass as a pointer to the method.

Figure 14: Reading Pressure Sensor

Accelerometer & Gyroscope Sensor

In order to read from this sensor we need to initialize it in the setup() method. This is done by instantiating a new class of type LSM6DSLSensor (which is part of the Microsoft Azure IoT Developer Kit library). This class takes a parameter of type DevI2C so we pass the pointer to the DevI2C variable we created earlier. We then call the init() method to initialize the sensor. Please also note that we can enable the accelerometer, gyroscope, and pedometer individually if we want.

Figure 15: Initializing the Accelerometer & Gyroscope Sensor

Once we have initialized this sensor we can now use it in the main loop() method. There are a number of supported methods for this sensor (located here). Note that we read the positional axes (x, y, and z) for the accelerometer and gyroscope, while we read a step count for the pedometer.

Figure 16: Reading Accelerometer & Gyroscope Sensor

Magnetometer Sensor

In order to read from this sensor we need to initialize it in the setup() method. This is done by instantiating a new class of type LIS2MDLSensor (which is part of the Microsoft Azure IoT Developer Kit library). This class takes a parameter of type DevI2C so we pass the pointer to the DevI2C variable we created earlier. We then call the init() method to initialize the sensor.

Figure 17: Initializing the Magnetometer Sensor

Once we have initialized this sensor we can now use it in the main loop() method. There are a number of supported methods for this sensor (located here). Note that we read the positional axes (x, y, and z) for this sensor.

Figure 18: Reading Magnetometer Sensor

Code Execution

In order to run this code on our MXChip device, we first need to compile the code successfully. In VSCode, press F1 and enter Azure IoT Device Workbench: Compile Device Code and select the entry. This will compile the code for your Arduino sketch file.

Figure 19: Compiling Arduino Sketch File

Once the file compiles successfully, you are now ready to upload the code to the device. Again, press F1 and type Azure IoT Device Workbench: Upload Device Code and select the entry. You can alternatively click the Upload button in the upper right.

Figure 20: Uploading Code to Device

Once the code uploads successfully, it begins executing immediately. If you open the Serial Monitor in VSCode you can see the output, which should look something like this:

Figure 21: Code Execution Output

I hope this article was helpful in explaining the details of utilizing the different on-board sensors in the MXChip. If you would like to download the full source code for this example, please visit my github repository here.

Thanks for reading!

Leave a comment