i2c MPU6050 Mega freeze Wire.requestFrom


bonjour,
j'ai une mega avec un gyro mpu6050 (dfrobot 6 dof ou phirobotics 6 dof) installée sur un robot roulant. donc ils subissent pas mal de vibrations… de bruits et autres agressions… je communique en i2c avec les 2 à la fois (0x68 et 0x69) pour reconstruire un signal de meilleure qualité (capteur à 2 endroits sur le robot). je rencontre des problèmes lors de la lecture des accel / vitesse angulaire avec la fonction wire.requestfrom(address_gyro_df,14,true). même dans le cas où j'ai qu'un seul gyro. le problème est que la carte arduino semble entrer dans un pédalage dans la semoule pour ne jamais en sortir… pour éviter de tous planter, j'ai alors ajouté un watchdog (wdt_reset /  wdt_enable(wdto_4s) / à 4 secondes)… mais c'est clairement pas l'idéal, car à chaque redémarrage je dois rejouer toutes les initialisations de actionneurs…
dans la boucle principale, pour réduire ces « freeze » intempestif, avant chaque lecture de mon mpu, je test si l'i2c est bien là avec la fonction checkbus()
code: [select]

bool checkbus()
{
  if (digitalread(20) == low || digitalread(21) == low)
  {
    buserrorbool = true;
  }
}

Ça améliore les choses… mais pas à 100 %
du coup, j'ai ajouté entre chaque instruction de lecture de l'i2c des délais
code: [select]

      wire.endtransmission(true);
      delaymicroseconds(50);
      checkbus();
      if (buserrorbool==false)
      {
        wire.begintransmission(address_gyro_df);
        wire.write(0x3b);  // starting register 0x3b (accel_xout_h)
        delaymicroseconds(50);
        wire.endtransmission(false);
        delaymicroseconds(50);
        wire.requestfrom(address_gyro_df,14,true);
        delaymicroseconds(200);
        gyrodf_acx=wire.read()<<8|wire.read();  // 0x3b (accel_xout_h) & 0x3c (accel_xout_l)
        gyrodf_acy=wire.read()<<8|wire.read();  // 0x3d (accel_yout_h) & 0x3e (accel_yout_l)
        gyrodf_acz=wire.read()<<8|wire.read();  // 0x3f (accel_zout_h) & 0x40 (accel_zout_l)
        gyrodf_tmp=wire.read()<<8|wire.read();  // 0x41 (temp_out_h) & 0x42 (temp_out_l)
        gyrodf_gyx=wire.read()<<8|wire.read()-0;  // 0x43 (gyro_xout_h) & 0x44 (gyro_xout_l)
        gyrodf_gyy=wire.read()<<8|wire.read()-0;  // 0x45 (gyro_yout_h) & 0x46 (gyro_yout_l)
        gyrodf_gyz=wire.read()<<8|wire.read()-0;  // 0x47 (gyro_zout_h) & 0x48 (gyro_zout_l)
      }
      buserrorbool=false;
      wire.endtransmission(true);
      gyrodf_angle = -(atan2(gyrodf_acz, gyrodf_acy) * 180 / pi -87.6); // angle de base [deg]
      gyrodf_omega = (gyrodf_gyy+430)/500; // vitesse rotation [rd/s]




comme pour le "checkbus », ça améliore encore un peu les choses… mais c'est toujours pas nickel
dès que le robot roule, j'ai des plantages de la mega tous les 30 à 40 secondes….

si je mets des serial.print(xxx) entre chaque ligne, je vois que le plantage est toujours à la ligne wire.requestfrom(address_gyro_df,14,true); que le dernier argument soit à « true » ou « false ».

la question :
 :o
avez-vous déjà rencontré ce genre de problème épineux ?
y a-t-il une fonction qui dit « wire.requestfrom » que si elle dépasse par exemple 1ms, elle s'arrête et redonne la main au reste du programme (un time out). si je perds l'info une fois toutes les 30 ou 40 secondes, je dois pouvoir largement survivre sachant que j'ai un « timer » (scheduler) dans mon programme qui me rafraichit l'info toutes les 100 ms.

merci par avance pour votre aide
vincent

bonjour,

pourquoi n'utilises-tu pas quelque chose de plus évolué pour communiquer avec ton capteur ?
la librairie suivante fait ses preuves:
https://github.com/jrowberg/i2cdevlib/tree/master/arduino/mpu6050


Arduino Forum > International > Français (Moderators: jfs, Snootlab) > i2c MPU6050 Mega freeze Wire.requestFrom


arduino

Comments

Popular posts from this blog

Error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode - Raspberry Pi Forums

class MPU6050 has no member named begin

missing filename after '-o'