1. Although not going to use MEMS sensor boards, I am going to use nucleo extension board  X-NUCLEO-IKS01A2X-NUCLEO-IKS01A2 to code with mother board of nucleo-STM32L476

The  X-NUCLEO-IKS01A2X-NUCLEO-IKS01A2 is a motion MEMS and environmental sensor expansion board for the STM32 Nucleo It is equipped with Arduino UNO R3 connector layout and is designed around the LSM6DSL 3D accelerometer and 3D gyroscope the LSM303AGR 3D accelerometer and 3D magnetometer the  HTS221HTS221 humidity and temperature sensor and the LPS22HB pressure sensor The  X-NUCLEO-IKS01A2X-NUCLEO-IKS01A2 interfaces with the STM32 microcontroller via the I²C pin I the sheme there are two I2C ports I2C1 and I2C2 While the I2C1 and I2C2 share same I/O pins so the I2C1 and I2C2 are same

According to I2C specification, I2C works in master-slave mode sharing same bus. Each slave bears unique address for communication. On boards parts are,

  • LSM303AGR MEMS 3D accelerometer (±2/±4/±8/±16 g) and MEMS3D magnetometer (±50 gauss)
  • LSM6DSL MEMS 3D accelerometer (±2/±4/±8/±16 g) and 3D gyroscope (±125/±245/±500/±1000/±2000 dps)
  • LPS22HB MEMS pressure sensor, 260-1260 hPa absolute digital output barometer
  • HTS221HTS221capacitive digital relative humidity and temperature
  • DIL24 socket for additional MEMS adapters and other sensors, this makes customized parts available.

Also, need to mention, there is X-NUCLEO-IKS01A1 board. This is quite different with 6D sensors instead of 3D sensor of IKS01A2.

2. First, create empty project from template, or you can directly import one demo HelloWorld project by ST teams,but not for IKS01A2, only for IKS01A1. But you can still use it, if right I2C slave address are set.

 

3.  After imported, the file structure is,

it is obvious what parts are used in this board. To use this template, scheme comparing is necessary. It would take extra effort. If not familiar with the difference, it is more safe to create new one.

4. Here is the code for reference,

 

/* Includes */
#include "mbed.h"
#include "x_nucleo_iks01a1.h"


/* Instantiate the expansion board */
static X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(D14, D15);


/* Retrieve the composing elements of the expansion board */
static GyroSensor *gyroscope = mems_expansion_board->GetGyroscope();
static MotionSensor *accelerometer = mems_expansion_board->GetAccelerometer();
static MagneticSensor *magnetometer = mems_expansion_board->magnetometer;
static HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor;
static PressureSensor *pressure_sensor = mems_expansion_board->pt_sensor;
static TempSensor *temp_sensor1 = mems_expansion_board->ht_sensor;
static TempSensor *temp_sensor2 = mems_expansion_board->pt_sensor;


/* Helper function for printing floats & doubles */
static char *printDouble(char* str, double v, int decimalDigits=2)
{
  int i = 1;
  int intPart, fractPart;
  int len;
  char *ptr;


  /* prepare decimal digits multiplicator */
  for (;decimalDigits!=0; i*=10, decimalDigits--);


  /* calculate integer & fractinal parts */
  intPart = (int)v;
  fractPart = (int)((v-(double)(int)v)*i);


  /* fill in integer part */
  sprintf(str, "%i.", intPart);


  /* prepare fill in of fractional part */
  len = strlen(str);
  ptr = &str[len];


  /* fill in leading fractional zeros */
  for (i/=10;i>1; i/=10, ptr++) {
    if(fractPart >= i) break;
    *ptr = '0';
  }


  /* fill in (rest of) fractional part */
  sprintf(ptr, "%i", fractPart);


  return str;
}




/* Simple main function */
int main() {
  uint8_t id;
  float value1, value2;
  char buffer1[32], buffer2[32];
  int32_t axes[3];
  
  printf("\r\n--- Starting new run ---\r\n");


  humidity_sensor->read_id(&id);
  printf("HTS221  humidity & temperature    = 0x%X\r\n", id);
  pressure_sensor->read_id(&id);
  printf("LPS25H  pressure & temperature    = 0x%X\r\n", id);
  magnetometer->read_id(&id);
  printf("LIS3MDL magnetometer              = 0x%X\r\n", id);
  gyroscope->read_id(&id);
  printf("LSM6DS0 accelerometer & gyroscope = 0x%X\r\n", id);
  
  wait(3);
 
  while(1) {
    printf("\r\n");


    temp_sensor1->get_temperature(&value1);
    humidity_sensor->get_humidity(&value2);
    printf("HTS221: [temp] %7s°C,   [hum] %s%%\r\n", printDouble(buffer1, value1), printDouble(buffer2, value2));
    
    temp_sensor2->get_fahrenheit(&value1);
    pressure_sensor->get_pressure(&value2);
    printf("LPS25H: [temp] %7s°F, [press] %smbar\r\n", printDouble(buffer1, value1), printDouble(buffer2, value2));


    printf("---\r\n");


    magnetometer->get_m_axes(axes);
    printf("LIS3MDL [mag/mgauss]:  %7ld, %7ld, %7ld\r\n", axes[0], axes[1], axes[2]);


    accelerometer->get_x_axes(axes);
    printf("LSM6DS0 [acc/mg]:      %7ld, %7ld, %7ld\r\n", axes[0], axes[1], axes[2]);


    gyroscope->get_g_axes(axes);
    printf("LSM6DS0 [gyro/mdps]:   %7ld, %7ld, %7ld\r\n", axes[0], axes[1], axes[2]);


    wait(1.5);
  }
}

5. Click 'compile', one exactable .bin file is build and download automatically. Drag and copy it to nucleo-board disk, flashing the memory.  It will run automatically

 

.

6. Then find your com-port for nucleo,

Use tools like putty to open serial port in 9600 baud rate, you will see.

It works. This is done by remark some unresolved lines. The sensors can easily be read via mbed demo codes.

7. If try to use other IDE on native library, it would be more complicated. First, clock shall be configured, the port setting, I2C parameter setting, interrution, sensor initializing, util then can you start the sensor and read the sensor value. But in this case, all you can say that matters in the IDE is only tow lines.

  humidity_sensor->read_id(&id);
  printf("HTS221  humidity & temperature    = 0x%X\r\n", id);

Isn't it wonderful?