Trames TIC ERDF

Bonjour à tous,

Nouveau sur ce forum, que je parcours depuis de nombreux mois, je viens vous demander un petit coup de main parce que là, je sèche.

Je tente d’exploiter la sortie télé-information client des compteurs ERDF/ENEDIS. Sujet souvent traité, mon approche est à l’image de mon niveau : basique ! Et je n’en suis pas encore aux pointeurs, etc… Souvent employé par les champions…

Il s’agit de d’enregistrer dans un fichier texte sur le PC sur lequel l’Arduino est branché à une fréquence quelconque [5 minutes, p.ex.].

J’en suis au début (étape 1) et butte depuis quelques semaines. Je veux afficher sur le moniteur série sur une ligne l’ensemble des caractères d’une trame.

Donc, je pense que les pros me comprendront sans que j’explicite le format série du compteur. Donc, ma méthode :

  • j’attends de “voir” un STX pour…
  • rentrer dans une boucle while qui au fur et à mesure stocke les caractères reçu dans un tableau
  • à la lecture d’un ETX, j’imprime le tableau sur le moniteur série et réinitialise le tableau…
/* 
Lecture simple des trames des compteur CEB
Pin 3  : Software Serial RX
*/

#include <SoftwareSerial.h>

#define startFrame 0x02   // Caractère de début de trame
#define endFrame 0x03     // Caractère de fin de trame
#define startLine 0x0A    // Caractère de début de ligne
#define endLine 0x0D      // Caractère de fin de le ligne

char charIn;                // Initialisaiton de la variable de stockage des caractères reçus
int compteurCharTrame = 0 ;       // Nombre de caratère de la trame
char tamponTrame[] = "0";    // Création d'un tableau vide stockant les caractères de chaque ligne de la trame

SoftwareSerial compteurSerie = SoftwareSerial(8, 9) ;// On crée un port serie virtuel les ports 8 (RX) et 9 (TX, non utilisé) dédié à la liaison série du compteur 

void setup()
{
  Serial.begin(9600); // Initialisation de la liaison série du terminal
  compteurSerie.begin(1200); // Initialisation de la liaison série du compteur à 1200 bauds
  Serial.println("setup complete"); // Message sur la moniteur série
}
void loop()
{ 
	int compteurCharTrame = 0; // On réinitialise le compteur de caractère à 0
  //memset(tamponTrame, 0, sizeof(tamponTrame)); // On réinitialise le taleau à 0 partout
  for (int j=0 ; j<=sizeof(tamponTrame);j++) tamponTrame[j]='\0';
  
  Serial.println("Début loop : RAZ tampon"); // Message sur la moniteur série
  Serial.println("Attente STX");
  
  while (charIn != startFrame) // Boucle d'attente de lecture de STX
  {
    if (compteurSerie.available()) // Si des caractères sont disponibles dans le buffer, on les lit
    {
    charIn = compteurSerie.read() & 0x7F; // On lit le char qui passe auquel on retranche son 8ème bit (0x7F : DEL)
    Serial.print("."); //on affiche un. à chaque caractere different de STX
    }
  }
  
  Serial.println(" ");//retour à la ligne
  
  while (charIn != endFrame) // Boucle d'attente d'ETX : tant qu'on ne voit pas ETX , on reste dans cette boucle.
  {
    if (compteurSerie.available()) // Si le buffer contient des caractères...
    {
    charIn = compteurSerie.read() & 0x7F ; // On lit le charactère qui passe auquel on retranche son 8ème bit (0x7F : DEL)
    Serial.print("caractère reçu: ");
    Serial.println(charIn);
    
    tamponTrame[compteurCharTrame] = charIn; // On stocke le caractère courant dans le tableau selon le compteur de caractère
    Serial.println("Caractères dans tableau");
    compteurCharTrame ++;
    Serial.print("numero de ligne : ");
    Serial.println(compteurCharTrame);
    }
  } // Fin de la boucle while(charIn != endFrame)
  
  Serial.println("fin de trame reçu");
  Serial.print("TRAME = ");
  
  for (int i=0; i<=compteurCharTrame; i++) // On lance une boucle for...
  {
    Serial.print(tamponTrame[compteurCharTrame]); // pour imprimer le tableau sur le terminal série
    Serial.println("FIN"); // Un petit FIN de confirmation
   }
   //delay(10000); // Une petite tempo qui va bien entre 2 lectureS de trames
} // Fin de loop

Le résultat est quelque peu décevant…

Carsetup complete
Début loop : RAZ tampon
Attente STX
............................... 
caractère reçu: 

Caractères dans tableau
numero de ligne : 1
caractère reçu: A
Caractères dans tableau
numero de ligne : 2
caractère reçu: D
Caractères dans tableau
numero de ligne : 3
caractère reçu: C
Caractères dans tableau
numero de ligne : 4
caractère reçu: O
Caractères dans tableau
numero de ligne : 5
caractère reçu:  
Caracו⸮⸮⸮⸮ complete
Début loop : RAZ tampon
Attente STX
.................. 
caractère reçu: 

Caractères dans tableau
numero de ligne : 1
caractère reçu: A
Caractères dans tableau
numero de ligne : 2
caractère reçu: D
Caractères dans tableau
numero de ligne : 3
caractère reçu: C
Caractères dans tableau

