LOCODUINO

Parlons Arduino => Vos projets => Discussion démarrée par: Loco28 le décembre 07, 2017, 12:05:56 am

Titre: Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le décembre 07, 2017, 12:05:56 am
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.
------------------------------------------------------------------------------------------------------------------------------------

#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
--------------------------------------------------------------------------------------------------------------------

Merci d'avance à ceux qui pourront m'aider
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le décembre 07, 2017, 10:53:10 pm
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
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le décembre 08, 2017, 07:56:46 am
Souvent il suffit d'exposer son problème pour le voir sous un autre jour et détecter l'erreur  :)
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: CATPLUS le décembre 08, 2017, 09:29:01 am
Bonjour

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

Cordialement

Marcel
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le décembre 08, 2017, 11:56:05 pm
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
----------------------------------------------------------------------------------------------------------------------
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: CATPLUS le décembre 09, 2017, 06:30:45 am
Bonjour

Merci pour ce partage :)
On attends la suite......

Cordialement
Marcel
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le janvier 22, 2018, 03:59:55 pm
J'aurais besoin que quelques spécialistes (plus que moi) regardent mon code.
Ce code fonctionne bien dans 95% des cas (sous CDM-Rail). par contre, dans le cas de commande d'itinéraires, quand, par exemple, 3 aiguillages doivent être commandés en même temps, et malgré le fait que CDM temporise les envois (0,5s), je loupe des commandes.
Il me semblait, qu'à partir du moment où je remplis un fichier FIFO dans le cadre de la routine d'interruption et que je le traite en dehors de cette routine (dans la LOOP) je ne pouvais rien rater.
Est-ce que j'ai bien compris? et est-ce que mon code est correct?
Une petite indication, en m'aidant des Serial.print (qui ne sont là que pour la mise au point), j'ai constaté qu'en supprimant les SHIFOUT je ne loupais plus de commandes DCC.

Ci-dessous mon code.

//Programme de gestion des aiguillages de la zone Bréauté
#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 LATCH1 = 6;
const int CLOCK1 = 7;
const int DATA1 = 5;

int OUT1[8];
int OUT2[8];
int OUT3[8];

int CDE1 = 0;
int CDE2 = 0;
int CDE3 = 0;


//Handler DCC
void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data){
  storadresse.push (address);
  storaction.push (data);
  Serial.print(address);
  Serial.print("   ");
  Serial.println(data);
}

void setup() {
  DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true);
  DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT );
  Serial.begin (115200);

  Serial.println(" DCC brut          ADRESSE   ACTION");
 
  pinMode(LATCH1, OUTPUT);
  pinMode(CLOCK1, OUTPUT);
  pinMode(DATA1, OUTPUT);

}

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("                        ");
    Serial.print(add);
    Serial.print("    ");
    Serial.println(action);
   
//Gestion aiguillages
 
//registre à décalage OUT1
  if((add >= 1) && (add <= 8)) {
    if (action == 1) {
      OUT1[add-1] = bit(add - 1);
    }
    else {
      OUT1[add-1] = 0;
    }
  } //fin OUT1

//registre à décalage OUT2
  if((add >= 9) && (add <= 16)) {
    if (action == 1) {
      OUT2[add-9] = bit(add - 9);
    }
    else {
      OUT2[add-9] = 0;
    }
  } //fin OUT2

  //registre à décalage OUT3
    if((add >= 17) && (add <= 24)) {
    if (action == 1) {
      OUT3[add-17] = bit(add - 17);
    }
    else {
      OUT3[add-17] = 0;
    }
  } //fin OUT3
 
//envoi des commandes

  CDE1 = OUT1[0]+OUT1[1]+OUT1[2]+OUT1[3]+OUT1[4]+OUT1[5]+OUT1[6]+OUT1[7];
  CDE2 = OUT2[0]+OUT2[1]+OUT2[2]+OUT2[3]+OUT2[4]+OUT2[5]+OUT2[6]+OUT2[7];
  CDE3 = OUT3[0]+OUT3[1]+OUT3[2]+OUT3[3]+OUT3[4]+OUT3[5]+OUT3[6]+OUT3[7];
 
  digitalWrite(LATCH1, LOW);
  shiftOut(DATA1, CLOCK1, LSBFIRST, CDE3);
  shiftOut(DATA1, CLOCK1, LSBFIRST, CDE2);
  shiftOut(DATA1, CLOCK1, LSBFIRST, CDE1);       
  digitalWrite(LATCH1, HIGH);
 
     }//fin boucle si nouveaux data
   }//fin while   
  }//fin programme principal
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le janvier 22, 2018, 04:20:27 pm
Commence par retirer les

  Serial.print(address);
  Serial.print("   ");
  Serial.println(data);

