Skip to main content
Arduino

Return to Question

Linked shield referenced in question; changed code quoting on enable syntax highlighting.
Source Link
timemage
  • 5.6k
  • 1
  • 14
  • 25

I'm revisiting my Arduino stuff (I want to revive Teleinfo shield to monitor closely my power consumption). I just cannot get the thing to work (Teleinfo ShieldTeleinfo Shield + Uno Wifi).

The code is the following Teleinfo_Arduino_V0_3E.ino (just added some lines writing to serial to follow progress; and modified Serial.beginSerial.begin accordingly and "shortened" to stay within size limits but it's sending wrong characters ate beginning))

/*
 Datalogger Téléinfo 2 compteurs sur Arduino
 Compteur 1: consommation
 Compteur 2: production solaire en tarif BASE
 Juin 2011:
 v0.2 * passage automatique à l'heure d'été
 correctif erreur abo BBR
 modification ecriture sur SD (utilisation de teleinfoFile.print à la place s'une variable STRING
 qui plante l'Arduino avec les abonnements BBR
 v0.2a * ajout mode sans puissance apparente pour ancien compteur et calcul de celle-ci pour les logiciels d'analyse
 v0.2b * pour Arduino 1.0 (mise à jour de la RTC et utilisation de la librairie SD livrée avec la 1.0)
 v0.2c * modif type de variable pour éviter d'avoir 2 enregistrements à la même minute (surtout sur des proc + rapide)
 v0.3 * détection automatique du type d'abonnement sur le compteur 1
 v0.3a * Fonction de mise à l'heure par l'usb (interface série) en 1200 bauds 7 bits parité pair
 Procédure:
 1- carte débranchée, enlevez la pile de son support (pour réinitialiser l'horloge)
 2- enlevez le cavalier du shield téléinfo
 3- configurer votre logiciel émulateur de terminal (termite,Hyperterminale...) en 1200 bauds 7 bits parité pair
 4- mettre sous tension la carte.
 -- Le programme détectera le reset de l'horloge et vous demandera de rentrer l'heure et la date. --
 v0.3b * Correction bug calcul PAP compteur 2, enregistrement journalier compteur 2
 v0.3c * Triphasé sur compteur 2
 v0.3d * correction bug retour ligne sur compteur 2 (entête fichier)
 v0.3e * Correction bug si pas de compteur 2
*/
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include <RTClib.h>
const char version_logiciel[6] = "V0.3e";
// #define echo_USB //envoie toutes les trames téléinfo sur l'USB
#define message_systeme_USB //envoie des messages sur l'USB (init SD, heure au demarrage, et echo des erreures)
//*****************************************************************************************
byte inByte = 0; // caractère entrant téléinfo
char buffteleinfo[21] = "";
byte bufflen = 0;
byte mem_sauv_minute = 1;
byte mem_sauv_journee = 1;
byte num_abo = 0;
byte type_mono_tri[2] = { 0, 0 };
uint8_t presence_teleinfo = 0; // si signal teleinfo présent
byte presence_PAP = 0; // si PAP présent
boolean cpt2_present = true; // mémorisation de la présence du compteur 2
boolean compteursluOK = false; // pour autoriser l'écriture de valeur sur la SD
boolean mem_affichage_cpt2_present = true;
int ReceptionOctet = 0; // variable de stockage des octets reçus par port série
unsigned int ReceptionNombre = 0; // variable de calcul du nombre reçu par port série
byte reg_horloge = 1;
boolean mem_reg_horloge = false;
const uint8_t val_max[6] = { 24, 59, 59, 31, 12, 99 };
// declarations Teleinfo
unsigned int papp = 0; // Puissance apparente, VA
uint8_t IINST[2][3] = { { 0, 0, 0 }, { 0, 0, 0 } }; // Intensité Instantanée Phase 1, A (intensité efficace instantanée) ou 1 phase en monophasé
unsigned long INDEX1 = 0; // Index option Tempo - Heures Creuses Jours Bleus, Wh
unsigned long INDEX2 = 0; // Index option Tempo - Heures Pleines Jours Bleus, Wh
unsigned long INDEX3 = 0; // Index option Tempo - Heures Creuses Jours Blancs, Wh
unsigned long INDEX4 = 0; // Index option Tempo - Heures Pleines Jours Blancs, Wh
unsigned long INDEX5 = 0; // Index option Tempo - Heures Creuses Jours Rouges, Wh
unsigned long INDEX6 = 0; // Index option Tempo - Heures Pleines Jours Rouges, Wh
// compteur 2 (solaire configuré en tarif BASE par ERDF)
unsigned long cpt2index = 0; // Index option Base compteur production solaire, Wh
unsigned int cpt2puissance = 0; // Puissance apparente compteur production solaire, VA
#define debtrame 0x02
#define debligne 0x0A
#define finligne 0x0D
// *************** déclaration carte micro SD ******************
const byte chipSelect = 4;
// *************** déclaration activation compteur 1 ou 2 ******
#define LEC_CPT1 5 // lecture compteur 1
#define LEC_CPT2 6 // lecture compteur 2
//
byte verif_cpt_lu = 0;
//
byte compteur_actif = 1; // numero du compteur en cours de lecture
byte donnee_ok_cpt[2] = { 0, 0 }; // pour vérifier que les donnees sont bien en memoire avant ecriture dans fichier
byte donnee_ok_cpt_ph[2] = { 0, 0 };
// *************** variables RTC ************************************
byte minute, heure, seconde, jour, mois, jour_semaine;
unsigned int annee;
char date_heure[18];
char mois_jour[7];
byte mem_chg_heure = 0; //pour pas passer perpetuellement de 3h à 2h du matin le dernier dimanche d'octobre
RTC_DS1307 RTC;
// ************** initialisation *******************************
void setup() {
 // initialisation du port 0-1 lecture Téléinfo
 Serial.begin(1200);
 // parité paire E
 // 7 bits data
 UCSR0C = B00100100;
#ifdef message_systeme_USB
 Serial.print(F("-- Teleinfo USB Arduino "));
 Serial.print(version_logiciel);
 Serial.println(F(" --"));
#endif
 // initialisation des sorties selection compteur
 pinMode(LEC_CPT1, OUTPUT);
 pinMode(LEC_CPT2, OUTPUT);
 digitalWrite(LEC_CPT1, HIGH);
 digitalWrite(LEC_CPT2, LOW);
 // verification de la présence de la microSD et si elle est initialisée:
#ifdef message_systeme_USB
 if (!SD.begin(chipSelect)) {
 Serial.println(F("> Erreur carte, ou carte absente !"));
 return;
 }
 Serial.println(F("> microSD initialisee !"));
#endif
 // initialisation RTC16
 Wire.begin();
 RTC.begin();
 if (!RTC.isrunning()) {
#ifdef message_systeme_USB
 Serial.println(F("RTC non configure !"));
#endif
 }
 DateTime now = RTC.now(); // lecture de l'horloge
 annee = now.year();
 mois = now.month();
 jour = now.day();
 heure = now.hour();
 minute = now.minute();
 jour_semaine = now.dayOfTheWeek();
 format_date_heure();
#ifdef message_systeme_USB
 Serial.println(date_heure);
#endif
}
// ************** boucle principale *******************************
void loop() // Programme en boucle
{
 if (!(RTC.isrunning()) && (reg_horloge < 7)) { // si l'horloge n'est pas configurée
 digitalWrite(LEC_CPT1, LOW);
 if (!mem_reg_horloge) {
 switch (reg_horloge) { // debut de la structure
 case 1:
 Serial.print(F("Entrer Heure: "));
 break;
 case 2:
 Serial.print(F("Entrer Minute: "));
 break;
 case 3:
 Serial.print(F("Entrer Seconde: "));
 break;
 case 4:
 Serial.print(F("Entrer Jour: "));
 break;
 case 5:
 Serial.print(F("Entrer Mois: "));
 break;
 case 6:
 Serial.print(F("Entrer Annee 20xx: "));
 break;
 }
 mem_reg_horloge = true;
 }
 if (Serial.available() > 0) { // si caractère dans la file d'attente
 Serial.print(F("un nombre a ete recu")); //---- lecture du nombre reçu
 while (Serial.available() > 0) {
 // tant que buffer pas vide pour lire d'une traite tous les caractères reçus
 inByte = Serial.read(); // renvoie le 1er octet présent dans la file attente série (-1 si aucun)
 Serial.println(inByte);
 if (((inByte > 47) && (inByte < 58)) || (inByte == 13)) {
 ReceptionOctet = inByte - 48; // transforme valeur ASCII en valeur décimale
 if ((ReceptionOctet >= 0) && (ReceptionOctet <= 9)) ReceptionNombre = (ReceptionNombre * 10) + ReceptionOctet;
 // si valeur reçue correspond à un chiffre on calcule nombre
 Serial.print(ReceptionNombre);
 Serial.print(reg_horloge);
 } else
 presence_teleinfo = -1;
 } // fin while
 if (inByte == 13) {
 if ((ReceptionNombre > val_max[reg_horloge - 1]) || (ReceptionNombre == -1)) {
 Serial.println(F("Erreur horaire"));
 ReceptionNombre = 0;
 mem_reg_horloge = true;
 } else {
 Serial.print("cela bugge");
 switch (reg_horloge) { // debut de la structure
 case 1:
 heure = ReceptionNombre;
 Serial.print("heure:");
 Serial.println(heure);
 case 2:
 minute = ReceptionNombre;
 break;
 case 3:
 seconde = ReceptionNombre;
 break;
 case 4:
 jour = ReceptionNombre;
 break;
 case 5:
 mois = ReceptionNombre;
 break;
 case 6:
 annee = 2000 + ReceptionNombre;
 break;
 }
 mem_reg_horloge = false;
 ReceptionNombre = 0;
 ++reg_horloge;
 if (reg_horloge > 6) {
 RTCsetTime();
 Serial.println(F("Reglage heure OK - installer le cavalier pour la teleinfo"));
 digitalWrite(LEC_CPT1, HIGH);
 }
 }
 }
 }
 }
 else {
 DateTime now = RTC.now(); // lecture de l'horloge
 minute = now.minute();
 heure = now.hour();
 seconde = now.second();
 if ((heure == 0) && (minute == 0) && (seconde == 0)) {
 annee = now.year();
 mois = now.month();
 jour = now.day();
 jour_semaine = now.dayOfTheWeek();
 }
 // passage à l'heure d'été +1 heure
 // la lib RTC a une fonction: dayOfWeek qui donne le jour de la semaine (la DS1307 se charge de tout !)
 // réponse: 0 -> dimanche, 1 -> lundi etc...
 //
 if ((heure == 2) && (minute == 0) && (seconde == 0) && (jour_semaine == 0) && (mois == 3) && (jour > 24)) {
 heure = 3;
 RTCsetTime();
 }
 // passage à l'heure d'hiver -1 heure
 if ((heure == 3) && (minute == 0) && (seconde == 0) && (jour_semaine == 0) && (mois == 10) && (jour > 24) && (mem_chg_heure == 0)) {
 heure = 2;
 RTCsetTime();
 mem_chg_heure = 1;
 }
 if ((heure == 23) && (minute == 59) && (seconde == 10)) // pour être sur de pas tomber pendant l'enregistrement toutes les minutes
 {
 if ((mem_sauv_journee == 0) && (compteursluOK)) // un seul enregistrement par jour !
 {
 fichier_annee();
 mem_sauv_journee = 1;
 mem_chg_heure = 0;
 }
 } else
 mem_sauv_journee = 0;
 if (seconde == 1) {
 if ((mem_sauv_minute == 0) && (compteursluOK)) // un seul enregistrement par minute !
 {
 enregistre();
 mem_sauv_minute = 1;
 }
 } else
 mem_sauv_minute = 0;
#ifdef message_systeme_USB
 if ((donnee_ok_cpt[1] == B00000111) && (mem_affichage_cpt2_present)) {
 if (mem_affichage_cpt2_present) Serial.println(F("- Compteur 2 detecte"));
 mem_affichage_cpt2_present = false;
 } else if ((!cpt2_present) && (mem_affichage_cpt2_present)) {
 if (mem_affichage_cpt2_present) Serial.println(F("- Compteur 2 non present !"));
 mem_affichage_cpt2_present = false;
 }
#endif
 if ((donnee_ok_cpt[0] == verif_cpt_lu) and (cpt2_present)) {
 if ((type_mono_tri[0] == 1) && (donnee_ok_cpt_ph[0] == B10000001)) bascule_compteur();
 else if ((type_mono_tri[0] == 3) && (donnee_ok_cpt_ph[0] == B10000111))
 bascule_compteur();
 } else if ((donnee_ok_cpt[1] == B00000001) or ((compteur_actif == 2) and (!cpt2_present))) {
 if ((type_mono_tri[1] == 1) && (donnee_ok_cpt_ph[1] == B10000001)) bascule_compteur();
 else if ((type_mono_tri[1] == 3) && (donnee_ok_cpt_ph[1] == B10000111))
 bascule_compteur();
 compteursluOK = true;
 }
 if (compteur_actif == 2) {
 if (presence_teleinfo > 200) {
 cpt2_present = false;
 compteursluOK = true;
 bascule_compteur();
 } else
 cpt2_present = true;
 }
 read_teleinfo();
 }
}
///////////////////////////////////////////////////////////////////
// Calcul Checksum teleinfo
///////////////////////////////////////////////////////////////////
char chksum(char *buff, uint8_t len) {
 int i;
 char sum = 0;
 for (i = 1; i < (len - 2); i++) sum = sum + buff[i];
 sum = (sum & 0x3F) + 0x20;
 return (sum);
}
///////////////////////////////////////////////////////////////////
// mise en forme Date & heure pour affichage ou enregistrement
///////////////////////////////////////////////////////////////////
void format_mois_jour() {
 sprintf(mois_jour, "%02d,%02d,", mois, jour);
}
// Convert normal decimal numbers to binary coded decimal
static uint8_t bin2bcd(uint8_t val) {
 return val + 6 * (val / 10);
}
///////////////////////////////////////////////////////////////////
// mise à l'heure de la RTC (DS1307)
///////////////////////////////////////////////////////////////////
void RTCsetTime(void) {
 Wire.beginTransmission(104); // 104 is DS1307 device address (0x68)
 Wire.write(bin2bcd(0)); // start at register 0
 Wire.write(bin2bcd(seconde)); //Send seconds as BCD
 Wire.write(bin2bcd(minute)); //Send minutes as BCD
 Wire.write(bin2bcd(heure)); //Send hours as BCD
 Wire.write(bin2bcd(jour_semaine)); // dow
 Wire.write(bin2bcd(jour)); //Send day as BCD
 Wire.write(bin2bcd(mois)); //Send month as BCD
 Wire.write(bin2bcd(annee % 1000)); //Send year as BCD
 Wire.endTransmission();
}
/*
 Datalogger Téléinfo 2 compteurs sur Arduino
 Compteur 1: consommation
 Compteur 2: production solaire en tarif BASE
 Juin 2011:
 v0.2 * passage automatique à l'heure d'été
 correctif erreur abo BBR
 modification ecriture sur SD (utilisation de teleinfoFile.print à la place s'une variable STRING
 qui plante l'Arduino avec les abonnements BBR
 v0.2a * ajout mode sans puissance apparente pour ancien compteur et calcul de celle-ci pour les logiciels d'analyse
 v0.2b * pour Arduino 1.0 (mise à jour de la RTC et utilisation de la librairie SD livrée avec la 1.0)
 v0.2c * modif type de variable pour éviter d'avoir 2 enregistrements à la même minute (surtout sur des proc + rapide)
 v0.3 * détection automatique du type d'abonnement sur le compteur 1
 v0.3a * Fonction de mise à l'heure par l'usb (interface série) en 1200 bauds 7 bits parité pair
 Procédure:
 1- carte débranchée, enlevez la pile de son support (pour réinitialiser l'horloge)
 2- enlevez le cavalier du shield téléinfo
 3- configurer votre logiciel émulateur de terminal (termite,Hyperterminale...) en 1200 bauds 7 bits parité pair
 4- mettre sous tension la carte.
 -- Le programme détectera le reset de l'horloge et vous demandera de rentrer l'heure et la date. --
 v0.3b * Correction bug calcul PAP compteur 2, enregistrement journalier compteur 2
 v0.3c * Triphasé sur compteur 2
 v0.3d * correction bug retour ligne sur compteur 2 (entête fichier)
 v0.3e * Correction bug si pas de compteur 2
*/
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include <RTClib.h>
const char version_logiciel[6] = "V0.3e";
// #define echo_USB //envoie toutes les trames téléinfo sur l'USB
#define message_systeme_USB //envoie des messages sur l'USB (init SD, heure au demarrage, et echo des erreures)
//*****************************************************************************************
byte inByte = 0; // caractère entrant téléinfo
char buffteleinfo[21] = "";
byte bufflen = 0;
byte mem_sauv_minute = 1;
byte mem_sauv_journee = 1;
byte num_abo = 0;
byte type_mono_tri[2] = { 0, 0 };
uint8_t presence_teleinfo = 0; // si signal teleinfo présent
byte presence_PAP = 0; // si PAP présent
boolean cpt2_present = true; // mémorisation de la présence du compteur 2
boolean compteursluOK = false; // pour autoriser l'écriture de valeur sur la SD
boolean mem_affichage_cpt2_present = true;
int ReceptionOctet = 0; // variable de stockage des octets reçus par port série
unsigned int ReceptionNombre = 0; // variable de calcul du nombre reçu par port série
byte reg_horloge = 1;
boolean mem_reg_horloge = false;
const uint8_t val_max[6] = { 24, 59, 59, 31, 12, 99 };
// declarations Teleinfo
unsigned int papp = 0; // Puissance apparente, VA
uint8_t IINST[2][3] = { { 0, 0, 0 }, { 0, 0, 0 } }; // Intensité Instantanée Phase 1, A (intensité efficace instantanée) ou 1 phase en monophasé
unsigned long INDEX1 = 0; // Index option Tempo - Heures Creuses Jours Bleus, Wh
unsigned long INDEX2 = 0; // Index option Tempo - Heures Pleines Jours Bleus, Wh
unsigned long INDEX3 = 0; // Index option Tempo - Heures Creuses Jours Blancs, Wh
unsigned long INDEX4 = 0; // Index option Tempo - Heures Pleines Jours Blancs, Wh
unsigned long INDEX5 = 0; // Index option Tempo - Heures Creuses Jours Rouges, Wh
unsigned long INDEX6 = 0; // Index option Tempo - Heures Pleines Jours Rouges, Wh
// compteur 2 (solaire configuré en tarif BASE par ERDF)
unsigned long cpt2index = 0; // Index option Base compteur production solaire, Wh
unsigned int cpt2puissance = 0; // Puissance apparente compteur production solaire, VA
#define debtrame 0x02
#define debligne 0x0A
#define finligne 0x0D
// *************** déclaration carte micro SD ******************
const byte chipSelect = 4;
// *************** déclaration activation compteur 1 ou 2 ******
#define LEC_CPT1 5 // lecture compteur 1
#define LEC_CPT2 6 // lecture compteur 2
//
byte verif_cpt_lu = 0;
//
byte compteur_actif = 1; // numero du compteur en cours de lecture
byte donnee_ok_cpt[2] = { 0, 0 }; // pour vérifier que les donnees sont bien en memoire avant ecriture dans fichier
byte donnee_ok_cpt_ph[2] = { 0, 0 };
// *************** variables RTC ************************************
byte minute, heure, seconde, jour, mois, jour_semaine;
unsigned int annee;
char date_heure[18];
char mois_jour[7];
byte mem_chg_heure = 0; //pour pas passer perpetuellement de 3h à 2h du matin le dernier dimanche d'octobre
RTC_DS1307 RTC;
// ************** initialisation *******************************
void setup() {
 // initialisation du port 0-1 lecture Téléinfo
 Serial.begin(1200);
 // parité paire E
 // 7 bits data
 UCSR0C = B00100100;
#ifdef message_systeme_USB
 Serial.print(F("-- Teleinfo USB Arduino "));
 Serial.print(version_logiciel);
 Serial.println(F(" --"));
#endif
 // initialisation des sorties selection compteur
 pinMode(LEC_CPT1, OUTPUT);
 pinMode(LEC_CPT2, OUTPUT);
 digitalWrite(LEC_CPT1, HIGH);
 digitalWrite(LEC_CPT2, LOW);
 // verification de la présence de la microSD et si elle est initialisée:
#ifdef message_systeme_USB
 if (!SD.begin(chipSelect)) {
 Serial.println(F("> Erreur carte, ou carte absente !"));
 return;
 }
 Serial.println(F("> microSD initialisee !"));
#endif
 // initialisation RTC16
 Wire.begin();
 RTC.begin();
 if (!RTC.isrunning()) {
#ifdef message_systeme_USB
 Serial.println(F("RTC non configure !"));
#endif
 }
 DateTime now = RTC.now(); // lecture de l'horloge
 annee = now.year();
 mois = now.month();
 jour = now.day();
 heure = now.hour();
 minute = now.minute();
 jour_semaine = now.dayOfTheWeek();
 format_date_heure();
#ifdef message_systeme_USB
 Serial.println(date_heure);
#endif
}
// ************** boucle principale *******************************
void loop() // Programme en boucle
{
 if (!(RTC.isrunning()) && (reg_horloge < 7)) { // si l'horloge n'est pas configurée
 digitalWrite(LEC_CPT1, LOW);
 if (!mem_reg_horloge) {
 switch (reg_horloge) { // debut de la structure
 case 1:
 Serial.print(F("Entrer Heure: "));
 break;
 case 2:
 Serial.print(F("Entrer Minute: "));
 break;
 case 3:
 Serial.print(F("Entrer Seconde: "));
 break;
 case 4:
 Serial.print(F("Entrer Jour: "));
 break;
 case 5:
 Serial.print(F("Entrer Mois: "));
 break;
 case 6:
 Serial.print(F("Entrer Annee 20xx: "));
 break;
 }
 mem_reg_horloge = true;
 }
 if (Serial.available() > 0) { // si caractère dans la file d'attente
 Serial.print(F("un nombre a ete recu")); //---- lecture du nombre reçu
 while (Serial.available() > 0) {
 // tant que buffer pas vide pour lire d'une traite tous les caractères reçus
 inByte = Serial.read(); // renvoie le 1er octet présent dans la file attente série (-1 si aucun)
 Serial.println(inByte);
 if (((inByte > 47) && (inByte < 58)) || (inByte == 13)) {
 ReceptionOctet = inByte - 48; // transforme valeur ASCII en valeur décimale
 if ((ReceptionOctet >= 0) && (ReceptionOctet <= 9)) ReceptionNombre = (ReceptionNombre * 10) + ReceptionOctet;
 // si valeur reçue correspond à un chiffre on calcule nombre
 Serial.print(ReceptionNombre);
 Serial.print(reg_horloge);
 } else
 presence_teleinfo = -1;
 } // fin while
 if (inByte == 13) {
 if ((ReceptionNombre > val_max[reg_horloge - 1]) || (ReceptionNombre == -1)) {
 Serial.println(F("Erreur horaire"));
 ReceptionNombre = 0;
 mem_reg_horloge = true;
 } else {
 Serial.print("cela bugge");
 switch (reg_horloge) { // debut de la structure
 case 1:
 heure = ReceptionNombre;
 Serial.print("heure:");
 Serial.println(heure);
 case 2:
 minute = ReceptionNombre;
 break;
 case 3:
 seconde = ReceptionNombre;
 break;
 case 4:
 jour = ReceptionNombre;
 break;
 case 5:
 mois = ReceptionNombre;
 break;
 case 6:
 annee = 2000 + ReceptionNombre;
 break;
 }
 mem_reg_horloge = false;
 ReceptionNombre = 0;
 ++reg_horloge;
 if (reg_horloge > 6) {
 RTCsetTime();
 Serial.println(F("Reglage heure OK - installer le cavalier pour la teleinfo"));
 digitalWrite(LEC_CPT1, HIGH);
 }
 }
 }
 }
 }
 else {
 DateTime now = RTC.now(); // lecture de l'horloge
 minute = now.minute();
 heure = now.hour();
 seconde = now.second();
 if ((heure == 0) && (minute == 0) && (seconde == 0)) {
 annee = now.year();
 mois = now.month();
 jour = now.day();
 jour_semaine = now.dayOfTheWeek();
 }
 // passage à l'heure d'été +1 heure
 // la lib RTC a une fonction: dayOfWeek qui donne le jour de la semaine (la DS1307 se charge de tout !)
 // réponse: 0 -> dimanche, 1 -> lundi etc...
 //
 if ((heure == 2) && (minute == 0) && (seconde == 0) && (jour_semaine == 0) && (mois == 3) && (jour > 24)) {
 heure = 3;
 RTCsetTime();
 }
 // passage à l'heure d'hiver -1 heure
 if ((heure == 3) && (minute == 0) && (seconde == 0) && (jour_semaine == 0) && (mois == 10) && (jour > 24) && (mem_chg_heure == 0)) {
 heure = 2;
 RTCsetTime();
 mem_chg_heure = 1;
 }
 if ((heure == 23) && (minute == 59) && (seconde == 10)) // pour être sur de pas tomber pendant l'enregistrement toutes les minutes
 {
 if ((mem_sauv_journee == 0) && (compteursluOK)) // un seul enregistrement par jour !
 {
 fichier_annee();
 mem_sauv_journee = 1;
 mem_chg_heure = 0;
 }
 } else
 mem_sauv_journee = 0;
 if (seconde == 1) {
 if ((mem_sauv_minute == 0) && (compteursluOK)) // un seul enregistrement par minute !
 {
 enregistre();
 mem_sauv_minute = 1;
 }
 } else
 mem_sauv_minute = 0;
#ifdef message_systeme_USB
 if ((donnee_ok_cpt[1] == B00000111) && (mem_affichage_cpt2_present)) {
 if (mem_affichage_cpt2_present) Serial.println(F("- Compteur 2 detecte"));
 mem_affichage_cpt2_present = false;
 } else if ((!cpt2_present) && (mem_affichage_cpt2_present)) {
 if (mem_affichage_cpt2_present) Serial.println(F("- Compteur 2 non present !"));
 mem_affichage_cpt2_present = false;
 }
#endif
 if ((donnee_ok_cpt[0] == verif_cpt_lu) and (cpt2_present)) {
 if ((type_mono_tri[0] == 1) && (donnee_ok_cpt_ph[0] == B10000001)) bascule_compteur();
 else if ((type_mono_tri[0] == 3) && (donnee_ok_cpt_ph[0] == B10000111))
 bascule_compteur();
 } else if ((donnee_ok_cpt[1] == B00000001) or ((compteur_actif == 2) and (!cpt2_present))) {
 if ((type_mono_tri[1] == 1) && (donnee_ok_cpt_ph[1] == B10000001)) bascule_compteur();
 else if ((type_mono_tri[1] == 3) && (donnee_ok_cpt_ph[1] == B10000111))
 bascule_compteur();
 compteursluOK = true;
 }
 if (compteur_actif == 2) {
 if (presence_teleinfo > 200) {
 cpt2_present = false;
 compteursluOK = true;
 bascule_compteur();
 } else
 cpt2_present = true;
 }
 read_teleinfo();
 }
}
///////////////////////////////////////////////////////////////////
// Calcul Checksum teleinfo
///////////////////////////////////////////////////////////////////
char chksum(char *buff, uint8_t len) {
 int i;
 char sum = 0;
 for (i = 1; i < (len - 2); i++) sum = sum + buff[i];
 sum = (sum & 0x3F) + 0x20;
 return (sum);
}
///////////////////////////////////////////////////////////////////
// mise en forme Date & heure pour affichage ou enregistrement
///////////////////////////////////////////////////////////////////
void format_mois_jour() {
 sprintf(mois_jour, "%02d,%02d,", mois, jour);
}
// Convert normal decimal numbers to binary coded decimal
static uint8_t bin2bcd(uint8_t val) {
 return val + 6 * (val / 10);
}
///////////////////////////////////////////////////////////////////
// mise à l'heure de la RTC (DS1307)
///////////////////////////////////////////////////////////////////
void RTCsetTime(void) {
 Wire.beginTransmission(104); // 104 is DS1307 device address (0x68)
 Wire.write(bin2bcd(0)); // start at register 0
 Wire.write(bin2bcd(seconde)); //Send seconds as BCD
 Wire.write(bin2bcd(minute)); //Send minutes as BCD
 Wire.write(bin2bcd(heure)); //Send hours as BCD
 Wire.write(bin2bcd(jour_semaine)); // dow
 Wire.write(bin2bcd(jour)); //Send day as BCD
 Wire.write(bin2bcd(mois)); //Send month as BCD
 Wire.write(bin2bcd(annee % 1000)); //Send year as BCD
 Wire.endTransmission();
}

enter image description hereExample output on Serial Monitor

I'm revisiting my Arduino stuff (I want to revive Teleinfo shield to monitor closely my power consumption). I just cannot get the thing to work (Teleinfo Shield + Uno Wifi).

The code is the following Teleinfo_Arduino_V0_3E.ino (just added some lines writing to serial to follow progress; and modified Serial.begin accordingly and "shortened" to stay within size limits but it's sending wrong characters ate beginning))

/*
 Datalogger Téléinfo 2 compteurs sur Arduino
 Compteur 1: consommation
 Compteur 2: production solaire en tarif BASE
 Juin 2011:
 v0.2 * passage automatique à l'heure d'été
 correctif erreur abo BBR
 modification ecriture sur SD (utilisation de teleinfoFile.print à la place s'une variable STRING
 qui plante l'Arduino avec les abonnements BBR
 v0.2a * ajout mode sans puissance apparente pour ancien compteur et calcul de celle-ci pour les logiciels d'analyse
 v0.2b * pour Arduino 1.0 (mise à jour de la RTC et utilisation de la librairie SD livrée avec la 1.0)
 v0.2c * modif type de variable pour éviter d'avoir 2 enregistrements à la même minute (surtout sur des proc + rapide)
 v0.3 * détection automatique du type d'abonnement sur le compteur 1
 v0.3a * Fonction de mise à l'heure par l'usb (interface série) en 1200 bauds 7 bits parité pair
 Procédure:
 1- carte débranchée, enlevez la pile de son support (pour réinitialiser l'horloge)
 2- enlevez le cavalier du shield téléinfo
 3- configurer votre logiciel émulateur de terminal (termite,Hyperterminale...) en 1200 bauds 7 bits parité pair
 4- mettre sous tension la carte.
 -- Le programme détectera le reset de l'horloge et vous demandera de rentrer l'heure et la date. --
 v0.3b * Correction bug calcul PAP compteur 2, enregistrement journalier compteur 2
 v0.3c * Triphasé sur compteur 2
 v0.3d * correction bug retour ligne sur compteur 2 (entête fichier)
 v0.3e * Correction bug si pas de compteur 2
*/
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include <RTClib.h>
const char version_logiciel[6] = "V0.3e";
// #define echo_USB //envoie toutes les trames téléinfo sur l'USB
#define message_systeme_USB //envoie des messages sur l'USB (init SD, heure au demarrage, et echo des erreures)
//*****************************************************************************************
byte inByte = 0; // caractère entrant téléinfo
char buffteleinfo[21] = "";
byte bufflen = 0;
byte mem_sauv_minute = 1;
byte mem_sauv_journee = 1;
byte num_abo = 0;
byte type_mono_tri[2] = { 0, 0 };
uint8_t presence_teleinfo = 0; // si signal teleinfo présent
byte presence_PAP = 0; // si PAP présent
boolean cpt2_present = true; // mémorisation de la présence du compteur 2
boolean compteursluOK = false; // pour autoriser l'écriture de valeur sur la SD
boolean mem_affichage_cpt2_present = true;
int ReceptionOctet = 0; // variable de stockage des octets reçus par port série
unsigned int ReceptionNombre = 0; // variable de calcul du nombre reçu par port série
byte reg_horloge = 1;
boolean mem_reg_horloge = false;
const uint8_t val_max[6] = { 24, 59, 59, 31, 12, 99 };
// declarations Teleinfo
unsigned int papp = 0; // Puissance apparente, VA
uint8_t IINST[2][3] = { { 0, 0, 0 }, { 0, 0, 0 } }; // Intensité Instantanée Phase 1, A (intensité efficace instantanée) ou 1 phase en monophasé
unsigned long INDEX1 = 0; // Index option Tempo - Heures Creuses Jours Bleus, Wh
unsigned long INDEX2 = 0; // Index option Tempo - Heures Pleines Jours Bleus, Wh
unsigned long INDEX3 = 0; // Index option Tempo - Heures Creuses Jours Blancs, Wh
unsigned long INDEX4 = 0; // Index option Tempo - Heures Pleines Jours Blancs, Wh
unsigned long INDEX5 = 0; // Index option Tempo - Heures Creuses Jours Rouges, Wh
unsigned long INDEX6 = 0; // Index option Tempo - Heures Pleines Jours Rouges, Wh
// compteur 2 (solaire configuré en tarif BASE par ERDF)
unsigned long cpt2index = 0; // Index option Base compteur production solaire, Wh
unsigned int cpt2puissance = 0; // Puissance apparente compteur production solaire, VA
#define debtrame 0x02
#define debligne 0x0A
#define finligne 0x0D
// *************** déclaration carte micro SD ******************
const byte chipSelect = 4;
// *************** déclaration activation compteur 1 ou 2 ******
#define LEC_CPT1 5 // lecture compteur 1
#define LEC_CPT2 6 // lecture compteur 2
//
byte verif_cpt_lu = 0;
//
byte compteur_actif = 1; // numero du compteur en cours de lecture
byte donnee_ok_cpt[2] = { 0, 0 }; // pour vérifier que les donnees sont bien en memoire avant ecriture dans fichier
byte donnee_ok_cpt_ph[2] = { 0, 0 };
// *************** variables RTC ************************************
byte minute, heure, seconde, jour, mois, jour_semaine;
unsigned int annee;
char date_heure[18];
char mois_jour[7];
byte mem_chg_heure = 0; //pour pas passer perpetuellement de 3h à 2h du matin le dernier dimanche d'octobre
RTC_DS1307 RTC;
// ************** initialisation *******************************
void setup() {
 // initialisation du port 0-1 lecture Téléinfo
 Serial.begin(1200);
 // parité paire E
 // 7 bits data
 UCSR0C = B00100100;
#ifdef message_systeme_USB
 Serial.print(F("-- Teleinfo USB Arduino "));
 Serial.print(version_logiciel);
 Serial.println(F(" --"));
#endif
 // initialisation des sorties selection compteur
 pinMode(LEC_CPT1, OUTPUT);
 pinMode(LEC_CPT2, OUTPUT);
 digitalWrite(LEC_CPT1, HIGH);
 digitalWrite(LEC_CPT2, LOW);
 // verification de la présence de la microSD et si elle est initialisée:
#ifdef message_systeme_USB
 if (!SD.begin(chipSelect)) {
 Serial.println(F("> Erreur carte, ou carte absente !"));
 return;
 }
 Serial.println(F("> microSD initialisee !"));
#endif
 // initialisation RTC16
 Wire.begin();
 RTC.begin();
 if (!RTC.isrunning()) {
#ifdef message_systeme_USB
 Serial.println(F("RTC non configure !"));
#endif
 }
 DateTime now = RTC.now(); // lecture de l'horloge
 annee = now.year();
 mois = now.month();
 jour = now.day();
 heure = now.hour();
 minute = now.minute();
 jour_semaine = now.dayOfTheWeek();
 format_date_heure();
#ifdef message_systeme_USB
 Serial.println(date_heure);
#endif
}
// ************** boucle principale *******************************
void loop() // Programme en boucle
{
 if (!(RTC.isrunning()) && (reg_horloge < 7)) { // si l'horloge n'est pas configurée
 digitalWrite(LEC_CPT1, LOW);
 if (!mem_reg_horloge) {
 switch (reg_horloge) { // debut de la structure
 case 1:
 Serial.print(F("Entrer Heure: "));
 break;
 case 2:
 Serial.print(F("Entrer Minute: "));
 break;
 case 3:
 Serial.print(F("Entrer Seconde: "));
 break;
 case 4:
 Serial.print(F("Entrer Jour: "));
 break;
 case 5:
 Serial.print(F("Entrer Mois: "));
 break;
 case 6:
 Serial.print(F("Entrer Annee 20xx: "));
 break;
 }
 mem_reg_horloge = true;
 }
 if (Serial.available() > 0) { // si caractère dans la file d'attente
 Serial.print(F("un nombre a ete recu")); //---- lecture du nombre reçu
 while (Serial.available() > 0) {
 // tant que buffer pas vide pour lire d'une traite tous les caractères reçus
 inByte = Serial.read(); // renvoie le 1er octet présent dans la file attente série (-1 si aucun)
 Serial.println(inByte);
 if (((inByte > 47) && (inByte < 58)) || (inByte == 13)) {
 ReceptionOctet = inByte - 48; // transforme valeur ASCII en valeur décimale
 if ((ReceptionOctet >= 0) && (ReceptionOctet <= 9)) ReceptionNombre = (ReceptionNombre * 10) + ReceptionOctet;
 // si valeur reçue correspond à un chiffre on calcule nombre
 Serial.print(ReceptionNombre);
 Serial.print(reg_horloge);
 } else
 presence_teleinfo = -1;
 } // fin while
 if (inByte == 13) {
 if ((ReceptionNombre > val_max[reg_horloge - 1]) || (ReceptionNombre == -1)) {
 Serial.println(F("Erreur horaire"));
 ReceptionNombre = 0;
 mem_reg_horloge = true;
 } else {
 Serial.print("cela bugge");
 switch (reg_horloge) { // debut de la structure
 case 1:
 heure = ReceptionNombre;
 Serial.print("heure:");
 Serial.println(heure);
 case 2:
 minute = ReceptionNombre;
 break;
 case 3:
 seconde = ReceptionNombre;
 break;
 case 4:
 jour = ReceptionNombre;
 break;
 case 5:
 mois = ReceptionNombre;
 break;
 case 6:
 annee = 2000 + ReceptionNombre;
 break;
 }
 mem_reg_horloge = false;
 ReceptionNombre = 0;
 ++reg_horloge;
 if (reg_horloge > 6) {
 RTCsetTime();
 Serial.println(F("Reglage heure OK - installer le cavalier pour la teleinfo"));
 digitalWrite(LEC_CPT1, HIGH);
 }
 }
 }
 }
 }
 else {
 DateTime now = RTC.now(); // lecture de l'horloge
 minute = now.minute();
 heure = now.hour();
 seconde = now.second();
 if ((heure == 0) && (minute == 0) && (seconde == 0)) {
 annee = now.year();
 mois = now.month();
 jour = now.day();
 jour_semaine = now.dayOfTheWeek();
 }
 // passage à l'heure d'été +1 heure
 // la lib RTC a une fonction: dayOfWeek qui donne le jour de la semaine (la DS1307 se charge de tout !)
 // réponse: 0 -> dimanche, 1 -> lundi etc...
 //
 if ((heure == 2) && (minute == 0) && (seconde == 0) && (jour_semaine == 0) && (mois == 3) && (jour > 24)) {
 heure = 3;
 RTCsetTime();
 }
 // passage à l'heure d'hiver -1 heure
 if ((heure == 3) && (minute == 0) && (seconde == 0) && (jour_semaine == 0) && (mois == 10) && (jour > 24) && (mem_chg_heure == 0)) {
 heure = 2;
 RTCsetTime();
 mem_chg_heure = 1;
 }
 if ((heure == 23) && (minute == 59) && (seconde == 10)) // pour être sur de pas tomber pendant l'enregistrement toutes les minutes
 {
 if ((mem_sauv_journee == 0) && (compteursluOK)) // un seul enregistrement par jour !
 {
 fichier_annee();
 mem_sauv_journee = 1;
 mem_chg_heure = 0;
 }
 } else
 mem_sauv_journee = 0;
 if (seconde == 1) {
 if ((mem_sauv_minute == 0) && (compteursluOK)) // un seul enregistrement par minute !
 {
 enregistre();
 mem_sauv_minute = 1;
 }
 } else
 mem_sauv_minute = 0;
#ifdef message_systeme_USB
 if ((donnee_ok_cpt[1] == B00000111) && (mem_affichage_cpt2_present)) {
 if (mem_affichage_cpt2_present) Serial.println(F("- Compteur 2 detecte"));
 mem_affichage_cpt2_present = false;
 } else if ((!cpt2_present) && (mem_affichage_cpt2_present)) {
 if (mem_affichage_cpt2_present) Serial.println(F("- Compteur 2 non present !"));
 mem_affichage_cpt2_present = false;
 }
#endif
 if ((donnee_ok_cpt[0] == verif_cpt_lu) and (cpt2_present)) {
 if ((type_mono_tri[0] == 1) && (donnee_ok_cpt_ph[0] == B10000001)) bascule_compteur();
 else if ((type_mono_tri[0] == 3) && (donnee_ok_cpt_ph[0] == B10000111))
 bascule_compteur();
 } else if ((donnee_ok_cpt[1] == B00000001) or ((compteur_actif == 2) and (!cpt2_present))) {
 if ((type_mono_tri[1] == 1) && (donnee_ok_cpt_ph[1] == B10000001)) bascule_compteur();
 else if ((type_mono_tri[1] == 3) && (donnee_ok_cpt_ph[1] == B10000111))
 bascule_compteur();
 compteursluOK = true;
 }
 if (compteur_actif == 2) {
 if (presence_teleinfo > 200) {
 cpt2_present = false;
 compteursluOK = true;
 bascule_compteur();
 } else
 cpt2_present = true;
 }
 read_teleinfo();
 }
}
///////////////////////////////////////////////////////////////////
// Calcul Checksum teleinfo
///////////////////////////////////////////////////////////////////
char chksum(char *buff, uint8_t len) {
 int i;
 char sum = 0;
 for (i = 1; i < (len - 2); i++) sum = sum + buff[i];
 sum = (sum & 0x3F) + 0x20;
 return (sum);
}
///////////////////////////////////////////////////////////////////
// mise en forme Date & heure pour affichage ou enregistrement
///////////////////////////////////////////////////////////////////
void format_mois_jour() {
 sprintf(mois_jour, "%02d,%02d,", mois, jour);
}
// Convert normal decimal numbers to binary coded decimal
static uint8_t bin2bcd(uint8_t val) {
 return val + 6 * (val / 10);
}
///////////////////////////////////////////////////////////////////
// mise à l'heure de la RTC (DS1307)
///////////////////////////////////////////////////////////////////
void RTCsetTime(void) {
 Wire.beginTransmission(104); // 104 is DS1307 device address (0x68)
 Wire.write(bin2bcd(0)); // start at register 0
 Wire.write(bin2bcd(seconde)); //Send seconds as BCD
 Wire.write(bin2bcd(minute)); //Send minutes as BCD
 Wire.write(bin2bcd(heure)); //Send hours as BCD
 Wire.write(bin2bcd(jour_semaine)); // dow
 Wire.write(bin2bcd(jour)); //Send day as BCD
 Wire.write(bin2bcd(mois)); //Send month as BCD
 Wire.write(bin2bcd(annee % 1000)); //Send year as BCD
 Wire.endTransmission();
}

enter image description here

I'm revisiting my Arduino stuff (I want to revive Teleinfo shield to monitor closely my power consumption). I just cannot get the thing to work (Teleinfo Shield + Uno Wifi).

The code is the following Teleinfo_Arduino_V0_3E.ino (just added some lines writing to serial to follow progress; and modified Serial.begin accordingly and "shortened" to stay within size limits but it's sending wrong characters ate beginning))

/*
 Datalogger Téléinfo 2 compteurs sur Arduino
 Compteur 1: consommation
 Compteur 2: production solaire en tarif BASE
 Juin 2011:
 v0.2 * passage automatique à l'heure d'été
 correctif erreur abo BBR
 modification ecriture sur SD (utilisation de teleinfoFile.print à la place s'une variable STRING
 qui plante l'Arduino avec les abonnements BBR
 v0.2a * ajout mode sans puissance apparente pour ancien compteur et calcul de celle-ci pour les logiciels d'analyse
 v0.2b * pour Arduino 1.0 (mise à jour de la RTC et utilisation de la librairie SD livrée avec la 1.0)
 v0.2c * modif type de variable pour éviter d'avoir 2 enregistrements à la même minute (surtout sur des proc + rapide)
 v0.3 * détection automatique du type d'abonnement sur le compteur 1
 v0.3a * Fonction de mise à l'heure par l'usb (interface série) en 1200 bauds 7 bits parité pair
 Procédure:
 1- carte débranchée, enlevez la pile de son support (pour réinitialiser l'horloge)
 2- enlevez le cavalier du shield téléinfo
 3- configurer votre logiciel émulateur de terminal (termite,Hyperterminale...) en 1200 bauds 7 bits parité pair
 4- mettre sous tension la carte.
 -- Le programme détectera le reset de l'horloge et vous demandera de rentrer l'heure et la date. --
 v0.3b * Correction bug calcul PAP compteur 2, enregistrement journalier compteur 2
 v0.3c * Triphasé sur compteur 2
 v0.3d * correction bug retour ligne sur compteur 2 (entête fichier)
 v0.3e * Correction bug si pas de compteur 2
*/
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include <RTClib.h>
const char version_logiciel[6] = "V0.3e";
// #define echo_USB //envoie toutes les trames téléinfo sur l'USB
#define message_systeme_USB //envoie des messages sur l'USB (init SD, heure au demarrage, et echo des erreures)
//*****************************************************************************************
byte inByte = 0; // caractère entrant téléinfo
char buffteleinfo[21] = "";
byte bufflen = 0;
byte mem_sauv_minute = 1;
byte mem_sauv_journee = 1;
byte num_abo = 0;
byte type_mono_tri[2] = { 0, 0 };
uint8_t presence_teleinfo = 0; // si signal teleinfo présent
byte presence_PAP = 0; // si PAP présent
boolean cpt2_present = true; // mémorisation de la présence du compteur 2
boolean compteursluOK = false; // pour autoriser l'écriture de valeur sur la SD
boolean mem_affichage_cpt2_present = true;
int ReceptionOctet = 0; // variable de stockage des octets reçus par port série
unsigned int ReceptionNombre = 0; // variable de calcul du nombre reçu par port série
byte reg_horloge = 1;
boolean mem_reg_horloge = false;
const uint8_t val_max[6] = { 24, 59, 59, 31, 12, 99 };
// declarations Teleinfo
unsigned int papp = 0; // Puissance apparente, VA
uint8_t IINST[2][3] = { { 0, 0, 0 }, { 0, 0, 0 } }; // Intensité Instantanée Phase 1, A (intensité efficace instantanée) ou 1 phase en monophasé
unsigned long INDEX1 = 0; // Index option Tempo - Heures Creuses Jours Bleus, Wh
unsigned long INDEX2 = 0; // Index option Tempo - Heures Pleines Jours Bleus, Wh
unsigned long INDEX3 = 0; // Index option Tempo - Heures Creuses Jours Blancs, Wh
unsigned long INDEX4 = 0; // Index option Tempo - Heures Pleines Jours Blancs, Wh
unsigned long INDEX5 = 0; // Index option Tempo - Heures Creuses Jours Rouges, Wh
unsigned long INDEX6 = 0; // Index option Tempo - Heures Pleines Jours Rouges, Wh
// compteur 2 (solaire configuré en tarif BASE par ERDF)
unsigned long cpt2index = 0; // Index option Base compteur production solaire, Wh
unsigned int cpt2puissance = 0; // Puissance apparente compteur production solaire, VA
#define debtrame 0x02
#define debligne 0x0A
#define finligne 0x0D
// *************** déclaration carte micro SD ******************
const byte chipSelect = 4;
// *************** déclaration activation compteur 1 ou 2 ******
#define LEC_CPT1 5 // lecture compteur 1
#define LEC_CPT2 6 // lecture compteur 2
//
byte verif_cpt_lu = 0;
//
byte compteur_actif = 1; // numero du compteur en cours de lecture
byte donnee_ok_cpt[2] = { 0, 0 }; // pour vérifier que les donnees sont bien en memoire avant ecriture dans fichier
byte donnee_ok_cpt_ph[2] = { 0, 0 };
// *************** variables RTC ************************************
byte minute, heure, seconde, jour, mois, jour_semaine;
unsigned int annee;
char date_heure[18];
char mois_jour[7];
byte mem_chg_heure = 0; //pour pas passer perpetuellement de 3h à 2h du matin le dernier dimanche d'octobre
RTC_DS1307 RTC;
// ************** initialisation *******************************
void setup() {
 // initialisation du port 0-1 lecture Téléinfo
 Serial.begin(1200);
 // parité paire E
 // 7 bits data
 UCSR0C = B00100100;
#ifdef message_systeme_USB
 Serial.print(F("-- Teleinfo USB Arduino "));
 Serial.print(version_logiciel);
 Serial.println(F(" --"));
#endif
 // initialisation des sorties selection compteur
 pinMode(LEC_CPT1, OUTPUT);
 pinMode(LEC_CPT2, OUTPUT);
 digitalWrite(LEC_CPT1, HIGH);
 digitalWrite(LEC_CPT2, LOW);
 // verification de la présence de la microSD et si elle est initialisée:
#ifdef message_systeme_USB
 if (!SD.begin(chipSelect)) {
 Serial.println(F("> Erreur carte, ou carte absente !"));
 return;
 }
 Serial.println(F("> microSD initialisee !"));
#endif
 // initialisation RTC16
 Wire.begin();
 RTC.begin();
 if (!RTC.isrunning()) {
#ifdef message_systeme_USB
 Serial.println(F("RTC non configure !"));
#endif
 }
 DateTime now = RTC.now(); // lecture de l'horloge
 annee = now.year();
 mois = now.month();
 jour = now.day();
 heure = now.hour();
 minute = now.minute();
 jour_semaine = now.dayOfTheWeek();
 format_date_heure();
#ifdef message_systeme_USB
 Serial.println(date_heure);
#endif
}
// ************** boucle principale *******************************
void loop() // Programme en boucle
{
 if (!(RTC.isrunning()) && (reg_horloge < 7)) { // si l'horloge n'est pas configurée
 digitalWrite(LEC_CPT1, LOW);
 if (!mem_reg_horloge) {
 switch (reg_horloge) { // debut de la structure
 case 1:
 Serial.print(F("Entrer Heure: "));
 break;
 case 2:
 Serial.print(F("Entrer Minute: "));
 break;
 case 3:
 Serial.print(F("Entrer Seconde: "));
 break;
 case 4:
 Serial.print(F("Entrer Jour: "));
 break;
 case 5:
 Serial.print(F("Entrer Mois: "));
 break;
 case 6:
 Serial.print(F("Entrer Annee 20xx: "));
 break;
 }
 mem_reg_horloge = true;
 }
 if (Serial.available() > 0) { // si caractère dans la file d'attente
 Serial.print(F("un nombre a ete recu")); //---- lecture du nombre reçu
 while (Serial.available() > 0) {
 // tant que buffer pas vide pour lire d'une traite tous les caractères reçus
 inByte = Serial.read(); // renvoie le 1er octet présent dans la file attente série (-1 si aucun)
 Serial.println(inByte);
 if (((inByte > 47) && (inByte < 58)) || (inByte == 13)) {
 ReceptionOctet = inByte - 48; // transforme valeur ASCII en valeur décimale
 if ((ReceptionOctet >= 0) && (ReceptionOctet <= 9)) ReceptionNombre = (ReceptionNombre * 10) + ReceptionOctet;
 // si valeur reçue correspond à un chiffre on calcule nombre
 Serial.print(ReceptionNombre);
 Serial.print(reg_horloge);
 } else
 presence_teleinfo = -1;
 } // fin while
 if (inByte == 13) {
 if ((ReceptionNombre > val_max[reg_horloge - 1]) || (ReceptionNombre == -1)) {
 Serial.println(F("Erreur horaire"));
 ReceptionNombre = 0;
 mem_reg_horloge = true;
 } else {
 Serial.print("cela bugge");
 switch (reg_horloge) { // debut de la structure
 case 1:
 heure = ReceptionNombre;
 Serial.print("heure:");
 Serial.println(heure);
 case 2:
 minute = ReceptionNombre;
 break;
 case 3:
 seconde = ReceptionNombre;
 break;
 case 4:
 jour = ReceptionNombre;
 break;
 case 5:
 mois = ReceptionNombre;
 break;
 case 6:
 annee = 2000 + ReceptionNombre;
 break;
 }
 mem_reg_horloge = false;
 ReceptionNombre = 0;
 ++reg_horloge;
 if (reg_horloge > 6) {
 RTCsetTime();
 Serial.println(F("Reglage heure OK - installer le cavalier pour la teleinfo"));
 digitalWrite(LEC_CPT1, HIGH);
 }
 }
 }
 }
 }
 else {
 DateTime now = RTC.now(); // lecture de l'horloge
 minute = now.minute();
 heure = now.hour();
 seconde = now.second();
 if ((heure == 0) && (minute == 0) && (seconde == 0)) {
 annee = now.year();
 mois = now.month();
 jour = now.day();
 jour_semaine = now.dayOfTheWeek();
 }
 // passage à l'heure d'été +1 heure
 // la lib RTC a une fonction: dayOfWeek qui donne le jour de la semaine (la DS1307 se charge de tout !)
 // réponse: 0 -> dimanche, 1 -> lundi etc...
 //
 if ((heure == 2) && (minute == 0) && (seconde == 0) && (jour_semaine == 0) && (mois == 3) && (jour > 24)) {
 heure = 3;
 RTCsetTime();
 }
 // passage à l'heure d'hiver -1 heure
 if ((heure == 3) && (minute == 0) && (seconde == 0) && (jour_semaine == 0) && (mois == 10) && (jour > 24) && (mem_chg_heure == 0)) {
 heure = 2;
 RTCsetTime();
 mem_chg_heure = 1;
 }
 if ((heure == 23) && (minute == 59) && (seconde == 10)) // pour être sur de pas tomber pendant l'enregistrement toutes les minutes
 {
 if ((mem_sauv_journee == 0) && (compteursluOK)) // un seul enregistrement par jour !
 {
 fichier_annee();
 mem_sauv_journee = 1;
 mem_chg_heure = 0;
 }
 } else
 mem_sauv_journee = 0;
 if (seconde == 1) {
 if ((mem_sauv_minute == 0) && (compteursluOK)) // un seul enregistrement par minute !
 {
 enregistre();
 mem_sauv_minute = 1;
 }
 } else
 mem_sauv_minute = 0;
#ifdef message_systeme_USB
 if ((donnee_ok_cpt[1] == B00000111) && (mem_affichage_cpt2_present)) {
 if (mem_affichage_cpt2_present) Serial.println(F("- Compteur 2 detecte"));
 mem_affichage_cpt2_present = false;
 } else if ((!cpt2_present) && (mem_affichage_cpt2_present)) {
 if (mem_affichage_cpt2_present) Serial.println(F("- Compteur 2 non present !"));
 mem_affichage_cpt2_present = false;
 }
#endif
 if ((donnee_ok_cpt[0] == verif_cpt_lu) and (cpt2_present)) {
 if ((type_mono_tri[0] == 1) && (donnee_ok_cpt_ph[0] == B10000001)) bascule_compteur();
 else if ((type_mono_tri[0] == 3) && (donnee_ok_cpt_ph[0] == B10000111))
 bascule_compteur();
 } else if ((donnee_ok_cpt[1] == B00000001) or ((compteur_actif == 2) and (!cpt2_present))) {
 if ((type_mono_tri[1] == 1) && (donnee_ok_cpt_ph[1] == B10000001)) bascule_compteur();
 else if ((type_mono_tri[1] == 3) && (donnee_ok_cpt_ph[1] == B10000111))
 bascule_compteur();
 compteursluOK = true;
 }
 if (compteur_actif == 2) {
 if (presence_teleinfo > 200) {
 cpt2_present = false;
 compteursluOK = true;
 bascule_compteur();
 } else
 cpt2_present = true;
 }
 read_teleinfo();
 }
}
///////////////////////////////////////////////////////////////////
// Calcul Checksum teleinfo
///////////////////////////////////////////////////////////////////
char chksum(char *buff, uint8_t len) {
 int i;
 char sum = 0;
 for (i = 1; i < (len - 2); i++) sum = sum + buff[i];
 sum = (sum & 0x3F) + 0x20;
 return (sum);
}
///////////////////////////////////////////////////////////////////
// mise en forme Date & heure pour affichage ou enregistrement
///////////////////////////////////////////////////////////////////
void format_mois_jour() {
 sprintf(mois_jour, "%02d,%02d,", mois, jour);
}
// Convert normal decimal numbers to binary coded decimal
static uint8_t bin2bcd(uint8_t val) {
 return val + 6 * (val / 10);
}
///////////////////////////////////////////////////////////////////
// mise à l'heure de la RTC (DS1307)
///////////////////////////////////////////////////////////////////
void RTCsetTime(void) {
 Wire.beginTransmission(104); // 104 is DS1307 device address (0x68)
 Wire.write(bin2bcd(0)); // start at register 0
 Wire.write(bin2bcd(seconde)); //Send seconds as BCD
 Wire.write(bin2bcd(minute)); //Send minutes as BCD
 Wire.write(bin2bcd(heure)); //Send hours as BCD
 Wire.write(bin2bcd(jour_semaine)); // dow
 Wire.write(bin2bcd(jour)); //Send day as BCD
 Wire.write(bin2bcd(mois)); //Send month as BCD
 Wire.write(bin2bcd(annee % 1000)); //Send year as BCD
 Wire.endTransmission();
}

Example output on Serial Monitor

added 15313 characters in body
Source Link

The code is the following Teleinfo_Arduino_V0_3E.ino (just added some lines writing to serial to follow progress; and modified Serial.begin accordingly)

The code is the following Teleinfo_Arduino_V0_3E.ino (just added some lines writing to serial to follow progress; and modified Serial.begin accordingly and "shortened" to stay within size limits but it's sending wrong characters ate beginning))

/*
 Datalogger Téléinfo 2 compteurs sur Arduino
 Compteur 1: consommation
 Compteur 2: production solaire en tarif BASE
 Juin 2011:
 v0.2 * passage automatique à l'heure d'été
 correctif erreur abo BBR
 modification ecriture sur SD (utilisation de teleinfoFile.print à la place s'une variable STRING
 qui plante l'Arduino avec les abonnements BBR
 v0.2a * ajout mode sans puissance apparente pour ancien compteur et calcul de celle-ci pour les logiciels d'analyse
 v0.2b * pour Arduino 1.0 (mise à jour de la RTC et utilisation de la librairie SD livrée avec la 1.0)
 v0.2c * modif type de variable pour éviter d'avoir 2 enregistrements à la même minute (surtout sur des proc + rapide)
 v0.3 * détection automatique du type d'abonnement sur le compteur 1
 v0.3a * Fonction de mise à l'heure par l'usb (interface série) en 1200 bauds 7 bits parité pair
 Procédure:
 1- carte débranchée, enlevez la pile de son support (pour réinitialiser l'horloge)
 2- enlevez le cavalier du shield téléinfo
 3- configurer votre logiciel émulateur de terminal (termite,Hyperterminale...) en 1200 bauds 7 bits parité pair
 4- mettre sous tension la carte.
 -- Le programme détectera le reset de l'horloge et vous demandera de rentrer l'heure et la date. --
 v0.3b * Correction bug calcul PAP compteur 2, enregistrement journalier compteur 2
 v0.3c * Triphasé sur compteur 2
 v0.3d * correction bug retour ligne sur compteur 2 (entête fichier)
 v0.3e * Correction bug si pas de compteur 2
*/
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include <RTClib.h>
const char version_logiciel[6] = "V0.3e";
// #define echo_USB //envoie toutes les trames téléinfo sur l'USB
#define message_systeme_USB //envoie des messages sur l'USB (init SD, heure au demarrage, et echo des erreures)
//*****************************************************************************************
byte inByte = 0; // caractère entrant téléinfo
char buffteleinfo[21] = "";
byte bufflen = 0;
byte mem_sauv_minute = 1;
byte mem_sauv_journee = 1;
byte num_abo = 0;
byte type_mono_tri[2] = { 0, 0 };
uint8_t presence_teleinfo = 0; // si signal teleinfo présent
byte presence_PAP = 0; // si PAP présent
boolean cpt2_present = true; // mémorisation de la présence du compteur 2
boolean compteursluOK = false; // pour autoriser l'écriture de valeur sur la SD
boolean mem_affichage_cpt2_present = true;
int ReceptionOctet = 0; // variable de stockage des octets reçus par port série
unsigned int ReceptionNombre = 0; // variable de calcul du nombre reçu par port série
byte reg_horloge = 1;
boolean mem_reg_horloge = false;
const uint8_t val_max[6] = { 24, 59, 59, 31, 12, 99 };
// declarations Teleinfo
unsigned int papp = 0; // Puissance apparente, VA
uint8_t IINST[2][3] = { { 0, 0, 0 }, { 0, 0, 0 } }; // Intensité Instantanée Phase 1, A (intensité efficace instantanée) ou 1 phase en monophasé
unsigned long INDEX1 = 0; // Index option Tempo - Heures Creuses Jours Bleus, Wh
unsigned long INDEX2 = 0; // Index option Tempo - Heures Pleines Jours Bleus, Wh
unsigned long INDEX3 = 0; // Index option Tempo - Heures Creuses Jours Blancs, Wh
unsigned long INDEX4 = 0; // Index option Tempo - Heures Pleines Jours Blancs, Wh
unsigned long INDEX5 = 0; // Index option Tempo - Heures Creuses Jours Rouges, Wh
unsigned long INDEX6 = 0; // Index option Tempo - Heures Pleines Jours Rouges, Wh
// compteur 2 (solaire configuré en tarif BASE par ERDF)
unsigned long cpt2index = 0; // Index option Base compteur production solaire, Wh
unsigned int cpt2puissance = 0; // Puissance apparente compteur production solaire, VA
#define debtrame 0x02
#define debligne 0x0A
#define finligne 0x0D
// *************** déclaration carte micro SD ******************
const byte chipSelect = 4;
// *************** déclaration activation compteur 1 ou 2 ******
#define LEC_CPT1 5 // lecture compteur 1
#define LEC_CPT2 6 // lecture compteur 2
//
byte verif_cpt_lu = 0;
//
byte compteur_actif = 1; // numero du compteur en cours de lecture
byte donnee_ok_cpt[2] = { 0, 0 }; // pour vérifier que les donnees sont bien en memoire avant ecriture dans fichier
byte donnee_ok_cpt_ph[2] = { 0, 0 };
// *************** variables RTC ************************************
byte minute, heure, seconde, jour, mois, jour_semaine;
unsigned int annee;
char date_heure[18];
char mois_jour[7];
byte mem_chg_heure = 0; //pour pas passer perpetuellement de 3h à 2h du matin le dernier dimanche d'octobre
RTC_DS1307 RTC;
// ************** initialisation *******************************
void setup() {
 // initialisation du port 0-1 lecture Téléinfo
 Serial.begin(1200);
 // parité paire E
 // 7 bits data
 UCSR0C = B00100100;
#ifdef message_systeme_USB
 Serial.print(F("-- Teleinfo USB Arduino "));
 Serial.print(version_logiciel);
 Serial.println(F(" --"));
#endif
 // initialisation des sorties selection compteur
 pinMode(LEC_CPT1, OUTPUT);
 pinMode(LEC_CPT2, OUTPUT);
 digitalWrite(LEC_CPT1, HIGH);
 digitalWrite(LEC_CPT2, LOW);
 // verification de la présence de la microSD et si elle est initialisée:
#ifdef message_systeme_USB
 if (!SD.begin(chipSelect)) {
 Serial.println(F("> Erreur carte, ou carte absente !"));
 return;
 }
 Serial.println(F("> microSD initialisee !"));
#endif
 // initialisation RTC16
 Wire.begin();
 RTC.begin();
 if (!RTC.isrunning()) {
#ifdef message_systeme_USB
 Serial.println(F("RTC non configure !"));
#endif
 }
 DateTime now = RTC.now(); // lecture de l'horloge
 annee = now.year();
 mois = now.month();
 jour = now.day();
 heure = now.hour();
 minute = now.minute();
 jour_semaine = now.dayOfTheWeek();
 format_date_heure();
#ifdef message_systeme_USB
 Serial.println(date_heure);
#endif
}
// ************** boucle principale *******************************
void loop() // Programme en boucle
{
 if (!(RTC.isrunning()) && (reg_horloge < 7)) { // si l'horloge n'est pas configurée
 digitalWrite(LEC_CPT1, LOW);
 if (!mem_reg_horloge) {
 switch (reg_horloge) { // debut de la structure
 case 1:
 Serial.print(F("Entrer Heure: "));
 break;
 case 2:
 Serial.print(F("Entrer Minute: "));
 break;
 case 3:
 Serial.print(F("Entrer Seconde: "));
 break;
 case 4:
 Serial.print(F("Entrer Jour: "));
 break;
 case 5:
 Serial.print(F("Entrer Mois: "));
 break;
 case 6:
 Serial.print(F("Entrer Annee 20xx: "));
 break;
 }
 mem_reg_horloge = true;
 }
 if (Serial.available() > 0) { // si caractère dans la file d'attente
 Serial.print(F("un nombre a ete recu")); //---- lecture du nombre reçu
 while (Serial.available() > 0) {
 // tant que buffer pas vide pour lire d'une traite tous les caractères reçus
 inByte = Serial.read(); // renvoie le 1er octet présent dans la file attente série (-1 si aucun)
 Serial.println(inByte);
 if (((inByte > 47) && (inByte < 58)) || (inByte == 13)) {
 ReceptionOctet = inByte - 48; // transforme valeur ASCII en valeur décimale
 if ((ReceptionOctet >= 0) && (ReceptionOctet <= 9)) ReceptionNombre = (ReceptionNombre * 10) + ReceptionOctet;
 // si valeur reçue correspond à un chiffre on calcule nombre
 Serial.print(ReceptionNombre);
 Serial.print(reg_horloge);
 } else
 presence_teleinfo = -1;
 } // fin while
 if (inByte == 13) {
 if ((ReceptionNombre > val_max[reg_horloge - 1]) || (ReceptionNombre == -1)) {
 Serial.println(F("Erreur horaire"));
 ReceptionNombre = 0;
 mem_reg_horloge = true;
 } else {
 Serial.print("cela bugge");
 switch (reg_horloge) { // debut de la structure
 case 1:
 heure = ReceptionNombre;
 Serial.print("heure:");
 Serial.println(heure);
 case 2:
 minute = ReceptionNombre;
 break;
 case 3:
 seconde = ReceptionNombre;
 break;
 case 4:
 jour = ReceptionNombre;
 break;
 case 5:
 mois = ReceptionNombre;
 break;
 case 6:
 annee = 2000 + ReceptionNombre;
 break;
 }
 mem_reg_horloge = false;
 ReceptionNombre = 0;
 ++reg_horloge;
 if (reg_horloge > 6) {
 RTCsetTime();
 Serial.println(F("Reglage heure OK - installer le cavalier pour la teleinfo"));
 digitalWrite(LEC_CPT1, HIGH);
 }
 }
 }
 }
 }
 else {
 DateTime now = RTC.now(); // lecture de l'horloge
 minute = now.minute();
 heure = now.hour();
 seconde = now.second();
 if ((heure == 0) && (minute == 0) && (seconde == 0)) {
 annee = now.year();
 mois = now.month();
 jour = now.day();
 jour_semaine = now.dayOfTheWeek();
 }
 // passage à l'heure d'été +1 heure
 // la lib RTC a une fonction: dayOfWeek qui donne le jour de la semaine (la DS1307 se charge de tout !)
 // réponse: 0 -> dimanche, 1 -> lundi etc...
 //
 if ((heure == 2) && (minute == 0) && (seconde == 0) && (jour_semaine == 0) && (mois == 3) && (jour > 24)) {
 heure = 3;
 RTCsetTime();
 }
 // passage à l'heure d'hiver -1 heure
 if ((heure == 3) && (minute == 0) && (seconde == 0) && (jour_semaine == 0) && (mois == 10) && (jour > 24) && (mem_chg_heure == 0)) {
 heure = 2;
 RTCsetTime();
 mem_chg_heure = 1;
 }
 if ((heure == 23) && (minute == 59) && (seconde == 10)) // pour être sur de pas tomber pendant l'enregistrement toutes les minutes
 {
 if ((mem_sauv_journee == 0) && (compteursluOK)) // un seul enregistrement par jour !
 {
 fichier_annee();
 mem_sauv_journee = 1;
 mem_chg_heure = 0;
 }
 } else
 mem_sauv_journee = 0;
 if (seconde == 1) {
 if ((mem_sauv_minute == 0) && (compteursluOK)) // un seul enregistrement par minute !
 {
 enregistre();
 mem_sauv_minute = 1;
 }
 } else
 mem_sauv_minute = 0;
#ifdef message_systeme_USB
 if ((donnee_ok_cpt[1] == B00000111) && (mem_affichage_cpt2_present)) {
 if (mem_affichage_cpt2_present) Serial.println(F("- Compteur 2 detecte"));
 mem_affichage_cpt2_present = false;
 } else if ((!cpt2_present) && (mem_affichage_cpt2_present)) {
 if (mem_affichage_cpt2_present) Serial.println(F("- Compteur 2 non present !"));
 mem_affichage_cpt2_present = false;
 }
#endif
 if ((donnee_ok_cpt[0] == verif_cpt_lu) and (cpt2_present)) {
 if ((type_mono_tri[0] == 1) && (donnee_ok_cpt_ph[0] == B10000001)) bascule_compteur();
 else if ((type_mono_tri[0] == 3) && (donnee_ok_cpt_ph[0] == B10000111))
 bascule_compteur();
 } else if ((donnee_ok_cpt[1] == B00000001) or ((compteur_actif == 2) and (!cpt2_present))) {
 if ((type_mono_tri[1] == 1) && (donnee_ok_cpt_ph[1] == B10000001)) bascule_compteur();
 else if ((type_mono_tri[1] == 3) && (donnee_ok_cpt_ph[1] == B10000111))
 bascule_compteur();
 compteursluOK = true;
 }
 if (compteur_actif == 2) {
 if (presence_teleinfo > 200) {
 cpt2_present = false;
 compteursluOK = true;
 bascule_compteur();
 } else
 cpt2_present = true;
 }
 read_teleinfo();
 }
}
///////////////////////////////////////////////////////////////////
// Calcul Checksum teleinfo
///////////////////////////////////////////////////////////////////
char chksum(char *buff, uint8_t len) {
 int i;
 char sum = 0;
 for (i = 1; i < (len - 2); i++) sum = sum + buff[i];
 sum = (sum & 0x3F) + 0x20;
 return (sum);
}
///////////////////////////////////////////////////////////////////
// mise en forme Date & heure pour affichage ou enregistrement
///////////////////////////////////////////////////////////////////
void format_mois_jour() {
 sprintf(mois_jour, "%02d,%02d,", mois, jour);
}
// Convert normal decimal numbers to binary coded decimal
static uint8_t bin2bcd(uint8_t val) {
 return val + 6 * (val / 10);
}
///////////////////////////////////////////////////////////////////
// mise à l'heure de la RTC (DS1307)
///////////////////////////////////////////////////////////////////
void RTCsetTime(void) {
 Wire.beginTransmission(104); // 104 is DS1307 device address (0x68)
 Wire.write(bin2bcd(0)); // start at register 0
 Wire.write(bin2bcd(seconde)); //Send seconds as BCD
 Wire.write(bin2bcd(minute)); //Send minutes as BCD
 Wire.write(bin2bcd(heure)); //Send hours as BCD
 Wire.write(bin2bcd(jour_semaine)); // dow
 Wire.write(bin2bcd(jour)); //Send day as BCD
 Wire.write(bin2bcd(mois)); //Send month as BCD
 Wire.write(bin2bcd(annee % 1000)); //Send year as BCD
 Wire.endTransmission();
}

The code is the following Teleinfo_Arduino_V0_3E.ino (just added some lines writing to serial to follow progress; and modified Serial.begin accordingly)

The code is the following Teleinfo_Arduino_V0_3E.ino (just added some lines writing to serial to follow progress; and modified Serial.begin accordingly and "shortened" to stay within size limits but it's sending wrong characters ate beginning))

/*
 Datalogger Téléinfo 2 compteurs sur Arduino
 Compteur 1: consommation
 Compteur 2: production solaire en tarif BASE
 Juin 2011:
 v0.2 * passage automatique à l'heure d'été
 correctif erreur abo BBR
 modification ecriture sur SD (utilisation de teleinfoFile.print à la place s'une variable STRING
 qui plante l'Arduino avec les abonnements BBR
 v0.2a * ajout mode sans puissance apparente pour ancien compteur et calcul de celle-ci pour les logiciels d'analyse
 v0.2b * pour Arduino 1.0 (mise à jour de la RTC et utilisation de la librairie SD livrée avec la 1.0)
 v0.2c * modif type de variable pour éviter d'avoir 2 enregistrements à la même minute (surtout sur des proc + rapide)
 v0.3 * détection automatique du type d'abonnement sur le compteur 1
 v0.3a * Fonction de mise à l'heure par l'usb (interface série) en 1200 bauds 7 bits parité pair
 Procédure:
 1- carte débranchée, enlevez la pile de son support (pour réinitialiser l'horloge)
 2- enlevez le cavalier du shield téléinfo
 3- configurer votre logiciel émulateur de terminal (termite,Hyperterminale...) en 1200 bauds 7 bits parité pair
 4- mettre sous tension la carte.
 -- Le programme détectera le reset de l'horloge et vous demandera de rentrer l'heure et la date. --
 v0.3b * Correction bug calcul PAP compteur 2, enregistrement journalier compteur 2
 v0.3c * Triphasé sur compteur 2
 v0.3d * correction bug retour ligne sur compteur 2 (entête fichier)
 v0.3e * Correction bug si pas de compteur 2
*/
#include <SD.h>
#include <SPI.h>
#include <Wire.h>
#include <RTClib.h>
const char version_logiciel[6] = "V0.3e";
// #define echo_USB //envoie toutes les trames téléinfo sur l'USB
#define message_systeme_USB //envoie des messages sur l'USB (init SD, heure au demarrage, et echo des erreures)
//*****************************************************************************************
byte inByte = 0; // caractère entrant téléinfo
char buffteleinfo[21] = "";
byte bufflen = 0;
byte mem_sauv_minute = 1;
byte mem_sauv_journee = 1;
byte num_abo = 0;
byte type_mono_tri[2] = { 0, 0 };
uint8_t presence_teleinfo = 0; // si signal teleinfo présent
byte presence_PAP = 0; // si PAP présent
boolean cpt2_present = true; // mémorisation de la présence du compteur 2
boolean compteursluOK = false; // pour autoriser l'écriture de valeur sur la SD
boolean mem_affichage_cpt2_present = true;
int ReceptionOctet = 0; // variable de stockage des octets reçus par port série
unsigned int ReceptionNombre = 0; // variable de calcul du nombre reçu par port série
byte reg_horloge = 1;
boolean mem_reg_horloge = false;
const uint8_t val_max[6] = { 24, 59, 59, 31, 12, 99 };
// declarations Teleinfo
unsigned int papp = 0; // Puissance apparente, VA
uint8_t IINST[2][3] = { { 0, 0, 0 }, { 0, 0, 0 } }; // Intensité Instantanée Phase 1, A (intensité efficace instantanée) ou 1 phase en monophasé
unsigned long INDEX1 = 0; // Index option Tempo - Heures Creuses Jours Bleus, Wh
unsigned long INDEX2 = 0; // Index option Tempo - Heures Pleines Jours Bleus, Wh
unsigned long INDEX3 = 0; // Index option Tempo - Heures Creuses Jours Blancs, Wh
unsigned long INDEX4 = 0; // Index option Tempo - Heures Pleines Jours Blancs, Wh
unsigned long INDEX5 = 0; // Index option Tempo - Heures Creuses Jours Rouges, Wh
unsigned long INDEX6 = 0; // Index option Tempo - Heures Pleines Jours Rouges, Wh
// compteur 2 (solaire configuré en tarif BASE par ERDF)
unsigned long cpt2index = 0; // Index option Base compteur production solaire, Wh
unsigned int cpt2puissance = 0; // Puissance apparente compteur production solaire, VA
#define debtrame 0x02
#define debligne 0x0A
#define finligne 0x0D
// *************** déclaration carte micro SD ******************
const byte chipSelect = 4;
// *************** déclaration activation compteur 1 ou 2 ******
#define LEC_CPT1 5 // lecture compteur 1
#define LEC_CPT2 6 // lecture compteur 2
//
byte verif_cpt_lu = 0;
//
byte compteur_actif = 1; // numero du compteur en cours de lecture
byte donnee_ok_cpt[2] = { 0, 0 }; // pour vérifier que les donnees sont bien en memoire avant ecriture dans fichier
byte donnee_ok_cpt_ph[2] = { 0, 0 };
// *************** variables RTC ************************************
byte minute, heure, seconde, jour, mois, jour_semaine;
unsigned int annee;
char date_heure[18];
char mois_jour[7];
byte mem_chg_heure = 0; //pour pas passer perpetuellement de 3h à 2h du matin le dernier dimanche d'octobre
RTC_DS1307 RTC;
// ************** initialisation *******************************
void setup() {
 // initialisation du port 0-1 lecture Téléinfo
 Serial.begin(1200);
 // parité paire E
 // 7 bits data
 UCSR0C = B00100100;
#ifdef message_systeme_USB
 Serial.print(F("-- Teleinfo USB Arduino "));
 Serial.print(version_logiciel);
 Serial.println(F(" --"));
#endif
 // initialisation des sorties selection compteur
 pinMode(LEC_CPT1, OUTPUT);
 pinMode(LEC_CPT2, OUTPUT);
 digitalWrite(LEC_CPT1, HIGH);
 digitalWrite(LEC_CPT2, LOW);
 // verification de la présence de la microSD et si elle est initialisée:
#ifdef message_systeme_USB
 if (!SD.begin(chipSelect)) {
 Serial.println(F("> Erreur carte, ou carte absente !"));
 return;
 }
 Serial.println(F("> microSD initialisee !"));
#endif
 // initialisation RTC16
 Wire.begin();
 RTC.begin();
 if (!RTC.isrunning()) {
#ifdef message_systeme_USB
 Serial.println(F("RTC non configure !"));
#endif
 }
 DateTime now = RTC.now(); // lecture de l'horloge
 annee = now.year();
 mois = now.month();
 jour = now.day();
 heure = now.hour();
 minute = now.minute();
 jour_semaine = now.dayOfTheWeek();
 format_date_heure();
#ifdef message_systeme_USB
 Serial.println(date_heure);
#endif
}
// ************** boucle principale *******************************
void loop() // Programme en boucle
{
 if (!(RTC.isrunning()) && (reg_horloge < 7)) { // si l'horloge n'est pas configurée
 digitalWrite(LEC_CPT1, LOW);
 if (!mem_reg_horloge) {
 switch (reg_horloge) { // debut de la structure
 case 1:
 Serial.print(F("Entrer Heure: "));
 break;
 case 2:
 Serial.print(F("Entrer Minute: "));
 break;
 case 3:
 Serial.print(F("Entrer Seconde: "));
 break;
 case 4:
 Serial.print(F("Entrer Jour: "));
 break;
 case 5:
 Serial.print(F("Entrer Mois: "));
 break;
 case 6:
 Serial.print(F("Entrer Annee 20xx: "));
 break;
 }
 mem_reg_horloge = true;
 }
 if (Serial.available() > 0) { // si caractère dans la file d'attente
 Serial.print(F("un nombre a ete recu")); //---- lecture du nombre reçu
 while (Serial.available() > 0) {
 // tant que buffer pas vide pour lire d'une traite tous les caractères reçus
 inByte = Serial.read(); // renvoie le 1er octet présent dans la file attente série (-1 si aucun)
 Serial.println(inByte);
 if (((inByte > 47) && (inByte < 58)) || (inByte == 13)) {
 ReceptionOctet = inByte - 48; // transforme valeur ASCII en valeur décimale
 if ((ReceptionOctet >= 0) && (ReceptionOctet <= 9)) ReceptionNombre = (ReceptionNombre * 10) + ReceptionOctet;
 // si valeur reçue correspond à un chiffre on calcule nombre
 Serial.print(ReceptionNombre);
 Serial.print(reg_horloge);
 } else
 presence_teleinfo = -1;
 } // fin while
 if (inByte == 13) {
 if ((ReceptionNombre > val_max[reg_horloge - 1]) || (ReceptionNombre == -1)) {
 Serial.println(F("Erreur horaire"));
 ReceptionNombre = 0;
 mem_reg_horloge = true;
 } else {
 Serial.print("cela bugge");
 switch (reg_horloge) { // debut de la structure
 case 1:
 heure = ReceptionNombre;
 Serial.print("heure:");
 Serial.println(heure);
 case 2:
 minute = ReceptionNombre;
 break;
 case 3:
 seconde = ReceptionNombre;
 break;
 case 4:
 jour = ReceptionNombre;
 break;
 case 5:
 mois = ReceptionNombre;
 break;
 case 6:
 annee = 2000 + ReceptionNombre;
 break;
 }
 mem_reg_horloge = false;
 ReceptionNombre = 0;
 ++reg_horloge;
 if (reg_horloge > 6) {
 RTCsetTime();
 Serial.println(F("Reglage heure OK - installer le cavalier pour la teleinfo"));
 digitalWrite(LEC_CPT1, HIGH);
 }
 }
 }
 }
 }
 else {
 DateTime now = RTC.now(); // lecture de l'horloge
 minute = now.minute();
 heure = now.hour();
 seconde = now.second();
 if ((heure == 0) && (minute == 0) && (seconde == 0)) {
 annee = now.year();
 mois = now.month();
 jour = now.day();
 jour_semaine = now.dayOfTheWeek();
 }
 // passage à l'heure d'été +1 heure
 // la lib RTC a une fonction: dayOfWeek qui donne le jour de la semaine (la DS1307 se charge de tout !)
 // réponse: 0 -> dimanche, 1 -> lundi etc...
 //
 if ((heure == 2) && (minute == 0) && (seconde == 0) && (jour_semaine == 0) && (mois == 3) && (jour > 24)) {
 heure = 3;
 RTCsetTime();
 }
 // passage à l'heure d'hiver -1 heure
 if ((heure == 3) && (minute == 0) && (seconde == 0) && (jour_semaine == 0) && (mois == 10) && (jour > 24) && (mem_chg_heure == 0)) {
 heure = 2;
 RTCsetTime();
 mem_chg_heure = 1;
 }
 if ((heure == 23) && (minute == 59) && (seconde == 10)) // pour être sur de pas tomber pendant l'enregistrement toutes les minutes
 {
 if ((mem_sauv_journee == 0) && (compteursluOK)) // un seul enregistrement par jour !
 {
 fichier_annee();
 mem_sauv_journee = 1;
 mem_chg_heure = 0;
 }
 } else
 mem_sauv_journee = 0;
 if (seconde == 1) {
 if ((mem_sauv_minute == 0) && (compteursluOK)) // un seul enregistrement par minute !
 {
 enregistre();
 mem_sauv_minute = 1;
 }
 } else
 mem_sauv_minute = 0;
#ifdef message_systeme_USB
 if ((donnee_ok_cpt[1] == B00000111) && (mem_affichage_cpt2_present)) {
 if (mem_affichage_cpt2_present) Serial.println(F("- Compteur 2 detecte"));
 mem_affichage_cpt2_present = false;
 } else if ((!cpt2_present) && (mem_affichage_cpt2_present)) {
 if (mem_affichage_cpt2_present) Serial.println(F("- Compteur 2 non present !"));
 mem_affichage_cpt2_present = false;
 }
#endif
 if ((donnee_ok_cpt[0] == verif_cpt_lu) and (cpt2_present)) {
 if ((type_mono_tri[0] == 1) && (donnee_ok_cpt_ph[0] == B10000001)) bascule_compteur();
 else if ((type_mono_tri[0] == 3) && (donnee_ok_cpt_ph[0] == B10000111))
 bascule_compteur();
 } else if ((donnee_ok_cpt[1] == B00000001) or ((compteur_actif == 2) and (!cpt2_present))) {
 if ((type_mono_tri[1] == 1) && (donnee_ok_cpt_ph[1] == B10000001)) bascule_compteur();
 else if ((type_mono_tri[1] == 3) && (donnee_ok_cpt_ph[1] == B10000111))
 bascule_compteur();
 compteursluOK = true;
 }
 if (compteur_actif == 2) {
 if (presence_teleinfo > 200) {
 cpt2_present = false;
 compteursluOK = true;
 bascule_compteur();
 } else
 cpt2_present = true;
 }
 read_teleinfo();
 }
}
///////////////////////////////////////////////////////////////////
// Calcul Checksum teleinfo
///////////////////////////////////////////////////////////////////
char chksum(char *buff, uint8_t len) {
 int i;
 char sum = 0;
 for (i = 1; i < (len - 2); i++) sum = sum + buff[i];
 sum = (sum & 0x3F) + 0x20;
 return (sum);
}
///////////////////////////////////////////////////////////////////
// mise en forme Date & heure pour affichage ou enregistrement
///////////////////////////////////////////////////////////////////
void format_mois_jour() {
 sprintf(mois_jour, "%02d,%02d,", mois, jour);
}
// Convert normal decimal numbers to binary coded decimal
static uint8_t bin2bcd(uint8_t val) {
 return val + 6 * (val / 10);
}
///////////////////////////////////////////////////////////////////
// mise à l'heure de la RTC (DS1307)
///////////////////////////////////////////////////////////////////
void RTCsetTime(void) {
 Wire.beginTransmission(104); // 104 is DS1307 device address (0x68)
 Wire.write(bin2bcd(0)); // start at register 0
 Wire.write(bin2bcd(seconde)); //Send seconds as BCD
 Wire.write(bin2bcd(minute)); //Send minutes as BCD
 Wire.write(bin2bcd(heure)); //Send hours as BCD
 Wire.write(bin2bcd(jour_semaine)); // dow
 Wire.write(bin2bcd(jour)); //Send day as BCD
 Wire.write(bin2bcd(mois)); //Send month as BCD
 Wire.write(bin2bcd(annee % 1000)); //Send year as BCD
 Wire.endTransmission();
}
added 100 characters in body
Source Link

I'm revisiting my Arduino stuff (I want to revive Teleinfo shield to monitor closely my power consumption). I just cannot get the thing to work (Teleinfo Shield + Uno Wifi).

When trying to check what's happening this is the kind of Serial Monitor screens that I get.

Any hints on how to solve? It happens with other Uno as well and different versions of IDE.

Thank for any help, the answers I found in different places didn't lead me to a solution.

I tried several baud settings, (same for port and monitor, each time) and sometimes nothing was written, sometimes complete garbage, sometimes as illustrated

I will attach theThe code is the following Teleinfo_Arduino_V0_3E.ino (which is a "standard" that I modifiedjust added some lines writing to "trace" what was happening)serial to follow progress; and modified Serial.begin accordingly)

MacBookPro 2018 runnning Monterey

enter image description here

I'm revisiting my Arduino stuff (I want to revive Teleinfo shield to monitor closely my power consumption). I just cannot get the thing to work (Teleinfo Shield + Uno Wifi).

When trying to check what's happening this is the kind of Serial Monitor screens that I get.

Any hints on how to solve? It happens with other Uno as well and different versions of IDE.

Thank for any help, the answers I found in different places didn't lead me to a solution.

I tried several baud settings, (same for port and monitor, each time) and sometimes nothing was written, sometimes complete garbage, sometimes as illustrated

I will attach the code (which is a "standard" that I modified to "trace" what was happening).

enter image description here

I'm revisiting my Arduino stuff (I want to revive Teleinfo shield to monitor closely my power consumption). I just cannot get the thing to work (Teleinfo Shield + Uno Wifi).

When trying to check what's happening this is the kind of Serial Monitor screens that I get.

Any hints on how to solve? It happens with other Uno as well and different versions of IDE.

Thank for any help, the answers I found in different places didn't lead me to a solution.

I tried several baud settings, (same for port and monitor, each time) and sometimes nothing was written, sometimes complete garbage, sometimes as illustrated

The code is the following Teleinfo_Arduino_V0_3E.ino (just added some lines writing to serial to follow progress; and modified Serial.begin accordingly)

MacBookPro 2018 runnning Monterey

enter image description here

added 264 characters in body
Source Link
Loading
added 9 characters in body; edited title
Source Link
ocrdu
  • 1.8k
  • 3
  • 12
  • 24
Loading
Source Link
Loading

AltStyle によって変換されたページ (->オリジナル) /