+ Post New Thread
Results 1 to 17 of 17
  1. #1
    Junior Member level 1
    Points: 376, Level: 4

    Join Date
    Jul 2017
    Posts
    18
    Helped
    0 / 0
    Points
    376
    Level
    4

    PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C

    I am receiving same value as the output even when I change the orientation of the sensor.
    What could be the reason ?

    1) I send slave address (with write bit).
    2) I send sub address.
    3) I send slave address (with read bit).


    Code:
    void main(void)
    {
        
        TRISC = 0x18; // Set RC3(SCL) and RC4(SDA) as inputs.
        ANSELC = 0;   // In debug mode I can see RC3 and RC4 high after stepping into
                      // this line of code, so I know SDA and SCL are properly pulled
                      // high.
        TRISB = 0;    // Saving received I2C data in PORTB.
        ANSELB = 0;   // After this step the PORTB is filled with the last  
                      // SSPBUF data (0X3C), I find this weird 
     
     RC3PPS = 0X14;   // 
     RC4PPS = 0X15;   // Setting RC3 and RC4 as SCL and SDA pins
     SSP1CON1 = 0X28; // SSPEN - 1, SSPM - 1000
     SSP1ADD = 0X03; // clock frequency 31.25 kHz
     SSP1STAT = 0X80; // SMP - 1
     
     // First write with slave address
     SSP1CON2bits.SEN = 1;  // Start I2C
     
     while (SSP1CON2bits.SEN == 1); // Wait for "START" to finish
     PIR3bits.SSP1IF = 0;           
     SSP1BUF = 0X3C;                // LSM9DS0 Accelerometer address(with write bit)
                                    // Page 33 in LSM9DS0 data sheet
     while((PIR3bits.SSP1IF == 0) && (SSP1STATbits.BF == 1) && (SSP1STATbits.R_nW == 1));
     PIR3bits.SSP1IF = 0;           // Wait for transmission to complete 
     
     // Slave sub Address
     SSP1BUF = 0X2C;                // sub-address of Z-axis acceleration data 
                                    // register, first 8 bits
     while((PIR3bits.SSP1IF == 0) && (SSP1STATbits.BF == 1) && (SSP1STATbits.R_nW == 1));
     PIR3bits.SSP1IF = 0;           // Wait for transmission to complete
     
     // Repeated Start
     SSP1CON2bits.RSEN = 1;        // Repeated Start so that I can start reading the  
                                   // above Z axis data
     while (SSP1CON2bits.RSEN == 1);/* Wait if Transmit in progress */
     PIR3bits.SSP1IF = 0;
     SSP1BUF = 0X3D;               // LSM9DS0 Accelerometer address(with read bit)
                                    // Page 33 in LSM9DS0 data sheet
     while((PIR3bits.SSP1IF == 0) && (SSP1STATbits.BF == 1) && (SSP1STATbits.R_nW == 1));
     PIR3bits.SSP1IF = 0;          // Wait for transmission to complete
     
     SSP1CON2bits.RCEN = 1;        // Enable receive in I2C
     //while ( SSP1CON2bits.RCEN == 1);
     while(SSP1STATbits.BF == 0);
     PIR3bits.SSP1IF = 0;
     PORTB = SSP1BUF;              
     
     SSP1CON2bits.ACKDT = 1;
     SSP1CON2bits.ACKEN = 1;
     while( SSP1CON2bits.ACKEN == 1);
     PIR3bits.SSP1IF = 0;
     
     SSP1CON2bits.PEN = 1;
     while(1);
     
     
    }

  2. #2
    Advanced Member level 1
    Points: 2,419, Level: 11
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    470
    Helped
    45 / 45
    Points
    2,419
    Level
    11

    Re: PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C

    Put the I2C device reading code in main loop. Use a 100 ms delay before main loop.

    I2C clock freuency is 32.78 KHz or 100 KHz ? What is th evalue of I2C bus pullup resistors ?

    PIC16F18877 has LATx registers to output data. Use LATB instead of PORTB.
    Last edited by baileychic; 19th January 2019 at 15:30.


    1 members found this post helpful.

    •   AltAdvertisment

        
       

  3. #3
    Junior Member level 1
    Points: 376, Level: 4

    Join Date
    Jul 2017
    Posts
    18
    Helped
    0 / 0
    Points
    376
    Level
    4

    Re: PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C

    All of my code is in main function. Do you want me to separate the reading code to make it more readable ?

    I2C clock frequency is 31.25 KHz (SSP1ADD = 0X03). Should it necessarily be 32.78 KHz or 100 KHz ?

    10 Kilo Ohms - Pull up registers. The SDA and SCL pins are pulled high since I have verified this in debug mode.

    Sure I'll try LATB instead of PORTB.



  4. #4
    Advanced Member level 1
    Points: 2,419, Level: 11
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    470
    Helped
    45 / 45
    Points
    2,419
    Level
    11

    Re: PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C

    Have you checked I2C application note. Does i tmention that for 32.78 KHZ I2C Clock the I2C bus pullups need to be 10k ?

    You are reading I2C device only at the beginning and before while(1) loop and so you will not get continuous accelerometer readings. If both PIC and LSM9DS0 is powered from the same source then LSM9DS0 might need some 100 ms delay before it can stabilize and provide readings when power is applied. There is no initialization delay in your code. If you put your LSM90DS0 reading code in while(1) loop and move the sensor then you might seeing different readings on PORTB.

    http://www.ti.com/lit/an/slva689/slva689.pdf

    Are you sure that in your PIC the I2C pins are directly available for communication ? My Compilers tells that the I2C pins needs to be remapped.

    Edit:

    I see that you have remapped the pins.

    Try

    Code:
    SLRCONC = 0x00;
    What is your Fosc ? Are you using any PLL ?

    - - - Updated - - -

    PPS needs to be unloacked and then I2C pins needs to be remapped and PPS have to be locked.

    Show your config words configurations. In config words how the PPS unlocking and locking bit is configured ?


    8 MHz Fosc. Can you test this .hex file. Tell me what PORTB displays.
    Last edited by baileychic; 19th January 2019 at 17:29.


    1 members found this post helpful.

  5. #5
    Junior Member level 1
    Points: 376, Level: 4

    Join Date
    Jul 2017
    Posts
    18
    Helped
    0 / 0
    Points
    376
    Level
    4

    Re: PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C

    These are my config settings, You can see - CONFIG 2, one PPS setting is present.

    // PIC16F18877 Configuration Bit Settings

    // 'C' source line config statements

    Code:
    // CONFIG1
    #pragma config FEXTOSC = LP     // External Oscillator mode selection bits (LP (crystal oscillator) optimized for 32.768kHz; PFM set to low power)
    #pragma config RSTOSC = HFINT32 // Power-up default value for COSC bits (HFINTOSC with OSCFRQ= 32 MHz and CDIV = 1:1)
    #pragma config CLKOUTEN = OFF   // Clock Out Enable bit (CLKOUT function is disabled; i/o or oscillator function on OSC2)
    #pragma config CSWEN = OFF      // Clock Switch Enable bit (The NOSC and NDIV bits cannot be changed by user software)
    #pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (FSCM timer disabled)
    
    // CONFIG2
    #pragma config MCLRE = OFF      // Master Clear Enable bit (MCLR pin function is port defined function)
    #pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
    #pragma config LPBOREN = OFF    // Low-Power BOR enable bit (ULPBOR disabled)
    #pragma config BOREN = OFF      // Brown-out reset enable bits (Brown-out reset disabled)
    #pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 1.9V on LF, and 2.45V on F Devices)
    #pragma config ZCD = OFF        // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)
    #pragma config PPS1WAY = OFF    // Peripheral Pin Select one-way control (The PPSLOCK bit can be set and cleared repeatedly by software)
    #pragma config STVREN = OFF     // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will not cause a reset)
    
    // CONFIG3
    #pragma config WDTCPS = WDTCPS_31// WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)
    #pragma config WDTE = OFF       // WDT operating mode (WDT Disabled, SWDTEN is ignored)
    #pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
    #pragma config WDTCCS = HFINTOSC// WDT input clock selector (WDT reference clock is the 31.25 kHz HFINTOSC)
    
    // CONFIG4
    #pragma config WRT = OFF        // UserNVM self-write protection bits (Write protection off)
    #pragma config SCANE = available// Scanner Enable bit (Scanner module is available for use)
    #pragma config LVP = OFF        // Low Voltage Programming Enable bit (High Voltage on MCLR/Vpp must be used for programming)
    
    // CONFIG5
    #pragma config CP = OFF         // UserNVM Program memory code protection bit (Program Memory code protection disabled)
    #pragma config CPD = OFF        // DataNVM code protection bit (Data EEPROM code protection disabled)
    Last edited by bassa; 19th January 2019 at 17:50. Reason: add code tag



  6. #6
    Advanced Member level 1
    Points: 2,419, Level: 11
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    470
    Helped
    45 / 45
    Points
    2,419
    Level
    11

    Re: PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C

    My Compiler tells that for Fosc = 32 MHz, I2C Clock 31.25 KHz is out of range and it doesn't compile.

    Here is Fosc = 32 MHz and I2C Clock - 100 KHz .hex file for testing. Test and reply.



  7. #7
    Junior Member level 1
    Points: 376, Level: 4

    Join Date
    Jul 2017
    Posts
    18
    Helped
    0 / 0
    Points
    376
    Level
    4

    Re: PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C

    Can you please send me the .c file instead of HEX file so that I can do Step-by-Step debugging ?

    I haven't found any specific instruction about using 10k resistors I am just using them. During debugging I can see that SDA and SCL pins go high hence I am concluding that 10k resistors should do fine.

    I am trying to read the sensor only once, hence the while(1) in the end.

    Fosc = 32 MHz. I am not using any PLL.

    Thank You for the efforts you are taking for my solving my problem baileychic!
    Last edited by sr2w; 19th January 2019 at 18:06.



  8. #8
    Advanced Member level 1
    Points: 2,419, Level: 11
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    470
    Helped
    45 / 45
    Points
    2,419
    Level
    11

    Re: PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C

    My Compiler is mikroC PRO PIC. I didn't write code in MPLAB X XC8. Here is my mikroC PRO PIC project. Also view the .asm file which is my Compiler generated .asm code for my C code.

    Change I2C pullups to 4.7k and test my 100 KHz I2C clock code which I posted in this post. Just burn my .hex file to PIC and see if you get any readings.

    Data sheet page 494;

    FClock = Fosc/(4 * SSPxADD+1) = 32 MHz / (4 * 256) = 31250. SSPxADD = 256 - 1 = 255 but for 100 KHz I2C clock

    Fclock = Fosc/(4 * 80) = 100 KHz, SSPxADD = 79 (80 - 1) but my Compiler is generating 80 for SSPxADD. I found value in .asm code generated by mikroC PRO PIC Compiler. So, mikroC PRO PIC uses SSPxADD+1 as SSPxADD value. So, for 31.25 KHz it is 256 and doesn't fit in SSPxADD register and hence mikroC PRO PIC Compiler is generating error while compiling but I have used mikroC PRO PIC Compiler for many I2C projects and it works fine.
    Last edited by baileychic; 19th January 2019 at 18:34.


    1 members found this post helpful.

    •   AltAdvertisment

        
       

  9. #9
    Junior Member level 1
    Points: 376, Level: 4

    Join Date
    Jul 2017
    Posts
    18
    Helped
    0 / 0
    Points
    376
    Level
    4

    Re: PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C

    I don't have 4.7k resistors now. I'll have to go to college for that (day-after-tomorrow).

    I'll read the output on PORTB using LEDs that should be fine right ?



  10. #10
    Advanced Member level 1
    Points: 2,419, Level: 11
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    470
    Helped
    45 / 45
    Points
    2,419
    Level
    11

    Re: PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C

    For SSPxADD = 255 and Fosc = 32 MHz you will get 31.25 KHz I2C Clock. Use that value. So, in your original code SSP1ADD value was wrong.

    Don't configure SSP1STAT. Configure only SSP1ADD and SSP1CON.

    Yes, outputting read I2C data on PORTB Leds will be fine.



  11. #11
    Junior Member level 1
    Points: 376, Level: 4

    Join Date
    Jul 2017
    Posts
    18
    Helped
    0 / 0
    Points
    376
    Level
    4

    Re: PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C

    My debugger gets stuck at the green highlighted line when I set SSP1ADD as 255 (0xFF), when it is 0x03, it doesn't give me such problems.
    Click image for larger version. 

