Trouble Writing To Mini-IMU 9v2 Register - Node.js C++ Addon

Hi,

I’m working on an I2C addon for Node.js (on raspberry pi), and I’m having trouble writing to a register.
I’m using the mini-imu 9v2 as a test device.

I can read values without problem, and writing seems to work ok, it’s just that the value doesn’t change.
I’m probably doing something wrong in my i2c code in c++, but I just can’t see what it is.

I’m attempting to enable the device by writing 0xF to the register at 0x20.

Any help would be greatly appreciated :slight_smile:

Here’s the output of my code:

Created i2c object
Set Device: 0:6B
Read from 0x20: 7
Write to 0x20: F
Read from 0x20 7

Here’s the c++ code to actually perform the read/writes:

/**
 * Set the i2c device to be accessed
 * @param int i2c bus number
 * @param int i2c device address
 * @return String device address or error message
 */
Handle<Value> SetDevice(const Arguments& args) {
  HandleScope scope;
  
  busNum = args[0]->Int32Value();
  v8::Local<String> busTitle = args[0]->ToString();
  
  deviceAddress = args[1]->Int32Value();
  char deviceTitle[1]; 
  sprintf(deviceTitle, "%X", deviceAddress);
  
  v8::Local<String> addressTitle = String::Concat(String::Concat(busTitle, String::New(":")), String::New(deviceTitle));
  
  if (busNum != 0 && busNum != 1) {  // TODO: better validation
    return scope.Close(String::New("Unknown I2C Bus"));
  }
  
  // Open i2c bus
  if(( i2c_bus = open( "/dev/i2c-0", O_RDWR )) < 0 )  // TODO: fix hardcoded device address
  { 
    return scope.Close(String::New("Unable to open file /dev/i2c-0.\n"));
  }
  
  // Set the device address
  if( ioctl( i2c_bus, I2C_SLAVE, deviceAddress ) < 0 )
  { 
    return scope.Close(String::New("Open Device FAILED"));
  }
  
  return scope.Close(String::Concat(String::New("Set Device: "), addressTitle));
}

/**
 * Read a value from a regiser
 * @param int register address
 * @param int num bytes to read
 * @return String the value of the register, or error message
 */
Handle<Value> Read(const Arguments& args) {
  HandleScope scope;
  char buf[32];
  buf[0] = args[0]->Int32Value();
  int readSize = args[1]->Int32Value();
  
  // Set the device register to read from
  if ((write(i2c_bus, buf, 1)) != 1) {
    return scope.Close(String::New("Set register to read from failed"));
  }

  // Read from the device register into the buffer
  if (read(i2c_bus, buf, readSize) != readSize) {
    return scope.Close(String::New("Reading after write to register failed"));
  }

  // Return the result as a string
  char result[3];
  sprintf(result, "%X",buf[0]);
  return scope.Close(String::New(result));
}

/**
 * Write a value to a register
 * @param int register address
 * @param int value to write
 * @return String the value written to the register or error message
 */
Handle<Value> Write(const Arguments& args) {

  HandleScope scope;

  char buf[1];
  buf[0] = args[0]->Int32Value();
  int writeSize = 1;  // TODO: fix hardcoded value size

  // Set the device register to write to
  if ((write(i2c_bus, buf, 1)) != 1) {
    return scope.Close(String::New("Set register to write to failed"));
  }

  buf[0] = args[1]->Int32Value();

  // Write to the device register
  if (write(i2c_bus, buf, writeSize) != writeSize) {
    return scope.Close(String::New("Write to register failed"));
  }

  char writeVal[1];
  sprintf(writeVal, "%X", buf[0]);

  return scope.Close(String::New(writeVal));
}

I would imagine that you have to write everything in a single transaction on the bus.
Pack the register address and data into a single char[] array and write it with a single write() call.

Hello. You might want to try my simple example code for the Raspberry Pi and MinIMU-9 v2 from this blog post. It does not write any data to the device, but it does read the “Who Am I?” register:

blog.davidegrayson.com/2012/06/u … ry-pi.html

However, it might be easier for you to just use libi2c. That’s what I do in my I2CBus class, which is part of the minimu9-ahrs program:

github.com/DavidEGrayson/minimu … I2CBus.cpp

I recommend trying minimu9-ahrs on your Raspberry Pi to see if it works. Then you can take whatever pieces of it that you need.

–David

Hi All,

Thanks very much for your replies. Got it working now.
I tried the single write approach (suggested by jwatte), but no luck there.

Using libi2c resolved the issue. Specifically, replacing the direct write() calls with i2c_smbus_write_byte_data() was all I needed to do.

Thanks again for your help, I’m a bit of a noob when it comes to electronics/hardware programming :slight_smile:
Lime