Programme qui se bloque

Bonjour,
j'ai repris un programme de : // Aritro Mukherjee , April 2016
// For more information Aritro Mukherjee - Hackster.io
( DIY Flight Instruments for Horizon and Compass)
pour faire un horizon artificiel. j'ai rajouter un capteur de pression (BMP280) pour l'alti et vario,
le sérial comme sur le cite est envoyer vers une raspberry pour l'affichage.
Ce programme bug et bloque au bout de 10 a 15 secondes, après raz ou relance du programme c'est idem avec ou sans la raspberry.
je ne trouve pas le problème.
un petit coup de main me ferais bien plaisir.
voici le code:

// Aritro Mukherjee , April 2016
// For more information  https://www.hackster.io/Aritro

/********************************** encodeur rotatif ******************************/
#include <ClickEncoder.h>
#include <TimerOne.h>
ClickEncoder *encoder;
float last, value;
int adj;
void timerIsr() {
  encoder->service();
}


/////////////////// BMP /////////////////////////
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>

Adafruit_BMP280 bmp; // I2C

float pressure;
long int ancien_millis;

float Alti;
float Vario;
float vario;
float ancienne_altitude;


/////////////////////////////////////////////////


#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"

#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif

MPU6050 mpu;
#define OUTPUT_READABLE_YAWPITCHROLL
#define LED_PIN 13
bool blinkState = false;

// Variables de contrôle/état du MPU
bool dmpReady = false;  // définir vrai si l'initialisation DMP a réussi
uint8_t mpuIntStatus;   // détient l'octet d'état d'interruption réel du MPU
uint8_t devStatus;      // renvoie l'état après chaque opération de l'appareil (0 = succès, !0 = erreur)
uint16_t packetSize;    // taille de paquet DMP attendue (la valeur par défaut est de 42 octets)
uint16_t fifoCount;     // nombre de tous les octets actuellement dans FIFO
uint8_t fifoBuffer[64]; // Tampon de stockage FIFO

// vars d'orientation/mouvement
Quaternion q;           // [w, x, y, z]         conteneur de quaternion
VectorInt16 aa;         // [x, y, z]            mesures du capteur d'accélération
VectorInt16 aaReal;     // [x, y, z]            mesures du capteur d'accélération sans gravité
VectorInt16 aaWorld;    // [x, y, z]            mesures du capteur d'accélération à l'échelle mondiale
VectorFloat gravity;    // [x, y, z]            vecteur de gravité
float euler[3];         // 3 // [psi, theta, phi]    Conteneur d'angle d'Euler
float ypr[3];           // [yaw, pitch, roll] pres   lacet/tangage/rouleau conteneur et vecteur de gravité

// structure de paquet pour la démonstration de teapot InvenSense
uint8_t teapotPacket[14] = { '$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' }; //[14]

// ================================================================
// ===            ROUTINE DE DETECTION D'INTERRUPTION           ===
// ================================================================

volatile bool mpuInterrupt = false;     // indique si la broche d'interruption MPU est passée au niveau haut
void dmpDataReady() {
  mpuInterrupt = true;
}

// ================================================================
// ===                CONFIGURATION INITIALE                    ===
// ================================================================

