Shop OBEX P1 Docs P2 Docs Learn Events
I2C problems with CMPS01 and Activity Board — Parallax Forums

I2C problems with CMPS01 and Activity Board

Hal AlbachHal Albach Posts: 747
edited 2014-10-13 06:43 in Learn with BlocklyProp
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
/*
 * 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()



screenshot.jpg
1024 x 542 - 55K

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2014-10-12 23:34
    The Simple Library code expects in fact a 7bit address for I2C and shifts it internally by 1. IOW you should pass 0x60 instead of 0xC0. Personally I prefer the 8bit (pre-shifted) version (with LSBit cleared).
  • Hal AlbachHal Albach Posts: 747
    edited 2014-10-13 06:43
    Thank you, Kuroneko, for returning sanity back into my lost weekend. After reading your post I quickly referred to the DIY I2C tutorial and sure enough, it does use a 7 bit address. I replaced 0xC0 with 0b1100000 and the program works!
Sign In or Register to comment.