boylesg:
I changed my I2C readReg(...) to the following to try and get more info.
bool CSensor::dataReady(uint8_t nNumBytes)
{
uint32_t nMillisStart = millis(), nDeltaMillis = 0;
m_nWireError = 0;
while ((Wire.available() < nNumBytes) && (m_nWireError == 0))
{
Serial.println(nDeltaMillis);
Serial.println(Wire.available());
Serial.println(m_nI2CTimeOut);
Serial.println("");
nDeltaMillis = millis() - nMillisStart;
if (nDeltaMillis > m_nI2CTimeOut)
m_nWireError = 5;
}
return m_nWireError == 0;
}
uint8_t CSensor::readReg8(uint8_t nRegAddr)
{
uint8_t nValue = 0;
Wire.beginTransmission(m_nDevAddrRead);
#if ARDUINO >= 100
Wire.write(nRegAddr);
#else
Wire.send(nRegAddr);
#endif
m_nWireError = Wire.endTransmission();
if (m_nWireError == 0)
{
Wire.requestFrom(nRegAddr, (uint8_t)1);
if (dataReady(1))
{
#if ARDUINO >= 100
nValue = Wire.read();
#else
nValue = Wire.receive();
#endif
m_nWireError = Wire.endTransmission();
Serial.println("@@@@@@@@@@@@@@@@@@@@@");
Serial.println(nRegAddr, HEX);
Serial.println(m_nDevAddrRead, HEX);
Serial.println("");
Serial.println(m_nWireError);
Serial.println("");
Serial.println(nValue, HEX);
Serial.println("@@@@@@@@@@@@@@@@@@@@@");
}
else
m_nWireError = 5;
}
return nValue;
}
In the serial monitor that dataReady(...) function counts all the way up to 2000 ms with wire.available() always returning 0.
So I just don't get it.
What is the fundamental difference between my code and the code above from the similar code in the LSM303 library that does work with my device????? I just can't see it!
// Reads the 3 accelerometer channels and stores them in vector a
void LSM303::readAcc(void)
{
Wire.beginTransmission(acc_address);
// assert the MSB of the address to get the accelerometer
// to do slave-transmit subaddress updating.
Wire.write(OUT_X_L_A | (1 << 7));
last_status = Wire.endTransmission();
Wire.requestFrom(acc_address, (byte)6);
unsigned int millis_start = millis();
while (Wire.available() < 6) {
if (io_timeout > 0 && ((unsigned int)millis() - millis_start) > io_timeout)
{
did_timeout = true;
return;
}
}
byte xla = Wire.read();
byte xha = Wire.read();
byte yla = Wire.read();
byte yha = Wire.read();
byte zla = Wire.read();
byte zha = Wire.read();
// combine high and low bytes
// This no longer drops the lowest 4 bits of the readings from the DLH/DLM/DLHC, which are always 0
// (12-bit resolution, left-aligned). The D has 16-bit resolution
a.x = (int16_t)(xha << 8 | xla);
a.y = (int16_t)(yha << 8 | yla);
a.z = (int16_t)(zha << 8 | zla);
}
Your are not using the Arduino's I2C Wire.h library correctly.
// to send data to a device.
Wire.beginTransmission(byte); // address of I2C (7bit value 0x08 .. 0x78) 0x00..0x07 and 0x79..0x7F are reserved for special function, You can uses them at your parel.
Wire.write(byte); // the byte to send, limited to 31 bytes at a time.
Wire.endTransmission(); // actually do the I2C transaction.
//to Receive data from a device
Wire.requestFrom(byte,byte); // the first byte is the 7bit I2C address, the Second is howmany byte to request.
// a maximum to 31 is possible at one time.
while(Wire.available()){ // available returns a count of bytes in input buffer
char ch = Wire.read();
}
Don't put Wire.endTransmission() after Wire.requestFrom().
Chuck.