Name:	Capture.JPG 
Views:	3 
Size:	90.2 KB 
ID:	150835



  12. #12
    Advanced Member level 1
    Points: 2,419, Level: 11
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    470
    Helped
    45 / 45
    Points
    2,419
    Level
    11

    Re: PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C

    How did you calculate 0x03 for SSP1ADD ?

    First test the attached project and see if you get any readings on PORTB Leds. I have used 16 MHz HFINTOSC and 31.25 KHz I2C Clock. Just burn my .hex file and test.
    Last edited by baileychic; 19th January 2019 at 19:39.



  13. #13
    Junior Member level 1
    Points: 376, Level: 4

    Join Date
    Jul 2017
    Posts
    18
    Helped
    0 / 0
    Points
    376
    Level
    4

    Re: PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C

    0x03 has stuck along with me since my last code which I wrote for PIC16F1508 proteus simulation. I used to get 31.25 KHz clock set in simulation log(attached picture) if I used SSPADD = 0x03. Using this value for other PIC controller(now 16F18877) is something wrong which I am doing. This lets me easily debug through step-by-step my code.

    I am ready to forget 0x03. 0xFF should be the right answer as we get it from the formula. But then it is creating problems while debugging.
    Click image for larger version. 

Name:	Capture.JPG 
Views:	0 
Size:	87.8 KB 
ID:	150837



  14. #14
    Junior Member level 1
    Points: 376, Level: 4

    Join Date
    Jul 2017
    Posts
    18
    Helped
    0 / 0
    Points
    376
    Level
    4

    Re: PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C

    I am getting zero volts on all port B pins. I have burnt the code using MPLAB. This shouldn't be a problem right ? A hex file should be a hex file right ?



  15. #15
    Junior Member level 1
    Points: 376, Level: 4

    Join Date
    Jul 2017
    Posts
    18
    Helped
    0 / 0
    Points
    376
    Level
    4

    Re: PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C

    I tried using a logic analyzer, but the output doesn't change when I try to read the sensor register with different orientations.
    Click image for larger version. 

