Problème dans l'utilisation de capteur ultrasons et infrarouge

Bonjour à tous !

Comme je l'indiquait dans le titre j'ai un petit soucis dans l'utilisation simultanée d'un capteur infrarouge (récepteur pour une télécommande) et un capteur ultrasons (mesure de distances), je m'explique :

mon programme fait très régulièrement des mesures avec le capteur ultrason mais doit pouvoir détecter tout appuis sur une touche de la télécommande !

Séparément les deux capteurs (et programmes) fonctionnent impeccablement bien mais mais quand je réuni les deux parties la télécommande garde des résultats cohérents mais le capteur ultrason annonces des résultats complètement faux ...

J'ai identifié deux problèmes potentiels qui pourrait être à la cause de ces résultats aberrants :

  1. l'écoute de l'impulsion de retour des ultrasons est interrompue par celle du capteur infrarouge (problème de thread ou quelque chose comme ça ?!).
  2. Interférence entre infrarouge et ultrasons ... Je sais que c'est improbable mais sait on jamais ? :confused:

Si vous avez des idées pour me sortir de cette impasse je suis preneur !

Merci d'avance !

Willy22:
2) Interférence entre infrarouge et ultrasons ... Je sais que c'est improbable mais sait on jamais ? :confused:

La vitesse de la lumière étant supérieure à celle du son, il est normal que certaines personne paraissent brillantes ... jusqu'à ce qu'elles parlent :-)))

Sérieusement, poste ton code STP !

Voila mon code, à noter que si je commente la ligne "irrecv.enableIRIn(); " dans le setup tout le reste marche parfaitement ...

#include "NAxisMotion.h"        //Contains the bridge code between the API and the Arduino Environment
#include <Wire.h>
#include <IRremote.h>

// télécommande infrarouge
const int RECV_PIN = 8;
const unsigned long bp0 = 2704;
const unsigned long bp1 = 3280;
const unsigned long bp2 = 720;
const unsigned long bp3 = 1077926692;  // non utilisé
const unsigned long bp4 = 1077930262;  // non utilisé
const unsigned long bp5 = 2672; 
IRrecv irrecv(RECV_PIN);
decode_results results;

// commande des relais
const int sens1 = 12;
const int sens2 = 11; 

// variables programme
int capPilote = 0;
int exerreur = 0;
bool pilote = 0; 
int commande = 0;
int precision_finale = 2;
int consigne = 0;

// gestion du temps
unsigned long previousMillis = 0;


// telemetre ultrason
const byte TRIGGER_PIN = 5; // Broche TRIGGER
const byte ECHO_PIN = 6;    // Broche ECHO
const unsigned long MEASURE_TIMEOUT = 25000UL; // 25ms = ~8m à 340m/s
const float SOUND_SPEED = 340.0 / 1000;


NAxisMotion boussole;       
    

void setup()
{    
  Serial.begin(115200);           
  
  // accelerometre
  I2C.begin();                    
  boussole.initSensor();         
  boussole.setOperationMode(OPERATION_MODE_NDOF);   //other : OPERATION_MODE_COMPASS
  boussole.setUpdateMode(MANUAL);  //The default is AUTO. Changing to MANUAL requires calling the relevant update functions prior to calling the read functions
  
  // relais
  pinMode(sens1, OUTPUT);
  pinMode(sens2, OUTPUT);
  digitalWrite(sens1, HIGH);
  digitalWrite(sens2, HIGH);
  
  // infrarouge
  irrecv.enableIRIn(); // Start the receiver
  
  // ultrasons
  pinMode(TRIGGER_PIN, OUTPUT);
  digitalWrite(TRIGGER_PIN, LOW);
  pinMode(ECHO_PIN, INPUT);
}

void loop() //This code is looped forever
{ 
  if (irrecv.decode(&results)) {
    Serial.println(results.value);
    if (results.value == bp1)  // tirer
    {
      tirer(150);
    }
    else if (results.value == bp2) // pousser
    {
      pousser(150);
    }
     else if (results.value == bp0) // arret urgence + reset pilote
    {
      digitalWrite(sens1, HIGH);
      digitalWrite(sens2, HIGH);
      pilote = 0;
    }
    else if (results.value == bp5)
    {
      pilote = 1;
      boussole.updateEuler();        //Update the Euler data into the structure of the object
      capPilote = boussole.readEulerHeading();
    }
    irrecv.resume(); // Receive the next value
  }
  if (pilote)
      {
        gyro();
      }
  delay(50);
  Serial.println(" ");
}