Donc :

  • avec delay : rien sur le terminal série… A part qq caractères chelou… Voir PJ. Je vois pas pourquoi ça part pas…[/li][/list]
  • sans delay, ça bouge ! Mais :
  • il prend en compte uniquement les caractères du champs “ADC0” et pas le reste de la trame. [/li][/list]
  • Il n’imprime ni le tableau…, ni "TRAME : " reviens à "ATTENTE ST[/li][/list]

Désolé, ce n’est pas du haut niveau mais tout de même, j’ai vraiment besoin d’un coup de main…

Bonne soirée

char tamponTrame[] = "0";    // Création d'un tableau vide stockant les caractères de chaque ligne de la trame

Là, tu ne réserves qu'un tableau de 2 éléments. Tu vas avoir du mal à y placer la trame envoyée par ton compteur.

Maintenant, si tu ne reçois que la chaîne ADC0 c'est que le mode télé-information n'est pas activé sur ton compteur.
Extrait de la doc disponible chez EDF

L'état de la sortie de télé-information client du compteur « Bleu » électronique monophasé multitarif est
programmable dans l'une quelconque des 3 options : veille, métrologie, ou télé-information. L'option
métrologie permet d'émettre une impulsion (présence de porteuse à 50 kHz pendant un temps compris
entre 1 et 20 ms) à chaque fois que la consommation d'énergie mesurée par le compteur a augmenté
d'un wattheure. En option veille, le compteur émet en permanence une trame de télé -information réduite,
ne comportant que le groupe "ADCO" défini dans le tableau suivant. En option télé -information, le
compteur émet des trames complètes décrivant son état tarifaire.

Merci pour cette réponse !

tu ne réserves qu'un tableau de 2 éléments

Là, c'est sur que ça va être un peu juste : une première piste d'amélioration !

c'est que le mode télé-information n'est pas activé sur ton compteur

En fait, une "lecture simple" m'affiche l'intégralité de la TIC que je vois défilé. Tout va bien de ce coté. C'est vrai que je ne l'avais pas précisé)

Je ne sais pas par avance combien de caractères auront mes trames : en effet l'installation sera mise sur des compteurs ayant différents tarifs : BASE, HC, EJP, TEMPO... en MONO et TRI...

De plus, un champs de dépassement apparaît uniquement lorsqu'il y a.. dépassement.

Dès lors, faut-il réserver un gros tableau (400 caractères) dès le début quitte à le remplir au tiers la plus part du temps

char tamponTrame[400] = "0"

ou opter pour quelques chose de sans doute plus propre, mais là je sèche...

int compteurCharTrameMax

?

C'est pas une très bonne idée de faire un gros tableau.

Tu utilises un micro dont les capacités mémoire sont faibles.
Pour une uno, c'est 2kOctets, faire un tableau de 400 caractères, c'est donc 400 octets. Presque un quart de la mémoire totale
Il faut être plus économe, cherche la taille maxi que le compteur peut transmettre

L'usage de la mémoire est à adapter en fonction de l'application.
Si tu te contentes d'afficher la trame ce n'est même pas la peine de la mémoriser.
Si c'est pour la traiter en temps différé, tu peux ne conserver que les trames qui t'intéressent et ignorer les autres.
Si tu dois envoyer les informations sur l'Ethernet ou le Wifi (qui nécessitent des librairies conséquentes) il vaut mieux traiter ligne par ligne pour économiser la RAM.
Il faut bien voir que les caractères arrivent à 1200 bauds ce n'est pas particulièrement rapide et cela te laisse du temps pour traiter les trames au vol et limiter ainsi le stockage.

Merci pour vos réponses. :slight_smile:

Disons que je veux dans un premier temps afficher sur le moniteur série trame par trame. Voir ce que cela donne.

La suite consistait à écrire ces trames successives dans un fichier txt toutes les x minutes. D'où mon tableau. J'ai calculé que dans le pire des cas (compteur triphasé en dépassement sur les 3 phases : cas très rare), une trame fait environ 400 caractères (étiquette, champs et contrôle inclus).

Je vais essayer avec un tableau de 400 lignes déjà...

La question de la mémoire est aussi intéressante. 1200 bauds ce n'est pas rapide, on a le temps pour traiter ce qui arrive.

Et dans l'idéal, effectivement je n'ai pas besoin de toutes les lignes composant une trame. Mais dans l'immédiat, je ne fais dans la finesse, j'enregistre tout ce qui passe : je ne sais pas faire le tri !

Bonne journée à vous !

Bon, on avance !

J’ai donc défini un tableau à 400 lignes :

char tamponTrame[400] = "0";    // Création d'un tableau de 400 lignes stockant les caractères de chaque ligne de la trame

Les résultats sont très étranges : pour les 3 premières étiquettes ADC0, OPTARIF et ISOUSC, pas de problème, chaque caractère prend place dans une ligne comme il faut… [NB, c’est un compteur de test : l’ADC0 ne renvoi donc à aucun client réel…]

Je suppose que les lignes blanches correspondent au caractère “SP” entre 2 lignes de données.

