Hi,
We are using the MMA8451Q accelerometer in a project using i2c to communicate with an HCS08 processor. The x, y and z output values are transmitted fine as long as the x axis is a negative g number. We can tilt the board so the other two axis' go negative or positive and the data is still transmitted fine. The moment we tilt the board so that the x-axis goes positive the board starts transmitting 0,0,0 (0 on all three axis). Even if we move the board back so that the x-axis is negative again the board continues to broadcast 0,0,0 and will not resume normal operation until we power it off and back on again.
I have tried four separate chips and they all exhibit the same behaviour. Am I missing something fundamental here? Thanks in advance.
Solved! Go to Solution.
I finally discovered what the problem was.
My code was sending an acknowledge to the accelerometer after every read, including the last (7th) read. I should have sent a Not Acknowledge (i.e. nothing) after the last read. I have no idea why it exhibited itself in this weird x-axis behaviour - but it definitely fixed it (and removing the line reverts back to the broken behaviour.).
The missing line was
IICC_TXAK = 1;
Which suppresses the acknowledge bit on the next read.
Thanks for taking the time to look into it and for the advice.
Pete
See code below:
// Read FMode Register followed by the X MSB, XLSB, YMSB, YLSB, ZMSB and ZLSB registers (7 in total)
IICC_TX=0;
IICC_TXAK=0;
IICD; // Generate clock pulses
delay(6);
accFMode = iic_ReadNextByteOffBus();
accXmsb = iic_ReadNextByteOffBus(); // Read X Most Significant Byte (MSB)
accXlsb = iic_ReadNextByteOffBus(); // Read X Least Significant Byte (LSB)
accYmsb = iic_ReadNextByteOffBus(); // Read Y MSB Byte
accYlsb = iic_ReadNextByteOffBus(); // Read Y LSB Byte
accZmsb = iic_ReadNextByteOffBus(); // Read Z MSB Byte
IICC_TXAK=1; // Don't send an acknowledge bit so that the accelerometer knows this is the last byte
accZlsb = iic_ReadNextByteOffBus(); // Read Z LSB Byte
I finally discovered what the problem was.
My code was sending an acknowledge to the accelerometer after every read, including the last (7th) read. I should have sent a Not Acknowledge (i.e. nothing) after the last read. I have no idea why it exhibited itself in this weird x-axis behaviour - but it definitely fixed it (and removing the line reverts back to the broken behaviour.).
The missing line was
IICC_TXAK = 1;
Which suppresses the acknowledge bit on the next read.
Thanks for taking the time to look into it and for the advice.
Pete
See code below:
// Read FMode Register followed by the X MSB, XLSB, YMSB, YLSB, ZMSB and ZLSB registers (7 in total)
IICC_TX=0;
IICC_TXAK=0;
IICD; // Generate clock pulses
delay(6);
accFMode = iic_ReadNextByteOffBus();
accXmsb = iic_ReadNextByteOffBus(); // Read X Most Significant Byte (MSB)
accXlsb = iic_ReadNextByteOffBus(); // Read X Least Significant Byte (LSB)
accYmsb = iic_ReadNextByteOffBus(); // Read Y MSB Byte
accYlsb = iic_ReadNextByteOffBus(); // Read Y LSB Byte
accZmsb = iic_ReadNextByteOffBus(); // Read Z MSB Byte
IICC_TXAK=1; // Don't send an acknowledge bit so that the accelerometer knows this is the last byte
accZlsb = iic_ReadNextByteOffBus(); // Read Z LSB Byte
Hi Pete,
I have never heard of a similar problem. If you have a logic analyzer or an oscilloscope, could you please share here an image illustrating what is going on the bus? Are you able to read the WHO_AM_I register when the X axis goes positive?
Regards,
Tomas
Thank you Tomas for your quick response. I can confirm that I can read the WHO_AM_I register correctly when the X axis is negative, but as soon as the X axis goes positive the WHO_AM_I register also starts to return 0. Moving the x-axis back negative again does not fix the issue and it continues to read 0 for WHO_AM_I until I do a power off/on on the board.
Unfortunately the components on the printed circuit board (a prototype board) are too small to solder on to or get probes on to, however I have ordered the individual components and will try and replicate the processor-accelerometer part of the circuit on a breadboard. Then I will be able to get the logic analyser on it and I will post a picture of what's happening on the bus.
At least now I know I'm not just missing something obvious :-)
Thank you again. I will probably have the circuit built early next week and will post then.
Update: I just noticed something when applying your test. If I do not read the x,y,z registers (0x00 to 0x06), then I can still read the WHO_AM_I register, even when the x axis is positive. The moment I read the x,y,z registers (with x positive), then all other registers return 0. So, the problem only appears when I try to read the x,y,z registers when x is positive.