Changement de baud rate en pleine exécution d'un programme

Bonjour,

Je travail actuellement sur un projet qui consiste à lire sur une carte arduino un sortie de télé-information client d’un compteur linky quelconque.

Pour ce faire je dois recevoir et interpréter la trame transmise par le compteur électrique; Il faut savoir qu’en fonction du type de compteur, la trame en sortie de la TIC (télé-info client) peut prendre 2 type de baud rate différents : 1200 bauds pour le mode historique ou 9600 bauds pour le mode standard. Or j’essaie de faire 1 seul programme compatible avec les deux mode différents, pour cela je dois détecter automatiquement le mode en cours de transmission (si c’est 1200 ou 9600 bauds).

Il faut également savoir que j’utilise la bibliothèque SoftwareSerial pour créer une communication série sur les pins 8 et 9 (respectivement réception et émission). De plus je n’ai besoin que de lire les informations transmises par le compteur pour l’instant donc je n’utilise que le pin 8.

Mon problème est le suivant : Je n’arrive pas à créer un programme compatible avec les deux modes de transmission qui s’adapte au baud rate automatiquement j’ai essayé tout un tas de truc :

  • Faire une première lecture avec un baud rate de 1200 : Si je lis quelque chose alors le baud rate est
    correct et je le garde

Si je ne lis rien ou des caractères hs, je modifie
le baud rate à 9600

à savoir que pour changer le baud rate en lecture j’utilise la fonction serial.begin(1200 ou 9600)

Le problème de cette méthode c’est que le programme n’est pas stable et j’ai l’impression que dans
le programme je ne peux pas faire de modification de baud rate par la suite, ou alors elles ne sont
pas prises en compte

Ma question est donc la suivante, est il possible de changer le débit de données en lecture avec un serial.begin(x) en pendant l’exécution du programme ? Si oui comment faire, j’ai essayé beaucoup de chose mais sans succès à chaque fois.

Je vous joints mon programme si vous avez envie d’aller check (peut être que le problème est ailleurs)

Merci d’avance

Test_TIC_Linky_v3.ino (7.88 KB)

Je n’ai pas la réponse à la question, mais en revanche je peux dire que par expérience, software serial en dessous de 9600 ça fonctionne très mal…

prends une carte mega tu aura 3 ports série matériels

Essayer à 1200 puis à 9600 me semble hasardeux.
Si le compteur communique à 9600, à 1200 tu ne recevras rien.

Je ne vois rien dans la librairie SoftwareSerial qui interdise de changer le baudrate à la volée.

En général dans une installation le baudrate ne change pas.
Tu pourrais simplement prévoir un jumper ou un inter à glissière.

Fais un test avec begin(9600), sans changement ultérieur, et un compteur 9600 baud. Si la réception est mauvaise tu seras fixé.

@bricofoy déjà merci d’avoir pris le temps de lire et de répondre, pour l’instant le software serial fonctionne très bien à 1200 bauds, pour ce type d’application en tout cas je ne constate aucun problème. J’ai déjà une carte méga là n’est pas le problème, le problème vient du fait que sur une même entrée la débit en baud de transmission de bit peut changer et prendre successivement les valeurs de 1200 et 9600 bauds, ce ne sont donc pas 2 entrées différentes mais bien une seule, et il faut que le programme s’adapte à ce changement de débit.

@hbachetti Merci aussi pour ta réponse,

"Essayer à 1200 puis à 9600 me semble hasardeux." hélas, ce n'est pas n'est pas une simple manip hasardeuse de changer le baud rate à la volée, c'est nécessaire car le simulateur sur lequel je travail envoie successivement des trames à 1200 bauds et 9600 bauds et ils faut que les deux puissent être lue.

"En général dans une installation le baudrate ne change pas." Pour mon installation c'est le cas et c'est bien ça qui me pose soucis dans le code.

"Fais un test avec begin(9600), sans changement ultérieur, et un compteur 9600 baud. Si la réception est mauvaise tu seras fixé." Que ce soit pour 1200 ou 9600 bauds les deux réceptions marchent niquel, ce qui pose problème c'est de correctement réceptionner les 2 avec 1 seul programme. J'utilise le même programme (celui joint) pour 1200 et 9600 bauds en changeant à chaque fois manuellement le Serial.begin(x) et j'aimerais automatisé cela, là est le soucis.