numero de ligne : 1
caractère reçu: A
numero de ligne : 2
caractère reçu: D
numero de ligne : 3
caractère reçu: C
numero de ligne : 4
caractère reçu: O
numero de ligne : 5
caractère reçu:  
numero de ligne : 6
caractère reçu: 0
numero de ligne : 7
caractère reçu: 2
numero de ligne : 8
caractère reçu: 1
numero de ligne : 9
caractère reçu: 6
numero de ligne : 10
caractère reçu: 2
numero de ligne : 11
caractère reçu: 8
numero de ligne : 12
caractère reçu: 4
numero de ligne : 13
caractère reçu: 4
numero de ligne : 14
caractère reçu: 2
numero de ligne : 15
caractère reçu: 5
numero de ligne : 16
caractère reçu: 5
numero de ligne : 17
caractère reçu: 4
numero de ligne : 18
caractère reçu:  
numero de ligne : 19
caractère reçu: B
numero de ligne : 20
caractère reçu: 

numero de ligne : 21
caractère reçu: 

numero de ligne : 22
caractère reçu: O
numero de ligne : 23
caractère reçu: P
numero de ligne : 24
caractère reçu: T
numero de ligne : 25
caractère reçu: A
numero de ligne : 26
caractère reçu: R
numero de ligne : 27
caractère reçu: I
numero de ligne : 28
caractère reçu: F
numero de ligne : 29
caractère reçu:  
numero de ligne : 30
caractère reçu: H
numero de ligne : 31
caractère reçu: C
numero de ligne : 32
caractère reçu: .
numero de ligne : 33
caractère reçu: .
numero de ligne : 34
caractère reçu:  
numero de ligne : 35
caractère reçu: <
numero de ligne : 36
caractère reçu: 

numero de ligne : 37
caractère reçu: 

numero de ligne : 38
caractère reçu: I
numero de ligne : 39
caractère reçu: S
numero de ligne : 40
caractère reçu: O
numero de ligne : 41
caractère reçu: U
numero de ligne : 42
caractère reçu: S
numero de ligne : 43
caractère reçu: C
numero de ligne : 44
caractère reçu:  
numero de ligne : 45
caractère reçu: 4
numero de ligne : 46
caractère reçu: 5
numero de ligne : 47
caractère reçu:  
numero de ligne : 48
caractère reçu: ?
numero de ligne : 49
caractère reçu: 

numero de ligne : 50
caractère reçu:

Pour les étiquettes suivantes, ça part en cacahuète : les caractères devient aléatoires ne correspondent plus à rien…Après l’étiquette HCHC

numero de ligne : 51
caractère reçu: H
numero de ligne : 52
caractère reçu: C
numero de ligne : 53
caractère reçu: H
numero de ligne : 54
caractère reçu: C
numero de ligne : 55
caractère reçu:  
numero de ligne : 56
caractère reçu: 0
numero de ligne : 57
caractère reçu: 0
numero de ligne : 58
caractère reçu: 0
numero de ligne : 59
caractère reçu: 0
numero de ligne : 60
caractère reçu: 0
numero de ligne : 61
caractère reçu: 0
numero de ligne : 62
caractère reçu: 0
numero de ligne : 63
caractère reçu: 0
numero de ligne : 64
caractère reçu: 0
numero de ligne : 65
caractère reçu:  
numero de ligne : 66
caractère reçu: F
numero de ligne : 67
caractère reçu: 

numero de ligne : 68
caractère reçu: 

numero de ligne : 69
caractère reçu: 0
numero de ligne : 70
caractère reçu: P
numero de ligne : 71
caractère reçu:  
numero de ligne : 72
caractère reçu: 

numero de ligne : 73
caractère reçu: H
numero de ligne : 74
caractère reçu: A
numero de ligne : 75
caractère reçu: 
numero de ligne : 76
caractère reçu: 4
numero de ligne : 77
caractère reçu: C
numero de ligne : 78
caractère reçu: 

numero de ligne : 79
caractère reçu: F
numero de ligne : 80
caractère reçu: 

numero de ligne : 81
caractère reçu: 

numero de ligne : 82
caractère reçu: X
numero de ligne : 83
caractère reçu: 0
numero de ligne : 84
caractère reçu:  
numero de ligne : 85
caractère reçu: 0
numero de ligne : 86
caractère reçu: A
numero de ligne : 87
caractère reçu: 

numero de ligne : 88
caractère reçu: 

numero de ligne : 89
caractère reçu: H
numero de ligne : 90
caractère reçu: C
numero de ligne : 91
caractère reçu: T
numero de ligne : 92
caractère reçu: S
numero de ligne : 93
caractère reçu: 0
numero de ligne : 94
caractère reçu: 

numero de ligne : 95
caractère reçu: M
numero de ligne : 96
caractère reçu: 
numero de ligne : 97
caractère reçu: 2
numero de ligne : 98
caractère reçu: O
numero de ligne : 99
caractère reçu: U
numero de ligne : 100
caractère reçu: 0
numero de ligne : 101
caractère reçu: 0
numero de ligne : 102
caractère reçu: P
numero de ligne : 103
caractère reçu:  
numero de ligne : 104
caractère reçu:

Autre chose,cette ligne de RAZ du tableau est-elle bonne ? J’ai vu ça quelque part sans savoir si vraiment elle remetait à 0, toutes les lignes. J’en ai vu une autre (option B) qui ne change pas grand chose…

