PIC16f887 with MMA7455 accelerometer, I2C problem

Discussion in 'The Projects Forum' started by andrei_w, Nov 14, 2011.

  1. andrei_w

    Thread Starter New Member

    Jun 6, 2010
    Hi, I am trying get results with I2C from a MMA7455 accelerometer but i'm stuck. I use MikroC Pro and his library. I have connected the CS pin to VCC, SDA to RC4, SCL to RC3, VCC to VCC and GND to GND. First I want to read the values from the x axis. If the value it would be bigger then "0" i should have a led turned on, else the led should be turned off. I have read the datasheet and I have understood that the address of MMA7455 is 0x0D (please correct me if i'm wrong), and the register of X axis is 0x06( i have tried also 0x00). Because it didn't worked like this i have searched the web and I have found different addreses for the same accelerometer. Some people said that te address is 0x3A or 0x2D, i tried these addresses but it didn't work. Please help me. Here it is the code

    Code ( (Unknown Language)):
    1. // Software I2C connections
    2. sbit Soft_I2C_Scl           at RC3_bit;
    3. sbit Soft_I2C_Sda           at RC4_bit;
    4. sbit Soft_I2C_Scl_Direction at TRISC3_bit;
    5. sbit Soft_I2C_Sda_Direction at TRISC4_bit;
    6. // End Software I2C connections
    8. char X;
    10. void Read_X() {
    12.   Soft_I2C_Start();               // Issue start signal
    13.   Soft_I2C_Write(0x3A);          
    14.   Soft_I2C_Write(0x00);              
    15.   Soft_I2C_Start();               // Issue repeated start signal
    16.   Soft_I2C_Write(0x3B);        
    17.   X = Soft_I2C_Read(0u);    
    18.   Soft_I2C_Stop();
    19. }
    21. void Init_Main() {
    23.   ANSEL  = 0;                // Configure AN pins as digital I/O
    24.   ANSELH = 0;
    25.   C1ON_bit = 0;              // Disable comparators
    26.   C2ON_bit = 0;
    27.   Soft_I2C_Init();           // Initialize Soft I2C communication
    29. }
    32. void main() {                // Main procedure
    33.   Delay_ms(500);
    34.   Init_Main();               // Perform initialization
    36.   while (1) {
    37.     Read_X();
    38.       if (X<0)    
    39.       {  trisb.b5=0;
    40.          portb.b5=1;}
    41.   else              
    42.       {  trisb.b5=1;
    43.          portb.b5=0;}
    44.   }
    45. }
  2. russpatterson


    Feb 1, 2010
    So your problem is that the accelerometer is not responding as you expect and you think that you don't have the proper address to use?
  3. andrei_w

    Thread Starter New Member

    Jun 6, 2010
    yes I think this might be the problem
  4. SgtWookie


    Jul 17, 2007
    Excerpt from page 16 in the datasheet:

    A datasheet:
  5. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    Are you using a PICKit 2?

    Can you put it into logic record mode and see what your I2C bus signals actually are being sent?
  6. russpatterson


    Feb 1, 2010
    @thatoneguy, how do you put a PICKit 2 (or 3) into logic record mode?
  7. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    When it is plugged in, open the PICKit 2 standalone program, click on "Tools", then "Logic Tool" or "UART Debugger".

    There is a standalone program for the PICKit 3, but it only supports programming, no probing or logic injection.
  8. russpatterson


    Feb 1, 2010

    FWIW here's what I have done to find/fix digital communication issues:

    1) You need to be able to verify that you are sending and receiving is the right stuff. If you don't have access to a logic analyzer, I would recommend finding one. They sell a decent USB Logic analyzer, and one analog channel, at SparkFun.com. You could use a scope in a pinch as well. One way or another you need to be able to see what your sending and what is coming back. Read the data sheet and understand exactly what clock and data should look like. Draw the expected clock and data patterns on a piece of paper so you really understand what you're trying to get to happen.

    2) If step one looks good then try another I2C device that you know works and verify your code still makes that work. Sparkfun sells tons of breakout boards that talk I2C, & SPI. Use something like that to verify the rest of your setup. If that part works but not response from your new part then maybe the part got damaged and swap it out.

    There's only so far you can go with this stuff without some test gear.
  9. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    Your addresses for the device are fine. 0x3A is correct to write, 0x3B correct for read per the data sheet SgtWookie linked us to. That is the device I2C address, you must also talk to the registers inside.

    Register 0x00 is the LSB of the X value, read again should increment to address 0x01 to read the higher 2 bits.

    I do not see any register initiation, though it is possible none is required.

    I do not see you calling Soft_I2C_Init(); to turn the soft interface on. That should set the TRIS bits and the initial state.

    I2C is a static interface. meaning you can go as slow as you want. You can debug it with a voltmeter by sending the device address over 8 clocks and see if the 9th clock is hi or low (low means ACK and the slave is saying HI).
  10. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    It is called from main_Init(), which is called 1/2 second into the main loop.

    This is a workable idea, as well.
  11. andrei_w

    Thread Starter New Member

    Jun 6, 2010
    I have used this code with TPA81 sensor and it's working well. The signals on the oscilloscope are ok. I think the hardware it might be broken or this accelerometer have some special settings and i didn't make them. I will buy another accelerometer