Auteur Sujet: Bibliotheque minabay et le DCC.loop()  (Lu 4215 fois)

Mcarmina

  • Newbie
  • *
  • Messages: 5
    • Voir le profil
Bibliotheque minabay et le DCC.loop()
« le: juin 13, 2017, 12:10:42 am »
Bonsoir à vous tous,

je développe (j'essaye) un décodeur accessoire basé sur un nano et la bibliothèque de minabay pour piloter 7 servo d'aiguillage avec un relais pour la pointe de coeur.
mon système fonctionne bien, pas de soucis mais :
pour plus de réalisme j'ai ralenti la vitesse du décodeur dans une boucle comme ci dessous (les serial.print sont uniquement là pour comprendre ce qui se passe)
le temps de déplacement d'une butée à l’autre est de 1sec. Pendant ce temps le nano n'est pas capable de lire une commande DCC. Je suis sur Train Controller et Train Controller envoi les ordres les uns derrière les autres sans delai, le résultat fait que mon système n'est pas capable de lire toutes les commandes DCC envoyées par la centrale. en fait il lit la premiere et puis plus rien tant que le servo n'est pas arrivé
Logiquement j'ai inserré une commande DCC.loop() dans la boucle for pour pouvoir lire plusieurs commande DCC en provenance de la centrale.

case 0:  // bouge le servo vers position droite
        for (pos = Aig[xx][2] ; pos <= Aig[xx][1] ; pos = pos + Pas) {
          Aig1.writeMicroseconds(pos);
          Serial.println (pos);
          delay(30);
          if (pos == xP + Aig[xx][2] ) {
            Serial.println("vers pos droite pos Droit > devié relais actionne");
            digitalWrite (NumPinR[xx], LOW);
            DCC.loop();
          }
        }
        Aig1.writeMicroseconds(Aig[xx][1] + Ressort);
        break;
      case 1:  // bouge le servo vers position deviee
        for (pos = Aig[xx][1] ; pos >= Aig[xx][2] ; pos = pos - Pas) {
          Aig1.writeMicroseconds(pos);
          Serial.println (pos);
          delay(30);
          if (pos == Aig[xx][1] - xP) {
            Serial.println("vers pos deviee pos Droit > devié relais actionne");
            digitalWrite (NumPinR[xx], HIGH);
             DCC.loop();
          }     
        }

dans la routine de lecture de la commande j'ai cree une pile pour sauvegarder les commandes DCC envoyées par la centrale

void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data)
{
  // Convert NMRA packet address format to human address
  address -= 1;
  address *= 4;
  address += 1;
  address += (data & 0x06) >> 1;
  Etat = (data & 0x01) ? HIGH : LOW;

  Serial.print ("addresse lue DCC: ");
  Serial.print (address);
  Serial.print ("   Position cde: ");
  Serial.print (Etat);
  Serial.print ("  pointeur pile: ");
  Serial.println (PileAdrPointeur);

  if ((address >= DCC_AddressDeb) && (address < DCC_AddressDeb + NbrServo) && (PileAdrPointeur < NbrServo + 2))  {

    if ((PileAdrPointeur >= 1)) {  // gestion de la pile a l'empilage
      DCC_AddressLu = PileAdr[PileAdrPointeur-1] ;
      EtatCdeDCC = PileAigPos[PileAdrPointeur-1] ;
    }
    else {
      DCC_AddressLu = 0;
    }

    if ((DCC_AddressLu == address) && (EtatCdeDCC != Etat) || (DCC_AddressLu != address)) {
      PileAdrPointeur = PileAdrPointeur + 1 ;
      PileAdr[PileAdrPointeur-1] = address ;
      PileAigPos[PileAdrPointeur-1] = Etat;
      Serial.print ("addresse sauver sur pile: ");
      Serial.print (address);
      Serial.print ("  Position Cde sauve: ");
      Serial.print (Etat);
      Serial.print ("  pointeur :");
      Serial.println (PileAdrPointeur);
    }
  }
}

et dans ma void loop() je depile et actionne mes servos

