Earlier we have used xtrinsic as a temperature measuring module.

This time we shall use it as an accelerometer.


The Xtrinsic Sensor BoardXtrinsic Sensor Board comes bundled with multiple sensors & is arduino compatible.


The Xtrinsic module supports consists of  sensors:

MPL3115A2  - high-precision sensor used to provide accurate pressure and temperature.

MAG3110     - small, low-power, digital 3-axis magnetometer

MMA8491Q  - low voltage, 3-axis low-g accelerometer



Setting up the Hardware


Lets start with the pin mapping of Xtrinsic.

we will be using 5 pins of Xtrinsic board.



Pin Mapping for Xtrinsic Accelerometer.


5  Male to Female jumper wires are used  to connect Riotboard Expansion port pins to Xtrinsic CN1 & CN2 .



Connecting female headers in Xtrinsic CN2 Connector.




Connecting female headers in Xtrinsic CN1 Connector.




Connecting Male headers in Riotboard (J13)




Setup after Connections ....



In order to retrieve data from the accelerometer the Enable (EN) pin of Xtrinsic needs to be logic high.





Based on schematics I an using PIN5 (GPIO)  in J13 port to drive xtrinsic pin1(EN) high.

we need to configure PIN5 as gpio.


Execute below command to set Pin5 as GPIO

devmem 0x20E009C w 0x5


Export the pin to sysfs filesystem so that we can use it:

echo 112 > /sys/class/gpio/export


PIN5 = GPIO4_16 (from schematics)


GPIO4_16 = (4-1)*32+16 = 112


Drive the GPIO high.

echo out > /sys/class/gpio/gpio112/direction

echo 1 > /sys/class/gpio/gpio112/value


Once done with the gpio settings, we will move to accelerometer driver.


I wrote a  user-space driver  to access the accelerometer sensor .


#include <stdio.h>
#include <stdint.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>

#define I2CFILE "/dev/i2c-3"

static int write_register(int file,unsigned char address,unsigned char reg,unsigned char data)

   unsigned char output_buffer[2];
   struct i2c_rdwr_ioctl_data packets;
   struct i2c_msg messages[1];

    messages[0].addr  = address;
    messages[0].flags = 0;
    messages[0].len   = sizeof(output_buffer);
    messages[0].buf   = output_buffer;

    output_buffer[0] = reg;
    output_buffer[1] = data;

    packets.msgs  = messages;
    packets.nmsgs = 1;

    if(ioctl(file, I2C_RDWR, &packets) < 0) {
        perror("Error sending data");
        return 1;

    return 0;

static int read_register(int file, unsigned char address, unsigned char reg, unsigned char *data)
    unsigned char input_buffer, output_buffer;
    struct i2c_rdwr_ioctl_data packets;
    struct i2c_msg messages[2];

    output_buffer = reg;
    messages[0].addr  = address;
    messages[0].flags = 0;
    messages[0].len   = sizeof(output_buffer);
    messages[0].buf   = &output_buffer;

    messages[1].addr  = address;
    messages[1].flags = I2C_M_RD;
    messages[1].len   = sizeof(input_buffer);
    messages[1].buf   = &input_buffer;

    packets.msgs      = messages;
    packets.nmsgs     = 2;
    if(ioctl(file, I2C_RDWR, &packets) < 0) {
        perror("Error Receiving data");
        return 1;
    *data = input_buffer;

    return 0;

int main() {
    int file, i;
    unsigned char data_m;
    unsigned char data_l;
    char string[200];

if ((file = open(I2CFILE, O_RDWR)) < 0)
    perror("Error openning file!");
    printf("%s opened\n",I2CFILE);

//accel status
   if(read_register(file, 0x55, 0x00, &data_m))
     printf("\n\n\nAcc Status: [0x%02X]: 0x%02X\n" , 00 , data_m);

//read accel MSB/LSB - X axis
   if(read_register(file, 0x55, 0x01, &data_m))
   if(read_register(file, 0x55, 0x02, &data_l))
   printf("X-Register : 0x%02X:0x%02X\n" , data_m, data_l);

//read accel MSB/LSB - Y axis
   if(read_register(file, 0x55, 0x03, &data_m))
   if(read_register(file, 0x55, 0x04, &data_l))
   printf("Y-Register : 0x%02X:0x%02X\n" , data_m, data_l);

//read accel MSB/LSB - Z axis
   if(read_register(file, 0x55, 0x05, &data_m))
   if(read_register(file, 0x55, 0x06, &data_l))
    printf("Z-Register : 0x%02X:0x%02X\n" , data_m, data_l);

system("echo out > /sys/class/gpio/gpio112/direction");
system("echo 1 > /sys/class/gpio/gpio112/value");

    return 0;


Code Expln:

Once the values are read the EN pin is set low and the register contents are reset.

In Line 118 -119 we drive the EN pin high to preserve the register contents until next read.

Driving EN pin high, makes register [0x00] value as 0xFF.

Acc Status: [0x00]: 0xFF  (check terminal output towards the end of blog).


In Line 11  we  select /dev/i2c-3 (I2C4-SDA) pin as our communication path.



Compiling the program :

    On Riotboard:

    gcc xtrinsic_acc.c -o xtrinsic_acc


    On PC:

   <PATH_TO_TOOLCHAIN>/fsl-linaro-toolchain/bin/arm-fsl-linux-gnueabi-gcc xtrinsic_acc.c -o xtrinsic_acc


Once Compiled we will execute . To access a device file "/dev/i2c-3" (check line 11 above ) we need to be root.

# ./xtrinsic_acc


register values will change based on the inclination of the board ..

Even with no movement you can see changing values in the LSB part of register  due to table vibrations.





Ok It works ..


We completed  integration of xtrinsic accelerometer sensor with Riotboard.


In Next blog we shall see how to get meaningful information out of the captured register values.