De debug dans ton handler, ça prend des plombes à s'executer. Ça peut aussi bloquer ton application car ça ne doit pas être utilisé dans un handler d'interruption.

Ensuite tu as un problème de concurrence sur tes buffers entre le programme principal et ton handler d'IT.
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le janvier 22, 2018, 05:59:50 pm
OK pour enlever les "serial.print". C'était mon intention mais j'avais le problème sans ça.

Par contre, tu peux m'expliquer la "concurrence" entre les buffers?
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Dominique le janvier 22, 2018, 06:33:40 pm
Peut-être faut-il arrêter les interruptions avant
   add = storadresse.shift();
   act = storaction.shift();
et les rétablir après ?

Cette discussion est intéressante : je ne connaissais pas la biblio CircularBufffer !
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le janvier 23, 2018, 08:21:38 am
Oui,

Si une interruption survient alors que l'un des shift est en cours d'exécution, l'un des push va modifier un tampon circulaire qui est au milieu de son shift avec pour conséquence une altération des données ou des index de lecture et d'écriture. Il faut effectivement bloquer les IT pour les deux shift.
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le janvier 23, 2018, 08:11:55 pm
D'accord mais qu'est ce qui se passe si des données DCC arrivent pendant cet instant de blocage?

Et, question d'un néophyte dans le domaine des IT: comment bloque-t-on une IT et comment on la réactive?


Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le janvier 23, 2018, 08:48:33 pm
Si les IT sont bloquées, l’IT la plus prioritaire sera prise en compte quand les IT seront débloquées. Donc à moins de bloquer pendant une durée supérieure au temps dl’arrivée de deux IT consécutives de même type, rien ne sera perdu. Mais, dans le cas du DCC, le temps est important et il ne faut pas que le temps de blocage conduise à mal interpréter les bits d’une trame DCC.

Pour bloquer les IT, il faut appeler la fonction noInterrupts(). Pour les débloquer, interrupts().

https://www.arduino.cc/reference/en/language/functions/interrupts/nointerrupts/
https://www.arduino.cc/reference/en/language/functions/interrupts/interrupts/

Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le janvier 23, 2018, 09:57:03 pm
Donc, si j'ai bien compris, j'ajoute une ligne "nointerrupts() avant mes 2 lignes ".shift" et j'ajoute une ligne "interrupts()" juste après?
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le janvier 23, 2018, 10:29:10 pm
Exactement
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le janvier 24, 2018, 07:48:05 pm
Bon, c'est fait. j'ai ajouté un "noInterrupts()" juste avant le dépilage des fichiers (.shift) et j'ai mis un "interrupts()" après.
Malheureusement cela n'a rien changé.
J'ai évidemment supprimé le "Serial.print" dans le Handler DCC.

J'ai eu l'idée de supprimer les 3 lignes "shiftout" et là, cela marche, du moins en affichage car du coup je n'ai plus la commande de mes aiguilles.
Après j'ai remis 1 ligne "shiftout", OK puis 2, OK et à 3 NOK.
J'ai aussi essayé en mettant "noInterrupts()" et "interrupts()" de chaque côté des lignes "shiftout" mais sans succès.
Là, j'avoue que je suis un peu "sec" sur la suite.
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le janvier 24, 2018, 09:06:08 pm
Tu pourrais mettre ton sketch en fichier attaché ?
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le janvier 24, 2018, 10:40:58 pm
Ci-joint mon sketch
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le janvier 24, 2018, 11:57:48 pm
As tu essayé de mesurer le temps pris par les 3 shiftOut ? et par la totalité de ton programme principal ?

Ajoute avant le premier shiftOut

unsigned long date = micros();

Puis après les shiftOut

Serial.print("Duree = ");
Serial.println(micro() - date);

Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le janvier 25, 2018, 03:47:44 pm
Le programme principal (LOOP) s'exécute en 500 microsecondes et les 3 SHIFTOUT en 420/424 microsecondes.

D'un autre côté, la commande des aiguillages est censée se faire avec 0,5s entre chaque soit 500 000 microsecondes. Il ne devrait donc pas y avoir de problème.
J'ai déjà signalé à JPP38 sur le forum CDM-rail ce problème et il m'assure que même lors des commandes d'itinéraires les commandes sont cadencées.
Ce qui est bizarre, c'est qu'à l'initialisation du RUN, tous les aiguillages sont mis en place et là, je constate bien ce cadencement à 0,5s et il n'y a aucun ratés.
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le janvier 25, 2018, 03:49:40 pm
Quel registre à décalage utilises-tu ?
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le janvier 25, 2018, 05:09:04 pm
C'est des 74HC595
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le janvier 25, 2018, 05:17:38 pm
Ok,

