Problems with I2C

General discussion on mikroC PRO for ARM.
Post Reply
Author
Message
Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

Problems with I2C

#1 Post by Sobrietytest » 10 Feb 2018 06:32

I have been using a Bosch IMU as part of a system that I'm building, up until recently I was using a PIC but, for various reasons, I need to upgrade the system to STM32.

I had no problems reading data from the IMU with the PIC but I cannot get the ARM to read the data.

This is the PIC code first, the device address is 0x28 but this is bit shifted left and the R/W bit appended, hence 0x50 and 0x51...

Code: Select all

void Read_Data(){

    I2C2_Start();
    I2C2_Wr(0x50);
    I2C2_Wr(reg1);
    I2C2_Repeated_Start();
    I2C2_Wr(0x51);
    GravByte = I2C2_Rd(0);
    I2C2_Stop();
    Gravity = (Gravity + GravByte);
    Gravity = (Gravity << 8);

    I2C2_Start();
    I2C2_Wr(0x50);
    I2C2_Wr(reg2);
    I2C2_Repeated_Start();
    I2C2_Wr(0x51);
    GravByte = I2C2_Rd(0);
    I2C2_Stop();

    NewGrav = (Gravity | GravByte);
    NewGrav = (NewGrav/16);

    //OldHeading = NewHeading;
    IntToStr(NewGrav, GravStr);
  

    writebuff[0] = x;           // Selects whether first byte will be H, R or P
    //writebuff[1] = 0x3A;
    for (y = 1; y < 8; y++){
        writebuff[y] = GravStr[y + 1];
    }

  while((!HID_Write(writebuff,64));
}
And now this is the ARM code which is trying to do exactly the same thing. Note that compiler automatically sets the R/W bit so the device address remains at 0x28.

Code: Select all

void Read_IMU_Data(){
    I2C_Set_Active(&I2C2_Start, &I2C2_Read, &I2C2_Write); // Sets the I2C2 module active
    
    // Read the first register byte...
    I2C2_Start();
    I2C2_Write(0x28, reg1, 1, END_MODE_RESTART);
    I2C2_Read(0x28, I2CReadByte, 1, END_MODE_STOP);
    MSAngle = (MSAngle + I2CReadByte);
    MSAngle = (MSAngle << 8);

    // Read the second register byte...
    I2C2_Start();
    I2C2_Write(0x28, reg2, 1, END_MODE_RESTART);
    I2C2_Read(0x28, I2CReadByte, 1, END_MODE_STOP);
    Angle = (MSAngle | I2CReadByte);
    Angle = (Angle/16);

    IntToStr(Angle, AngleStr);

    writebuff[0] = x;           // Selects whether first byte will be H, R or P
    for (y = 1; y < 8; y++){
        writebuff[y] = AngleStr[y + 1];
    }

  while(!HID_Write(writebuff,64));

}
In each case the data is sent over USB and can be read on an HID terminal, the PIC outputs something like 'H185 R-2 P15' depending on the position of the board, the ARM outputs 'H0 R0 P0' regardless.

Any ideas?

ST.

saschech
Posts: 298
Joined: 04 Sep 2012 07:13
Location: Schechingen Germany

Re: Problems with I2C

#2 Post by saschech » 12 Feb 2018 14:27

hello
have a look to:

help >> help >> index >> i2c

regards wolfgang
Attachments
i2c help.PNG
i2c help.PNG (130.65 KiB) Viewed 3962 times

Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

Re: Problems with I2C

#3 Post by Sobrietytest » 12 Feb 2018 14:59

Hi Wolfgang,

I'm running this firmware on a Clicker 2 for STM32, the two I2C pins are on PB10(SCL) and PB11(SCA), these relate to I2C channel 2.

I have initialised this using the standard 100kbps bit rate as follows...

Code: Select all

void SystemInit(){

  I2C2_Init();                      // Initialises the I2C2 module at PB10/11
  IMU_Init();                       // Runs the IMU configuration

}
This is the same bit rate used with the earlier PIC configuration. Perhaps I should have made that clear in my original post.

ST

User avatar
lana.arsic
mikroElektronika team
Posts: 1715
Joined: 15 Jan 2016 12:50

Re: Problems with I2C

#4 Post by lana.arsic » 13 Feb 2018 18:14

Hi,

Which exactly module are you using?
You may find useful example bellow:

https://libstock.mikroe.com/projects/vi ... mu-2-click

Kind regards,
Lana

Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

Re: Problems with I2C

#5 Post by Sobrietytest » 15 Feb 2018 11:13

Hi Lana,

I am using the Bosch BNO055 on a breakout board from Adafruit, this has the ability to output Heading, Pitch and Roll angles from it's internal fusion algorithm.

The calling function sets the register addresses (reg1 & reg2) and the Read_IMU_Data() function should retrieve the data, convert to ASCII and send it over USB.

As I mentioned, this works very well with the PIC but I cannot figure out why the ARM I2C doesn't!

ST.

User avatar
lana.arsic
mikroElektronika team
Posts: 1715
Joined: 15 Jan 2016 12:50

Re: Problems with I2C

#6 Post by lana.arsic » 20 Feb 2018 17:47

Hi,

Unfortunately, I don't have that board so I cannot try your code.
But you can try to use this example, it also uses BNO055:

https://libstock.mikroe.com/projects/vi ... ck-library

If you still have issues, I suggest you to try your code through debug.

Kind regards,
Lana

Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

Re: Problems with I2C

#7 Post by Sobrietytest » 24 Feb 2018 13:35

Hi Lana,

Thanks for the suggestion but that code package is incomplete - and useless - why is it even on Libstock???

I expected better from ME.

ST.

lololafripouille
Posts: 231
Joined: 25 Mar 2014 17:11

Re: Problems with I2C

#8 Post by lololafripouille » 25 Feb 2018 10:47

Hello,

I made some test with this library and a STM32F405 on a custom design without problem so I don't understand your problem.

Can you share your project to see what is going wrong ?

Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

Re: Problems with I2C

#9 Post by Sobrietytest » 26 Feb 2018 13:19

Okay, this is the code in its entirety...

Code: Select all


  char readbuff[64];
  char writebuff[64];
  char cnt;
  char x;
  char y;
  char I2CReadByte;
  char reg1;
  char reg2;
  int MSAngle;
  int Angle;
  char AngleStr[7];
  char test[4];
  
void USB0Interrupt() iv IVT_INT_OTG_FS{
  USB_Interrupt_Proc();
}

void IMU_Init(){
  // Initialises the Bosch IMU, on power up the Page ID defaults to 0
  // Remember that the I2C Lib automatically bitshifts the slave address to
  // the left and appends the R/W bit, i.e. it stays 0x28 not 0x50/0x51


// Sets the default register page to Page 0
  I2C2_Start();
  I2C2_Write(0x28, 0x07, 1, END_MODE_RESTART);
  I2C2_Write(0x28, 0x00, 1, END_MODE_STOP);
  Delay_ms(50);

// Sets power mode to Normal on power up
  I2C2_Start();
  I2C2_Write(0x28, 0x3E, 1, END_MODE_RESTART);
  I2C2_Write(0x28, 0x00, 1, END_MODE_STOP);
  Delay_ms(50);

// Sets the operation mode to NDOF w/fast magnetometer calibration
  I2C2_Start();
  I2C2_Write(0x28, 0x3D, 1, END_MODE_RESTART);
  I2C2_Write(0x28, 0x0C, 1, END_MODE_STOP);
  Delay_ms(50);

// Opens the axis remapping configuration
  I2C2_Start();
  I2C2_Write(0x28, 0x41, 1, END_MODE_RESTART);
  I2C2_Write(0x28, 0x21, 1, END_MODE_STOP);
  Delay_ms(50);

// Sets the axis polarity
  I2C2_Start();
  I2C2_Write(0x28, 0x42, 1, END_MODE_RESTART);
  I2C2_Write(0x28, 0x04, 1, END_MODE_STOP);
  Delay_ms(50);

// Sets the working units to metric/degrees
  I2C2_Start();
  I2C2_Write(0x28, 0x3B, 1, END_MODE_RESTART);
  I2C2_Write(0x28, 0x00, 1, END_MODE_STOP);
  Delay_ms(50);

}

void SystemInit(){

  // Initialises the I2C2 module at PB10/11
  I2C2_Init_Advanced(100000,&_GPIO_MODULE_I2C2_PB10_11);
  delay_ms(20);
  
  IMU_Init();                       // Runs the IMU configuration

}

void Read_IMU_Data(){
    I2C_Set_Active(&I2C2_Start, &I2C2_Read, &I2C2_Write); // Sets the I2C2 module active

    I2C2_Start();

    I2C2_Write(0x28, reg1, 1, END_MODE_RESTART);
    I2C2_Read(0x28, I2CReadByte, 1, END_MODE_STOP);

    MSAngle = (MSAngle + I2CReadByte);
    MSAngle = (MSAngle << 8);

    I2C2_Start();

    I2C2_Write(0x28, reg2, 1, END_MODE_RESTART);
    I2C2_Read(0x28, I2CReadByte, 1, END_MODE_STOP);
    Angle = (MSAngle | I2CReadByte);
    Angle = (Angle/16);

    IntToStr(Angle, AngleStr);

    writebuff[0] = x;           // Selects whether first byte will be H, R or P
    for (y = 1; y < 8; y++){
        writebuff[y] = AngleStr[y + 1];
    }

  while(!HID_Write(writebuff,64));

}

void Read_HRP(){      // Read heading, roll & pitch

      x = 0x48;       // 'H'
      reg1 = 0x1B;    //Heading registers
      reg2 = 0x1A;
      Read_IMU_Data();

      x = 0x52;       // 'R'
      reg1 = 0x1D;    //Roll registers
      reg2 = 0x1C;
      Read_IMU_Data();

      x = 0x50;       // 'P'
      reg1 = 0x1F;    //Pitch  registers
      reg2 = 0x1E;
      Read_IMU_Data();

}

void main(void){

  HID_Enable(&readbuff,&writebuff); // Sets up the USB HID Comms
  Delay_ms(20);
  SystemInit();       // Initialises all system components
  
  while(1){
    Read_HRP();
    delay_ms(500);

  }
}
I've had a scope on the SCL/SDA lines and there is definitely activity with each request (every 500ms), I don't have a logic analyser to decode the binary but it all looks the same as when I use the PIC to read the IMU.

I just cannot figure out why I'm reading zero from all the IMU registers.

ST.

User avatar
lana.arsic
mikroElektronika team
Posts: 1715
Joined: 15 Jan 2016 12:50

Re: Problems with I2C

#10 Post by lana.arsic » 26 Feb 2018 18:12

Hi,
Sobrietytest wrote: Thanks for the suggestion but that code package is incomplete - and useless - why is it even on Libstock???
Example which comes with the package is tested with 10DOF click and it works properly.
Can you please explain why do you mean that package is incomplete?
You only need to add Uses folder from the package in in Project -> Edit Search Paths...

Uses folder is located in the installation folder of the package, for example in:

c:\Users\Public\Documents\Mikroelektronika\mikroC PRO for ARM\Packages\Click_10DOF_M4\Uses\

Regarding your code, can you try to use a library?

Kind regards,
Lana

Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

Re: Problems with I2C

#11 Post by Sobrietytest » 02 Mar 2018 16:20

Hi Lana,

Not sure what you mean by using a Library? I'm using the I2C library to communicate with the IMU which is the point of the original post. As far as I can tell, there is no difference (electronically) between the PIC circuit and the STM32 circuit. Therefore I'm assuming this is a software issue, unless I've done something really stupid (which is also possible!).

This is a basic part of a much more complex system and I'm frustrated that I cannot get a simple I2C comm to work.

ST.

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: Problems with I2C

#12 Post by filip » 02 Mar 2018 16:34

Hi,

Please find the library and project for the 10DOF click in the attachment, it features BN055 and BMP180 sensors on-board.

Regards,
Filip.
Attachments
10dof.rar
(806.68 KiB) Downloaded 136 times

Post Reply

Return to “mikroC PRO for ARM General”