Aller au contenu


Photo
- - - - -

i2c entre pic16f887 est gyro accelerometre mpu6050


1 réponse à ce sujet

#1 sam2302

sam2302

    Nouveau membre

  • Membres
  • 7 messages

Posté 28 décembre 2012 - 10:43

Je suis entrain de battailler sur un mpu6050, ou je n'arrive pas à le faire dialoguer avec mon pic.
Dès que j'envoie la commande REstart et le Read, on dirai que ça me plante tout.
La fréquence d'init de l'I2c du mpu6050 est en 400khz.
Je pense avoir un problème sur l'initialisation du Pic sur la com I2c avec la fréquence 400khz. (Sachant que mes autres montages en I2c fonctionne très bien SRF02 (ultrason), CMPS09(module boussole avec accelerometre).
Si quelqu'un a une solution je suis preneur, Voici mon prog en mikrobasic (avec un exemple Arduino pour multicoptère en commentaire):

J'ai fait les test avec MPU6050_ADDRESS=$68 et $69 MPU6050_ADDRESS_read= $69 (equivaut à 105 en decimal)
Ainsi que la doc pour l'écriture et la lecture des registres : http://invensense.com/mems/gyro/documents/RM-MPU-6000A.pdf

Si quelqu'un à déjà fait un montage avec ce type de capteur je suis preneur.

program MPU6050_16F887