memset(tamponTrame, 0, sizeof(tamponTrame)); // On réinitialise le taleau à 0 partout OPTION A
  //for (int j=0 ; j<=sizeof(tamponTrame);j++) tamponTrame[j]='\0'; // On réinitialise le taleau à 0 partout OPTION B

Enfin, la trame, sur une seule ligne [caractères mis bout à bout] ne s’affichent pas. La boucle for ne semble pas fonctionner…

numero de ligne : 358
caractère reçu: 
numero de ligne : 359
fin de trame reçu
TRAME = FIN
FIN
FIN

Bonjour,

Pour afficher la trame, j'essaierai de remplacer dans la derniere boucle for :

Serial.print(tamponTrame[compteurCharTrame]);

par

Serial.print(tamponTrame[i]);

et Serial.println("FIN");
en dehors de la boucle for sinon tu vas afficher FIN 400 fois

Salut Poilding,

Je vais essayer ça et reviens dès que j'ai testé le code.

A+

Voici une version plus basique contrôle que l’on voit ou ça pêche : Ici on a :

  • “début de trame”,
  • “début de ligne”,
  • valeurs successives présentes dans la ligne,
  • “fin de ligne”.
  • “fin de trame”,
  • “début de trame”, etc…

Je poste le résultat sous peu… Il faut que je branche mon installation…

#include <SoftwareSerial.h>

#define startFrame 0x02   // Caractère de début de trame
#define endFrame 0x03     // Caractère de fin de trame
#define startLine 0x0A    // Caractère de début de ligne
#define endLine 0x0D      // Caractère de fin de le ligne

char charIn = 0 ;                 // Initialisaiton de la variable de stockage des caractères reçus
int indexTamponTrame = 0 ;   // Nombre de caratère de la trame
int indexTamponLigne = 0 ;
char tamponTrame[400] = "" ;   // Création d'un tableau vide stockant les caractères de chaque ligne de la trame
char tamponLigne[30]= "" ;

SoftwareSerial compteurSerie = SoftwareSerial(3, 4) ;// On crée un port serie virtuel

void setup()
{
  Serial.begin(9600);                 // Initialisation de la liaison série du terminal
  compteurSerie.begin(1200);            // Initialisation de la liaison série du compteur à 1200 bauds/
  Serial.println("setup complete");     // Message sur la moniteur série
}

void loop()
{
  while (charIn != endFrame)                         // Boucle d'attente de lecture de STX
  {
    charIn = compteurSerie.read() & 0x7F ;         // On lit en boucle le char qui passe auquel on retranche son 8ème bit (0x7F : DEL)
    Serial.print("Attente d'une fin de trame. charIn courant : ");
    Serial.println(charIn);
  }
  
  while (true)
  {
    charIn = 0 ; 
    compteurSerie.flush(); 
    
    charIn = (compteurSerie.read() & 0x7F) ;          // On relit le charactère qui passe auquel on retranche son 8ème bit (0x7F : DEL)

  	  if (charIn==endFrame)                           // Si le caractère courant est ETX, on traite la trame
      {
      Serial.println("Fin de Trame");
      }
  	  
  	  if (charIn==startFrame)                         // Si le caractère courant est STX
      {
      Serial.println("Début de trame"); 
      memset(tamponTrame, 0, sizeof(tamponTrame));
      indexTamponLigne = 0 ;
      }
      
      if (charIn==startLine)                       //Si le caractère courant est LF
			{
      Serial.println("Début de ligne"); 
    	memset(tamponLigne, 0, sizeof(tamponLigne)); 
    	indexTamponLigne = "0" ;                                         //On réinitialise le compteur de ligne
			}
     
      if (charIn==endLine)                                   //Si le caractère courant est CR
			{
      Serial.println("Fin de ligne"); 
      tamponLigne[indexTamponLigne+1]='\0';                                  //On termine la ligne par \0 (signifie fin de tableau)
			}
      
      else  //Si ni ETX, STX, LF, CR
			{
			tamponLigne[indexTamponLigne] = charIn ;           //On place le caractère courant dans un tableau "Line"
      Serial.print("Index : ") ;
      Serial.print(indexTamponLigne) ;
      Serial.print(" Caractère : ") ;
      Serial.println(tamponLigne[indexTamponLigne]);
      indexTamponLigne ++ ;
			}
  }
  delay(5000); // On attend un peu// On incrémente le compteur d'index de Line
}

Pour rappel, voici à quoi ressemble une trame standard… Avec la configuration actuelle.

ADCO 021628442554 B
OPTARIF HC.. <
ISOUSC 75 B
HCHC 000000000 F
HCHP 000000000 S
PTEC HP..  
IINST 000 W
IMAX 000 ?
PAPP 00000 !
HHPHC A ,
MOTDETAT 000000 B

Voici le résultat du code ci-dessus avec mes observations : PARTIE 1/1 (limitation des caractères par post oblige !)

Ici on prend une trame en cours, on attend donc de voir ETX afin de lancer l’acquisition compète d’une trame…

setup complete
Attente d'une fin de trame. charIn courant : 
Attente d'une fin de trame. charIn courant : 
Attente d'une fin de trame. charIn courant : 
Attente d'une fin de trame. charIn courant : 