Name:	image.png 
Views:	4 
Size:	119.6 KB 
ID:	150894

    Did some variations in code,

    Code:
     void wait()
    {
        while(PIR3bits.SSP1IF == 0);
    PIR3bits.SSP1IF = 0;
    }
    void main()
    {
        
        TRISC = 0x18;
        ANSELC = 0;
        TRISB = 0;
        ANSELB = 0;
     
     RC3PPS = 0X14;
     RC4PPS = 0X15;
     SSP1CON1 = 0X28; // SSPEN - 1, SSPM - 1000
     SSP1ADD = 0X4F; // clock frequency 31.25 kHz
     SSP1STAT = 0X80; // SMP - 1
     
     
     while(1)
     {
     SSP1CON2bits.SEN = 1;
     
     while (SSP1CON2bits.SEN == 1);
     PIR3bits.SSP1IF = 0;
     SSP1BUF = 0X3C; // Slave Add + Write
     wait();
    SSP1BUF = 0X2C; // Slave sub Add
    wait();
    SSP1CON2bits.RSEN = 1;
     while (SSP1CON2bits.RSEN == 1);
     PIR3bits.SSP1IF = 0;
     
     SSP1BUF = 0X3D; // Slave Add + Read
     wait();
     
     
    SSP1CON2bits.RCEN = 1;
    while (SSP1CON2bits.RCEN == 1);
    wait();
     PORTB = SSP1BUF;
     
     SSP1CON2bits.ACKDT = 0;
     SSP1CON2bits.ACKEN = 1;
    while (SSP1CON2bits.ACKEN == 1);
    wait();
    
     
     SSP1CON2bits.PEN = 1;
     __delay_ms(1000);
     
     }
     
    }
    Last edited by sr2w; 30th January 2019 at 08:50.



    •   AltAdvertisment

        
       

  16. #16
    Advanced Member level 4
    Points: 7,367, Level: 20

    Join Date
    Jan 2015
    Posts
    1,035
    Helped
    325 / 325
    Points
    7,367
    Level
    20

    Re: PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C




  17. #17
    Advanced Member level 1
    Points: 2,419, Level: 11
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    470
    Helped
    45 / 45
    Points
    2,419
    Level
    11

    Re: PIC16F18877: Trying to read Accelerometer data from LSM9DS0 on I2C

    Your Oscillator settings might be wrong if yoiu ar egetting 31.25 KhZ I2C clock for SSPADD value 0x03. Are you doing oscillator switching in the code ? Somewhere maybe in another forum thread of yours I saw that you are switching oscillator. Is this right ?



--[[ ]]--