[Résolu] Différence Vitesse entre port série Matériel et logiciel

Bonjour,

en lecture de Téléinfo EDF avec un sketch utilisant un port série logiciel (Librairie SoftwareSerial) je faisais l'acquisition complète de ma trame en moyenne en 300 ms et je trouvais déjà ça un peux long pour la réactivité du sketch.

Mais j'utilise un Mega + shield Ethernet et utilisation de la carte SD donc tous les pin disponibles avec la librairie SoftwareSerial sont bloqués sur ma méga.

Not all pins on the Mega and Mega 2560 support change interrupts, so only the following can be used for RX: 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69

D’ailleurs je ne sais pas où on trouve les pin 62 à 69 sur la méga ::)

Je me suis donc tourné vers le port série Matériel RX3 et TX3 (1 et 2 sont "cachés" par un module ds1307) sans rien changé à mon sketch mais juste ajouter une résistance de tirage de 4,7Kohms sur RX3.

Mais là, l'acquisition complète de ma trame passe en moyenne à 1400 ms. :o

D’où peu venir une telle différence ? Cela ralenti énormément mon sketch la réactivité est vraiment médiocre.

Salut,

Alors les pin 62 à 69 c'est les pin analogiques (A0 A1 A2 ....) qui sont aussi digitaux.

Port matérielle : bin c'est quand même bien mieux je vois pas trop pourquoi tu voulais t'embêter avec du soft ^^

Sinon : pourquoi cette résistance de 4.7k ?

De part le principe de base, a technologie identique, une fonction matérielle sera plus rapide qu'une fonction logicielle. C'est bien pour cela que les concepteurs de microcontrôleur implantent des fonctions matérielles dans les puces.

Si tu obtiens l'inverse c'est qu'il se passe quelque chose d'autre.

Bonjour B@tto et 68tjs

B@tto: Alors les pin 62 à 69 c'est les pin analogiques (A0 A1 A2 ....) qui sont aussi digitaux.

OK ça déjà je serais moins bête ce soir. Est si je ne règle pas mon problème de vitesse je peux essayer avec ceux-ci.

B@tto: Port matérielle : bin c'est quand même bien mieux je vois pas trop pourquoi tu voulais t'embêter avec du soft ^^

D'abord par fainéantise :) pour tester vite fait en recopiant les sketch que d'autres on déjà fait => promis je le referai plus ;D

B@tto: Salut, Sinon : pourquoi cette résistance de 4.7k ?

Je ne sortais rien sans cette résistance j'ai lu sur un Blog (Le Blog de C-quad) que quelqu'un avait fait fonctionné le port série avec cette résistance. Ça marche mais pas d'explication sur pourquoi elle est nécessaire.

68tjs: De part le principe de base, a technologie identique, une fonction matérielle sera plus rapide qu'une fonction logicielle. Si tu obtiens l'inverse c'est qu'il se passe quelque chose d'autre.

C'est bien ce que je j’espérais mais je ne sais pas où chercher le problème

Bonjour pepe,

En fait pour écarter toutes “interaction” je teste un sketch basique car effectivement mon sketch utile et déjà bien trop gros et je saurais où regarder en détail.

Quand je dis ne rien changer au sketch tu as raison il faut bien modifier un peu mais je trouvais ça minime :

En logiciel :

#include <SoftwareSerial.h>

SoftwareSerial Teleinfo(11,2);


long Index_HC=0;
long Index_HP=0;
byte I_A=0;
int P_W=0;
char PERIODE=' ';

unsigned long temps_d_acquisition_teleinfo = 0;



void setup() {
Serial.begin(9600);  // Port série pour liasion Arduino <-> PC
Teleinfo.begin(1200); // Port série pour liasion Arduino <-> Teleinfo
}

void loop() {

                  
                  Recupere_la_Teleinfo();
                  
                  Serial.print("Temps d'aquisition : ");Serial.print(millis()-temps_d_acquisition_teleinfo);Serial.println(" Millisecondes");
                  
                  Serial.print(" => Index HC : ");Serial.print(Index_HC);Serial.println(" Wh");
                  Serial.print(" => Index HP : ");Serial.print(Index_HP);Serial.println(" Wh");
                  Serial.print(" => PERIODE : H") ;Serial.println(PERIODE);
                  Serial.print(" => Intensite instantanee : ");Serial.print(I_A);Serial.println(" A");
                  Serial.print(" => Puissance apparente : ");Serial.print(P_W); Serial.println(" W");
                  
      
}



