CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Interfacing MPU-6050 with i2c
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
rfjhh



Joined: 31 Mar 2011
Posts: 51
Location: Mexico

View user's profile Send private message

Interfacing MPU-6050 with i2c
PostPosted: Tue Feb 12, 2019 12:32 pm     Reply with quote

I'm new in using MPU-650 accelerometer/gyroscope with a i2c so I have a lot of doubts. I've wrote a program but It doesn't work. I've read a lot of information, some in this forum.

The program is as follows:
Code:

#include <16F887.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(clock=4M)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#include<LCD.c>

void giro_ini()
{
   i2c_start();         // Secuencia de inicio
   i2c_write(0xD0);      // Envío la dirección del esclavo
   i2c_write(0x1A);      // Dirección del registro CONFIG
   i2c_write(0x00);      // EXT_SYNC_SET = deshabilitado;
                     // Ancho de banda acelerómetro = 260Hz
                     // Ancho de banda giroscopio = 256Hz
                     // Fs giroscopio = 8KHz
   i2c_stop();            // Secuencia de paro
   
   i2c_start();         // Secuencia de inicio
   i2c_write(0xD0);      // Envío la dirección del esclavo
   i2c_write(0x19);      // Dirección del registro Sample Rate Divider
   i2c_write(0x07);      // Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV)
                     // Sample Rate = 8 KHz/(1 + 7)= 1 KHz
   i2c_stop();            // Secuencia de paro
   
   i2c_start();         // Secuencia de inicio
   i2c_write(0xD0);      // Envío la dirección del esclavo
   i2c_write(0x6B);      // Dirección del registro Power Management 1
   i2c_write(0x01);      // Frecuencia de referencia del eje X del giroscopio
                     // Se elige según 7.15 Internal Clock Generation *
   i2c_stop();            // Secuencia de paro
   
   i2c_start();         // Secuencia de inicio
   i2c_write(0xD0);      // Envío la dirección del esclavo
   i2c_write(0x1B);      // Dirección del registro GYRO_CONFIG
   i2c_write(0x18);      // Escala completa +/- 2000°
                     //
   i2c_stop();            //
   
   i2c_start();         // Secuencia de inicio
   i2c_write(0xD0);      // Envío la dirección del esclavo
   i2c_write(0x38);      // Dirección del registro INT_ENABLE
   i2c_write(0x01);      // DATA_RDY_EN = 1
                     //
   i2c_stop();            //
}

void acel_ini()
{
   i2c_start();         // Secuencia de inicio
   i2c_write(0xD0);      // Envío la dirección del esclavo
   i2c_write(0x1C);      // Dirección del registro ACCEL_CONFIG
   i2c_write(0x00);      // Escala completa +/- 2g
                     //
   i2c_stop();            //
   
}


void main()
{
   float ax, ay, az, gx, gy, gz;
   int8 acxB = 0, acxA = 0;
   int8 dato = 0, status;
   giro_ini();
   lcd_init();
   lcd_gotoxy(1,1);
   printf(lcd_putc, "Lectura Acelera");
   for(;;)
   {      
      i2c_start();               // Secuencia de inicio
      i2c_write(0x3B);            // Dirección de ACCEL_XOUT[15:8]
      i2c_write(0xD1);            // Envío la dirección del esclavo lectura
      acxA = i2c_read(0);            // Byte más significativo
      i2c_stop();
      i2c_start();   
      i2c_write(0x3C);            // Dirección de ACCEL_XOUT[7:0]
      i2c_write(0xD1);            // Envío la dirección del esclavo lectura   
      acxB = i2c_read(0);
      i2c_stop();
      lcd_gotoxy(1,2);
       printf(lcd_putc, "AA: %u %u", acxA, acxB);
       delay_ms(200);   
   }
}

All I see in the LCD is AA: 255 255

Can somebody tell me what I'm doing wrong please????

Regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Tue Feb 12, 2019 12:53 pm     Reply with quote

Give the proper chip number. MPU6000, MPU6500?. MPU650 doesn't exist...

However big 'glaring' thing. These chips are generally 3.3v devices. As
such you really need a level translator to use with a 5v PIC. Though you
may be able to work with a PIC that supports SMBUS, by selecting
this in the settings, and 3.3v pull-ups. Honestly much better to use a
3.3v PIC.
rfjhh



Joined: 31 Mar 2011
Posts: 51
Location: Mexico

View user's profile Send private message

PostPosted: Tue Feb 12, 2019 1:08 pm     Reply with quote

MPU 6050

I'm using a small board that works at 5V. There is a 3,3V regulator on board.
temtronic



