Telecommande xBee - bugs si hors portée ou coupure emetteur

Bonjour, j’avais déjà demandé de l’aide il y a quelques temps lorsque j’essayai de faire une télécommande à base d’arduino et module 433Mhz.
Je me suis finalement tourné vers des modules xBee S1 car trop de coupure et latence avec le 433, inexploitable. Probablement que cela était dû à une mauvaise programmation mais je suis parti du niveau 0…
Donc j’ai fini par obtenir ce que je voulais avec l’xBee :

  • temps de réponse
  • portée (pas encore testé en situation réelle mais sur le papier ça colle…)
  • fonctionnalité (quelque boutons qui commandent quelque relais)
  • possibilité d’avoir dans le même espace plusieurs “couple émetteur - récepteur” différents (pas testé)

Mon problème est le suivant :
j’émet en continu sur le TX l’état voulu de mes sorties sur le récepteur, or, si l’émetteur devient hors portée ou n’ai plus alimenté, le récepteur continu d’effectuer le dernier ordre envoyé.
Je cherche à réinitialiser les sorties du récepteur en cas de non réception.

Si quelqu’un peut m’aiguiller…
Merci

Emetteur :

/*================ EMETTEUR ====================
                      
  2 leviers et 1 commutateur commandent l’émission de huit bits sur un octet
  les leviers sont des inters 3 positions 2 NO à position fixe au centre
  le connutateur est un inter 3 positions 2 NO à 3 positions fixe
                          BRANCHEMENT
        * Levier 1 haut        --------->   pin 2   --> monter verin N°1 / dérouler treuil 1 ou 2
        * Levier 1 bas         --------->   pin 3   --> descente verin N°1 / enrouler treuil 1 ou 2
        * Levier 2 haut        --------->   pin 4   --> monter verin N°2 / dérouler treuil 1 ou 2
        * Levier 2 bas         --------->   pin 5   --> descente verin N°1 / enrouler treuil 1 ou 2
        * Commutateur 1 gauche --------->   pin 6   --> fonction vérin
        * Commutateur 1 droite --------->   pin 7   --> fonction treui envers  ( au milieu fontion treuil endroit)
        * Voyant vert batterie --------->   pin 8   --> niveau batterie au dessu de 7,5V
        * Voyant rouge batterie -------->   pin 9   --> niveau batterie faible
        * Mesure tension batterie ------>   pin A1  --> via pont diviseur

=============DEBUT DU PROGRAMME ======================*/
const int L1H = 2;   // Levier 1 haut connecté à la broche 2
const int L1B = 3;   // Levier 1 bas connecté à la broche 3
const int L2H = 4;   // Levier 2 haut connecté à la broche 4
const int L2B = 5;   // Levier 2 bas connecté à la broche 5
const int C1G = 6;   // Commutateur 1 gauche connecté à la broche 6
const int C1D = 7;   // Commutateur 1 droite connecté à la broche 7
const int vert = 8;          // Indicateur niveau batterie
const int rouge = 9;         // Indicateur niveau batterie
//unsigned int lect_bat = A7;
int lect_bat_val;            // Mesure baterie
int etat_L1H = 0;
int etat_L1B = 0;
int etat_L2H = 0;
int etat_L3H = 0;
int etat_C1G = 0;
int etat_C1D = 0;
int val1 = 0;
int val2 = 0;
int val3 = 0;
int val4 = 0;     // variable pour mémoriser la valeur lue
int val5 = 0;
int val6 = 0;
int val0;

const int B = 8;
int tab_B[B]={0,1,2,3,4,5,6,7} ; 
int tab_etat[B]={0,0,0,0,0,0,0,0};


