I2C Comms with Orientation Sensor

This forum handles questions and discussions concerning Microchip’s MPLAB® Code Configurator (MC2).

I2C Comms with Orientation Sensor

Postby GettinBetter » Sun Nov 03, 2019 3:08 pm

HW: Explorer 16/32, 8MHz, PIC24FJ256GB110 PIM
SW: MPLABX, MCC, terminal via UART1/USB
Slave: BNO055 Absolute Orientation Sensor
Aims: Output data to terminal via UART.

PIN Config:
Debug (PGEC2- pin 26, PGED2 - Pin 27) Previously Tested.
I2C (SCL - Pin 66, SDA - Pin 67)
UART (Tx - 50, Rx out - Pin 49 in ) Previously Tested.

Hi Peeps,
Upgraded my stuff to the above, familiarised myself with pin assignments Oscillator setting etc.
Am now trying to communicate with the sensor using the MCC for the I2C Oscillator & UART.
I've downloaded the Bosch Sensortec Quickstart Manual & Data Sheet as per below...

https://ae-bst.resource.bosch.com/media/_tech/media/application_notes/BST-BNO055-AN007.pdf
https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BNO055-DS000.pdf

and the driver bno055.c, header bno055.h, & support file from
https://github.com/BoschSensortec/BNO055_driver
I'm now trying to create the main.c file with the appropriate calls.....
My issue is linking the bno055.c write bus command to the driver to the MCC created I2c.c

Looking at the I2C.c file the write Bus command is "(I2C1_MasterWrite)" whereas the bno055.c uses "BNO055_I2C_bus_Write"
The quick start suggests creating a struct to hold the device information, but to me (a novice) it looks like it's already done in bno055.h at line 324?
So ......been messing with this for a week now...getting nowhere.

I'm thinking I need to break this down into a really simple single transmission to prove output to the Sensor but linking to the I2C control is mind boggling.

Any thoughts or suggestions would be appreciated.

Regards
Les
History teaches us that history doesn't teach us.
User avatar
GettinBetter
 
Posts: 43
Joined: Wed Jun 06, 2018 8:48 pm

Re: I2C Comms with Orientation Sensor

Postby Roche » Sun Nov 03, 2019 4:11 pm

How about forgetting about the Bosch stuff for the moment and just making sure you can get some data on the bus.
Roche
 
Posts: 72
Joined: Fri Jul 11, 2014 12:35 pm
PIC experience: Professional 5+ years with MCHP products

Re: I2C Comms with Orientation Sensor

Postby GettinBetter » Sun Nov 03, 2019 7:03 pm

Roche wrote:How about forgetting about the Bosch stuff for the moment and just making sure you can get some data on the bus.


Ok, that sounds like the "really simple single transmission" plan... I'll try it.

Thank you.
Regards
Les
History teaches us that history doesn't teach us.
User avatar
GettinBetter
 
Posts: 43
Joined: Wed Jun 06, 2018 8:48 pm

Re: I2C Comms with Orientation Sensor

Postby GettinBetter » Sat Nov 09, 2019 7:52 pm

Hi Guys,
So...I'm attempting to confirm connection to the sensor reading the temperature of the device via I2C. Currently getting compile errors with the way I'm using 'pstatus'.
Links to any files are in the first post.
Any suggestions as to the correct syntax for the errors would be really appreciated.
I've used the MCC to configure the I2C1 & UART1, the UART1 I'm pretty familiar with now and use most of the time without any problems.

Code: Select all
#include "mcc_generated_files/system.h"
#include <libpic30.h> //Defines __delay32();
#include <stdio.h> // Defines printf("");
#include "mcc_generated_files/i2c1.h"
#include "../stdint.h"
#include "mcc_generated_files/i2c1.h"

#define BNO055_I2C_ADDR1      (0x28)    // slave device address from bno055.h line 318
#define BNO055_TEMP_ADDR      (0X34)    // Chip temperature register from bno055.h line 397


uint8_t DataRCVD; // Variable to hold temperature value

int main(void)
{
    // initialize the device
    SYSTEM_Initialize();
//    PIN_MANAGER_Initialize();     // called in system.c
//    INTERRUPT_Initialize();     // called in system.c
//    CLOCK_Initialize();     // called in system.c
//    UART1_Initialize();     // called in system.c
//    I2C1_Initialize();     // called in system.c
   
   
//      Expected format......
//      void I2C1_MasterRead(
//                                uint8_t *pdata,       // This must be where the received info will be saved
//                                uint8_t length,       // number of bytes to be sent
//                                uint16_t address,  //This must be the Slave address
//                                I2C1_MESSAGE_STATUS *pstatus); //status of transaction
   
//    To write or read a 16 bit register in a I2C device, you may use an array of bytes
//    as the "data" argument, and set "length" argument to 2 or what value is needed.
   
   I2C1_MasterRead(BNO055_TEMP_ADDR,1,BNO055_I2C_ADDR1, &pstatus); //Compiler not happy with '&pstatus'

   return (DataRCVD);
   printf("BNO055 Chip Temp is %d3",DataRCVD);

}