Joined: 01 Jul 2010
Posts: 9241
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Feb 12, 2019 1:16 pm     Reply with quote

The MPU6050 is a 3 volt device so the onboard regulator converts VDD to 3. As Mr T points out, the 3 volts FROM the MPU6050 is NOT 'high' enough to properly communicate with the 5 volt PIC.
As he says a 3 volt PIC is the easy solution. Another option, You could ADD a 5 to 3 level translation module.

Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Feb 12, 2019 1:24 pm     Reply with quote

To put Ttelmah's comments into code and pictures, do this:
Code:
#use i2c(Master, I2C1, SMBUS)


Code:
              +3.3v
               |
               <
               > 3.3K       
               <         
To PIC         |          To MPU6050
pin C4 ------------------ SDA pin 
(SDA)                     


              +3.3v
               |
               <
               > 3.3K       
               <         
To PIC         |          To MPU6050
pin C3 ------------------ SCL pin 
(SCL)
rfjhh



Joined: 31 Mar 2011
Posts: 51
Location: Mexico

View user's profile Send private message

PostPosted: Tue Feb 12, 2019 1:41 pm     Reply with quote

As I told you, I'm using a small board (GY-521) with a MPU 6050, 3,3 V regulator and pull up resistors included in the same configuration you proposed.
It has been designed to work with Arduino (I don't like it at all), so, talking about hardware, all you have to do is connect the SDA and SCL pins to the uC.
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Tue Feb 12, 2019 2:15 pm     Reply with quote

Based on what I can see from the GY521, the I2C bus will pull up to 3v3
when high. On your MCU datasheet for the I2C bus which uses a Schmitt
Trigger buffer, the MCU flips high when the voltage on the bus reaches
0.8*Vdd, which is 4 V. So, 3v3 is too low to flip the pin.

At least that's what I'm reading off the datasheet, in the electrical
characteristics chapter.

We are talking about level translator like this:
https://www.sparkfun.com/products/12009

It translates the voltage level of your signal bus, not power.
newguy



Joined: 24 Jun 2004
Posts: 1909

View user's profile Send private message

PostPosted: Tue Feb 12, 2019 3:37 pm     Reply with quote

That level converter is essentially just a multiple of this: http://www.hobbytronics.co.uk/mosfet-voltage-level-converter

Easy to create with a n-MOSFET and two resistors.
temtronic



Joined: 01 Jul 2010
Posts: 9241
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Feb 12, 2019 3:59 pm     Reply with quote

The Arduino uC uses a totally different architecture in the die (the chip ( the 'computer')) compared to the PIC series.
That's why you must read and understand the different hardware configurations of the PIC for I2C.
Yes the voltage reg of the module reduces 5v to 3v to power the device BUT as others have said a '1' from the device will NOT be seen as a '1' by the PIC.
At the very least you need a dual, bidirectional logic level converter. Easier to just use a 3 volt PIC. a 16LF887 would work, note the 'L' ,which means Low voltage ( good for 3 v operation).

OK.. I just downloaded the 16F887 datasheet...and it WILL run at 4MHz with a VDD of 3 volts. so NO need to power the PIC from 5 volts ! So it will interface without additional parts IF run at 3 volts.
I suggest copying/compile and run PCM P 'I2C scanner' program in the code library. It will confirm IF the PIC can 'see' the peripheral. If it does, then there's a problem with your program. If it doesn't see it,and the wiring is correct, then perhaps the device is dead.
rfjhh



Joined: 31 Mar 2011
Posts: 51
Location: Mexico

View user's profile Send private message

PostPosted: Tue Feb 12, 2019 7:35 pm     Reply with quote

I've use this program to look for the address of the slave, MPU 6050 in this case and it runs well, so I don't know what is wrong with the other program.
The hardware conditions are the same.....

Code:

#include <16F887.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(clock=4M)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#include<LCD.c>

int8 estado_ack(int8 direccion)
{
int8 status;

i2c_start();
status = i2c_write(direccion);  // Status = 0 si se obtuvo un ACK
i2c_stop();

if(status == 0)
   return(TRUE);
else
   return(FALSE);
}

//=================================
 
void main()
{
   unsigned int8 i;
   unsigned int8 status;
   unsigned int8 count = 0;
   lcd_init();
   lcd_gotoxy(1,1);
   printf(lcd_putc, "Inicia: ");
   
   delay_ms(1000);
   
   for(i=0x10; i < 0xF0; i+=2)
      {
       status = estado_ack(i);
       if(status == TRUE)
         {
        lcd_gotoxy(1,1);
            printf(lcd_putc, "Dir ACK: %u", i);
               count++;
             delay_ms(2000);
         }
      }
   
   if(count == 0)
      {lcd_gotoxy(1,2);
        printf(lcd_putc, "Nada encontrado.");}
   else
      {lcd_gotoxy(1,2);
       printf(lcd_putc, "Num de chips %u", count);}
   while(1);
}
temtronic



Joined: 01 Jul 2010
Posts: 9241
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Feb 12, 2019 8:11 pm     Reply with quote

What is the address of the peripheral ?
'255' usually means bus is high.
Are you running the PIC with 3 volts or 5 ?

OK... I did a search here... found this..
https://www.ccsinfo.com/forum/viewtopic.php?t=52866&postdays=0&postorder=asc&start=15
2nd page appears to have working code.. something about 'sleep' mode, it needs to be told to wakeup !!
I don't know if it's the same device but does seem similar....

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Wed Feb 13, 2019 2:35 am     Reply with quote

Key point to understand, is that Arduino inputs accept a signal of 2.4v as
'high'. The PIC, in I2C mode (using the I2C hardware), requires the signal to
go up to 0.8*Vdd to be seen as a 'high'. So a 5v PIC will require the signals
to reach 4v.
This won't happen.

However you can use the PIC in 'software' I2C mode, on different pins
(look in the data sheet for ones supporting TTL input levels), or you can
switch to SMBUS mode (which changes the input thresholds).

#use i2c(Master, sda=PIN_C4, scl=PIN_C3, SMBUS)

One or the other of these is needed before you have any hope of working.

It'll be seeing a bus error, because the line will be sampled as low:
Quote:

Note: If, at the beginning of START condition, the
SDA and SCL pins are already sampled
low, or if during the START condition the
SCL line is sampled low before the SDA
line is driven low, a bus collision occurs,
the Bus Collision Interrupt Flag (BCLIF) is
set, the START condition is aborted, and
the I2C module is reset into its IDLE state.

so values returned will be meaningless. This is why it returns 255.
temtronic



Joined: 01 Jul 2010
Posts: 9241
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Feb 13, 2019 6:22 am     Reply with quote

what is odd is that he says his test program works....
I'd still like to know the PICs VDD.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: Interfacing MPU-6050 with i2c
PostPosted: Wed Feb 13, 2019 6:42 am     Reply with quote

rfjhh wrote:

for(;;)
{
i2c_start(); // Secuencia de inicio
i2c_write(0x3B); // Dirección de ACCEL_XOUT[15:8]
i2c_write(0xD1); // Envío la dirección del esclavo lectura
acxA = i2c_read(0); // Byte más significativo
i2c_stop();

i2c_start();
i2c_write(0x3C); // Dirección de ACCEL_XOUT[7:0]
i2c_write(0xD1); // Envío la dirección del esclavo lectura
acxB = i2c_read(0);
i2c_stop();

lcd_gotoxy(1,2);
printf(lcd_putc, "AA: %u %u", acxA, acxB);
delay_ms(200);
}
}[/code]
All I see in the LCD is AA: 255 255