void Recupere_la_Teleinfo(){

char charIn_Trame_Teleinfo = 0; // stock chaque charactère recu de la trame teleinfo

String Ligne;      // stock la ligne complette (entre LF(0x0A) et CR(0x0D))
String Etiquette;  // stock l'intitulé
String Valeur;     // stock la valeur apres l'intitulé
char Checksum;
/*
Trame recu par la teleinfo      

ADCO 040422040644 5	        (N° d’identification du compteur : ADCO (12 caractères))
OPTARIF HC.. <	                (Option tarifaire (type d’abonnement) : OPTARIF (4 car.))
ISOUSC 45 ?	                (Intensité souscrite : ISOUSC ( 2 car. unité = ampères))
HCHC 077089461 0	        (Index heures creuses si option = heures creuses : HCHC ( 9 car. unité = Wh))
HCHP 096066754 >	        (Index heures pleines si option = heures creuses : HCHP ( 9 car. unité = Wh))
PTEC HP..  	                (Période tarifaire en cours : PTEC ( 4 car.))
IINST 002 Y	                (Intensité instantanée : IINST ( 3 car. unité = ampères))
IMAX 044 G	                (Intensité maximale : IMAX ( 3 car. unité = ampères))
PAPP 00460 +	                (Puissance apparente : PAPP ( 5 car. unité = Volt.ampères))
HHPHC E 0	                (Groupe horaire si option = heures creuses ou tempo : HHPHC (1 car.))
MOTDETAT 000000 B	        (Mot d’état (autocontrôle) : MOTDETAT (6 car.))
*/


temps_d_acquisition_teleinfo=millis(); // remise a zero du temps

//RAZ des valeurs
              Index_HC=Index_HP=I_A=P_W=0;
              PERIODE= ' ';

while ( Index_HC==0 || Index_HP==0 || I_A==0 || P_W==0 || PERIODE==' ' ){ // recommence tant que l'on a pas recu tous les élément voulus

  
          //Attend un début de ligne (0x0A)
                       charIn_Trame_Teleinfo = Teleinfo.read() & 0x7F ; 
                       while (charIn_Trame_Teleinfo != 0x0A){ // reste dans cette boucle tant qu'on ne recoit pas le Charactere de début de ligne 0x0A
                             if ((millis()-temps_d_acquisition_teleinfo)>2000 ) {Serial.println("Teleinfo Inaccesible");loop();} // Affiche un erreur si la teleinfo est inaccesible et retourne à Loop 
                             if (Teleinfo.available()){ // Tant qu'il y a des caractères disponibles
                                     charIn_Trame_Teleinfo = Teleinfo.read() & 0x7F ; // Stock 1 caractere recu
                             }
                       }
          //Vide Ligne
                       Ligne="";
          //Vide Etiquette
                       Etiquette="";
          //Concatene les carateres recus jusqu'a l'espace suivant (0x20)
                       charIn_Trame_Teleinfo = Teleinfo.read() & 0x7F ; 
                       while (charIn_Trame_Teleinfo != 0x20){ // reste dans cette boucle tant qu'on ne recoit pas le Charactere Espace
                                          if (Teleinfo.available()){ // Tant qu'il y a des caractères disponibles
                                                  charIn_Trame_Teleinfo = Teleinfo.read() & 0x7F ; // Stock 1 caractere recu
                                                  if (charIn_Trame_Teleinfo != 0x20){Etiquette += charIn_Trame_Teleinfo;}      // concatene les caractères reçus sauf les espaces
                                                  Ligne += charIn_Trame_Teleinfo;
                                          }                     
                        }
                               
          //Vide Valeur
                       Valeur="";     
          //Concatene les carateres recus jusqu'a l'espace suivant (0x20)
                       charIn_Trame_Teleinfo = Teleinfo.read() & 0x7F ; 
                       while (charIn_Trame_Teleinfo != 0x20){ // reste dans cette boucle tant qu'on ne recoit pas le Charactere Espace
                                          if (Teleinfo.available()){ // Tant qu'il y a des caractères disponibles
                                                  charIn_Trame_Teleinfo = Teleinfo.read() & 0x7F ; // Stock 1 caractere recu
                                                  if (charIn_Trame_Teleinfo != 0x20){Valeur += charIn_Trame_Teleinfo;}      // concatene les caractères reçus sauf les espaces
                                                  Ligne += charIn_Trame_Teleinfo;
                                          }                     
                        }
                
          //Concatene les carateres recus jusqu'a la fin de ligne (0x0D)
                       charIn_Trame_Teleinfo = Teleinfo.read() & 0x7F ; 
                       while (charIn_Trame_Teleinfo != 0x0D){ // reste dans cette boucle tant qu'on ne recoit pas le Charactere de fin de ligne
                                          if (Teleinfo.available()){ // Tant qu'il y a des caractères disponibles
                                                  charIn_Trame_Teleinfo = Teleinfo.read() & 0x7F ; // Stock 1 caractere recu
                                                  if (charIn_Trame_Teleinfo != 0x0D){Ligne += charIn_Trame_Teleinfo;} // concatene les caractères reçus sauf le Charactere de fin de ligne (0x0D)
                                                  if (charIn_Trame_Teleinfo != 0x0D){Checksum = charIn_Trame_Teleinfo;}
                                          }                     
                        }
         //Controle du Checksum (Le dernier caractere de la ligne et un caractere de controle)

                            char Controle=0;
                            String trame= Etiquette + " " + Valeur;
                            for (byte i=0;i<(trame.length());i++){
                                      Controle += trame[i];
                            }  
                            Controle = (Controle & 0x3F) + 0x20;
                            
              
              if (Controle == Checksum) { // Si le checksum correspond bien au code controlé
                
          //Associe la valeur lue à son etiquette
                if (Etiquette.substring (0,4)=="HCHC") {Index_HC = Valeur.toInt();}
                if (Etiquette.substring (0,4)=="HCHP") {Index_HP = Valeur.toInt();}
                if (Etiquette.substring (0,4)=="PTEC") {PERIODE  = Valeur[1];     }
                if (Etiquette.substring (0,4)=="IINS") {I_A      = Valeur.toInt();}
                if (Etiquette.substring (0,4)=="PAPP") {P_W      = Valeur.toInt();}      
              }
}


}

