Copyright ©

Mongoose OS Forum


Reading I2C from MPU9150 with NodeMCU, Mongoose-OS and Javascript


I want to read data from an IMU (MPU9150) using I2C. I have really tried to find examples using I2C with no success.

  1. I have success with Arduino wire on Arduino Uno.
  2. I am building on the demo-js template.
  3. I have tried to convert the working Wire code to work with I2C library on Mongoose-OS.
  4. I wired MPU9150 #SCL to NodeMCU #D5 and MPU9150 #SDA to NodeMCU #D6

I get -1 on all reads.

If I insert I2C.close() after all reads, then I get garbage in the console. However the printout is not originated in my code.

This is my code:


let led = Cfg.get('pins.led');
let button = Cfg.get('pins.button');
let topic = '/devices/' + Cfg.get('') + '/events';

// Register names according to the datasheet.
// According to the InvenSense document
// "MPU-9150 Register Map and Descriptions Revision 4.0",
let MPU9150_SELF_TEST_X        = 0x0D;  // R/W
let MPU9150_SELF_TEST_Y        = 0x0E;  // R/W
let MPU9150_SELF_TEST_X        = 0x0F;  // R/W
let MPU9150_SELF_TEST_A        = 0x10;  // R/W
// Definitions is really longer, but cut here so that the post is valid. 

let COMPASS_I2C_ADDRESS        = 0x0C;  // change Adress to Compass
let MPU_I2C_ADDRESS            = 0x68;      // change Adress to MPU

print('LED GPIO:', led, 'button GPIO:', button);