Attente d'une fin de trame. charIn courant : A
Attente d'une fin de trame. charIn courant : D
Attente d'une fin de trame. charIn courant : C
Attente d'une fin de trame. charIn courant : O
Attente d'une fin de trame. charIn courant :  
Attente d'une fin de trame. charIn courant : 0
Attente d'une fin de trame. charIn courant : 2
Attente d'une fin de trame. charIn courant : 1
Attente d'une fin de trame. charIn courant : 6
Attente d'une fin de trame. charIn courant : 2
Attente d'une fin de trame. charIn courant : 8
Attente d'une fin de trame. charIn courant : 4
Attente d'une fin de trame. charIn courant : 4
Attente d'une fin de trame. charIn courant : 2
Attente d'une fin de trame. charIn courant : 5
Attente d'une fin de trame. charIn courant : 5
Attente d'une fin de trame. charIn courant : 4
Attente d'une fin de trame. charIn courant :  
Attente d'une fin de trame. charIn courant : B
Attente d'une fin de trame. charIn courant : 

Attente d'une fin de trame. charIn courant : 

Attente d'une fin de trame. charIn courant : O
Attente d'une fin de trame. charIn courant : P
Attente d'une fin de trame. charIn courant : T
Attente d'une fin de trame. charIn courant : A
Attente d'une fin de trame. charIn courant : R
Attente d'une fin de trame. charIn courant : I
Attente d'une fin de trame. charIn courant : F
Attente d'une fin de trame. charIn courant :  
Attente d'une fin de trame. charIn courant : H
Attente d'une fin de trame. charIn courant : C
Attente d'une fin de trame. charIn courant : .
Attente d'une fin de trame. charIn courant : .
Attente d'une fin de trame. charIn courant :  
Attente d'une fin de trame. charIn courant : <
Attente d'une fin de trame. charIn courant : 

Attente d'une fin de trame. charIn courant : 

Attente d'une fin de trame. charIn courant : I
Attente d'une fin de trame. charIn courant : S
Attente d'une fin de trame. charIn courant : O
Attente d'une fin de trame. charIn courant : U
Attente d'une fin de trame. charIn courant : S
Attente d'une fin de trame. charIn courant : C
Attente d'une fin de trame. charIn courant :  
Attente d'une fin de trame. charIn courant : 7
Attente d'une fin de trame. charIn courant : 5
Attente d'une fin de trame. charIn courant :  
Attente d'une fin de trame. charIn courant : B
Attente d'une fin de trame. charIn courant : 

Attente d'une fin de trame. charIn courant : 

Attente d'une fin de trame. charIn courant : H
Attente d'une fin de trame. charIn courant : C
Attente d'une fin de trame. charIn courant : H
Attente d'une fin de trame. charIn courant : C
Attente d'une fin de trame. charIn courant :  
Attente d'une fin de trame. charIn courant : 0
Attente d'une fin de trame. charIn courant : 0
Attente d'une fin de trame. charIn courant : 0
Attente d'une fin de trame. charIn courant : 0
Attente d'une fin de trame. charIn courant : 0
Attente d'une fin de trame. charIn courant : 0
Attente d'une fin de trame. charIn courant : 0
Attente d'une fin de trame. charIn courant : 0
Attente d'une fin de trame. charIn courant : 0
Attente d'une fin de trame. charIn courant : H // C'est ici que ça part en vrille, au 73ème caractère lu
Attente d'une fin de trame. charIn courant :  
Attente d'une fin de trame. charIn courant : 

Attente d'une fin de trame. charIn courant : P
Attente d'une fin de trame. charIn courant : A
Attente d'une fin de trame. charIn courant : B
Attente d'une fin de trame. charIn courant : 0
Attente d'une fin de trame. charIn courant : A
Attente d'une fin de trame. charIn courant :  
Attente d'une fin de trame. charIn courant :  
Attente d'une fin de trame. charIn courant : 

Attente d'une fin de trame. charIn courant :  
Attente d'une fin de trame. charIn courant : 

Attente d'une fin de trame. charIn courant : H
Attente d'une fin de trame. charIn courant : 0
Attente d'une fin de trame. charIn courant : 

Attente d'une fin de trame. charIn courant : 

Attente d'une fin de trame. charIn courant : U
Attente d'une fin de trame. charIn courant : 0

On le voit, une fois partit en vrille les caractères lus sont purement aléatoires et on ne voit plus les lignes. Du coup, la lecture d’un ETX, condition nécessaire au passage au While peut prendre du temps…

suivant n’est que pur hasard… Donc, ça défile…

PARTIE 2/2

Attente d'une fin de trame. charIn courant : 
Attente d'une fin de trame. charIn courant : 
Attente d'une fin de trame. charIn courant : 
Début de trame // Oui, enfin un début de trame ! 
Index : 0 Caractère :         // Oui, index 0 mais pourquoi STX ? 
Début de trame // Encore début de trame ?
Index : 0 Caractère :         // Encore ?
Début de trame ...
Index : 0 Caractère : 
Début de trame
Index : 0 Caractère : 
Début de trame
Index : 0 Caractère : 
Index : 1 Caractère :         // ??
Index : 2 Caractère : j
Début de ligne // Ah, un début de ligne !
Index : 397 Caractère :        // Pourquoi index à 397 ?