"Tu pourrais simplement prévoir un jumper ou un inter à glissière." je débute un peu en arduino, est ce que tu pourrais apporter plus de précision stp ?
Merci

Il y a peut être un temps de stabilisation a prévoir, un vidage de tampon (je ne trouve plus le nom anglais, c'est pas beau de vieillir) entre les deux vitesses.

hello
une idée comme ça:
une méga et le linky raccordé sur Serial1 à 1200 bauds et sur Sérial2 à 9600 bauds
le prg scrute les deux et détermine qui envoie des données cohérentes

68tjs:
Il y a peut être un temps de stabilisation a prévoir, un vidage de tampon (je ne trouve plus le nom anglais, c'est pas beau de vieillir) entre les deux vitesses.

flush ?
a priori ce 'est pas dispo sous softwareserial
peut etre jouer avec la valeur du tampon de reception et de "tirer la chasse" à la main ? :grin:

A voir ce discriminerait reellement selon le contenu

Pour vider le buffer d'entrée on appelle généralement [i]leFlux[/i].end();
(cf code source)

Et si vous avez une MEGA pourquoi s'embêter avec Software Serial ?

Aussi - vous pouvez lire cela (et il y'en a d'autres)

Flush faut oublier

void SoftwareSerial::flush()
{
  // There is no tx buffering, simply return
}

end() appelle une méthode privée stopListening() qui désactive la gestion d'interruption pour cette instance

begin() normalement appelle stopListening() mais comme begin modifie des paramètres avant de stopper la réception il y a peut-être des effets de bord non prévus et c'est peut-être ça qui rend l'ensemble instable. begin remet à zéro le buffer de réception.

Tu pourrais donc essayer:

leFlux.end(); // stop la reception avant toute modification
leFlux.begin(nouveau_baudrate); // change le baudrate

fdufnews:
Tu pourrais donc essayer:

leFlux.end(); // stop la reception avant toute modification

leFlux.begin(nouveau_baudrate); // change le baudrate

j'ai déjà essayé cela sur des shield GPRS

  • ouverture a 115200 bauds car c'était la valeur par défaut
  • envoi de la commande AT pour passer à 9600 bauds
  • fermeture de la liaison avec end()
  • réouverture avec begin(9600)

-> ça fonctionne.

elkilleros:
@bricofoy déjà merci d'avoir pris le temps de lire et de répondre, pour l'instant le software serial fonctionne très bien à 1200 bauds, pour ce type d'application en tout cas je ne constate aucun problème. J'ai déjà une carte méga là n'est pas le problème, le problème vient du fait que sur une même entrée la débit en baud de transmission de bit peut changer et prendre successivement les valeurs de 1200 et 9600 bauds, ce ne sont donc pas 2 entrées différentes mais bien une seule, et il faut que le programme s'adapte à ce changement de débit.

Mais alors si tu utilises une mega, utilise plutot les ports série materiels et pas software serial, ce sera bien plus fiable dans tous les cas, indépendamment du problème de réglage de la vitesse

Merci pour vos réponses, juste pour prévenir : j'ai trouvé une solution à mon problème :

J'ai créé une fonction qui viens lire les 10 premiers temps d'une impulsion haute grâce à la fonction pulseIn(n°pin, HIGH) je stock ces 10 valeurs dans un tableau, je stocke dans un variable la plus petite de ces 10 valeurs, j'obtiens alors le temps de transmission d'un bit '1'. On sait que 1200 bauds = 1200 bits/s et 9600 bauds = 9600 bits/s je regarde alors si ce temps de transmission d'un bit est plus proche de 833 us (1/1200) ou 105 (1/9600); Globalement si le temps de transmission d'un bit est plus proche de 833 us je fait un serial.begin(1200) sinon serial.begin(9600).

Je sais pas si c'est très clair mais c'est la solution que j'ai trouvée et elle marche plutôt très bien.

Ce genre de truc est utilisé depuis longtemps dans des micro pour faire une détection automatique de baudrate. Et effectivement cela fonctionne bien à quelques exceptions près,

  • si les premiers caractères envoyés ne contiennent pas de 1 isolé tu peux de trouver avec un mauvais baudrate
  • tu perds systématiquement les premiers caractères après un reset. Si tu as un problème d’initialisation tu peux ne pas voir le compte-rendu d’erreur. Dans ton cas ce n’est pas un problème.