En matériel :

/*
Utilise le port serie RX3 de l'adruino MEGA
!! mettre une résitance de tirage de 4,7 kOhms entre Rx3 et VCC
*/


long Index_HC=0;
long Index_HP=0;
byte I_A=0;
int P_W=0;
char PERIODE=' ';

unsigned long temps_d_acquisition_teleinfo = 0;



void setup() {
Serial.begin(9600);  // Port série pour liasion Arduino <-> PC
Serial3.begin(1200); // Port série pour liasion Arduino <-> Teleinfo
}

void loop() {

                  
                  Recupere_la_Teleinfo();
                  
                  Serial.print("Temps d'aquisition : ");Serial.print(millis()-temps_d_acquisition_teleinfo);Serial.println(" Millisecondes");
                  
                  Serial.print(" => Index HC : ");Serial.print(Index_HC);Serial.println(" Wh");
                  Serial.print(" => Index HP : ");Serial.print(Index_HP);Serial.println(" Wh");
                  Serial.print(" => PERIODE : H") ;Serial.println(PERIODE);
                  Serial.print(" => Intensite instantanee : ");Serial.print(I_A);Serial.println(" A");
                  Serial.print(" => Puissance apparente : ");Serial.print(P_W); Serial.println(" W");
                  
      
}



void Recupere_la_Teleinfo(){

char charIn_Trame_Teleinfo = 0; // stock chaque charactère recu de la trame teleinfo

String Ligne;      // stock la ligne complette (entre LF(0x0A) et CR(0x0D))
String Etiquette;  // stock l'intitulé
String Valeur;     // stock la valeur apres l'intitulé
char Checksum;
/*
Trame recu par la teleinfo      

ADCO 040422040644 5	        (N° d’identification du compteur : ADCO (12 caractères))
OPTARIF HC.. <	                (Option tarifaire (type d’abonnement) : OPTARIF (4 car.))
ISOUSC 45 ?	                (Intensité souscrite : ISOUSC ( 2 car. unité = ampères))
HCHC 077089461 0	        (Index heures creuses si option = heures creuses : HCHC ( 9 car. unité = Wh))
HCHP 096066754 >	        (Index heures pleines si option = heures creuses : HCHP ( 9 car. unité = Wh))
PTEC HP..  	                (Période tarifaire en cours : PTEC ( 4 car.))
IINST 002 Y	                (Intensité instantanée : IINST ( 3 car. unité = ampères))
IMAX 044 G	                (Intensité maximale : IMAX ( 3 car. unité = ampères))
PAPP 00460 +	                (Puissance apparente : PAPP ( 5 car. unité = Volt.ampères))
HHPHC E 0	                (Groupe horaire si option = heures creuses ou tempo : HHPHC (1 car.))
MOTDETAT 000000 B	        (Mot d’état (autocontrôle) : MOTDETAT (6 car.))
*/


temps_d_acquisition_teleinfo=millis(); // remise a zero du temps

//RAZ des valeurs
              Index_HC=Index_HP=I_A=P_W=0;
              PERIODE= ' ';

while ( Index_HC==0 || Index_HP==0 || I_A==0 || P_W==0 || PERIODE==' ' ){ // recommence tant que l'on a pas recu tous les élément voulus

  
          //Attend un début de ligne (0x0A)
                       charIn_Trame_Teleinfo = Serial3.read() & 0x7F ; 
                       while (charIn_Trame_Teleinfo != 0x0A){ // reste dans cette boucle tant qu'on ne recoit pas le Charactere de début de ligne 0x0A
                             if ((millis()-temps_d_acquisition_teleinfo)>2000 ) {Serial.println("Teleinfo Inaccesible");loop();} // Affiche un erreur si la teleinfo est inaccesible et retourne à Loop 
                             if (Serial3.available()){ // Tant qu'il y a des caractères disponibles
                                     charIn_Trame_Teleinfo = Serial3.read() & 0x7F ; // Stock 1 caractere recu
                             }
                       }
          //Vide Ligne
                       Ligne="";
          //Vide Etiquette
                       Etiquette="";
          //Concatene les carateres recus jusqu'a l'espace suivant (0x20)
                       charIn_Trame_Teleinfo = Serial3.read() & 0x7F ; 
                       while (charIn_Trame_Teleinfo != 0x20){ // reste dans cette boucle tant qu'on ne recoit pas le Charactere Espace
                                          if (Serial3.available()){ // Tant qu'il y a des caractères disponibles
                                                  charIn_Trame_Teleinfo = Serial3.read() & 0x7F ; // Stock 1 caractere recu
                                                  if (charIn_Trame_Teleinfo != 0x20){Etiquette += charIn_Trame_Teleinfo;}      // concatene les caractères reçus sauf les espaces
                                                  Ligne += charIn_Trame_Teleinfo;
                                          }                     
                        }
                               
          //Vide Valeur
                       Valeur="";     
          //Concatene les carateres recus jusqu'a l'espace suivant (0x20)
                       charIn_Trame_Teleinfo = Serial3.read() & 0x7F ; 
                       while (charIn_Trame_Teleinfo != 0x20){ // reste dans cette boucle tant qu'on ne recoit pas le Charactere Espace
                                          if (Serial3.available()){ // Tant qu'il y a des caractères disponibles
                                                  charIn_Trame_Teleinfo = Serial3.read() & 0x7F ; // Stock 1 caractere recu
                                                  if (charIn_Trame_Teleinfo != 0x20){Valeur += charIn_Trame_Teleinfo;}      // concatene les caractères reçus sauf les espaces
                                                  Ligne += charIn_Trame_Teleinfo;
                                          }                     
                        }
                
          //Concatene les carateres recus jusqu'a la fin de ligne (0x0D)
                       charIn_Trame_Teleinfo = Serial3.read() & 0x7F ; 
                       while (charIn_Trame_Teleinfo != 0x0D){ // reste dans cette boucle tant qu'on ne recoit pas le Charactere de fin de ligne
                                          if (Serial3.available()){ // Tant qu'il y a des caractères disponibles
                                                  charIn_Trame_Teleinfo = Serial3.read() & 0x7F ; // Stock 1 caractere recu
                                                  if (charIn_Trame_Teleinfo != 0x0D){Ligne += charIn_Trame_Teleinfo;} // concatene les caractères reçus sauf le Charactere de fin de ligne (0x0D)
                                                  if (charIn_Trame_Teleinfo != 0x0D){Checksum = charIn_Trame_Teleinfo;}
                                          }                     
                        }
         //Controle du Checksum (Le dernier caractere de la ligne et un caractere de controle)

                            char Controle=0;
                            String trame= Etiquette + " " + Valeur;
                            for (byte i=0;i<(trame.length());i++){
                                      Controle += trame[i];
                            }  
                            Controle = (Controle & 0x3F) + 0x20;
                            
              
              if (Controle == Checksum) { // Si le checksum correspond bien au code controlé
                
          //Associe la valeur lue à son etiquette
                if (Etiquette.substring (0,4)=="HCHC") {Index_HC = Valeur.toInt();}
                if (Etiquette.substring (0,4)=="HCHP") {Index_HP = Valeur.toInt();}
                if (Etiquette.substring (0,4)=="PTEC") {PERIODE  = Valeur[1];     }
                if (Etiquette.substring (0,4)=="IINS") {I_A      = Valeur.toInt();}
                if (Etiquette.substring (0,4)=="PAPP") {P_W      = Valeur.toInt();}      
              }
}


}