void setup()
{
  pinMode(L1H, INPUT_PULLUP);        // configure la broche 2 en ENTREE 
  pinMode(L1B, INPUT_PULLUP);        // configure la broche 3 en ENTREE 
  pinMode(L2H, INPUT_PULLUP);        // configure la broche 4 en ENTREE 
  pinMode(L2B, INPUT_PULLUP);        // configure la broche 5 en ENTREE 
  pinMode(C1G, INPUT_PULLUP);        // configure la broche 6 en ENTREE
  pinMode(C1D, INPUT_PULLUP);        // configure la broche 7 en ENTREE
  pinMode(vert, OUTPUT);             // configure la broche 8 en SORTIE
  pinMode(rouge, OUTPUT);            // configure la broche 9 en SORTIE
 // pinMode(lect_bat, INPUT);
 digitalWrite(L1H, HIGH);
 digitalWrite(L1B, HIGH);
 digitalWrite(L2H, HIGH);
 digitalWrite(L2B, HIGH);
 digitalWrite(C1G, HIGH);
 digitalWrite(C1D, HIGH);

Serial.begin(9600); // Initialisation du port série
}

  void loop()

// envoie code
{
{
  int i = 0;   
 Serial.print("#");
 
  for (i=0; i < B ; i++) {
      Serial.print (tab_etat[i]);
   }
  Serial.println("");
  delay(50);
}


  val1 = digitalRead(L1H);    // lit l'état de la broche en entrée
  val2 = digitalRead(L1B);    // et met le résultat dans la variable
  val3 = digitalRead(L2H);
  val4 = digitalRead(L2B);
  val5 = digitalRead(C1G);
  val6 = digitalRead(C1D);


// codage fonction
{
   {if(val5 == LOW && val6 ==  HIGH ) // bouton à gauche    ---> Vérin
    val0 = 1;
   {digitalRead(tab_etat[4] = 0);}
   {digitalRead(tab_etat[5] = 0);}
   {digitalRead(tab_etat[6] = 0);}
   {digitalRead(tab_etat[7] = 0);}
   }

   {if(val5 == HIGH && val6 ==  HIGH ) // bouton au milieu  ---> Treuil endroit
    val0 = 2;    
   {digitalRead(tab_etat[0] = 0);}
   {digitalRead(tab_etat[1] = 0);}
   {digitalRead(tab_etat[2] = 0);}
   {digitalRead(tab_etat[3] = 0);}
   }

   {if(val5 == HIGH && val6 ==  LOW ) // bouton au milieu   ---> Treuil envers
    val0 = 3;
   {digitalRead(tab_etat[0] = 0);}
   {digitalRead(tab_etat[1] = 0);}
   {digitalRead(tab_etat[2] = 0);}
   {digitalRead(tab_etat[3] = 0);}
   }
}

// --> Fonction Verin
{
{  if (val0 == 1)
 {

//  allongement Verin gauche
    if(val1 == 1) 
    {digitalRead(tab_etat[0] = 0);}
    else
    {digitalRead(tab_etat[0] = 1);}

//  retraction Verin gauche
    if(val2 == 1)
    {digitalRead(tab_etat[1] = 0);}
    else
    {digitalRead(tab_etat[1] = 1);}

//  allongement Verin droite
    if(val3 == 1)
    {digitalRead(tab_etat[2] = 0);}
    else
    {digitalRead(tab_etat[2] = 1);}


//  retraction Verin droite
    if(val4 == 1) 
    {digitalRead(tab_etat[3] = 0);}
    else
    {digitalRead(tab_etat[3] = 1);}

   }
  }
}
// --> Fonction treuil

{  if(val0 != 1)
 {

   // fonction Treuil endroit
    if(val0 == 2)
  {
//  enroulement treuil gauche
    if(val1 == 1)
    {digitalRead(tab_etat[4] = 0);}
    else
    {digitalRead(tab_etat[4] = 1);}


//  déroulement treuil gauche
    if(val2 == 1)
    {digitalRead(tab_etat[5] = 0);}
    else
    {digitalRead(tab_etat[5] = 1);}


//  enroulement treuil droite
    if(val3 == 1) 
    {digitalRead(tab_etat[6] = 0);}
    else
    {digitalRead(tab_etat[6] = 1);}


//  déroulement treuil droite
    if(val4 == 1)
    {digitalRead(tab_etat[7] = 0);}
    else
    {digitalRead(tab_etat[7] = 1);}

 }


   // fonction Treuil envers
   else if(val0 == 3)
{
//  enroulement treuil gauche
    if(val1 == 1)
    {digitalRead(tab_etat[6] = 0);}
    else
    {digitalRead(tab_etat[6] = 1);}

//  déroulement treuil gauche
    if(val2 == 1)
    {digitalRead(tab_etat[7] = 0);}
    else
    {digitalRead(tab_etat[7] = 1);}


//  enroulement treuil droite
    if(val3 == 1)
    {digitalRead(tab_etat[4] = 0);}
    else
    {digitalRead(tab_etat[4] = 1);}


//  déroulement treuil droite
    if(val4 == 1) 
    {digitalRead(tab_etat[5] = 0);}
    else
    {digitalRead(tab_etat[5] = 1);}

}
}}

/*// mesure et signalisation niveau batterie
{
//unsigned int lect_bat = analogRead(A6);                // mesure de la tension brute
//float real_bat = ((raw_bat * (5.0 / 1024 )) * 3);     // calcul tension réel --> x3 car pont diviseur de 3
lect_bat_val = analogRead(lect_bat);
//Serial.print("Tension :");
//Serial.println(lect_bat_val);

if (lect_bat_val >= 0) {digitalWrite (vert, LOW);
                        digitalWrite (rouge, HIGH);}
else if (lect_bat_val > 512 & lect_bat_val <= 1000) {digitalWrite (vert, LOW);
                                                       digitalWrite (rouge, LOW);}
else if (lect_bat_val > 10 & lect_bat_val <= 512) {digitalWrite (vert, HIGH);
                                                   digitalWrite (rouge, LOW);}

else (lect_bat_val < 0); {digitalWrite (vert, HIGH);
                          digitalWrite (rouge, LOW);
                          delay(100);
                          digitalWrite (rouge, HIGH);
                          delay(200);}
}*/
}======= FIN DE PROGRAMME ===================