'**************************************************************************************************************************************************
'programme issue d'un Arduino
'
'#if defined(MPU6050)
'
'void Gyro_init() {
' TWBR = ((F_CPU / 400000L) - 16) / 2; // change the I2C clock rate to 400kHz
' i2c_writeReg(MPU6050_ADDRESS, 0x6B, 0x80); //PWR_MGMT_1 -- DEVICE_RESET 1
' delay(5);
' i2c_writeReg(MPU6050_ADDRESS, 0x6B, 0x03); //PWR_MGMT_1 -- SLEEP 0; CYCLE 0; TEMP_DIS 0; CLKSEL 3 (PLL with Z Gyro reference)
' i2c_writeReg(MPU6050_ADDRESS, 0x1A, MPU6050_DLPF_CFG); //CONFIG -- EXT_SYNC_SET 0 (disable input pin for data sync) ; default DLPF_CFG = 0 => ACC bandwidth = 260Hz GYRO bandwidth = 256Hz)
' i2c_writeReg(MPU6050_ADDRESS, 0x1B, 0x18); //GYRO_CONFIG -- FS_SEL = 3: Full scale set to 2000 deg/sec
' // enable I2C bypass for AUX I2C
' #if defined(MAG)
' i2c_writeReg(MPU6050_ADDRESS, 0x37, 0x02); //INT_PIN_CFG -- INT_LEVEL=0 ; INT_OPEN=0 ; LATCH_INT_EN=0 ; INT_RD_CLEAR=0 ; FSYNC_INT_LEVEL=0 ; FSYNC_INT_EN=0 ; I2C_BYPASS_EN=1 ; CLKOUT_EN=0
' #endif
'}
'
'void Gyro_getADC () {
' i2c_getSixRawADC(MPU6050_ADDRESS, 0x43);
' GYRO_ORIENTATION( ((rawADC[0]<<8) | rawADC[1])/4 , // range: +/- 8192; +/- 2000 deg/sec
' ((rawADC[2]<<8) | rawADC[3])/4 ,
' ((rawADC[4]<<8) | rawADC[5])/4 );
' GYRO_Common();
'}
'
'void ACC_init () {
' i2c_writeReg(MPU6050_ADDRESS, 0x1C, 0x10); //ACCEL_CONFIG -- AFS_SEL=2 (Full Scale = +/-8G) ; ACCELL_HPF=0 //note something is wrong in the spec.
' //note: something seems to be wrong in the spec here. With AFS=2 1G = 4096 but according to my measurement: 1G=2048 (and 2048/8 = 256)
' //confirmed here: http://www.multiwii.com/forum/viewtopic.php?f=8&t=1080&start=10#p7480
' #if defined(FREEIMUv04)
' acc_1G = 255;
' #else
' acc_1G = 512;
' #endif
'
' #if defined(MPU6050_I2C_AUX_MASTER)
' //at this stage, the MAG is configured via the original MAG init function in I2C bypass mode
' //now we configure MPU as a I2C Master device to handle the MAG via the I2C AUX port (done here for HMC5883)
' i2c_writeReg(MPU6050_ADDRESS, 0x6A, 0b00100000); //USER_CTRL -- DMP_EN=0 ; FIFO_EN=0 ; I2C_MST_EN=1 (I2C master mode) ; I2C_IF_DIS=0 ; FIFO_RESET=0 ; I2C_MST_RESET=0 ; SIG_COND_RESET=0
' i2c_writeReg(MPU6050_ADDRESS, 0x37, 0x00); //INT_PIN_CFG -- INT_LEVEL=0 ; INT_OPEN=0 ; LATCH_INT_EN=0 ; INT_RD_CLEAR=0 ; FSYNC_INT_LEVEL=0 ; FSYNC_INT_EN=0 ; I2C_BYPASS_EN=0 ; CLKOUT_EN=0
' i2c_writeReg(MPU6050_ADDRESS, 0x24, 0x0D); //I2C_MST_CTRL -- MULT_MST_EN=0 ; WAIT_FOR_ES=0 ; SLV_3_FIFO_EN=0 ; I2C_MST_P_NSR=0 ; I2C_MST_CLK=13 (I2C slave speed bus = 400kHz)
' i2c_writeReg(MPU6050_ADDRESS, 0x25, 0x80|MAG_ADDRESS);//I2C_SLV0_ADDR -- I2C_SLV4_RW=1 (read operation) ; I2C_SLV4_ADDR=MAG_ADDRESS
' i2c_writeReg(MPU6050_ADDRESS, 0x26, MAG_DATA_REGISTER);//I2C_SLV0_REG -- 6 data bytes of MAG are stored in 6 registers. First register address is MAG_DATA_REGISTER
' i2c_writeReg(MPU6050_ADDRESS, 0x27, 0x86); //I2C_SLV0_CTRL -- I2C_SLV0_EN=1 ; I2C_SLV0_BYTE_SW=0 ; I2C_SLV0_REG_DIS=0 ; I2C_SLV0_GRP=0 ; I2C_SLV0_LEN=3 (3x2 bytes)
' #endif
'}
'
'void ACC_getADC () {
' i2c_getSixRawADC(MPU6050_ADDRESS, 0x3B);
' ACC_ORIENTATION( ((rawADC[0]<<8) | rawADC[1])/8 ,
' ((rawADC[2]<<8) | rawADC[3])/8 ,
' ((rawADC[4]<<8) | rawADC[5])/8 );
' ACC_Common();
'}
'
'void ACC_init () {
' i2c_writeReg(MPU6050_ADDRESS, 0x1C, 0x10); //ACCEL_CONFIG -- AFS_SEL=2 (Full Scale = +/-8G) ; ACCELL_HPF=0 //note something is wrong in the spec.
' //note: something seems to be wrong in the spec here. With AFS=2 1G = 4096 but according to my measurement: 1G=2048 (and 2048/8 = 256)
' //confirmed here: http://www.multiwii.com/forum/viewtopic.php?f=8&t=1080&start=10#p7480
' #if defined(FREEIMUv04)
' acc_1G = 255;
' #else
' acc_1G = 512;
' #endif
'
' #if defined(MPU6050_I2C_AUX_MASTER)
' //at this stage, the MAG is configured via the original MAG init function in I2C bypass mode
' //now we configure MPU as a I2C Master device to handle the MAG via the I2C AUX port (done here for HMC5883)
' i2c_writeReg(MPU6050_ADDRESS, 0x6A, 0b00100000); //USER_CTRL -- DMP_EN=0 ; FIFO_EN=0 ; I2C_MST_EN=1 (I2C master mode) ; I2C_IF_DIS=0 ; FIFO_RESET=0 ; I2C_MST_RESET=0 ; SIG_COND_RESET=0
' i2c_writeReg(MPU6050_ADDRESS, 0x37, 0x00); //INT_PIN_CFG -- INT_LEVEL=0 ; INT_OPEN=0 ; LATCH_INT_EN=0 ; INT_RD_CLEAR=0 ; FSYNC_INT_LEVEL=0 ; FSYNC_INT_EN=0 ; I2C_BYPASS_EN=0 ; CLKOUT_EN=0
' i2c_writeReg(MPU6050_ADDRESS, 0x24, 0x0D); //I2C_MST_CTRL -- MULT_MST_EN=0 ; WAIT_FOR_ES=0 ; SLV_3_FIFO_EN=0 ; I2C_MST_P_NSR=0 ; I2C_MST_CLK=13 (I2C slave speed bus = 400kHz)
' i2c_writeReg(MPU6050_ADDRESS, 0x25, 0x80|MAG_ADDRESS);//I2C_SLV0_ADDR -- I2C_SLV4_RW=1 (read operation) ; I2C_SLV4_ADDR=MAG_ADDRESS
' i2c_writeReg(MPU6050_ADDRESS, 0x26, MAG_DATA_REGISTER);//I2C_SLV0_REG -- 6 data bytes of MAG are stored in 6 registers. First register address is MAG_DATA_REGISTER
' i2c_writeReg(MPU6050_ADDRESS, 0x27, 0x86); //I2C_SLV0_CTRL -- I2C_SLV0_EN=1 ; I2C_SLV0_BYTE_SW=0 ; I2C_SLV0_REG_DIS=0 ; I2C_SLV0_GRP=0 ; I2C_SLV0_LEN=3 (3x2 bytes)
' #endif
'}
'
'void ACC_getADC () {
' i2c_getSixRawADC(MPU6050_ADDRESS, 0x3B);
' ACC_ORIENTATION( ((rawADC[0]<<8) | rawADC[1])/8 ,
' ((rawADC[2]<<8) | rawADC[3])/8 ,
' ((rawADC[4]<<8) | rawADC[5])/8 );
' ACC_Common();
'}
' **********************************************************************************************************************
' Lcd module connections
dim LCD_RS as sbit at RB4_bit
LCD_EN as sbit at RB5_bit
LCD_D4 as sbit at RB0_bit
LCD_D5 as sbit at RB1_bit
LCD_D6 as sbit at RB2_bit
LCD_D7 as sbit at RB3_bit