Même si ce n'est pas le sujet de ma question peux tu me dire ce qu'est l'indentation du code ? Si tu veux parler de la "mise en page", c'est vrai que j’essaye de beaucoup commenter à ma façon pour être sur de comprendre ce que je fais mais il doit y avoir des normes "d’indentation" que je ne connais pas désolé.

Pour le problème que tu pointe est-ce que remplacer "Loop();" par "return;" est plus exacte ? J'avoue avoir ajouter ce petit bout de code un peu trop vite.

Mais en ce qui concerne la lecture voila ce que me retroune la console

avec le sketch port matériel :

Temps d'aquisition : 1662 Millisecondes
 => Index HC : 77375090 Wh
 => Index HP : 96359211 Wh
 => PERIODE : HP
 => Intensite instantanee : 8 A
 => Puissance apparente : 1840 W
Temps d'aquisition : 1433 Millisecondes
 => Index HC : 77375090 Wh
 => Index HP : 96359212 Wh
 => PERIODE : HP
 => Intensite instantanee : 8 A
 => Puissance apparente : 1840 W
Temps d'aquisition : 1433 Millisecondes
 => Index HC : 77375090 Wh
 => Index HP : 96359213 Wh
 => PERIODE : HP
 => Intensite instantanee : 8 A
 => Puissance apparente : 1830 W