void gyro(){
  int erreur = rotation();
  unsigned long currentMillis = millis();
  int pasTemps = (int)(currentMillis - previousMillis);
  if (pasTemps > 300)
  {
  int K1 = 1;
  int K2 = 400;
  Serial.print("  Erreur : ");
  Serial.print(erreur);
  commande = erreur * K1 + (K2*(erreur - exerreur))/(pasTemps);
  exerreur = erreur;
  Serial.print("  Commande : ");
  Serial.print(commande);
  previousMillis = currentMillis;
  go_to_consigne(commande);
  }
}

int rotation(){

  /*  ///////////////////////////////////////////////////////////////////////////
   *                                                                           // 
   *                            Choisir un mode compas                         // 
   *                                                                           //
   *  /////////////////////////////////////////////////////////////////////////*/
  boussole.updateEuler();        //Update the Euler data into the structure of the object
  int cap2 = boussole.readEulerHeading();
  int delta = capPilote - cap2;
  Serial.print("     Cap compas  ");
  Serial.print(cap2);    
  if (delta > 180){
    delta = delta - 360;
  }
  
  else if (delta < -180) {
    delta = 360 + delta;
  }
  return delta;
}

void go_to_consigne(int correction){   // la consigne doit être comprise entre -100 et 100 !
  consigne += correction;
  if (consigne > 95){
    consigne = 95; 
  }
  else if (consigne < -95){
    consigne = -95;
  }
  int distance_mm = mesure_ratio();

  int ecart = consigne - distance_mm;
  int K3 = 2;   // constante de vitesse de reaction
  int vitesse = abs(ecart)* K3;
  Serial.print("       consigne : ");
  Serial.print(consigne);
  if (ecart > precision_finale){
    pousser(vitesse);
  }

  else if (ecart < - precision_finale){
    tirer(vitesse);
  }
  
}

void tirer(int vitesse){
    if (vitesse > 150){
      vitesse = 150;
      }
    Serial.print("       vitesse de sortie : ");
    Serial.print(vitesse);
    int distance_mm = mesure();
    if (distance_mm > 40 && distance_mm < 300)  // tirer
    {
      digitalWrite(sens1, LOW);
      delay(vitesse);
      digitalWrite(sens1, HIGH);
      delay(25);
    }
}

void pousser(int vitesse){
    if (vitesse > 150){
      vitesse = 150;
      }
    Serial.print("       vitesse de sortie : ");
    Serial.print(vitesse);
    int distance_mm = mesure();
    if (distance_mm < 270 && distance_mm > 20)  // pousser
    {
      digitalWrite(sens2, LOW);
      delay(vitesse);
      digitalWrite(sens2, HIGH);
      delay(25);
    }
}

int mesure(){
  delay(50);
  digitalWrite(TRIGGER_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGGER_PIN, LOW);
  long measure = pulseIn(ECHO_PIN, HIGH, MEASURE_TIMEOUT);
  float distance_mm = measure / 2.0 * SOUND_SPEED;
  return distance_mm;
}

int mesure_ratio(){
  int distance_mm = map(mesure(), 30, 280, -100, 100);
  Serial.print("   distance_r : ");
  Serial.print(distance_mm);
  return distance_mm;
}


void serialEvent() //déclaration de la fonction d'interruption sur la voie série
{
    char carlu = 0; //variable contenant le caractère à lire
    int cardispo = 0; //variable contenant le nombre de caractère disponibles dans le buffer
    cardispo = Serial.available();
    
    while(cardispo > 0) //tant qu'il y a des caractères à lire
    {
        carlu = Serial.read(); //on lit le caractère
        Serial.println(carlu); //puis on le renvoi à l’expéditeur tel quel
        cardispo = Serial.available(); //on relit le nombre de caractères dispo
            if (carlu == 'r'){
               setup();
            }
    }
}

Je ne sais pas si ça a un rapport direct, mais j'ai un problème analogue avec un récepteur/contrôleur de vol que j'ai réalisé à partir d'Arduino Pro Mini.

J'ai un HC-SR04 (capteur Ultra-Son) qui me sert à mesure l'altitude de mon drone (jusqu'à 2 mètres). les mesures qu'il me donne sont très aléatoires. J'ai pu mettre en évidence que c'est sa proximité avec le transmetteur à 2.4 GHz qui le perturbait (quelques centimètres dans mon cas).

J'ai soigné les découplages d'alim et j'ai blindé le HC-SR04 : rien n'y fait.

J'ai fait un montage où il n'y avait que le HC-SR04 et le transmetteur. J'ai pu vérifier qu'en éloignant ou rapprochant ces deux composants, il y avait perturbation ou non. Je ne me souvient plus exactement, mais il fallait de l'orde de 15 cm au minimum.

Cordialement.

Pierre