Index : 398 Caractère : H       // On est censé débuter une trame par ADC0 ! 
Index : 399 Caractère : H
Index : 400 Caractère : P
Index : 401 Caractère : H
Index : 402 Caractère : C
Index : 403 Caractère :  
Index : 404 Caractère : A
Index : 405 Caractère :  
Index : 406 Caractère : ,
Fin de ligne //  Fin de ligne! 
Début de ligne // Une nouvelle ligne : MOTDETAT
Index : 397 Caractère :        // Index pas RAZ ! 

Index : 398 Caractère : M
Index : 399 Caractère : O
Index : 400 Caractère : T
Index : 401 Caractère : D
Index : 402 Caractère : E
Index : 403 Caractère : T
Index : 404 Caractère : A
Index : 405 Caractère : T
Index : 406 Caractère :  
Index : 407 Caractère : 0
Index : 408 Caractère : 0
Index : 409 Caractère : 0
Index : 410 Caractère : 0
Index : 411 Caractère : 0
Index : 412 Caractère : 0
Index : 413 Caractère :  
Index : 414 Caractère : B
Fin de ligne // Ok fin de ligne, c'est propre
Fin de Trame // MOTDETAT est le dernier champs d'une trame, donc trame suivante
Index : 415 Caractère :         // Index pas RAZ !
Début de trame // Oui, c'est correct ! 
Index : 0 Caractère :         // Index à 0, OK ! 
Début de ligne // On commence une nouvelle ligne : ADC0
Index : 397 Caractère :        // Pourquoi index à 397 ! 

Index : 398 Caractère : A 
Index : 399 Caractère : D
Index : 400 Caractère : C
Index : 401 Caractère : O
Index : 402 Caractère :  
Index : 403 Caractère : 0
Index : 404 Caractère : 2
Index : 405 Caractère : 1
Index : 406 Caractère : 6
Index : 407 Caractère : 2
Index : 408 Caractère : 8
Index : 409 Caractère : 4
Index : 410 Caractère : 4
Index : 411 Caractère : 2
Index : 412 Caractère : 5
Index : 413 Caractère : 5
Index : 414 Caractère : 4
Index : 415 Caractère :  
Index : 416 Caractère : B
Fin de ligne // OK ! 
Début de ligne // OK ! 
Index : 397 Caractère :        // Pas d'index RAZ ! 

Index : 398 Caractère : O
Index : 399 Caractère : P
Index : 400 Caractère : T
Index : 401 Caractère : A
Index : 402 Caractère : R
Index : 403 Caractère : O // A PARTIR DE LA, CA PART EN VRILLE !!! env. 73ème caractère lu ! 
Index : 404 Caractère : 0 // Après, tout est incohérent
Index : 405 Caractère : 0
Index : 406 Caractère : P
Début de ligne
Index : 397 Caractère : 

Index : 398 Caractère : I
Début de ligne
Index : 397 Caractère : 

Index : 398 Caractère : !
Index : 399 Caractère : A
Index : 400 Caractère : A
Début de trame
Index : 0 Caractère : 
Début de ligne
Index : 397 Caractère : 

Index : 398 Caractère : 4
Index : 399 Caractère : O
Index : 400 Caractère : <
Index : 401 Caractère : U
Index : 402 Caractère : 0
Index : 403 Caractère : C
Index : 404 Caractère : S
Index : 405 Caractère :  
Index : 406 Caractère :  
Index : 407 Caractère : A
Index : 408 Caractère : A
Index : 409 Caractère : H
Index : 410 Caractère : O
Index : 411 Caractère : 0
Début de trame
Index : 0 Caractère : 
Index : 1 Caractère : 2
Fin de ligne
Index : 2 Caractère : .
Index : 3 Caractère : 7
Index : 4 Caractère :  
Début de ligne
Index : 397 Caractère : 

Index : 398 Caractère : 0
Début de ligne
Index : 397 Caractère : 

Index : 398 Caractère : I
Index : 399 Caractère :  
Index : 400 Caractère :  
Index : 401 Caractère :  
Index : 402 Caractère : T
Fin de Trame
Index : 403 Caractère : 
Début de trame
Index : 0 Caractère : 
Index : 1 Caractère : 8
Début de ligne
...

Bilan des courses :

  • Après un nombre +/- constant (73ème) de caractères lus, ça part en vrille : buffer ?
  • la RAZ des index des tableaux de ligne ne se fait pas…
  • sauf au début d’une trame ou les index sont bien à “0”
  • après, un début de ligne commence systématiquement par 397 ! Pourquoi ?

On doit pas être loin… Ce parait pas si incohérent dans l’ensemble. Les erreurs sont redondantes.

Salut Clarky
Je pense qu’une des boulettes vient du fait que tu lis à chaque boucle même lorsqu’il n’y a pas de données disponibles.
As-tu fait exprès de retirer le

if (compteurSerie.available()) // Si des caractères sont disponibles dans le buffer, on les lit

?

J'arrête là !

N’ayant pas de compteur sous la main, j’ai fait un petit prog pour simuler le compteur. Il fonctionne avec une Leonardo mais pourrait fonctionner avec une Mega (peut-être avec quelques petites modifs!)