LCD_RS_Direction as sbit at TRISB4_bit
LCD_EN_Direction as sbit at TRISB5_bit
LCD_D4_Direction as sbit at TRISB0_bit
LCD_D5_Direction as sbit at TRISB1_bit
LCD_D6_Direction as sbit at TRISB2_bit
LCD_D7_Direction as sbit at TRISB3_bit
' End Lcd module connections

dim txt1 as char[16]
txt2 as char[4]
txt3 as char[8]
txt4 as char[7]
i as word
j as word
txt as string [5]
i2c as word
accx_out_h as word
accx_out_l as word
accx_out as word
gyrox_out_h as integer
gyrox_out_l as integer
gyrox_out as integer
gyroy_out_h as word
gyroy_out_l as word
gyroy_out as word
gyroz_out_h as word
gyroz_out_l as word
gyroz_out as word
MPU6050_ADDRESS as byte
MPU6050_ADDRESS_read as byte

sub procedure Move_Delay() ' Function used for text moving
Delay_ms(500) ' You can change the moving speed here
end sub

sub procedure init_lecturei2c_acc



I2C1_Start() ' issue I2C start signal
I2C1_Wr(MPU6050_ADDRESS) ' send byte via I2C (device address + W) adresse mpu6050
I2C1_Wr($1C) ' send byte (address of EEPROM location)
I2C1_Wr($10) ' send data (data to be written)
I2C1_Stop() ' issue I2C stop signal

