bonjour fm, moi j'utilise actuellement les librairies Wire et SoftwareSerial sur un nano "esclave" sans aucun soucis.
je récupéré la teleinfo de mon compteur EDF via SoftwareSerial , et la renvoie "décodé" via le bus I2C vers un arduino maitre.
J'ai gardé la liaison série classique pour le debug.
#include <SoftwareSerial.h>
#include <Wire.h>
SoftwareSerial Serial_Teleinfo(3, 4);
// Créé une liason série sur les pins 3 et 4
// Seulement Pin 3 sur l'optocoupleur
long top1 = 0;
long top2 = 0;
long obtention = 0;
long Index_HC = 0;
long Index_HP = 0;
byte I_A = 0;
int P_W = 0;
char PERIODE = ' ';
byte compteurOK = 0;
unsigned long temps_d_acquisition = 0;
int go = 0;
volatile byte* Long1ArrayPtr;
volatile byte* Long2ArrayPtr;
volatile byte* Long3ArrayPtr;
volatile byte* Int1ArrayPtr;
void setup() {
pinMode(13, OUTPUT);
Wire.begin(8);
Wire.onRequest(requestEvent);
Wire.onReceive(receiveEvent);
Serial.begin(9600); // Port série pour liasion Arduino <-> PC
Serial_Teleinfo.begin(1200); // Port SoftwareSerial pour liasion Arduino <-> Teleinfo
}
void loop() {
if (go == 1) {
recup_teleinfo();
}
}
void requestEvent()
{
byte Data[16];
if (compteurOK == 1) {
digitalWrite(13, HIGH);
Long1ArrayPtr = (byte*) &obtention;
Data[0] = Long1ArrayPtr[0];
Data[1] = Long1ArrayPtr[1];
Data[2] = Long1ArrayPtr[2];
Data[3] = Long1ArrayPtr[3];
Long2ArrayPtr = (byte*) &Index_HC;
Data[4] = Long2ArrayPtr[0];
Data[5] = Long2ArrayPtr[1];
Data[6] = Long2ArrayPtr[2];
Data[7] = Long2ArrayPtr[3];
Long3ArrayPtr = (byte*) &Index_HP;
Data[8] = Long3ArrayPtr[0];
Data[9] = Long3ArrayPtr[1];
Data[10] = Long3ArrayPtr[2];
Data[11] = Long3ArrayPtr[3];
Int1ArrayPtr = (byte*) &P_W;
Data[12] = Int1ArrayPtr[0];
Data[13] = Int1ArrayPtr[1];
Data[14] = I_A;
Data[15] = byte(PERIODE);
Data[16] = compteurOK;
}
else {
Data[0] = 0;
Data[1] = 0;
Data[2] = 0;
Data[3] = 0;
Data[4] = 0;
Data[5] = 0;
Data[6] = 0;
Data[7] = 0;
Data[8] = 0;
Data[9] = 0;
Data[10] = 0;
Data[11] = 0;
Data[12] = 0;
Data[13] = 0;
Data[14] = 0;
Data[15] = 0;
Data[16] = 0;
}
Wire.write(Data, 17);
}
void receiveEvent(int howMany) {
while (1 < Wire.available()) { // loop through all but the last
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
go = Wire.read(); // receive byte as an integer
Serial.println(go); // print the integer
top1 = millis();
temps_d_acquisition = millis();
compteurOK = 0;
}
void recup_teleinfo() {
digitalWrite(13, LOW);
go = 0;
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 (Expliquations ! non 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.))
*/
//RAZ des valeurs
Index_HC = Index_HP = 0;
I_A = 250;
P_W = 32000;
PERIODE = 'A';
obtention = 0;
while ( Index_HC == 0 || Index_HP == 0 || I_A == 250 || P_W == 32000 || PERIODE == 'A' ) { // recommence tant que l'on a pas recu tous les élément voulus
//Attend un début de ligne (0x0A)
charIn_Trame_Teleinfo = Serial_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) > 1000 ) {
Serial.println("Teleinfo Inaccesible"); // Affiche un erreur si la teleinfo est inaccesible et retourne à Loop
loop();
}
if (Serial_Teleinfo.available()) { // Tant qu'il y a des caractères disponibles
charIn_Trame_Teleinfo = Serial_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 = Serial_Teleinfo.read() & 0x7F ;
while (charIn_Trame_Teleinfo != 0x20) { // reste dans cette boucle tant qu'on ne recoit pas le Charactere Espace
if (Serial_Teleinfo.available()) { // Tant qu'il y a des caractères disponibles
charIn_Trame_Teleinfo = Serial_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 = Serial_Teleinfo.read() & 0x7F ;
while (charIn_Trame_Teleinfo != 0x20) { // reste dans cette boucle tant qu'on ne recoit pas le Charactere Espace
if (Serial_Teleinfo.available()) { // Tant qu'il y a des caractères disponibles
charIn_Trame_Teleinfo = Serial_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 = Serial_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 (Serial_Teleinfo.available()) { // Tant qu'il y a des caractères disponibles
charIn_Trame_Teleinfo = Serial_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();
}
}
}
if (( Index_HC != 0) && (Index_HP != 0) && (I_A != 250) && (P_W != 32000) && (PERIODE != 'A' )) {
compteurOK = 1;
Serial.print("Temps d'aquisition : "); Serial.print(millis() - temps_d_acquisition); 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");
top2 = millis();
obtention = top2 - top1;
Serial.print("Temps obtention : "); Serial.print(obtention); Serial.println(" Millisecondes");
}
}