mon programme intègre aussi une partie mesure de la batterie qui ne fonctionne pas pour le moment, chaque choses en son temps…

Bonjour,

Je ne vois pas du tout ce que sont supposé faire tes digitalRead() de ce type

       digitalRead(tab_etat[4] = 0);

Tel quel ça met 0 dans tab_etat[4] puis ça lit la pin 0 sans rien en faire

j’avais fait ça pour corriger un bug, de mémoire, si un levier était actionné et que l’on changeait de fonction (vérin / treuil) pendant une commande, celle-ci continuait

code Récepteur :

/*     ==================== RECEPTEUR XBee TOUT OU RIEN ======================
Commande de 9 relais en fonction de l’état de 2 leviers et 1 commutateur de l’émetteur.

                         BRANCHEMENT
        * relais 1)  --------->   pin 2   --> monter verin N°1
        * relais 2)  --------->   pin 3   --> monter verin N°1
        * relais 3)  --------->   pin 4   --> descente verin N°2
        * relais 4)  --------->   pin 5   --> descente verin N°2
        * relais 5)  --------->   pin 6   --> dérouler treui N°1
        * relais 6)  --------->   pin 7   --> enrouler treui N°1  
        * relais 7)  --------->   pin 8   --> dérouler treui N°2
        * relais 8)  --------->   pin 9   --> enrouler treui N°2
        * relais 9)  --------->   pin 10  --> by-pass hydraulique pour les vérins

========================== DEBUT DU PROGRAMME ====================================*/

const int nb_B = 8; 
int tab_etat[nb_B]={2,3,4,5,6,7,8,9} ; 