Temps d'aquisition : 1433 Millisecondes
 => Index HC : 77375090 Wh
 => Index HP : 96359214 Wh
 => PERIODE : HP
 => Intensite instantanee : 8 A
 => Puissance apparente : 1830 W
Temps d'aquisition : 1434 Millisecondes
 => Index HC : 77375090 Wh
 => Index HP : 96359215 Wh
 => PERIODE : HP
 => Intensite instantanee : 8 A
 => Puissance apparente : 1840 W
Temps d'aquisition : 1432 Millisecondes
 => Index HC : 77375090 Wh
 => Index HP : 96359215 Wh
 => PERIODE : HP
 => Intensite instantanee : 8 A
 => Puissance apparente : 1850 W
Temps d'aquisition : 1434 Millisecondes
 => Index HC : 77375090 Wh
 => Index HP : 96359216 Wh
 => PERIODE : HP
 => Intensite instantanee : 8 A
 => Puissance apparente : 1880 W
Temps d'aquisition : 1424 Millisecondes
 => Index HC : 77375090 Wh
 => Index HP : 96359217 Wh
 => PERIODE : HP
 => Intensite instantanee : 8 A
 => Puissance apparente : 1900 W

Et ce que me retourne la console avec le sketch port logiciel :

Temps d'aquisition : 388 Millisecondes
 => Index HC : 77375090 Wh
 => Index HP : 96359296 Wh
 => PERIODE : HP
 => Intensite instantanee : 14 A
 => Puissance apparente : 3280 W
Temps d'aquisition : 285 Millisecondes
 => Index HC : 77375090 Wh
 => Index HP : 96359297 Wh
 => PERIODE : HP
 => Intensite instantanee : 14 A
 => Puissance apparente : 3320 W