main.c:79:58: error: 'pstatus' undeclared (first use in this function)
main.c:79:58: note: each undeclared identifier is reported only once for each function it appears in
main.c:79:4: warning: passing argument 1 of 'I2C1_MasterRead' makes pointer from integer without a cast
mcc_generated_files/i2c1.h:447:6: note: expected 'uint8_t *' but argument is of type 'int'



Regards
Les
History teaches us that history doesn't teach us.
User avatar
GettinBetter
 
Posts: 43
Joined: Wed Jun 06, 2018 8:48 pm

Re: I2C Comms with Orientation Sensor

Postby ric » Mon Nov 11, 2019 12:00 am

Presumably you need to create that pstatus variable for it to write the status to.
e.g. add
Code: Select all
I2C1_MESSAGE_STATUS pstatus;

where you declare your variables.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 659
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products

Re: I2C Comms with Orientation Sensor

Postby GettinBetter » Tue Nov 12, 2019 9:32 pm

ric wrote:Presumably you need to create that pstatus variable for it to write the status to.
e.g. add
Code: Select all
I2C1_MESSAGE_STATUS pstatus;

where you declare your variables.


Ok, so I tried that..no luck. Compiler complained, although maybe I did it wrong, but also it maybe that it's already declared in the i2c files..so after I decided that I'd exhausted that suggestion...