void loop()
{

  Tp1 = millis();
  DCC.loop();

  if (PileAdrPointeur >= 1) {  // Gestion de la pile au depilage
    DCC_AddressLu = PileAdr[0] ;
    EtatCdeDCC = PileAigPos
  • ;

    AigPos[DCC_AddressLu - DCC_AddressDeb] = EtatCdeDCC;
    EtatChange = true ;
    for (xx = 2 ; xx <= PileAdrPointeur ; xx++) {  // depile
      PileAdr[xx - 2] =  PileAdr[xx - 1];
      PileAigPos[xx - 2] =  PileAigPos[xx - 1];
    }
    PileAdrPointeur = PileAdrPointeur - 1;
  }

  if (EtatChange == true) {   //   actionne le servo lu par le DCC
    Serial.print("@ à bouger: ");
    Serial.print(DCC_AddressLu);
    Serial.print("  etat: ");
    Serial.println(EtatCdeDCC);
    Tp = millis();

    switch (DCC_AddressLu - DCC_AddressDeb) {
      case 0:  // aiguillage 1
        xx = 0;
        Update_Aig();
        Update_Aig1();
        break ;
      case 1:  // aiguillage 2
        xx = 1;
        Update_Aig();
        Update_Aig2();
        break;
      case 2:  // aiguillage 3


bon ben ça ne marche pas, j'ai comme l'impression que les commandes DCC.loop() dans les boucles for ne fonctionnent pas
un peu d'aide svp, merci, je bloque et ne comprends pas pourquoi.
pour info, il y a 10 mois je ne connaissais pas l’existence du langage C, donc il doit bien y avoir dans mon code quelques problemes, soyez donc  indulgent :)

jeanmi67

  • Newbie
  • *
  • Messages: 29
    • Voir le profil
Re : Bibliotheque minabay et le DCC.loop()
« Réponse #1 le: juin 13, 2017, 12:24:27 am »
...
le temps de déplacement d'une butée à l’autre est de 1sec. Pendant ce temps le nano n'est pas capable de lire une commande DCC. Je suis sur Train Controller et Train Controller envoi les ordres les uns derrière les autres sans delai, le résultat fait que mon système n'est pas capable de lire toutes les commandes DCC envoyées par la centrale. en fait il lit la premiere et puis plus rien tant que le servo n'est pas arrivé
Logiquement j'ai inserré une commande DCC.loop() dans la boucle for pour pouvoir lire plusieurs commande DCC en provenance de la centrale.

Bonjour,

Une première piste : je ne sais pas quelle est la finalité des instructions delay(30) dans la routine mais toujours est-il que la fonction delay() met en pause totale le programme. Donc si des commandes DCC arrivent durant cette pause, elles seront perdues.

Par ailleurs, et à titre personnel, je ne trouve pas très heureux le choix de la police utilisée pour retranscrire du code.
L'utilisation de la balise "Code" (bouton #) serait sans doute plus judicieux. Exemple :
case 0:  // bouge le servo vers position droite
        for (pos = Aig[xx][2] ; pos <= Aig[xx][1] ; pos = pos + Pas) {
          Aig1.writeMicroseconds(pos);
          Serial.println (pos);
          delay(30);
          if (pos == xP + Aig[xx][2] ) {
            Serial.println("vers pos droite pos Droit > devié relais actionne");
            digitalWrite (NumPinR[xx], LOW);
            DCC.loop();
          }
        }
        Aig1.writeMicroseconds(Aig[xx][1] + Ressort);
        break;
      case 1:  // bouge le servo vers position deviee
        for (pos = Aig[xx][1] ; pos >= Aig[xx][2] ; pos = pos - Pas) {
          Aig1.writeMicroseconds(pos);
          Serial.println (pos);
          delay(30);
          if (pos == Aig[xx][1] - xP) {
            Serial.println("vers pos deviee pos Droit > devié relais actionne");
            digitalWrite (NumPinR[xx], HIGH);
             DCC.loop();
          }     
        }

Jean-Michel  :)
jeaNmi

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 2583
  • 100% Arduino et N
    • Voir le profil
Re : Bibliotheque minabay et le DCC.loop()
« Réponse #2 le: juin 13, 2017, 02:41:56 pm »
Bonjour Jean-Michel,

Tu as raison, il ne faut absolument pas utiliser l'instruction delay() qui te fera perdre tous les événements arrivant pendant ce temps là (sauf à utiliser les interruption, et encore...).

Il faut mémoriser le temps machine avec millis() au début d'une phase d'attente et tester ensuite, à chaque tour de loop, la position du temps machine par rapport à la valeur mémorisée augmentée du temps d'attente désiré.

Voilà !
Il y a plein d'exmples dans Locoduino (utiliser la fonction de recherche)

Amicalement
Dominique
Cordialement,
Dominique

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 2583
  • 100% Arduino et N
    • Voir le profil
Re : Re : Bibliotheque minabay et le DCC.loop()
« Réponse #3 le: juin 13, 2017, 02:45:01 pm »
Citer
L'utilisation de la balise "Code" (bouton #) serait sans doute plus judicieux
C'est fait pour cela  ;D ;D
Cordialement,
Dominique

Mcarmina

  • Newbie
  • *
  • Messages: 5
    • Voir le profil
Re : Bibliotheque minabay et le DCC.loop()
« Réponse #4 le: juin 13, 2017, 11:41:48 pm »
merci pour vos réponses je vais donc aller vers une orientation plutôt millis() que delay()
et pour l'option "code" , promis je n'utiliserai que cette option pour visualiser du code

Thierry

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 690
    • Voir le profil
Re : Bibliotheque minabay et le DCC.loop()
« Réponse #5 le: juin 14, 2017, 09:53:25 am »
Sinon, tu peux t'inspirer de ce que j'ai fait dans la bibliothèque Accessories qui déplace le servo d'un pas à chaque loop(), jusqu'à ce que le mouvement soit terminé. Cela permet aussi de déplacer plusieurs servos simultanément... Au final, pourquoi ne pas utiliser Accessories et Commanders qui ont déjà géré tout ça ?

Mcarmina

  • Newbie
  • *
  • Messages: 5
    • Voir le profil
Re : Re : Bibliotheque minabay et le DCC.loop()
« Réponse #6 le: juin 15, 2017, 07:28:01 pm »
Sinon, tu peux t'inspirer de ce que j'ai fait dans la bibliothèque Accessories qui déplace le servo d'un pas à chaque loop(), jusqu'à ce que le mouvement soit terminé. Cela permet aussi de déplacer plusieurs servos simultanément... Au final, pourquoi ne pas utiliser Accessories et Commanders qui ont déjà géré tout ça ?
Merci pour ta reponse,
honnêtement je n'ai pas regardé les codes de ces programmes et encore une fois je n'ai pas une grande experience du C, donc il m'est difficile de comprendre.
Avec ceux ci pendant le déplacement du (des) servo , peux tu recevoir d'autres commandes DCC pour le même Nano ?
en d'autres termes, Accessories et commanders enregistrent ils les commandes en provenance de la centrale sans pertes pendant un déplacement servo ?

Thierry

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 690
    • Voir le profil
Re : Bibliotheque minabay et le DCC.loop()
« Réponse #7 le: juin 15, 2017, 08:27:55 pm »
Un  déplacement n'est pas bloquant pour le reste du programme, donc oui, les événements DCC sont reçus, y compris pendant les mouvements des servos. C'est même plutôt l'inverse: comme c'est géré par des interruptions, le Dcc est prioritaire. Du coup les mouvement des servos peuvent être perturbés par la réception Dcc, mais vu les timings concernés, je ne pas sûr que l'interruption soit détectable...

Mcarmina

  • Newbie
  • *
  • Messages: 5
    • Voir le profil
Re : Re : Bibliotheque minabay et le DCC.loop()
« Réponse #8 le: juin 15, 2017, 10:45:22 pm »
Un  déplacement n'est pas bloquant pour le reste du programme, donc oui, les événements DCC sont reçus, y compris pendant les mouvements des servos. C'est même plutôt l'inverse: comme c'est géré par des interruptions, le Dcc est prioritaire. Du coup les mouvement des servos peuvent être perturbés par la réception Dcc, mais vu les timings concernés, je ne pas sûr que l'interruption soit détectable...
merci pour cette rapide reponse,
il ne me reste plus qu'à me pencher un peu plus sur Accessories et commanders
mais honnêtement je ne comprends pas pourquoi mon code ne peut pas interpretrer une commande DCC si un servo est en mouvement.