let setupCompass = function() {
  let bus = I2C.get();

  I2C.writeRegB(bus, MPU_I2C_ADDRESS, MPU9150_PWR_MGMT_1, 0);

  I2C.writeRegB(bus, COMPASS_I2C_ADDRESS, 0x0A, 0x00); // PowerDownMode
  I2C.writeRegB(bus, COMPASS_I2C_ADDRESS, 0x0A, 0x0F); // SelfTest
  I2C.writeRegB(bus, COMPASS_I2C_ADDRESS, 0x0A, 0x00); // PowerDownMode

  I2C.writeRegB(bus, MPU_I2C_ADDRESS, 0x24, 0x40); // Wait for Data at Slave0
  I2C.writeRegB(bus, MPU_I2C_ADDRESS, 0x25, 0x8C); // Set i2c address at slave0 at 0x0C
  I2C.writeRegB(bus, MPU_I2C_ADDRESS, 0x26, 0x02); // Set where reading at slave 0 starts
  I2C.writeRegB(bus, MPU_I2C_ADDRESS, 0x27, 0x88); // set offset at start reading and enable
  I2C.writeRegB(bus, MPU_I2C_ADDRESS, 0x28, 0x0C); // set i2c address at slv1 at 0x0C
  I2C.writeRegB(bus, MPU_I2C_ADDRESS, 0x29, 0x0A); // Set where reading at slave 1 starts
  I2C.writeRegB(bus, MPU_I2C_ADDRESS, 0x2A, 0x81); // Enable at set length to 1
  I2C.writeRegB(bus, MPU_I2C_ADDRESS, 0x64, 0x01); // overvride register
  I2C.writeRegB(bus, MPU_I2C_ADDRESS, 0x67, 0x03); // set delay rate
  I2C.writeRegB(bus, MPU_I2C_ADDRESS, 0x01, 0x80);

  I2C.writeRegB(bus, MPU_I2C_ADDRESS, 0x34, 0x04); // set i2c slv4 delay
  I2C.writeRegB(bus, MPU_I2C_ADDRESS, 0x64, 0x00); // override register
  I2C.writeRegB(bus, MPU_I2C_ADDRESS, 0x6A, 0x00); // clear usr setting
  I2C.writeRegB(bus, MPU_I2C_ADDRESS, 0x64, 0x01); // override register
  I2C.writeRegB(bus, MPU_I2C_ADDRESS, 0x6A, 0x20); // enable master i2c mode
  I2C.writeRegB(bus, MPU_I2C_ADDRESS, 0x34, 0x13); // disable slv4


let MPU9150_readSensor = function(bus, addr, low, high){
   let l = I2C.readRegB(bus, addr, low);
   let h = I2C.readRegB(bus, addr, high);
   return h + l;

let logSensor = function() {
  // Print all sensor values which the sensor provides
  // Formated all values as x, y, and z in order for
  // Compass, Gyro, Acceleration. The First value is
  // the temperature.

  let bus = I2C.get();
  let dT = (MPU9150_readSensor(bus, MPU_I2C_ADDRESS, MPU9150_TEMP_OUT_L, MPU9150_TEMP_OUT_H) + 12412.0) / 340.0;
  print(MPU9150_readSensor(bus, MPU_I2C_ADDRESS, MPU9150_CMPS_XOUT_L, MPU9150_CMPS_XOUT_H));
  print(MPU9150_readSensor(bus, MPU_I2C_ADDRESS, MPU9150_CMPS_YOUT_L, MPU9150_CMPS_YOUT_H));
  print(MPU9150_readSensor(bus, MPU_I2C_ADDRESS, MPU9150_CMPS_ZOUT_L, MPU9150_CMPS_ZOUT_H));
  print(MPU9150_readSensor(bus, MPU_I2C_ADDRESS, MPU9150_GYRO_XOUT_L, MPU9150_GYRO_XOUT_H));
  print(MPU9150_readSensor(bus, MPU_I2C_ADDRESS, MPU9150_GYRO_YOUT_L, MPU9150_GYRO_YOUT_H));
  print(MPU9150_readSensor(bus, MPU_I2C_ADDRESS, MPU9150_GYRO_ZOUT_L, MPU9150_GYRO_ZOUT_H));
  print(MPU9150_readSensor(bus, MPU_I2C_ADDRESS, MPU9150_ACCEL_XOUT_L, MPU9150_ACCEL_XOUT_H));
  print(MPU9150_readSensor(bus, MPU_I2C_ADDRESS, MPU9150_ACCEL_YOUT_L, MPU9150_ACCEL_YOUT_H));
  print(MPU9150_readSensor(bus, MPU_I2C_ADDRESS, MPU9150_ACCEL_ZOUT_L, MPU9150_ACCEL_ZOUT_H));

let getInfo = function() {
  return JSON.stringify({
    total_ram: Sys.total_ram(),
    free_ram: Sys.free_ram()

// Blink built-in LED every second
GPIO.set_mode(led, GPIO.MODE_OUTPUT);
Timer.set(1000 /* 1 sec */, true /* repeat */, function() {

  let value = GPIO.toggle(led);
  print(value ? 'Tick' : 'Tock', 'uptime:', Sys.uptime(), getInfo());
}, null);

// Publish to MQTT topic on a button press. Button is wired to GPIO pin 0
GPIO.set_button_handler(button, GPIO.PULL_UP, GPIO.INT_EDGE_NEG, 200, function() {
  let message = getInfo();
  let ok =, message, 1);
  print('Published:', ok, topic, '->', message);
}, null);

// Monitor network connectivity.
Net.setStatusEventHandler(function(ev, arg) {
  let evs = '???';
  if (ev === Net.STATUS_DISCONNECTED) {
    evs = 'DISCONNECTED';
  } else if (ev === Net.STATUS_CONNECTING) {
    evs = 'CONNECTING';
  } else if (ev === Net.STATUS_CONNECTED) {
    evs = 'CONNECTED';
  } else if (ev === Net.STATUS_GOT_IP) {
    evs = 'GOT_IP';
  print('== Net event:', ev, evs);
}, null);


  • SergeySergey Dublin, Ireland

    check i2c section in the config, is it set up correctly?

  • I get this in the boot log:

    ``[Nov 29 11:18:59.371] mgos_i2c_create I2C GPIO init ok (SDA: 12, SCL: 14)

    So it seems to be working.

  • All right - some updates,

    I have tried using Wire compatibility library with the same results. Wire is obvoiusly using mgos_i2c behind the scenes so I think the problem is within the I2C implementation.

    What I find strange is that I can run the setupCompas() function without any problems. However once I start reading a single value, the console get filled with jibberish. I suppose it originates from mgos_i2c code. However, when I look through the code I can't find any code that would output this sort of garbage without prepending it with some string that I should be able to identify in the console.

    More suggestions?

  • It looks like the function MPU9150_readSensor is intended to return a 16 bits value composed of 2 bytes low and high.
    But the return h + l; just adds the 2 bytes.

    I don't know if this is valid in mJS, but I would write return l+(h<<8);

    Thanked by 1fsrc
Sign In or Register to comment.