I eventually found some example code from i2c.h file starting on line 489 which describes how to write/read to/from EEPROM, & so attempted to modify it for the BNO055. After all it can't be that different, the BNO access should be faster and it doesn't have 16bit register addresses (least I think it doesn't) but if it does I'll explore the example in the example code.

It now compiles and when uploaded, gives me the first two text responses (that I added for debug) on terminal.

I think at this stage I need to put a scope on the output and see what exactly is being sent. However my scope is and old bulky one with out any storage capacity....might need to invest in a new one.
Before I get around to that I thought I'd ask if any of you guys can see anything really obvious in my abortion of an edit..that sticks out like a sore thumb.

Code: Select all
#include "mcc_generated_files/system.h"
#include <libpic30.h> //Defines __delay32();
#include <stdio.h> // Defines printf("");
#include "mcc_generated_files/i2c1.h"
#include "../stdint.h"
#include "mcc_generated_files/i2c1.h"

#define BNO055_I2C_ADDR1      (0x28)    // slave device address from bno055.h line 318 (addr pin low)
#define BNO055_TEMP_ADDR      (0X34)    // Chip temperature register from bno055.h line 397
#define BNO055_RETRY_MAX       100      // define the retry count
#define BNO055_DEVICE_TIMEOUT  50       // define slave timeout

uint8_t DataRCVD; // Variable to hold temperature value

    // example code from i2c.h line 489 modified for BNO055

            uint8_t BNO055_Read(
                                            uint16_t address,
                                            uint8_t *pData,
                                            uint16_t nCount)
            {
                I2C1_MESSAGE_STATUS status;
                uint8_t     writeBuffer;     // was 3
                uint16_t    retryTimeOut, slaveTimeOut;
                uint16_t    counter;
                uint8_t     *pD;
                printf("0 read initiated.. "); //debug assist - success
                pD = pData;

                for (counter = 0; counter < nCount; counter++)
                {

                    // build the write buffer first
                    // starting address of the EEPROM memory - NOT USING THIS!
                    //writeBuffer = (address >> 8);                // high address - not sure which to use?
                      writeBuffer = (uint8_t)(address);       // low low address
                    // retry sending the transaction
                    retryTimeOut = 0;
                    slaveTimeOut = 0;

                    while(status != I2C1_MESSAGE_FAIL)
                    {
                        // write one byte to BNO055
                        I2C1_MasterWrite(    writeBuffer, // Temperature register address
                                                1,  // was two but BNO temperature register address is 1 byte
                                                BNO055_I2C_ADDR1, // BNO Device address
                                                &status);
                         printf("1 message sent %u", status);//debug assist - success
                       
                        while(status == I2C1_MESSAGE_PENDING) // wait for the message to be sent or status has changed.
                        {
                            // add some delay here
                               __delay32(50000);
                            // timeout checking
                            // check for max retry and skip this byte
                            if (slaveTimeOut == BNO055_DEVICE_TIMEOUT)
                                return (0);
                            else
                                slaveTimeOut++;
                        }

                        if (status == I2C1_MESSAGE_COMPLETE)
                            printf("2 message complete %u", status);//debug assist
                            break;

                        // if status is  I2C1_MESSAGE_ADDRESS_NO_ACK,
                        //               or I2C1_DATA_NO_ACK,
                        // The device may be busy and needs more time for the last
                        // write so we can retry writing the data, this is why we
                        // use a while loop here

                        // check for max retry and skip this byte
                        if (retryTimeOut == BNO055_RETRY_MAX)
                            break;
                        else
                            retryTimeOut++;
                    }

                    if (status == I2C1_MESSAGE_COMPLETE)
                    {

                        // this portion will read the byte from the memory location.
                        retryTimeOut = 0;
                        slaveTimeOut = 0;

                        while(status != I2C1_MESSAGE_FAIL)
                        {
                            // write one byte to EEPROM (2 is the count of bytes to write)
                            I2C1_MasterRead(     pD,
                                                    1,
                                                    BNO055_I2C_ADDR1,
                                                    &status);

                           
                            while(status == I2C1_MESSAGE_PENDING) // wait for the message to be sent or status has changed.
                            {
                                // add some delay here
                                   __delay32(50000);
                                // timeout checking
                                // check for max retry and skip this byte
                                if (slaveTimeOut == BNO055_DEVICE_TIMEOUT)
                                    return (0);
                                else
                                    slaveTimeOut++;
                            }

                            if (status == I2C1_MESSAGE_COMPLETE)
                                break;

                            // if status is  I2C1_MESSAGE_ADDRESS_NO_ACK,
                            //               or I2C1_DATA_NO_ACK,
                            // The device may be busy and needs more time for the last
                            // write so we can retry writing the data, this is why we
                            // use a while loop here

                            // check for max retry and skip this byte
                            if (retryTimeOut == BNO055_RETRY_MAX)
                                break;
                            else
                                retryTimeOut++;
                        }
                    }

                    // exit if the last transaction failed
                    if (status == I2C1_MESSAGE_FAIL)
                       
                    {
                        printf("3 message failed %u", status);//debug assist
                        return(0);
                        break;
                    }

                    pD++;
                    address++;

                }
                return(1);
                DataRCVD = &pD;
            }

int main(void)
{
    // initialize the device
    SYSTEM_Initialize();
//    PIN_MANAGER_Initialize();     // called in system.c
//    INTERRUPT_Initialize();     // called in system.c
//    CLOCK_Initialize();     // called in system.c
//    UART1_Initialize();     // called in system.c
//    I2C1_Initialize();     // called in system.c
   
 __delay32(5000);
   
    printf("Explorer 16/32, 8MHz, PIC24FJ256GB110 \n\r");
    printf("MPLABX, MCC, UART1/USB  \n\r");
    printf("BNO055 temperature out to terminal test - 11-11-19 \n\n\r");
     
   while(1)
   {
        BNO055_Read(BNO055_TEMP_ADDR,BNO055_I2C_ADDR1,10); // why 10? good question, I had to start somewhere.
        __delay32(50000);
        printf("   BNO055 Temp is  %03u\r", DataRCVD);
   }
}


Output on terminal is..

0 Read Initiated.. 1 1 Message Sent 1 BNO055 Temp is 000

The '1' after Initiated & Sent is the status, although I've no idea what it means.

Any thoughts or comments appreciated.
History teaches us that history doesn't teach us.
User avatar
GettinBetter
 
Posts: 43
Joined: Wed Jun 06, 2018 8:48 pm

Re: I2C Comms with Orientation Sensor

Postby ric » Tue Nov 12, 2019 10:22 pm

GettinBetter wrote:Ok, so I tried that..no luck. Compiler complained,

It's really hard to help if you don't report WHAT the compiler said.

I think at this stage I need to put a scope on the output and see what exactly is being sent.

That's always a good idea.


I've never used MCC, so am not sure of the "right" way to do it.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 659
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products

Re: I2C Comms with Orientation Sensor

Postby Roche » Wed Nov 13, 2019 10:57 am

I can really recommend the Salae logic analysers for IIC work. Integrated protocol decoding. Be careful that the one you select is up to the speed you run the bus at though.
Roche
 
Posts: 72
Joined: Fri Jul 11, 2014 12:35 pm
PIC experience: Professional 5+ years with MCHP products

Re: I2C Comms with Orientation Sensor

Postby GettinBetter » Tue Nov 19, 2019 10:27 pm

ric wrote:It's really hard to help if you don't report WHAT the compiler said.

Ah, sorry about that ric (I'll make a point of adding precise compiler comments in the future), TBH I had tried various options at fixing the pointer issue before posting, then tried again after reading your post, but things quickly moved on, so I couldn't remember. The arguments for the I2C_MasterWrite was expecting a pointer, and I hadn't got my code/syntax correct. I know you're not too keen on the MCC, but it creates lots of code that I can explore, and use as an example. Then get out my C references and dig in to the basics, and swat up. When I think I understand I try to fix the problem. Emphasis on the 'try'.
Here's where I am at the moment....

Code: Select all
//#define BNO_I2C_ADDR1         (0x28)
//#define BNO055_TEMP_ADDR      (0X34)    // Chip temperature register from bno055.h line 397
#define BNO055_RETRY_MAX       100      // define the retry count
#define BNO055_DEVICE_TIMEOUT  50       // define slave timeout

uint8_t *DataRCVD; // Variable to hold temperature value
uint8_t *pstatus;
    // see example code from i2c.h line 489 modified for BNO055

int main(void)
{
    SYSTEM_Initialize();
   
 __delay32(50000);
   
    printf("Explorer 16/32, 8MHz, PIC24FJ256GB110 \n\r");
    printf("MPLABX, MCC, UART1/USB  \n\r");
    printf("BNO055 temperature out to terminal test - 11-11-19 \n\n\r");
     

   
   while(1)
   {
        //write address of (register to read from) to device at address 0x34
       // to device address 0x28
       I2C1_MasterWrite(0x34,1,0x28,&pstatus);
       
         __delay32(50000);
       
        // read from device at address 0x28 and assign it to DataRCVD
        I2C1_MasterRead(&DataRCVD,1,0x28,&pstatus);

         __delay32(50000);
       
        printf("  BNO055 Temp is  %u , Status is: %u\r", DataRCVD,pstatus);
   }
}



LIST OF WARNINGS
Code: Select all
main.c:78:8: warning: passing argument 1 of 'I2C1_MasterWrite' makes pointer from integer without a cast
mcc_generated_files/i2c1.h:274:6: note: expected 'uint8_t *' but argument is of type 'int'
main.c:78:8: warning: passing argument 4 of 'I2C1_MasterWrite' from incompatible pointer type
mcc_generated_files/i2c1.h:274:6: note: expected 'enum I2C1_MESSAGE_STATUS *' but argument is of type 'uint8_t **'
main.c:83:9: warning: passing argument 1 of 'I2C1_MasterRead' from incompatible pointer type
mcc_generated_files/i2c1.h:447:6: note: expected 'uint8_t *' but argument is of type 'uint8_t **'
main.c:83:9: warning: passing argument 4 of 'I2C1_MasterRead' from incompatible pointer type
mcc_generated_files/i2c1.h:447:6: note: expected 'enum I2C1_MESSAGE_STATUS *' but argument is of type 'uint8_t **'
main.c:87:9: warning: format '%u' expects type 'unsigned int', but argument 2 has type 'uint8_t *'
main.c:87:9: warning: format '%u' expects type 'unsigned int', but argument 3 has type 'uint8_t *'


Roche wrote:I can really recommend the Salae logic analysers for IIC work. Integrated protocol decoding. Be careful that the one you select is up to the speed you run the bus at though.

Ah, Plugged my old one in and thought I'd just see what its reading, as the program is looping I'd still get to see something. After half an hour there was this horrible burning smell... need I say more....
I had actually ordered an oscilloscope, main title said (Model x = 200MHz) but spotted a discrepancy in the description text which that what would be delivered in the 'package' was (model y = 70MHz) I immediately cancelled and reported the advert to ebay, once I got the cancellation confirmation, I looked up the analyser option and bought one (Saleae Logic 16). Plugged it in for a quick test and connected it to the UART pin as I know that's working, and got the expected output. However I got diddly squat out of the I2C SCL or SDA pins. Both pins are pulled high through the resistors on the BNO board, so need to find out why the start condition isn't happening.
As usual guys your help and comments are always appreciated
Regards
Les
History teaches us that history doesn't teach us.
User avatar
GettinBetter
 
Posts: 43
Joined: Wed Jun 06, 2018 8:48 pm

Re: I2C Comms with Orientation Sensor

Postby ric » Tue Nov 19, 2019 10:37 pm

your code wrote:I2C1_MasterWrite(0x34,1,0x28,&pstatus);

error message wrote:main.c:78:8: warning: passing argument 1 of 'I2C1_MasterWrite' makes pointer from integer without a cast

Surely the first parameter is meant to be a pointer to a buffer of data to write. You can't pass "0x34" as a pointer.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 659
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products

Next

Return to MPLAB® Code Configurator

Who is online

Users browsing this forum: No registered users and 4 guests