void setup() {

  /********************************** encodeur rotatif ********************************/
  encoder = new ClickEncoder(A1, A0, A2);
  Timer1.initialize(1000);
  Timer1.attachInterrupt(timerIsr);


  ////////// Connexion au capteur BMP /////////
  if (!bmp.begin()) {
    Serial.println("Could not find a valid BMP280 sensor, check wiring!");
    while (1);
  }
  Serial.println(F("Reading BMP280 : "));
  //////////////////////////////////////////////

  // rejoindre le bus I2C (la bibliothèque I2Cdev ne le fait pas automatiquement)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  Wire.begin();
  TWBR = 24; // Horloge I2C 400 kHz (200 kHz si le processeur est à 8 MHz)
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
  Fastwire::setup(400, true);
#endif

  // initialiser la communication série
  // (115200 choisi car il est requis pour la sortie Teapot Demo, mais c'est
  Serial.begin(115200);
  while (!Serial); //attendre le dénombrement arduino, les autres continuent immédiatement
  mpu.initialize();
  devStatus = mpu.dmpInitialize();

  // décalages de gyroscope, mis à l'échelle pour une sensibilité minimale
  mpu.setXGyroOffset(220);
  mpu.setYGyroOffset(76);
  mpu.setZGyroOffset(-85);
  mpu.setZAccelOffset(1788); 

  //assurez-vous que cela a fonctionné (renvoie 0 si oui)
  if (devStatus == 0) {
    mpu.setDMPEnabled(true);

    // enable Arduino interrupt detection
    //Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
    attachInterrupt(0, dmpDataReady, RISING);
    mpuIntStatus = mpu.getIntStatus();

    // activer la détection d'interruption Arduino
    //Serial.println(F("Activation de la détection d'interruption (interruption externe Arduino 0)..."));
    dmpReady = true;

    // obtenir la taille de paquet DMP attendue pour une comparaison ultérieure
    packetSize = mpu.dmpGetFIFOPacketSize();
  } else {

    Serial.print(devStatus);
    Serial.println(F(")"));
  }

  // configure LED for output
  pinMode(LED_PIN, OUTPUT);
}

// ================================================================
// ===                    MAIN PROGRAM LOOP                     ===
// ================================================================

void loop() {

  /********************************** encodeur rotatif ********************************/
  ClickEncoder::Button b = encoder->getButton();
  if (b != ClickEncoder::Open) {
    encodeur();
  }
 /*************************************************************************************/
  // si la programmation a échoué, n'essayez pas de faire quoi que ce soit
  if (!dmpReady) return;

  // attend l'interruption du MPU ou des paquets supplémentaires disponibles
  while (!mpuInterrupt && fifoCount < packetSize) {

  }

  // réinitialiser l'indicateur d'interruption et obtenir l'octet INT_STATUS
  mpuInterrupt = false;
  mpuIntStatus = mpu.getIntStatus();

  // obtenir le nombre FIFO actuel
  fifoCount = mpu.getFIFOCount();

  // vérifie le débordement (cela ne devrait jamais arriver à moins que notre code ne soit trop inefficace)
  if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
    // réinitialiser pour que nous puissions continuer proprement
    mpu.resetFIFO();
    //Serial.println(F("FIFO overflow!"));

    // sinon, vérifiez l'interruption de la disponibilité des données DMP (cela devrait se produire fréquemment)
  } else if (mpuIntStatus & 0x02) {
    // attend la longueur correcte des données disponibles, devrait être une attente TRÈS courte
    while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

    // lit un paquet depuis FIFO
    mpu.getFIFOBytes(fifoBuffer, packetSize);

    // suivre le nombre de FIFO ici au cas où il y aurait > 1 paquet disponible
    // (cela nous permet d'en lire plus immédiatement sans attendre une interruption)
    fifoCount -= packetSize;

#ifdef OUTPUT_READABLE_QUATERNION
    // affiche les valeurs des quaternions sous forme de matrice simple : w x y z
    mpu.dmpGetQuaternion(&q, fifoBuffer);
    Serial.print("quat\t");
    Serial.print(q.w);
    Serial.print("\t");
    Serial.print(q.x);
    Serial.print("\t");
    Serial.print(q.y);
    Serial.print("\t");
    Serial.println(q.z);
#endif

#ifdef OUTPUT_READABLE_EULER
    // affiche les angles d'Euler en degrés
    mpu.dmpGetQuaternion(&q, fifoBuffer);
    mpu.dmpGetEuler(euler, &q);
    Serial.print("euler\t");
    Serial.print(euler[0] * 180 / M_PI);
    Serial.print("\t");
    Serial.print(euler[1] * 180 / M_PI);
    Serial.print("\t");
    Serial.println(euler[2] * 180 / M_PI);
#endif

#ifdef OUTPUT_READABLE_YAWPITCHROLL
    // affiche les angles d'Euler en degrés
    mpu.dmpGetQuaternion(&q, fifoBuffer);
    mpu.dmpGetGravity(&gravity, &q);
    mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);

    //Serial.print("Phi: ");
    Serial.print(ypr[2] * 18 / M_PI);
    //Serial.print("\t theta: ");
    Serial.print(" ");
    Serial.print(ypr[1] * 180 / M_PI);
    //Serial.print("\t Psi: ");
    Serial.print(" ");
    Serial.print(ypr[0] * 180 / M_PI);
    
    /******************************************/
    //   envoie Alti et Vario a la Raspberry  //
    /******************************************/
    ////////// lecture du capteur BMP //////////
    
    Alti = bmp.readAltitude (1013+value);
    Serial.print(" ");
    Serial.print(Alti);
    calcule_vario();
    Serial.print(" ");   
    Serial.print(vario);
    Serial.print(" ");    
    Serial.println(value);


