Function not successfully reading sensor registers I'm trying to write a library for an accelerometer/magnetometer sensor.  The sensor is a LSM303D chip (https://www.pololu.com/file/0J703/LSM303D.pdf).

I've written a function, readRegister() (below) that's supposed to get the data from the sensor.  However, I put in many different registers into the function into the function, but it always returns the same number.  That number changes every time I unplug my Arduino from my computer.

byte fp::readRegister(byte register_address, int numBytes) {
  Wire.requestFrom(register_address, numBytes);
  byte c;
  Serial.println(Wire.read());
  while (Wire.available()) {
    c = Wire.read();
  }
  Serial.print("0x");
  Serial.print(register_address, HEX);
  Serial.print("\t");
  Serial.print(c);
  Serial.print("\t");
  Serial.println(millis());
  return c;
}


Here's an example of the problem output:

0x8 190 2 
0x9 190 3
0xA 190 11


And here is something more like what I'd expect:

0x8 193 [time]
0x9 189 [time]
0xA 195 [time]


Here is the Git repo with the rest of the code: https://github.com/fpdotmonkey/fp_accel

Thank you in advance for your help.
Wire.requestFrom(register_address, numBytes);
  byte c;
  Serial.println(Wire.read());
  while (Wire.available()) {
    c = Wire.read();
  }


This has a number of problems. For one thing your (I presume) debugging print consumes the data from Wire.read, so when you go to get it into c, you have already printed it. In other words, you are reading byte #1 and printing it, but using byte #2. This seems an odd thing to do.

Next, what is this doing?

  while (Wire.available()) {
    c = Wire.read();
  }


You are reading an indefinite number of bytes, and retaining the last one. Why?

Possible rework:

byte fp::readRegister(byte register_address, int numBytes) {
  Wire.requestFrom(register_address, numBytes);
  byte c = Wire.read()
  Serial.println(c);
  Serial.print("0x");
  Serial.print(register_address, HEX);
  Serial.print("\t");
  Serial.print(c);
  Serial.print("\t");
  Serial.println(millis());
  return c;
}





  Here is the Git repo with the rest of the code: https://github.com/fpdotmonkey/fp_accel


From your linked code:

  byte xlm = readRegister(fp::OUT_X_L_M, 1);
  byte xhm = readRegister(fp::OUT_X_H_M, 1);
  byte ylm = readRegister(fp::OUT_Y_L_M, 1);
  byte yhm = readRegister(fp::OUT_Y_H_M, 1);
  byte zlm = readRegister(fp::OUT_Z_L_M, 1);
  byte zhm = readRegister(fp::OUT_Z_H_M, 1);


You have the wrong end of the stick here.

  Wire.requestFrom(register_address, numBytes);


You request from the I2C address - that is the device address. The register is something else.

Judging by the datasheet you first have to send the register address, and then request the data. Something along the lines of:

byte fp::readRegister(byte register_address, int numBytes) {
  Wire.beginTransmission (DEVICE_ADDRESS);
  Wire.write (register_address);
  Wire.endTransmission (false);  // repeated start
  Wire.requestFrom(DEVICE_ADDRESS, 1);
  byte c = Wire.read()
  Serial.println(c);
  Serial.print("0x");
  Serial.print(register_address, HEX);
  Serial.print("\t");
  Serial.print(c);
  Serial.print("\t");
  Serial.println(millis());
  return c;
}


Similarly for writing to a register:

void fp::writeRegister(byte register_address, byte val) {
  Wire.beginTransmission(DEVICE_ADDRESS);
  Wire.write (register_address);
  Wire.write(val);
  Wire.endTransmission();
}


This is untested because I don't have the device here, but I know that what you had won't work. To check the actual device address run the I2C scanner I mentioned before.