Temps d'aquisition : 286 Millisecondes
 => Index HC : 77375090 Wh
 => Index HP : 96359299 Wh
 => PERIODE : HP
 => Intensite instantanee : 14 A
 => Puissance apparente : 3300 W
Temps d'aquisition : 272 Millisecondes
 => Index HC : 77375090 Wh
 => Index HP : 96359300 Wh
 => PERIODE : HP
 => Intensite instantanee : 14 A
 => Puissance apparente : 3300 W
Temps d'aquisition : 279 Millisecondes
 => Index HC : 77375090 Wh
 => Index HP : 96359302 Wh
 => PERIODE : HP
 => Intensite instantanee : 14 A
 => Puissance apparente : 3320 W
Temps d'aquisition : 266 Millisecondes
 => Index HC : 77375090 Wh
 => Index HP : 96359303 Wh
 => PERIODE : HP
 => Intensite instantanee : 14 A
 => Puissance apparente : 3340 W
Temps d'aquisition : 287 Millisecondes
 => Index HC : 77375090 Wh
 => Index HP : 96359305 Wh
 => PERIODE : HP
 => Intensite instantanee : 14 A
 => Puissance apparente : 3330 W
Temps d'aquisition : 273 Millisecondes

Même si la trame est longue et lente il y a une réelle différence entre les 2 méthode

Waouh ça c’est une réponse détaillée, je vais essayer d’être à la hauteur du boulot que tu as fournis.

Pour essayer d’éliminer l’hypothèse n°2 j’ai refais un sketch éliminant tout traitement pour ne m’attarder que sur le délai d’acquisition de la trame dans sa totalité :

1-Attendre le caractère de début de trame
2-Commencer le décompte du temps d’acquisition
3-Attendre le caractère de fin de trame
4-afficher la différence entre 2 et 3

Voici le sketch pour utiliser le Port Matériel(j’espère que l’indentation serra meilleur)

/*
Utilise le port serie RX3 de l'adruino MEGA
+ une résitance de 4,7 kOhms entre Rx3 et VCC
*/

unsigned long temps_d_acquisition_teleinfo = 0;

void setup() {
  Serial.begin(9600);  // Port série pour liasion Arduino <-> PC
  Serial3.begin(1200); // Port série pour liasion Arduino <-> Teleinfo
}

void loop() {
  
  char charIn_Trame_Teleinfo = 0;
  
  //Attend un début de trame (0x02)
         charIn_Trame_Teleinfo = Serial3.read() & 0x7F ; 
         while (charIn_Trame_Teleinfo != 0x02){
               if (Serial3.available()){ 
                       charIn_Trame_Teleinfo = Serial3.read() & 0x7F ;
               }
         }
  
  //Démarre le décompte du temps d'acquisition
  temps_d_acquisition_teleinfo=millis();
  
  //Attend la fin de trame (0x03)
         charIn_Trame_Teleinfo = Serial3.read() & 0x7F ; 
         while (charIn_Trame_Teleinfo != 0x03){ 
               if (Serial3.available()){
                       charIn_Trame_Teleinfo = Serial3.read() & 0x7F ;
               }                     
          }
                                 
  Serial.print("Temps d'aquisition : ");
  Serial.print(millis()-temps_d_acquisition_teleinfo);
  Serial.println(" Millisecondes");

}

Et son homologue pour le port Logiciel

#include <SoftwareSerial.h>
SoftwareSerial Serial_Logiciel(11,2);

unsigned long temps_d_acquisition_teleinfo = 0;

void setup() {
  Serial.begin(9600);  // Port série pour liasion Arduino <-> PC
  Serial_Logiciel.begin(1200); // Port série pour liasion Arduino <-> Teleinfo
}

void loop() {
  
  char charIn_Trame_Teleinfo = 0;
  
  //Attend un début de trame (0x02)
         charIn_Trame_Teleinfo = Serial_Logiciel.read() & 0x7F ; 
         while (charIn_Trame_Teleinfo != 0x02){
               if (Serial_Logiciel.available()){ 
                       charIn_Trame_Teleinfo = Serial_Logiciel.read() & 0x7F ;
               }
         }
  
  //Démarre le décompte du temps d'acquisition
  temps_d_acquisition_teleinfo=millis();
  
  //Attend la fin de trame (0x03)
         charIn_Trame_Teleinfo = Serial_Logiciel.read() & 0x7F ; 
         while (charIn_Trame_Teleinfo != 0x03){ 
               if (Serial_Logiciel.available()){
                       charIn_Trame_Teleinfo = Serial_Logiciel.read() & 0x7F ;
               }                     
          }
                                 
  Serial.print("Temps d'aquisition : ");
  Serial.print(millis()-temps_d_acquisition_teleinfo);
  Serial.println(" Millisecondes");
 

}