//GENERATION TRAME TELEINFO
char charIn='0';
String trame="";
boolean flagInfini=HIGH; //DEMARRAGE DES TRAMES AU DEBUT DU PROG



void setup() {
  Serial.begin(9600); 
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
 // Open serial communications and wait for port to open:
  Serial1.begin(1200,SERIAL_7E1);
  Serial.begin(9600);
  Serial.println(F("OUVERTURE LIAISON SERIE EFFECTUEE !"));
  geneTrame();
  Serial.println("trame prete :");
  Serial.println(trame); 
   
  Serial.println(F("\n\n trame a l'infini              ENVOYER S pour arreter"));
 }

void geneTrame(){
  trame=char(0x02);
  trame+=char(0xA);
  trame+="ADCO 021628442554 B";
  trame+=char(0xD);
  trame+=char(0xA);
  trame+="OPTARIF HC.. <";
  trame+=char(0xD);
  trame+=char(0xA);
  trame+="ISOUSC 75 B";
  trame+=char(0xD);
  trame+=char(0xA);
  trame+="HCHC 000000000 F";
  trame+=char(0xD);
  trame+=char(0xA);
  trame+="HCHP 000000000 S";
  trame+=char(0xD);
  trame+=char(0xA);
  trame+="PTEC HP.. ";
  trame+=char(0xD);
  trame+=char(0xA);
  trame+="IINST 000 W";
  trame+=char(0xD);
  trame+=char(0xA);
  trame+="IMAX 000 ?";
  trame+=char(0xD);
  trame+=char(0xA);
  trame+="PAPP 00000 !";
  trame+=char(0xD);
  trame+=char(0xA);
  trame+="HHPHC A ,";
  trame+=char(0xD);
  trame+=char(0xA);
  trame+="MOTDETAT 000000 B";
  trame+=char(0xD);
  trame+=char(0x03);
}

void loop() { // run over and over

  
  if (Serial.available()) {
    charIn=Serial.read();
     if (charIn=='t'){
      Serial.println(F("ENVOIE TRAME"));
      //Serial.print(trame);  
      Serial1.print(trame);
      }
      else if(charIn=='T'){
      Serial.println(F("ENVOIE 2 TRAMES"));
      //Serial.print(trame);  
      Serial1.print(trame);
      Serial1.print(trame); 
      }
      else if (charIn=='B'){
      Serial.println(F("ENVOIE 100 TRAMES"));
        for (int  i=0;i<99;i++){
        Serial1.print(trame);  
        //Serial1.print(trame);
        }
      }
      else if (charIn=='I'){
      Serial.println(F("ENVOIE TRAMES EN BOUCLE"));
      Serial.println(F("TRAMES EN BOUCLE"));
      flagInfini=HIGH;           
      }
       else if (charIn=='S'){
      Serial.println(F("STOP"));
      Serial.println(F("envoyer t pour lancer 1 trame, T pour 2 trames, B pour 100 et I pour infini puis S pour arreter"));
      flagInfini=LOW;           
      }
      
  }
  
 if (flagInfini==HIGH) Serial1.print(trame); 
 delay(100);
}

donc, si ça peut servir à quelqu’un…

et voici le prog qui enregistre dans un tableau la trame.
Tous les problèmes venaient du buffer de la liaison série logiciel.

/*
Lecture simple des trames des compteurs
Pin 3  : Software Serial RX
*/

#include <SoftwareSerial.h>

#define startFrame 0x02   // Caractère de début de trame
#define endFrame 0x03     // Caractère de fin de trame
#define startLine 0x0A    // Caractère de début de ligne
#define endLine 0x0D      // Caractère de fin de le ligne


char tamponTrame[500] = "0";    // Création d'un tableau vide stockant les caractères de chaque ligne de la trame

SoftwareSerial compteurSerie = SoftwareSerial(3, 4) ;// On crée un port serie virtuel les ports 3 (RX) et 4 (TX, non utilisé) dédié à la liaison série du compteur


void lectureTrame(){
int  compteurCharTrame=0; // Nombre de caratère de la trame
char charIn='0';                // Initialisaiton de la variable de stockage des caractères reçus

  while (charIn != endFrame) // Boucle d'attente d'ETX : tant qu'on ne voit pas ETX , on reste dans cette boucle.
  {
    if (compteurSerie.available()) // Si le buffer contient des caractères...
    {
    charIn = compteurSerie.read() & 0x7F ; // On lit le charactère qui passe auquel on retranche son 8ème bit (0x7F : DEL)
    tamponTrame[compteurCharTrame] = charIn; // On stocke le caractère courant dans le tableau selon le compteur de caractère
    compteurCharTrame ++;
    }
  } // Fin de la boucle while(charIn != endFrame)
  tamponTrame[compteurCharTrame]='\0';    //terminaison tableau
}


void attenteStx(){
  char charIn='|';  
 do
  {
  charIn = compteurSerie.read() & 0x7F; // On lit le char (le + rapidement possible) pour vider le buffer de la liaison série logiciel
  }while (charIn != startFrame); // Boucle d'attente de lecture de STX
}



void setup()
{
  Serial.begin(9600); // Initialisation de la liaison série du terminal
  compteurSerie.begin(1200); // Initialisation de la liaison série du compteur à 1200 bauds
  Serial.println("setup complete"); // Message sur la moniteur série
}

