I2C problems with CMPS01 and Activity Board
Hal Albach
Posts: 747
Trying to get a CMPS01 Compass by Devantech to work on my Prop Activity Board for later use as a navigation device for a bot I'm building. Before trying the activity board I tested it on a BS2 setup and it checked out fine. Even reduced the I2C bus pull up voltage to 3.3 to make it prop friendly without ill effects. The device has an address of 0xC0 and only registers 2 & 3 are read for a compass heading. Surprisingly, the CMPS01 readings were very close to what my compass app on my iPhone 4S was showing. Knowing that it worked I attached it to the Prop Activity Board and cobbled together the following code to test it out. Double checked all the connections, 5 Volts to the compass power and 3.3 Volts to the bus pull ups (2.2K), I loaded the program and.......nothing. Undaunted I got out my o'scope and verified activity on the bus, both were toggling. Next I got out my Saleae Logic analyzer and it immediately showed the problem. The 0xC0 address had become 0x80! The compass was not being addressed and all transmissions from the prop were being nacked. On a hunch I tried address 0xD0 and the analyzer showed it as 0xA0. Several more different addresses showed that the address was off by 1 bit to the left! I the deduced that either 0x60 or 0xE0 should work since shifting both left by one bit yields 0xC0, and I was right, the compass responded and I was able to retrieve readings and display them on the LCD.
I am at a loss as to why the address byte winds up 1 byte to the left. The activity board has no problem using the onboard EEPROM, and with the BS2 set up the compass responded to the 0xC0 address. I ruled out any problem with the compass by removing from the circuit and sending out various addresses on the bus which the analyzer continued to show each address byte off by one bit. I have to have missed something in the I2C setup, but cannot put my finger on it. I'm hoping that someone here may have better insight as to the workings of the I2C protocol under Simpletools. Following is a link for info on the compass and the code, and hopefully a screenshot of the analyzer. http://www.robot-electronics.co.uk/htm/cmpsdoc.shtml
I am at a loss as to why the address byte winds up 1 byte to the left. The activity board has no problem using the onboard EEPROM, and with the BS2 set up the compass responded to the 0xC0 address. I ruled out any problem with the compass by removing from the circuit and sending out various addresses on the bus which the analyzer continued to show each address byte off by one bit. I have to have missed something in the I2C setup, but cannot put my finger on it. I'm hoping that someone here may have better insight as to the workings of the I2C protocol under Simpletools. Following is a link for info on the compass and the code, and hopefully a screenshot of the analyzer. http://www.robot-electronics.co.uk/htm/cmpsdoc.shtml
/* * Test compass.c * CMPS01 * device address is C0 * regs 2&3 contain compass reading 0.0 - 359.9 * * Display is a 16x4 LCD with a Paul Badger serial interface */ #include "simpletools.h" serial *lcd; // serial LCD Declaration //============================================================================== int main() { lcd = serial_open(-1, 12, 0, 9600); // open serial port for LCD Display pause(3000); // let serial LCD get its **** together dprint(lcd, "?f"); // clear screen short bearing = 0; // 2 byte var for compass char temp[2]; // input array for compass reading i2c *cmps01 = i2c_newbus(9, 10, 0); // new bus ID for compass while(1) // Forever loop { low(9); // without this every other reading fails i2c_in(cmps01, 0xE0, 0x02, 1, temp, 2); // device address is actually 0xC0 bearing = ((temp[0] << 8) + temp[1])/10; // combine two bytes to a short and drop LS byte pause(250); // 4 readings per second // display heading on lcd dprint(lcd, "?y3?x08 ?x00Heading %d", bearing); // display on bottom line of 16 x 4 } // ends while(1) } // ends Main()
Comments