J’ai fait un essai en concaténant tous les octets reçu dans un String puis en l’affichant pour être sur de bien recevoir la trame en totalité puis j’ai supprimer aussi la concaténation pour ne garder que le stricte minimum.

J’ai relevé les temps d’acquisition uniquement au démarrage de l’arduino ou en tournant en boucle pendant plusieurs minutes

En Logiciel ils oscillent entre 313 et 366 Millisecondes et en Matériel entre 1512 et 1539 Millisecondes

Toujours cette différence “énorme” entre les deux, je pense pouvoir écarter les options 2 et 1.1

Pour l’hypothèse 1.2

L’option 1.2.2 si je ne me trompe pas cela voudrait dire que le sketch perd systématiquement l’octet de fin de trame et pas les autres et cela un cycle sur deux.
Cela semble peux probable aussi dans mon cas.

Reste l’option 1.2.1 mais sur ce point je ne suis pas certain de comprendre ce que tu me suggère.

La trame reçu ne serrait plus en 1200 baud et l’arduino réussirais à ce synchroniser au bon débit puis commencer à lire les données ?

Bonjour, je n'ai pu tester que ce midi voici quelques relevés de la console :

Démarrage en Port Matériel 1
        Période de la boucle : 0 millisecondes
            Avant la trame : 4 octets
            Longueur trame : 171 octets
            Temps de lecture : 1575 millisecondes
            Temps d'acquisition : 1521 millisecondes
        Période de la boucle : 1692 millisecondes
            Avant la trame : 0 octets
            Longueur trame : 170 octets
            Temps de lecture : 1437 millisecondes
            Temps d'acquisition : 1437 millisecondes
Démarrage en Port Matériel 2
        Période de la boucle : 0 millisecondes
            Avant la trame : 135 octets
            Longueur trame : 171 octets
            Temps de lecture : 2746 millisecondes
            Temps d'acquisition : 1513 millisecondes
        Période de la boucle : 2866 millisecondes
            Avant la trame : 0 octets
            Longueur trame : 170 octets
            Temps de lecture : 1434 millisecondes
            Temps d'acquisition : 1434 millisecondes
Démarrage en Port Matériel 3
        Période de la boucle : 0 millisecondes
            Avant la trame : 84 octets
            Longueur trame : 171 octets
            Temps de lecture : 2299 millisecondes
            Temps d'acquisition : 1520 millisecondes
        Période de la boucle : 2418 millisecondes
            Avant la trame : 0 octets
            Longueur trame : 170 octets
            Temps de lecture : 1427 millisecondes
            Temps d'acquisition : 1427 millisecondes


Démarrage en Port Logicel 1        
        Période de la boucle : 0 millisecondes
            Avant la trame : 149 octets
            Longueur trame : 171 octets
            Temps de lecture : 700 millisecondes
            Temps d'acquisition : 353 millisecondes
        Période de la boucle : 796 millisecondes
            Avant la trame : 0 octets
            Longueur trame : 170 octets
            Temps de lecture : 271 millisecondes
            Temps d'acquisition : 271 millisecondes
Démarrage en Port Logicel 2    
        Période de la boucle : 0 millisecondes
            Avant la trame : 97 octets
            Longueur trame : 171 octets
            Temps de lecture : 569 millisecondes
            Temps d'acquisition : 349 millisecondes
        Période de la boucle : 667 millisecondes
            Avant la trame : 0 octets
            Longueur trame : 170 octets
            Temps de lecture : 291 millisecondes
            Temps d'acquisition : 291 millisecondes
Démarrage en Port Logicel 3
        Période de la boucle : 0 millisecondes
            Avant la trame : 20 octets
            Longueur trame : 171 octets
            Temps de lecture : 413 millisecondes
            Temps d'acquisition : 369 millisecondes
        Période de la boucle : 502 millisecondes
            Avant la trame : 0 octets
            Longueur trame : 170 octets
            Temps de lecture : 289 millisecondes
            Temps d'acquisition : 289 millisecondes