I2C1_Start() ' issue I2C start signal
I2C1_Wr(MPU6050_ADDRESS) ' send byte via I2C (device address + W) adresse mpu6050
I2C1_Wr($6A) ' send byte (address of EEPROM location)
I2C1_Wr(%00100000) ' send data (data to be written)
I2C1_Stop() ' issue I2C stop signal


I2C1_Start() ' issue I2C start signal
I2C1_Wr(MPU6050_ADDRESS) ' send byte via I2C (device address + W)
I2C1_Wr($37) ' send byte (address of EEPROM location)
I2C1_Wr($00) ' send data (data to be written)
I2C1_Stop() ' issue I2C stop signal

I2C1_Start() ' issue I2C start signal
I2C1_Wr(MPU6050_ADDRESS) ' send byte via I2C (device address + W)
I2C1_Wr($24) ' send byte (address of EEPROM location)
I2C1_Wr($0D) ' send data (data to be written)
I2C1_Stop() ' issue I2C stop signal

I2C1_Start() ' issue I2C start signal
I2C1_Wr(MPU6050_ADDRESS) ' send byte via I2C (device address + W)
I2C1_Wr($25) ' send byte (address of EEPROM location)
I2C1_Wr($80) ' send data (data to be written)
I2C1_Stop() ' issue I2C stop signal

I2C1_Start() ' issue I2C start signal
I2C1_Wr(MPU6050_ADDRESS) ' send byte via I2C (device address + W)
I2C1_Wr($26) ' send byte (address of EEPROM location)
I2C1_Wr($01) ' send data (data to be written)
I2C1_Stop() ' issue I2C stop signal

I2C1_Start() ' issue I2C start signal
I2C1_Wr(MPU6050_ADDRESS) ' send byte via I2C (device address + W)
I2C1_Wr($27) ' send byte (address of EEPROM location)
I2C1_Wr($86) ' send data (data to be written)
I2C1_Stop() ' issue I2C stop signal

end sub

sub procedure lecturei2c_acc

I2C1_Start() ' issue I2C start signal
I2C1_Wr(MPU6050_ADDRESS) ' send byte via I2C (device address + W)
I2C1_Wr(59) ' send byte (data address)
I2C1_repeated_Start() ' issue I2C signal repeated start
I2C1_Wr(MPU6050_ADDRESS_read) ' send byte (device address + R)
accx_out_l = I2C1_Rd(0) ' read the data (NO acknowledge)
'gyrox_out_l = word(gyrox_out_l <<8)
'gyrox_out_h = I2C1_Rd(1)/4 ' read the data (NO acknowledge)
'gyroy_out_h = I2C1_Rd(2) ' read the data (NO acknowledge)
'gyroy_out_h = I2C1_Rd(3)/4 ' read the data (NO acknowledge)
'gyroz_out_h = I2C1_Rd(4) ' read the data (NO acknowledge)
'gyroz_out_h = I2C1_Rd(5)/4 ' read the data (NO acknowledge)
I2C1_Stop() ' issue I2C stop signal
end sub

sub procedure init_lecturei2c_gyro



I2C1_Start() ' issue I2C start signal
I2C1_Wr(MPU6050_ADDRESS) ' send byte via I2C (device address + W) adresse mpu6050
I2C1_Wr($6B) ' send byte (address of EEPROM location)
I2C1_Wr($80) ' send data (data to be written)
I2C1_Stop() ' issue I2C stop signal

delay_ms(5)

I2C1_Start() ' issue I2C start signal
I2C1_Wr(MPU6050_ADDRESS) ' send byte via I2C (device address + W) adresse mpu6050
I2C1_Wr($6B) ' send byte (address of EEPROM location)
I2C1_Wr($03) ' send data (data to be written)
I2C1_Stop() ' issue I2C stop signal


