Parlons Arduino > Vos projets

Récupération données DCC: CircularBuffer et ShiftOut

(1/9) > >>

Loco28:
Bonsoir,
J'ai commencé depuis quelques temps la réalisation de décodeurs d'accessoires sur base ARDUINO.
J'utilise la bibliothèque DCC_Decoder. Le système marche très bien pour les aiguillages mais je me suis aperçu récemment que du côté des signaux il y avait des ratés.
Après analyse, tests et interrogations sur les forums, je suis arrivé à la conclusion que le traitement des données, que je faisais à la suite du void BasicAccDecoderPacket_Handler, me faisait louper des données.
j'ai donc inclus une autre bibliothèque, CircularBuffer, pour enregistrer les données immédiatement après le "Handler" puis les récupérer et les traiter, cette fois-ci dans la "loop".
Et là, impeccable, je ne loupais plus de données, au vu du Serial.print.
J'ai donc continué le traitement des données pour activer les sorties: tout est OK jusqu'au calcul de la valeur à envoyer (ici CDE4) mais rien ne se passe avec le ShiftOut (j'utilise des registres à décalage).
J'en viens à me demander si l'instruction ShiftOut ne se percute pas avec la fonction buffer.shift() de CircularBuffer!
Je précise que je travaille avec CDM-Rail et que je ne suis pas un grand spécialiste de la programmation (cela ressemble sûrement à "la programmation pour les nuls")
Ci-dessous une copie de mon code que j'ai allégé pour aller au plus simple, mais avec lequel j'ai bien un problème au moment de l'envoi du ShiftOut.
------------------------------------------------------------------------------------------------------------------------------------


--- Code: ---#include <DCC_Decoder.h>
#define kDCC_INTERRUPT    0    // pin 2 for UNO
#include <CircularBuffer.h>

CircularBuffer <int, 100> storadresse;
CircularBuffer <byte, 100> storaction;

int add = 0;
int act = 0;
int old_add = 0;
int old_act = 0;
int action = 0;

const int CLOCK2 = 8;
const int LATCH2 = 9;
const int DATA2 = 10;

int OUT4[8];

int CDE4 = 0;

//Handler DCC
void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data){
  //Serial.print(address);
  //Serial.print("    ");
  //Serial.println(data);
 storadresse.push (address);
 storaction.push (data);
  }
void setup() {     
  DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true);
  DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT );
  Serial.begin (115200); 
  Serial.println("Debut test");
}
void loop() {
  DCC.loop();

  while(!storadresse.isEmpty()) {
   add = storadresse.shift();
   act = storaction.shift();

 if ((add != old_add) || (act != old_act)){
    old_add = add;
    old_act = act;
// Conversion de l'adresse NMRA en adresse decodeur d'accessoire
   add -= 1;
   add *= 4;
   add += 1;
   add += (act & 0x06) >> 1;
   action =(act & 0x01);
   Serial.print(add);
   Serial.print("   ");
   Serial.println(action);

  //Gestion des signaux
 
 //Registre à décalage OUT4
  if((add >=127) && (add <= 134)){ 
    if(action = 1){
    OUT4[add - 127] = bit(add - 127);
    }
    else{
    OUT4[add - 127] = 0;
    }
  }//fin boucle OUT4
         
//Envoi OUTT4

    CDE4 = OUT4[0]+OUT4[1]+OUT4[2]+OUT4[3]+OUT4[4]+OUT4[5]+OUT4[6]+OUT4[7];
    Serial.println(CDE4);
   
    digitalWrite(LATCH2, LOW);
    shiftOut(DATA2, CLOCK2, LSBFIRST, CDE4);     
    digitalWrite(LATCH2, HIGH);

   } //fin nouvelle donnée
  } //fin while   
} //fin loop

--- Fin du code ---
--------------------------------------------------------------------------------------------------------------------

Merci d'avance à ceux qui pourront m'aider

Loco28:
Désolé, je clos le post.
le problème est dans le SETUP: il manque la définition en OUTPUT pour CLOCK, LATCH et DATA

Jean-Luc:
Souvent il suffit d'exposer son problème pour le voir sous un autre jour et détecter l'erreur  :)

CATPLUS:
Bonjour

Aurais-tu STP l'amabilité de nous faire partager ton fichier ".ino" revisé
et le montage qui va avec.

Cordialement

Marcel

