|
|
View previous topic :: View next topic |
Author |
Message |
Ruby
Joined: 04 Jul 2014 Posts: 44
|
i2c MPU-6050 |
Posted: Mon Sep 08, 2014 12:33 pm |
|
|
Hi. I am trying to connect accelerometer and gyroscope to pic16f877a via i2c but I don't know anything about it. I read about i2c communication. But I need an example.
Here is the module :
[/url]http://www.ebay.com/itm/131158208929?_trksid=p2059210.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT[url] |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9220 Location: Greensville,Ontario
|
|
Posted: Mon Sep 08, 2014 1:40 pm |
|
|
Well the 877 is an 'old' PIC to be using especially since newer, drop in replacements are CHEAPER, faster, more 'stuff inside'...
You'll need 'drivers' for that device, try 'google' or find the manufacturer for the driver.You will the the correct driver for the 'chip' on the board.
There may be a basic driver in the 'code forum' here, just do a 'search' to see.
I2C does require pullup resistors on the I2C bus ! Hopefully you'll get a schematic of that board to see what they've done.
hth
jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19491
|
|
Posted: Wed Sep 10, 2014 2:54 am |
|
|
You are connecting the I2C device to the PIC. To handle it in any way more easily than writing all the code yourself, you need a driver for the PIC.
If you look in the 'drivers' folder with the compiler, there are drivers there for the PIC, for hundreds of devices. Then in the 'examples' folder, there are examples of these being used. However, not for your device.
There has been code for using the MPU6000/6050 discussed here in the past.
However you have a bigger problem. Easier to switch to a 3.3v PIC, or one supporting SMBUS.
Problem is that the MPU6050, is a 3.3v device. It's allowable supply voltage, is 2.375 to 3.46v. The board you have, has a voltage regulator dropping the internal supply to run the chip. Problem is that this means the chip cannot give a high enough output voltage to drive your PIC's hardware I2C. Now you potentially can talk to the chip using 'software' I2C, or a lot of later PIC's, have a hardware option 'SMBUS', which allows them to talk to devices with this lower output voltage.
So you are starting with problems.
Have a look at this thread:
<http://www.ccsinfo.com/forum/viewtopic.php?t=50172&highlight=mpu6050> |
|
|
Ruby
Joined: 04 Jul 2014 Posts: 44
|
|
Posted: Sun Sep 14, 2014 9:25 pm |
|
|
Thanks. If i get right I need to change pic ( I have also 18f2450 and 18f2550 ) or I need to use B port of 16f877a. Any way in forum people saying that 16f877a i2c works 0.7Vd so if it is right I can make pic work with 4 volts and I will get 2.8 volts which is less than 3. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Sep 14, 2014 11:33 pm |
|
|
There is no schematic for the MPU-6050 board on the Ebay link that you
posted. Your board appears similar to this one:
http://playground.arduino.cc/uploads/Main/mpu-6050.jpg
This board has a 3.3v regulator and 2.2K pull-up resistors on SDA and SCL.
The following connections and settings should allow you to communicate
with the MPU-6050 board:
1. Run the PIC at +5v.
2. Connect +5v to the Vcc pin on the MPU-6050 board. The on-board
regulator will reduce it to the necessary +3.3v for the board.
3. Connect ground between the PIC and the GND pin on the MPU-6050 board.
4. Connect the SDA pin (pin C4) on the PIC to the SDA pin on the MPU-6050.
5. Connect the SCL pin (pin C3) on the PIC to the SCL pin on the MPU-6050.
6. Use this statement to setup the i2c for the PIC:
Code: | #use i2c(Master, SDA=PIN_C4, SCL=PIN_C3, SMBUS) |
7. When you have all these connections setup, use the program in this
post to check if the PIC can find the MPU-6050 board on the i2c bus:
http://www.ccsinfo.com/forum/viewtopic.php?t=49713
Assuming that your PIC is running with a 20 MHz crystal, change the top
5 lines of the scanner program to be like this:
Code: | #include <16F877A.h>
#fuses HS, NOWDT, PUT, BROWNOUT, NOLVP
#use delay(clock=20M)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3, SMBUS)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS) |
Run it, look at the output in a terminal window and see if it finds the
MPU-6050 board. |
|
|
elephant2009
Joined: 04 Aug 2014 Posts: 7
|
|
Posted: Tue Sep 16, 2014 8:57 am |
|
|
Thank you Mr PCM,
I have used your bus scanner program, and i was able to retrieve the famous 0xd0 slave address.
However i am unable to get raw data from MPU6050 ACC/GYRO.
The following code gives me always zero reading :
Code: |
#include <33EP512MU810.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOJTAG //JTAG disabled
#device ICSP=1
#use delay(clock=80MHz,crystal=8MHz)
#include <flex_lcd_16x2.c>
#use i2c(MASTER, SCL=PIN_F5, SDA=PIN_F4,slow,restart_wdt)
#define MPU6050_SLAVE_WRT 0xD0
#define MPU6050_SLAVE_RD 0xD1
#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
int16 MPU6050_read_word(int8 reg_addr)
{
int8 lsb, msb;
int16 retval;
i2c_start();
i2c_write(MPU6050_SLAVE_WRT);
i2c_write(reg_addr);
i2c_start();
i2c_write(MPU6050_SLAVE_RD);
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);
}
void main()
{
int16 x_accel;
lcd_init();
delay_ms(1000);
while (true)
{
// Read X Accel word.
x_accel = MPU6050_read_word(ACCEL_XOUT_H);
lcd_gotoxy(1,1);
printf(lcd_putc,"%u", x_accel);
}
}
|
Any help would be appreciated. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Sep 16, 2014 9:37 am |
|
|
One immediate problem is you're trying to display an int16 with the
format specifier for an int8:
Quote: | printf(lcd_putc,"%u", x_accel); |
You should use %lu or %lx, etc. |
|
|
elephant2009
Joined: 04 Aug 2014 Posts: 7
|
|
Posted: Tue Sep 16, 2014 9:49 am |
|
|
Same results : i get always zero readings
Please find the corrected code here :
Code: |
#include <33EP512MU810.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOJTAG //JTAG disabled
#device ICSP=1
#use delay(clock=80MHz,crystal=8MHz)
#include <flex_lcd_16x2.c>
#use i2c(MASTER, SCL=PIN_F5, SDA=PIN_F4,slow,restart_wdt)
#define MPU6050_SLAVE_WRT 0xD0
#define MPU6050_SLAVE_RD 0xD1
#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
int16 MPU6050_read_word(int8 reg_addr)
{
int8 lsb, msb;
int16 retval;
i2c_start();
i2c_write(MPU6050_SLAVE_WRT);
i2c_write(reg_addr);
i2c_start();
i2c_write(MPU6050_SLAVE_RD);
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);
}
void main()
{
int16 x_accel;
lcd_init();
delay_ms(1000);
while (true)
{
// Read X Accel word.
x_accel = MPU6050_read_word(ACCEL_XOUT_H);
lcd_gotoxy(1,1);
printf(lcd_putc,"%lu", x_accel);
}
}
|
Would you think i need some other initialization ? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9220 Location: Greensville,Ontario
|
|
Posted: Tue Sep 16, 2014 10:14 am |
|
|
Please post a schematic of your hardware..
Also have you tried the I2C scanner program in the code library ?
hth
jay |
|
|
elephant2009
Joined: 04 Aug 2014 Posts: 7
|
|
Posted: Tue Sep 16, 2014 10:26 am |
|
|
Hi,
I am trying to interface a GY-86 IMU module with a dspic33EP512MU810 (a 3.3v development board):
The imu module module was purchased from ebay:
http://www.ebay.com/itm/1pc-GY-86-10DOF-MS5611-HMC5883L-MPU6050-module-MWC-flight-control-sensor-module-/321494954357?pt=US_Surveillance_Cables_Adapters_Connectors&hash=item4ada97b175
Here are the pin connections:
GY-86 -------------- dspic33EP512MU810
3.3v ------------ 3.3v
GND ----------- GND
SCL ----------- PIN_F5
SDA ----------- PIN_F4
Quote: |
Also have you tried the I2C scanner program in the code library ?
|
Yes, and i successfully get the famous 0xd0 slave address (or 0x68 7-bit address).
However, i am still getting zero reading ?
Should i need to perform some additional configuration, to prevent MPU6050 from going to sleep for example ?
I am really confused, and i would like to decide whether the imu is damaged or not ?
I need your ideas please... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Sep 16, 2014 11:00 am |
|
|
I don't have one of these boards. They are so cheap, I will order one.
Then maybe I can help later. |
|
|
elephant2009
Joined: 04 Aug 2014 Posts: 7
|
|
Posted: Tue Sep 16, 2014 11:11 am |
|
|
PCM programmer wrote: | I don't have one of these boards. They are so cheap, I will order one.
Then maybe I can help later. |
thank you mr pcm.
please let us know about any further news.
regards |
|
|
Ruby
Joined: 04 Jul 2014 Posts: 44
|
|
Posted: Tue Sep 16, 2014 2:32 pm |
|
|
Thank you , thank you and thank you PCM. It works great and also i get the same address like Elephant.
And elephant , i don't think that you chip is damaged cause i am getting the same result "0" or both of the chips are damaged.... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Sep 16, 2014 2:58 pm |
|
|
I am told that I will receive the MPU6050 board by Friday. I will work on
it then. |
|
|
Ruby
Joined: 04 Jul 2014 Posts: 44
|
|
Posted: Wed Sep 17, 2014 1:52 pm |
|
|
Hi guys.
Today i tried this in 16f877a and 18f2550 and got the same result...
Code: |
#include <16f877a.h>
#fuses hs,nowrt,nowdt,nodebug,brownout,nolvp,nocpd,put,noprotect
#use delay (clock=20000000)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3, SMBUS)
#use rs232(baud=2400, xmit=PIN_C6, rcv=PIN_C7, bits=8, parity=N, errors)
#define LCD_ENABLE_PIN PIN_B0 //#define use_portb_lcd TRUE
#define LCD_RS_PIN PIN_B1
#define LCD_RW_PIN PIN_B2
#define LCD_DATA4 PIN_B4
#define LCD_DATA5 PIN_B5
#define LCD_DATA6 PIN_B6
#define LCD_DATA7 PIN_B7
#include <lcd.c> // For LCD and has to be after #use delay()
#define MPU6050_SLAVE_WRT 0xD0
#define MPU6050_SLAVE_RD 0xD1
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define WHO_AM_I 0x75
int8 lsb=0, msb=0;
int16 retval=0;
int16 MPU6050_read_word(int8 reg_addr)
{
i2c_start();
i2c_write(MPU6050_SLAVE_WRT);
i2c_write(reg_addr);
i2c_start();
i2c_write(MPU6050_SLAVE_RD);
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);
}
void main()
{
int16 x_gyro;
lcd_init();
delay_ms(1000);
printf(lcd_putc,"Ready");
delay_ms(1000);
while (true)
{
x_gyro = MPU6050_read_word(GYRO_XOUT_H);
printf(lcd_putc,"\fG=%16X", x_gyro);
delay_ms(500);
printf(lcd_putc,"\fL=%8X", lsb);
delay_ms(500);
printf(lcd_putc,"\fM=%8X", msb);
delay_ms(500);
x_gyro = MPU6050_read_word(WHO_AM_I);
printf(lcd_putc,"\fG2=%lu", x_gyro);
delay_ms(500);
printf(lcd_putc,"\fL2=%u", lsb);
delay_ms(500);
printf(lcd_putc,"\fM2=%u", msb);
delay_ms(500);
}
}
|
G 0
L 0
M 0
G2 26624 ==> 6800
L2 0
M2 104 ==> 68
I guess G2 and M2 are the address of the chip.
And i tried to run the 16f877a and the gyro with 3.7 volts (0.7*Vdd=2.59 volts - page 180) but i got the same result...
[/img] |
|
|
|
|
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
|