On situe bien mieux les choses et je n'ai limité l'affichage qu'a 2 loop puisque les suivantes sont quasi identiques au deuxième loop. (Normal le programme recommence directement sur l'octet de départ de la trame.)

Mais comme les autres tests "the winner is" le port logiciel.

J'ai aussi tester avec un potentiomètre à la place de la résistance de tirage pour la diminuer au minium ou l'augmenter jusqu’à 40KOhms au cas ou elle ai de l'importance => aucun changement sur la durée d’acquisition

Et pour finir j'ai fais aussi le test sur RX1 ou RX2 => aucun changement sur la durée d’acquisition

Là je sèche :(

A mon sens les mesures de temps dans la version "UART logicielle" ne sont pas pertinentes. La routine de gestion d'interruption appelle une fonction qui gère des délais pour échantillonner au milieu du bit. Ce délai tourne alors que les interruptions sont toujours masquées donc je ne suis pas loin de penser que pendant ce temps là millis() n'est pas mis à jour.

De tout les façons, à la base la question n'a pas de sens. La trame est envoyé par le compteur à la même vitesse que la réception soit faite par une UART soft ou une UART matérielle. Le temps de traitement par une UART logicielle ne peut être que plus long puisqu'il faut assurer la réception des données par le soft alors que dans l'autre cas le matériel s'en charge et donc le processeur est disponible pour une autre tâche. Dans la mesure où la transmission des messages est longue (imposé par le 1200 bauds) il faut que ton programme ne soit pas bloqué en attendant la réception de la trame d'info. Ce qui va te laisser un temps important pour faire plein de trucs.

8) c'est dans ces moments que l'on voit la différence entre un néophyte qui bidouille et quelqu'un qui comprend le système qu'il utilise, je me borne depuis plusieurs jours sur un chiffre à vouloir trouver une différence qui n'existe pas.

J'ai suivi les conseils de pepe et refais tourner les deux sketch en mesurant le temps d'acquisition de la 5eme à la 35eme trame avec un chrono "manuel" => effectivement 46 secondes pour les deux,nous sommes bien devant des valeurs affichés erronées et non une différence d'acquisition.

Vraiment désolé du temps que je vous ai pris et un grand merci pour ta patience pepe

Si je me permet une dernière question, fdufnews évoque la possibilité de ne pas bloquer le programme pendant l’acquisition de la trame, mais comment faire alors que le programme est obligé de lire chaque octet reçu via le port série 1 par 1. A part un autre arduino qui fait l’acquisition et un autre pour le sketch je ne vois pas.

Je ne demande pas la solution toute faite bien sur ;) mais si vous aviez une piste par où commencer car mon sketch domotique et bloqué par plein de temps d’acquisition (sondes températures/hygrométrie OnWire, réception d'info en I2C et lecture de données sur une carte micro SD) Ce n'est que quelques secondes en totalité mais si ces acquisition pouvaient se faire en marge du sketch principale ce serrai une petite révolution pour moi !!!

Si tu utilises l'UART matérielle, rien ne t'oblige à lire le message reçu octet par octet. Les données arrivant très lentement, tu peux très bien attendre d'avoir un certain nombre de caractères reçu pour commencer à traiter celles-ci ce qui laisse du temps pour faire autre chose. Autre chose, une fois le début de trame détecté, il est assez facile d'utiliser SerialEvent() pour détecter une fin de "ligne" et ainsi n'interrompre longuement la boucle principale que lorsqu'il y a un ensemble complet de données à traiter.

Ensuite, il faut rester conscient du fait qu'il n'est absolument par nécessaire d'avoir sa consommation électrique à la seconde près. Laisser passer quelques trame est sans conséquence.

Je crois comprendre ...

-SerialEvent() se déclenche à chaque nouveau caractère reçu dans le buffer du port série -SérialEvent() détecte un caractère de nouvel ligne -Dans SérialEvent(),ce qui ne devrait pas bloquer mon sketch, on concatène chaque caractère dans un String -SérialEvent() détecte un caractère de fin de ligne et "prévient" le sketch qu'il à fini

=>mon sketch traite la ligne

bon ben au boulot :D