Loco28:
Effectivement il y avait une grossière erreur (suite à un effacement malheureux ou un copier/coller raté)) que je ne voyais pas, d'où l'intérêt de faire appel à d'autres paires d'yeux.
Tout est rentré dans l'ordre.
J'ai encore du boulot pour finaliser mon projet mais j'ai commencé à écrire un document pour rassembler tout ça (schémas, programme, photos de cartes, ...).
En attendant, ci-dessous le programme, sûrement perfectible, qui me permet de piloter 12 signaux, au travers de 3 registres à décalage
-------------------------------------------------------------------------------------------------------------
#include <DCC_Decoder.h>
#define kDCC_INTERRUPT    0    // pin 2 for UNO

#include <CircularBuffer.h>

CircularBuffer <int, 100> storadresse;
CircularBuffer <byte, 100> storaction;
int add = 0;
int act = 0;
int old_add = 0;
int old_act = 0;
int action = 0;

//pour les 595
const int CLOCK1 = 4;
const int LATCH1 = 5;
const int DATA1 = 6;

int OUT5[8];
int OUT6[8];
int OUT7[8];

int CDE5 = 0;
int CDE6 = 0;
int CDE7 = 0;

//Handler DCC

void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data){
 storadresse.push (address);
 storaction.push (data);
}
void setup() {
  DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true);
  DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT );
  Serial.begin(115200);
  Serial.println("ADRESSE      ACTION");
 
  pinMode(LATCH1, OUTPUT);
  pinMode(CLOCK1, OUTPUT);
  pinMode(DATA1, OUTPUT);

//mise à zéro OUT5, OUT6, et OUT7
   digitalWrite(LATCH1, LOW);
  shiftOut(DATA1, CLOCK1, MSBFIRST, 0);
  shiftOut(DATA1, CLOCK1, MSBFIRST, 0);
  shiftOut(DATA1, CLOCK1, MSBFIRST, 0);
  digitalWrite(LATCH1, HIGH); 
}

void loop() { 
  DCC.loop();

  while(!storadresse.isEmpty()) {
   add = storadresse.shift();
   act = storaction.shift();

 if ((add != old_add) || (act != old_act)){
    old_add = add;
    old_act = act;

// Conversion de l'adresse NMRA en adresse decodeur d'accessoire
   add -= 1;
   add *= 4;
   add += 1;
   add += (act & 0x06) >> 1;
   act =(act & 0x01);
   Serial.print(add);
   Serial.print("   ");
   Serial.println(act);
 
 //Gestion des signaux
  if((add >=151) && (add <= 174)) { //boucle adresse feux
   
 //Registre à décalage OUT5
  if((add >=151) && (add <= 158)) {
    if(act == 1){
    OUT5[add - 151] = bit(add - 151);
    }
    else{
    OUT5[add - 151] = 0;
    }
  }//fin boucle OUT5
 
   //Registre à décalage OUT6
  if((add >=159) && (add <= 166)) {
    if(act == 1){
    OUT5[add - 159] = bit(add - 159);
    }
    else{
    OUT5[add - 159] = 0;
    }
  }//fin boucle OUT6
 
   //Registre à décalage OUT7
  if((add >=167) && (add <= 174)) {
    if(act == 1){
    OUT5[add - 167] = bit(add - 167);
    }
    else{
    OUT5[add - 167] = 0;
    }
  }//fin boucle OUT7
   
//envoi data vers OUT5, OUT6 et OUT7

    CDE5 = OUT5[0]+OUT5[1]+OUT5[2]+OUT5[3]+OUT5[4]+OUT5[5]+OUT5[6]+OUT5[7];
    CDE6 = OUT6[0]+OUT6[1]+OUT6[2]+OUT6[3]+OUT6[4]+OUT6[5]+OUT6[6]+OUT6[7];
    CDE7 = OUT7[0]+OUT7[1]+OUT7[2]+OUT7[3]+OUT7[4]+OUT7[5]+OUT7[6]+OUT7[7];

    digitalWrite(LATCH1, LOW);
    shiftOut(DATA1, CLOCK1, LSBFIRST, CDE7);
    shiftOut(DATA1, CLOCK1, LSBFIRST, CDE6);
    shiftOut(DATA1, CLOCK1, LSBFIRST, CDE5);           
    digitalWrite(LATCH1, HIGH);
     
         }//fin boucle adresse feux
      }//fin boucle si nouveaux data   
  }//fin while
}//fin loop
----------------------------------------------------------------------------------------------------------------------

Navigation

[0] Index des messages

[#] Page suivante

Utiliser la version classique