void loop()
{
  int compteurCharTrame = 0; // On réinitialise le compteur de caractère à 0
  tamponTrame[0]='\0';  //init tampon
  Serial.println(F("Debut loop : RAZ tampon")); // Message sur le moniteur série
  Serial.println(F("Attente STX"));
  attenteStx();
  attenteStx();
  lectureTrame();
  Serial.print(F("\nTRAME = "));
  Serial.print(tamponTrame); // pour imprimer le tableau sur le terminal série
  Serial.println(F("FIN\n\n")); // Un petit FIN de confirmation
   
  delay(1000); // Une petite tempo qui va bien entre 2 lectures de trames
} // Fin de loop

reste à décoder la trame :confused:

Un début de traitement (séparation ligne puis construction de la trame (avec utilisation de Sting à la place des tableaux)

/*
Lecture simple des trames des compteur 
Pin 3  : Software Serial RX
*/

#include <SoftwareSerial.h>

#define startFrame 0x02   // Caractère de début de trame
#define endFrame 0x03     // Caractère de fin de trame
#define startLine 0x0A    // Caractère de début de ligne
#define endLine 0x0D      // Caractère de fin de le ligne



SoftwareSerial compteurSerie = SoftwareSerial(3, 4) ;// On crée un port serie virtuel les ports 3 (RX) et 4 (TX, non utilisé) dédié à la liaison série du compteur


void lectureTrame(){
String ligne = "";
String trame="";
char charIn='0';                // Initialisation de la variable de stockage des caractères reçus


  while (charIn != endFrame) // Boucle d'attente d'ETX : tant qu'on ne voit pas ETX , on reste dans cette boucle.
  {
    if (compteurSerie.available()) // Si le buffer contient des caractères...
    {
    charIn = (compteurSerie.read() & 0x7F) ;          // On relit le charactère qui passe auquel on retranche son 8ème bit (0x7F : DEL)

     if (charIn==endFrame)                           // Si le caractère courant est ETX, on traite la trame
      {
      Serial.println("Fin de Trame");
      Serial.print(F("\nTRAME = "));
      Serial.print(trame); // pour imprimer le tableau sur le terminal série
      }
     
      else if (charIn==startFrame)                         // Si le caractère courant est STX
      {
      Serial.println("Debut de trame");
      trame="|";                                    // init trame et  debut avec le champs |
      }
     
      else if (charIn==startLine)                       //Si le caractère courant est LF
      {
      Serial.print("Debut de ligne : ");
      ligne="";
      }
     
      else if (charIn==endLine)                                   //Si le caractère courant est CR
      {
      Serial.print(ligne);
      Serial.println("  Fin de ligne");
      trame+=ligne+'|';                       // construction trame et separation des champs avec |
      }
     
      else  //Si ni ETX, STX, LF, CR
      {
      ligne += charIn ;           //On place le caractère courant dans un tableau "Line"
      }
 
    }
  } // Fin de la boucle while(charIn != endFrame)
  
}


void attenteEtx(){
  char charIn='|';  
 do
  {
  charIn = compteurSerie.read() & 0x7F; // On lit le char (le + rapidement possible) pour vider le buffer de la liaison série logiciel
  }while (charIn != endFrame); // Boucle d'attente de lecture de STX
}



void setup()
{
  Serial.begin(9600); // Initialisation de la liaison série du terminal
  compteurSerie.begin(1200); // Initialisation de la liaison série du compteur à 1200 bauds
  Serial.println("setup complete"); // Message sur la moniteur série
}

void loop()
{

  Serial.println(F("Debut loop")); // Message sur le moniteur série
  Serial.println(F("Attente ETX"));
  attenteEtx();
  attenteEtx();
  lectureTrame();
  Serial.println(F("FIN\n\n")); // Un petit FIN de confirmation
   
  delay(1000); // Une petite tempo qui va bien entre 2 lectureS de trames
} // Fin de loop

Merci Poilding pour ce beau boulot ! J’ai testé tout ça.

Code du post de 0149pm :

setup complete
Debut loop : RAZ tampon
Attente STX

TRAME = ee|!EoC HP..  
IINST 000 W
IMAX 000 ?
PAPP 00000 !
HHPHC A ,
MOTDETAT 000000 B
FIN


Debut loop : RAZ tampon
Attente STX

TRAME = 
ADCO 021628442554 B
OPTARIF HC.. <
ISOUSC 75 B
HCHC 000000P 000000000 S
PTEC HP..  
IINST 000 W
IMAX 000 ?
PAPP 00000 !
HHPHC A ,
MOTDETAT 000000 B
FIN


Debut loop : RAZ tampon
Attente STX

TRAME = 
ADCO 021628442554 B
OPTARIF HC.. <
ISOUSC 75 B
HCHC 000000ST 000 W
IMAX 000 ?
PAPP 00000 !
HHPHC A ,
MOTDETAT 000000 B
FIN


Debut loop : RAZ tampon
Attente STX

TRAME = 
ADCO 021628442554 B
OPTARIF HC.. <
ISOUSC 75 B
HCHC 000000TEC HP..  
IINST 000 W
IMAX 000 ?
PAPP 00000 !
HHPHC A ,
MOTDETAT 000000 B
FIN