I just spent all morning trying control a new I2C sensor. It is the AS5601 Hall Effect Rotation Encoder.
It is a nice chip, simp 3.3v or 5.v Vcc, I2C interface with A B Encoder outputs.
my problem: I could not get reliable Writes and Reads. Some would work, others would fail.
The AS5601 can almost be sequentially accessed. Unless you specifically set the 'register pointer' a couple of pot holes.
Basically, if you directly access register 0x0C, 0x0E, 0x1B the chip will loop the register point in a special manner. If you specify 0x0C, it will automatically increment to 0x0D then automagically back to 0x0C. If you specifiy 0x00 to 0x0B it will respond differently; It will NOT automagically loop! The same pattern exists of 0x0E and 0x1B.
#rant ON
Now the REAL hair puller. Say I want to write the value 0x09fA into register 0x01:
Wire.begintransmission(EncoderAddress);
Wire.write(0x01);
Wire.write(0x09);
Wire.write(0xFA);
Wire.endTransmission();
does Anyone see the problem here? The device uses an 8bit address pointer, so Everything looks good right?
Well, This stupid GCC compiler decide my constants are WORDS and the Wire.h library kindly has many overloaded write() members.
This is the one that KILLED my MORNING!
inline size_t write(int n) { return write((uint8_t*)&n,sizeof n); }
Since the compiler decided my constant was a word (2 bytes) it amplified my single Wire.write() call into effectively two **Wire.write()**calls.
The I2C buss had this stream on it.
[EncoderAddress] 1 0 9 0 FA 0
It is no wonder that my Encoder was going crazy!
So the moral of the story is always Type Cast constants!
Wire.begintransmission(EncoderAddress);
Wire.write((uint8_t)0x01);
Wire.write((uint8_t)0x09);
Wire.write((uint8_t)0xFA);
Wire.endTransmission();
#rant Off
Chuck