Je pense que déjà tu peux améliorer les choses en utilisant le SPI pour envoyer tes données. Regarde la dernière section de http://www.instructables.com/id/74HC595-Shift-Register-With-Arduino-Uno/

Tu passera de 420µs à, à vue de nez, 4µs

Il y a aussi du temps à gagner dans la manière dont tu assembles les bits que tu envoies.
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le janvier 25, 2018, 07:19:32 pm
Effectivement cela me semble plus qu'intéressant et relativement simple. Il faut effectivement que je gagne du temps sur l'envoi vers les registres. j'ai refait des essais cet am en enlevant 1 registre et cela marchait presque à tous les coups.
Je sens que je vais ressortir ma platine d'essai.
Par contre, ce que je ne vois pas, c'est comment on fait si on veut envoyer des valeurs vers 2 ou 3 HC595.
J'ai essayé de m'inscrire sur ce site pour poser une question mais je n'y arrive pas ("date de naissance erronée" ??)
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le janvier 25, 2018, 07:24:06 pm
Par contre, ce que je ne vois pas, c'est comment on fait si on veut envoyer des valeurs vers 2 ou 3 HC595.

Il faut les chainer, la sortie série du premier sur l'entrée série du second, etc

Citer
J'ai essayé de m'inscrire sur ce site pour poser une question mais je n'y arrive pas ("date de naissance erronée" ??)

Je n'y arrive pas non plus.
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le janvier 25, 2018, 07:51:36 pm
Je sais les chainer sur l'aspect hardware mais je ne vois pas, dans son programme avec le SPI, comment on envoie plusieurs valeurs à la suite surtout qu'il utilise un sous-programme qui ne prends qu'un seul argument. A moins qu'il suffise de passer plusieurs arguments comme value1, value2, value3 et de les envoyer avant la ligne de "fin SPI"?

Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le janvier 25, 2018, 08:14:14 pm
SPI.transfer envoie un octet comme shiftOut. Pour envoyer plusieurs octets il faut faire plusieurs SPI.transfer
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le janvier 25, 2018, 11:11:28 pm

Donc ca donnerait quelque chose comme:

void shiftByte( CDE1, CDE2, CDE3){
PORTC &= B11111101;//Data clock low
   SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
   SPI.transfer(CDE3);
        SPI.transfer(CDE2);
        SPI.transfer(CDE1);
   SPI.endTransaction();
   PORTC |= B00000010;//Data clock high, latch data
}
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le janvier 25, 2018, 11:54:45 pm
Plus simplement, remplace

    digitalWrite(LATCH1, LOW);
    shiftOut(DATA1, CLOCK1, LSBFIRST, CDE3);
    shiftOut(DATA1, CLOCK1, LSBFIRST, CDE2);
    shiftOut(DATA1, CLOCK1, LSBFIRST, CDE1);           
    digitalWrite(LATCH1, HIGH);

Par

    digitalWrite(LATCH1, LOW);
    SPI.beginTransaction(SPISettings(16000000, LSBFIRST, SPI_MODE0));
    SPI.tranfer(CDE3);
    SPI.tranfer(CDE2);
    SPI.tranfer(CDE1);
    SPI.endTransaction();
    digitalWrite(LATCH1, HIGH);
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le janvier 28, 2018, 05:45:58 pm
J'ai effectué une modification "hard" (changement des pins CLOCK, LATCH, DATA) pour pouvoir tester avec SPI.
Pour le LATCH, j'ai pris la pin 12 (à priori on n'est pas obligé de prendre A1). Comme ça, mes 3 pins sont groupées (11, 12 et 13).
Je me suis assuré que la carte fonctionne toujours en "SHIFTOUT", puis j'ai modifié le programme pour utiliser la fonction SPI.
Problème: je reste "coincé" au premier passage: j'envoi une commande, le la vois bien avec le Serial.print, puis plus rien.
Je ne peux envoyer aucune autre commande.
Je mets mon sketch en pièce jointe.

Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le janvier 28, 2018, 05:56:36 pm
Il manque le

SPI.begin();

dans setup

Et tu devrais commencer par tester que tu envoies bien en SPI aux 595 dans un sketch séparé sans DCC. Test unitaire !
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le janvier 28, 2018, 06:16:54 pm
Un truc qui serait bien : indenter correctement le code. À chaque fois que je regarde un programme il faut que je le ré-indente, c'est pas cool
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le janvier 28, 2018, 07:37:39 pm
OK, je vais tester en rajoutant le SPI.begin()