I2C1_Start() ' issue I2C start signal
I2C1_Wr(MPU6050_ADDRESS) ' send byte via I2C (device address + W)
I2C1_Wr($1A) ' send byte (address of EEPROM location)
I2C1_Wr($01) ' send data (data to be written)
I2C1_Stop() ' issue I2C stop signal



I2C1_Start() ' issue I2C start signal
I2C1_Wr(MPU6050_ADDRESS) ' send byte via I2C (device address + W)
I2C1_Wr($1B) ' send byte (address of EEPROM location)
I2C1_Wr($18) ' send data (data to be written)
I2C1_Stop() ' issue I2C stop signal


end sub
sub procedure lecturei2c_gyro

I2C1_Start() ' issue I2C start signal
I2C1_Wr(MPU6050_ADDRESS) ' send byte via I2C (device address + W)
I2C1_Wr(67) ' send byte (data address)
I2C1_repeated_Start() ' issue I2C signal repeated start
I2C1_Wr(MPU6050_ADDRESS_read) ' send byte (device address + R)
gyrox_out_l = I2C1_Rd(0) ' read the data (NO acknowledge)
'gyrox_out_l = word(gyrox_out_l <<8)
'gyrox_out_h = I2C1_Rd(1)/4 ' read the data (NO acknowledge)
'gyroy_out_l = I2C1_Rd(2) ' read the data (NO acknowledge)
'gyroy_out_h = I2C1_Rd(3)/4 ' read the data (NO acknowledge)
'gyroz_out_l = I2C1_Rd(4) ' read the data (NO acknowledge)
'gyroz_out_h = I2C1_Rd(5)/4 ' read the data (NO acknowledge)
I2C1_Stop() ' issue I2C stop signal

'gyrox_out= (gyrox_out_h << 8)+(gyrox_out_l)
end sub


main:
SSPSTAT=%00011100
SSPADD=$09
SSPCON=$28
TRISA=255
TRISB = 0
PORTA=0
PORTB = $FF
TRISB = $FF
TRISC = 0
MPU6050_ADDRESS=104
MPU6050_ADDRESS_read= 105 '$69 equivaut à 105 en decimal
gyrox_out_l=5
accx_out_l=254
adcon1=%10001110
ANSEL = 0 ' Configure AN pins as digital I/O
ANSELH = 0
I2C1_Init(400000) ' initialize I2C communication 400khz pour mpu6050 horloge pic 8 mhz

txt1 = "afficheur"
txt2 = "sam BO"
txt3 = "gyroscope"
txt4 = "Altimetre"

Lcd_Init() ' Initialize Lcd
Lcd_Cmd(_LCD_CLEAR) ' Clear display
Lcd_Cmd(_LCD_CURSOR_OFF) ' Cursor off
Lcd_Out(1,3,txt3) ' Write text in first row
Lcd_Out(2,6,txt2) ' Write text in second row
Delay_ms(2000)
Lcd_Cmd(_LCD_CLEAR) ' Clear display

Lcd_Out(1,1,txt1) ' Write text in first row
Lcd_Out(2,6,"sam") ' Write text in second row
Delay_ms(500)
Lcd_Cmd(_LCD_CLEAR) ' Clear display
Lcd_Out(1,6,"gyro")

'init_lecturei2c_acc()
'init_lecturei2c_gyro()

while TRUE ' boucle
init_lecturei2c_acc()
init_lecturei2c_gyro()
lecturei2c_gyro()
lecturei2c_acc()


wordToStr(accx_out_l, txt)
Lcd_out(2,5,txt)
'delay_ms(200)
wend
end.

#2 sam2302

sam2302

    Nouveau membre

  • Membres
  • 7 messages

Posté 06 janvier 2013 - 12:56

Bon cool en fait mon capteur I2c était HS, je viens d'en recevoir un ça marche!!!



Répondre à ce sujet



  


2 utilisateur(s) li(sen)t ce sujet

0 members, 2 guests, 0 anonymous users