#endif

#ifdef OUTPUT_READABLE_REALACCEL
    // affiche l'accélération réelle, ajustée pour éliminer la gravité
    mpu.dmpGetQuaternion(&q, fifoBuffer);
    mpu.dmpGetAccel(&aa, fifoBuffer);
    mpu.dmpGetGravity(&gravity, &q);
    mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
    Serial.print("areal\t");
    Serial.print(aaReal.x);
    Serial.print("\t");
    Serial.print(aaReal.y);
    Serial.print("\t");
    Serial.println(aaReal.z);
#endif

#ifdef OUTPUT_READABLE_WORLDACCEL
    // affiche l'accélération initiale du cadre mondial, ajustée pour supprimer la gravité
    // et pivoté en fonction de l'orientation connue du quaternion
    mpu.dmpGetQuaternion(&q, fifoBuffer);
    mpu.dmpGetAccel(&aa, fifoBuffer);
    mpu.dmpGetGravity(&gravity, &q);
    mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
    mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);
    Serial.print("aworld\t");
    Serial.print(aaWorld.x);
    Serial.print("\t");
    Serial.print(aaWorld.y);
    Serial.print("\t");
    Serial.println(aaWorld.z);
#endif

#ifdef OUTPUT_TEAPOT
    // afficher les valeurs de quaternion dans le format de démonstration InvenSense Teapot :
    teapotPacket[2] = fifoBuffer[0];
    teapotPacket[3] = fifoBuffer[1];
    teapotPacket[4] = fifoBuffer[4];
    teapotPacket[5] = fifoBuffer[5];
    teapotPacket[6] = fifoBuffer[8];
    teapotPacket[7] = fifoBuffer[9];
    teapotPacket[8] = fifoBuffer[12];
    teapotPacket[9] = fifoBuffer[13];
    //teapotPacket[10] = 1013.12; // test
    Serial.write(teapotPacket, 14); //Serial.write(teapotPacket, 14);
    teapotPacket[11]++; // packetCount, boucle à 0xFF exprès //test teapotPacket[11]++;


#endif

    // LED clignotante pour indiquer l'activité
    blinkState = !blinkState;
    digitalWrite(LED_PIN, blinkState);
  }
}

/************************************ Void Vario *******************************/
void calcule_vario() {

  if ((millis() - ancien_millis) >= 1000) {
    ancien_millis = millis();
    float moyenne = 0;

    for (int i = 0; i <= 20; i++) {
      moyenne += bmp.readAltitude();
      delay(1);
    }
    moyenne /= 20;

    vario = (moyenne - ancienne_altitude);
    ancienne_altitude = moyenne;
  }
}

/************************************ Void Encodeur *******************************/
void encodeur () {
  encoder->setAccelerationEnabled(true);
  value += encoder->getValue();

  if (value != last) {
    last = value;
  }
}

hello
quelques Serial.print judicieusement placés devraient t'aider.

certe, mais c'est un peut le bazar dans l'affichage du moniteur série.
et je ne sais pas ou les placer pour voir ce blocage.

Salut ! Essaye d'en mettre avant les while() parce que mal conditionnés, il peuvent ne rien faire ou rester bloqué !

Un print dans chaque branche des if/else pour voir quel chemin prend le programme.
Ensuite, tu pourras ajouter des print dans les branches qui te paraissent suspectes.

ok, avec les print, je vais bien finir par trouver :grinning:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.