Excuse ma question, mais "re-indente" cela veut dire quoi?
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le janvier 28, 2018, 07:42:01 pm
https://fr.wikipedia.org/wiki/Style_d%27indentation

Je préfère le K&R ou le Allmann.
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le janvier 28, 2018, 08:42:08 pm
OK, je vais essayer de faire au mieux.


Je sais que mon câblage est bon car la carte a fonctionné avec les "SHIFTOUT".
Je vais faire un skectch pour tester un registre en allumant puis éteignant chaque sortie.
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le janvier 28, 2018, 10:47:47 pm
c'est bon ça fonctionne mais il a fallut que je mette le LATCH sur la pin A1 (au lieu de 12), alors que sur le site il est dit"generally this one can be any pin".
Maintenant il me faut tout remettre sous le train, recâbler les relais de commande des aiguillages et repasser à une phase de test sous CDM pour voir si mon problème de "ratés" est résolu.
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le janvier 29, 2018, 12:13:37 am
C’est pas tout à fait anormal. La pin 12 c’est MISO. Ton chip select entrait en conflit avec la réception des données sur le SPI (qui ne sert certes à rien ici mais qui ne peut pas être utilisé comme chip select quoiqu’il en soit)

Sur le site, la pin 12 est celle du 595, pas celle de l’Arduino.
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Loco28 le janvier 29, 2018, 11:17:15 pm
Tout fonctionne parfaitement. Plus de ratés.
Merci pour ton aide.....et ta patience.
Je mets en pièce jointe mon sketch (je l'ai "arrangé" au mieux).
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le avril 27, 2018, 12:30:06 pm
Bonjour,

J'ai regardé l'implémentation de CircularBuffer et je ne suis pas très fan de ce qui y est fait, j'ai notamment tiqué sur :

template<typename T, __CB_ST__ S>
T CircularBuffer<T,S>::pop() {
void(* crash) (void) = 0;
if (count <= 0) crash();
T result = *tail--;
if (tail < buffer) {
tail = buffer + S - 1;
}
count--;
return result;
}

Traduction :


Donc exécuté sur une machine de bureau, ce genre de code va planter l'application, ce qui est le but recherché, soit.

Exécuté sur un Arduino/AVR, on exécute le code situé à l'adresse 0. Qu'a-t-on à l'adresse 0 ? le vecteur reset. Sur un Arduino/ARM on a la valeur du pointeur de pile à l'adresse 0  :o

BREF ÇA FAIT N'IMPORTE QUOI. Comment peux-t-on écrire des trucs pareils  ::)

J'ai donc fait mon tampon circulaire, qui en plus occupe moins de mémoire, et qui propose aussi des fonctions de lecture et d'écriture qui sont blindées contre les interruptions.

C'est pour l'instant ici : https://github.com/Locoduino/RingBuffer/releases
et d'ici quelques jours dans le gestionnaire de bibliothèques de l'IDE.
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Dominique le avril 30, 2018, 09:38:26 am
Ça c’est du beau code !

Comme j’ai écrit mon propre tampon circulaire dans les réceptions de messages Can, je vais intégrer cette bibliothèque à la place.

Merci Jean-Luc  ;D
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Tony04 le mai 25, 2018, 06:53:04 pm
Coucou,

super échange entre Jean-Luc et Dominique sur les tampons circulaires.

Comme toutes mes cartes communiquent par CAN avec ton ancien tampon (à Dominique), pourrais-tu me faire parvenir un exemple avec le nouveau tampon, j'ai beau essayer de comprendre, mon cerveau ne suit plus.

Bon WE
Antoine
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: Jean-Luc le mai 25, 2018, 08:50:38 pm
Bonsoir Tony

Il y a des exemples dans la bibliothèque qui est disponible via le gestionnaire de l'IDE. Il y a également quelques bouts de code à la fin de la doc en bas de page : https://github.com/Locoduino/RingBuffer
Titre: Re : Récupération données DCC: CircularBuffer et ShiftOut
Posté par: SUPERN le septembre 26, 2018, 03:51:45 pm
Salut Loco28,

As-tu changé CircularBuffer pour la solution RingBuffer?
Si oui, peux-tu nous donner ton dernier sketch (je n'ai pas réussi à trouver circularbuffer et vu les remarques de Jean-Luc je ne le ferai pas....)?
Merci d'avance!

A+
Yves