const int r1 =  2;
const int r2 =  3;
const int r3 =  4;
const int r4 =  5;
const int r5 =  6;
const int r6 =  7;
const int r7 =  8;
const int r8 =  9;
const int r9 =  10;
int vr1;
int vr2;
int vr3;
int vr4;


//______________________________________________________________________________________________________________

void lire_etat()
{
int i = 0;
int data;
digitalWrite(data, 0);

  for (i=0; i < nb_B ; i++) {
        
      while (Serial.available () == 0) ; 
      // tant qu'on n'a rien à lire, on ne fait rien
     
      data = Serial.read() -'0';
       
          
      if (data == 1) 
         digitalWrite(tab_etat[i], LOW) ;
       else
         digitalWrite(tab_etat[i], HIGH) ;

vr1 = digitalRead(r1);
vr2 = digitalRead(r2);
vr3 = digitalRead(r3);
vr4 = digitalRead(r4);
  
 if (( vr1 == LOW)||( vr2 == LOW)||( vr3 == LOW)||( vr4 == LOW)){ 
      digitalWrite(r9, LOW);}
 else digitalWrite(r9, HIGH); 
            
  
  }     
}

void setup() // Fonction setup()
{   
 for (int i=0; i < nb_B ; i++) {
     pinMode(tab_etat[i], OUTPUT);
     pinMode(r9, OUTPUT);}
     
 Serial.begin(9600);     

  digitalWrite(r1, 1);
  digitalWrite(r2, 1);
  digitalWrite(r3, 1);
  digitalWrite(r4, 1);
  digitalWrite(r5, 1);
  digitalWrite(r6, 1);
  digitalWrite(r7, 1);
  digitalWrite(r8, 1);
  digitalWrite(r9, 1);
}

void loop() // executée en boucle
{
{ while (Serial.available () == 0);  
  if (Serial.read () == '#')        
        
     lire_etat();  
        
}
}


//========================= FIN DE PROGRAMME ===========================

Je ne comprend pas bien ce que tu veux faire coté émetteur.
Si tu veux ranger tes entrées dans tab_etat c’est très simple:

const byte tabEntrees[]={L1H,L1B,L2H,L2B,C1G,C1D};

void loop()
{
  for (int i=0; i<sizeof tabEntrees; i++)
    tab_etat[i]=digitalRead(tabEntrees[i]);
  delay(20);
}

Non je ne veux pas envoyer l'état brut des entrées, ce que j'envois diffère suivant le mode de la télécommande :

  • mode fonction vérin
  • mode fonction treuil
  • mode fonction treuil inverse

le récepteur comporte 9 relais et la télécommande 4 poussoir configurés par le commutateur 3 fonctions

"tab_etat est l'image de l'état des 8 premiers relais du récepteur
en mode vérin, seul les 4 premiers relais doivent fonctionner, en mode treuil et treuil inverse, seul les 4 suivant doivent fonctionner.
Le 9ème est commandé lorsque l'un des 4 premiers est commandé
Je sais c'est peut être pas très clair...
La partie émetteur fonctionne correctement, probablement que le code pourrait être plus simple.
Mon problème se situe niveau récepteur.
Si plus de signal reçu, je voudrai mettre tous les relais à l'arret.

Salut
tu peux envoyer depuis la télécommande un bit qui change d’état toute les 500ms.
sur le éecepteur, tu vérifie qu’il change d’état, sinon tu coupes toutes les sorties

il faut tester si tu n'a rien reçu pendant un certain temps

void loop() // executée en boucle
{
  static unsigned long lastReception = millis();
  if (Serial.available ())
  {
    if (Serial.read() == '#')
    {
      lastReception = millis();
      lire_etat();
    }
  }
  else
  {
    if (millis()-lastReception>1000UL)    // on n'a rien reçu pendant une seconde (1000 ms)
    {
      // ------- ici arrêter toutes les sorties ---------
      //
    }
  }
}