Can somebody tell me what I'm doing wrong please????

Regards

That's not the correct way to read ACCEL_XOUT_H and ACCEL_XOUT_L.
You have the device address and the register address out of order, and
it's still not the correct way to read two bytes. Look at this link:
http://www.ccsinfo.com/forum/viewtopic.php?t=52866&start=29

From that link, here is the correct way to read a 16-bit register:
Code:
int16 MPU6050_read_word(int8 reg_addr)
{
int8 lsb, msb;
int16 retval;

i2c_start();
i2c_write(MPU6050_SLAVE_WRT);   // 0xD0
i2c_write(reg_addr);
i2c_start();
i2c_write(MPU6050_SLAVE_RD);   // 0xD1
msb = i2c_read();   // Read MSB byte first.
lsb = i2c_read(0);  // Do a NACK on the last read
i2c_stop();   

retval = make16(msb, lsb);

return(retval);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Wed Feb 13, 2019 8:08 am     Reply with quote

Yes, he's addressing a device at address 0x3B or 0x3C, which doesn't exist, so
will get 255 as a 'nothing there' answer... Sad
Well spotted.

I actually don't see 'how' he can be successfully accessing the device unless
he is either running on 3.3v, or the board has got level translation. The
pictures of the boards with this number don't show any.
His chip actually has the 'high' for standard I2C mode, at 0.7*Vdd = 3.5v,
so if his 5v supply just happened to be a little low, and the 3.3v on the
board just a little high, it might 'just' work. Not a reliable way to run it
though....
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group