Parlons Arduino > Vos projets
Récupération données DCC: CircularBuffer et ShiftOut
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
[#] Page suivante
Utiliser la version classique