Téléinfo radio

Forum pour tous les autres objets : sondes météo, capteurs, actionneurs ...
Vous avez un besoin mais vous ne savez pas quel matériel choisir ? C'est ici.
snips
Messages : 272
Inscription : 18 mars 2015, 22:37

Re: Téléinfo radio

Message par snips »

Il est encore possible de descendre drastiquement la consommation de l'arduino (j'ai cela chez moi et alimenté par Pile uniquement ).
J'en ai parlé plusieurs fois ici mais comme cela n'a pas l'air d'intéresser grand monde (il est vrai que c'est un peu plus complexe ) je n'ai pas explicité la chose.
Mais si cela vous intéresse .....
(En gros prendre un arduino mini, couper les pistes du régulateur de tension qui est un gouffre ...virer la led verte sur l'optocoupleur qui clignotte et mettre une diode à l'envers qui peut encaisser du -5v.., alimenter cette led non pas depuis le 5 v mais avec une patte data de l'arduino - pour pouvoir l'éteindre pendant que l'arduino "dort").

Si non deux autres pistes :
Si vous n'avez pas l'utilité des 2 fils du contacteur heures creuses ... Pourquoi ne pas s'en servir pour passer l'alimentation à votre arduino ?

Il y a enfin la recharge de piles grâce à un petit panneau solaire.

Bien sur la prise + disjoncteur fait aussi l'affaire.
deennoo
Messages : 4036
Inscription : 25 janv. 2015, 02:00

Re: Téléinfo radio

Message par deennoo »

Moi je serais intéresser Mr Snips.

Tu nous ferais une petite publi information ?

Depuis combien de temps ton montage fonctionne ainsi ?
De quoi se faire Plaisir et essayer d'aider...
http://www.domo-attitude.fr
snips
Messages : 272
Inscription : 18 mars 2015, 22:37

Re: Téléinfo radio

Message par snips »

deennoo a écrit :Moi je serais intéresser Mr Snips.
Tu nous ferais une petite publi information ?
Depuis combien de temps ton montage fonctionne ainsi ?
depuis le début... car j'en avais marre de changer les piles rechargeables.

-En fait j'arrive à tenir 1 mois facile, avec une réactualisation toutes les 12 secondes, avec 4 piles rechargeables Ni MH (avec un arduino pro mini optimisé, lowpower, alimentation de l'emetteur 433 Mhz ainsi que l'optocoupleur avec les pattes data de l'arduino - que l'on éteint ou allume - ).

-Depuis peu (2 à 3 semaines) j'ai introduit une diode montée à l'envers, rapide, à la place de la led verte pour réduire drastiquement la conso (une diode à l'envers ça ne consomme pas beaucoup ! et c'est formidable... quand on étudie bien le truc on se rend compte que cela continue de fonctionner.
A titre d'information : le signal téléinfo transmet des "1" quand la tension est à 0 et inversement.... cela veut dire que quand la led verte est allumée fixement : 'il n'y a aucune info transmise par le compteur... par contre quand ça clignote (la led s'éteint)... ca veut dire qu'il y a des data.
Mon compteur transmet les infos que toutes les 4 sec. environ... cela veut dire que la led verte est la plupart du temps allumée fixement pour rien (et consomme du jus).

J'attends pour voir si cet upgrade me permet de dépasser les 2 à 3 mois d'autonomie.

Je suis en vacances la semaine prochaine, j'essaie de publier un truc bien comme tu as l'habitude de faire....
deennoo
Messages : 4036
Inscription : 25 janv. 2015, 02:00

Re: Téléinfo radio

Message par deennoo »

Super ! Dans ton système il doit y avoir moyen d'introduire un petit panneau solaire pour la recharge des piles...(je me documente pour le projet d'un voisin qui a son compteur a plus de 30m de son tableau, et qui en plus a l'exigence de vouloir quelque chose d'autonome énergétiquement)
De quoi se faire Plaisir et essayer d'aider...
http://www.domo-attitude.fr
snips
Messages : 272
Inscription : 18 mars 2015, 22:37

Re: Téléinfo radio

Message par snips »

J'étudie aussi l'alimentation par batterie + rechargement
Solaire. J'ai mis tout ce que j'ai trouvé de pertinent sur :
http://www.easydomoticz.com/forum/viewt ... =16&t=1736

J'ai déjà reçu tout le matériel pour faire les tests, il faut juste que je trouve du temps !
snips
Messages : 272
Inscription : 18 mars 2015, 22:37

Re: Téléinfo radio

Message par snips »

Attention : Version économie d'énergie non conseillée aux débutants
Si c'est votre premier montage : préférez la version "standard" sur http://easydomoticz.com/forum/viewtopic ... 8&start=70

Pour toi deenoo, d'abord le hard :

On modifie le schéma classique du teleinfo : on remplace la led habituelle par une diode 1N4148 montée dans le sens "bloqué" comme sur le schéma ci-dessous. L'objet de la diode montée à l'envers est de limiter très fortement le passage du courant sans modifier le fonctionnement de l'optocoupleur/arduino. Bien sur alimenter directement l'arduino en passant par VCC (et non par VIn), cela suppose de bien maitriser l'alimentation puisque que l'on ne passe pas par le régulateur (Vin) qui consomme trop de courant. Pour économiser aussi le courant consommé par l'émetteur 433mhz au repos, on alimente ce dernier via le pin digital 6 de l'arduino : ce dernier n'est mis à 5v que quand on a quelque chose à émettre.
domotique-info-schemamod2.png
domotique-info-schemamod2.png (29.56 Kio) Consulté 3492 fois
domotique-info-schemamod2.png
domotique-info-schemamod2.png (29.56 Kio) Consulté 9150 fois

Ensuite, il faut passer par exemple par une arduino pro mini 5V (qui coute moins de 2 dollars sur ebay) qui permet très facilement de désactiver le régulateur de tension en coupant une seule piste comme dans le schéma ci-dessous (vérifier que l'arduino mini que vous voulez acheter a les mêmes pistes que celui ci-dessous).
Préférez la version 5V poru avoir assez de puissance pour l'emetteur (3,3V = portée plus courte).

Attention, pour bénéficier d'une consommation très basse : utiliser la borne VCC sur le grand côté pour l'alimentation de l'arduino (dans ce cas le régulateur et la led ne sont pas alimentés). si on utilise la borne VCC "sur le petit côté" : le régulateur et la led sur l'arduino mini sont alimentés et la conso électrique est alors normale (forte).
arduino promini.jpg
arduino promini.jpg (95.28 Kio) Consulté 3492 fois
arduino promini.jpg
arduino promini.jpg (95.28 Kio) Consulté 9199 fois
Le soft en suite....
Bien sur il faut faire un peu de soudure avant sur le mini pour pouvoir le relier au PC via un ftdi, pour déverser le programme (ou utiliser un Uno avec la puce Atmel escamotable).

La différence de ce soft (économie d'énergie) par rapport à la version normale : c'est qu'il allume et éteint l'émetteur 433mhz via le pin 6, et qu'il utilise la librairie lowpower pour mettre l'arduino en sommeil profond.

le code à téléverser, maj du 1/5/2016

Code : Tout sélectionner

/* Version économie d'énergie (alimentation par batterie, pile rechargeable) non conseillée aux débutants !!!!!!
/* Ce programme a été élaboré à partir du code de M. Olivier LEBRUN réutilisé en grande partie pour réaliser un encodeur OWL CM180 (Micro+)
/* ainsi qu'à partir du code (+ carte électronique à relier au compteur) de M. Pascal CARDON pour la partie téléinfo 
/* Onlinux a fourni des trames du OWL CM180 pour le reverse ingineering (il a développé lui même un code de décodage des trames, différent de mon code )
/* j'ai fait le reverse ingineering du OWL CM180 et les algo d'encodage pour le RFXCOM - il n'est pas garantie que cet encodeur marche avec un autre recepteur que RFXCOM 
/* Je remercie les auteurs. Ci-dessous les liens vers leur site internet.

******** Snips *******
/******* version du 30/04/2016 : amélioration de l'autonomie par la désactivation de fonctions inutilisées de l'Atmel, mise en veille automatique en attendant la prochaine trame téléinfo
/* ***** version test du 13/06/2015 : adaptation pour un compteur teleinfo tarif de base (non HC et HP), 
// ****** adaptation pour un compteur qui ne retourne pas la puissance apparente PAPP (approximation IINST * 230)
// ****** exemple librairie LOWPOWER pour mettre en veille


/*=======================================================================================================================

ONLINUX :   Decode and parse the Oregon Scientific V3 radio data transmitted by OWL CM180 Energy sensor (433.92MHz)

http://blog.onlinux.fr

https://github.com/onlinux/OWL-CMR180
/*=======================================================================================================================


/*=======================================================================================================================
/*
 * connectingStuff, Oregon Scientific v2.1 Emitter
 * http://connectingstuff.net/blog/encodage-protocoles-oregon-scientific-sur-arduino/
 *
 * Copyright (C) 2013 olivier.lebrun@gmail.com
 
*/
//=======================================================================================================================


/*=======================================================================================================================
                                                        my_teleinfo
                                                 (c) 2012-2013 by  
                                                  Script name : my_teleinfo
                                 http://www.domotique-info.fr/2014/05/recuperer-teleinformation-arduino/

 Usage :                                                                                   
     + Arduino Teleinfo report program
     + This program receives data frames from the EDF counter teleinfo port, it parse it,
       validate each data group by verfying the checksum, stores it in local variables, 
       displays the actual counter, consumption ...
       Frame content is sent to a remote PHP server, thru Internet. The remote PHP
       server records the received data in a MySQL data base.                                                           
     + Runs on a Leonardo, RX on PIN 0
                                      
======================================================================================================================*/
// montage électronique conforme à http://www.domotique-info.fr/2014/05/recuperer-teleinformation-arduino/
// pin 8 de la carte arduino utilisé pour recevoir les informations téléinfo du compteur
// pin 4 utilisé pour l'emetteur 433 MHZ 


#include <SoftwareSerial.h>
#include <avr/power.h>   
#include <LowPower.h> //snips : télécharger la librairie LOwPower.h sur https://github.com/rocketscream/Low-Power/archive/master.zip et décompresser les fichiers et les ranger dans le répertoire (renommer si nécessaire le répertoir créé)  "LowPower" dans  arduino\libraries\


const byte TX_PIN = 4;  //data de l'emetteur 433 MHZ 
const byte ALIM_TX_PIN = 6;  //************Broche 6 de l'arduino utilisée pour alimenter le VCC de l'émetteur 433 Mhz *************

const unsigned long TIME = 488;
const unsigned long TWOTIME = TIME*2;

const int wakeUpPin = 2; // relié à l'optocoupleur, pour le réveil de l'arduino si le niveau est 0 (signal téléinfo = 1) 


#define SEND_HIGH() digitalWrite(TX_PIN, HIGH)
#define SEND_LOW() digitalWrite(TX_PIN, LOW)
byte OregonMessageBuffer[13];  //  OWL180
//*********************************************************
SoftwareSerial* mySerial;
  char HHPHC;
  int ISOUSC;             // intensité souscrite  
  int IINST;              // intensité instantanée en A
  int IMAX;               // intensité maxi en A
  int PAPP;               // puissance apparente en VA
  unsigned long HCHC;  // compteur Heures Creuses en W
  unsigned long HCHP;  // compteur Heures Pleines en W
  String PTEC;            // Régime actuel : HPJB, HCJB, HPJW, HCJW, HPJR, HCJR
  String ADCO;            // adresse compteur
  String OPTARIF;         // option tarifaire
  String MOTDETAT;        // status word
  String pgmVersion;      // TeleInfo program version
  boolean ethernetIsOK;
  boolean teleInfoReceived;


  char chksum(char *buff, uint8_t len);
  boolean handleBuffer(char *bufferTeleinfo, int sequenceNumnber);
  char version[17] = "TeleInfo  V 1.00";
  
  unsigned long PAPP_arrondi;               // PAPP*497/500/16 arrondi
  unsigned long chksum_CM180;
  unsigned long long HCP; 

  unsigned long milli_temps_attente_startframe=0;// new ***************** optimisation attente
  unsigned long milli_temps_attente_startframe2=0;// new ***************** optimisation attente
  boolean flag_SLEEP_15MS, flag_SLEEP_30MS, flag_SLEEP_60MS, flag_SLEEP_120MS, flag_SLEEP_250MS, flag_SLEEP_500MS, flag_SLEEP_1S, flag_SLEEP_2S, flag_SLEEP_4S, flag_SLEEP_8S;
  boolean first_time=true; 
  boolean first_boot=true;
  unsigned nb_boucle0 =0;
  unsigned nb_boucle1 =0;
  unsigned nb_boucle_optimum =0; 
  // boolean attente_plus=true;  *************** A virer *************************
  boolean sens_attente=false;
  boolean optimum=false;
  //********** debug
 // char buffer[100];// à  virer ***************
//**********************************************************************

/**
 * \brief    Send logical "0" over RF
 * \details  azero bit be represented by an off-to-on transition
 * \         of the RF signal at the middle of a clock period.
 * \         Remenber, the Oregon v2.1 protocol add an inverted bit first 
 */
inline void sendZero(void)
{
  SEND_LOW();
  delayMicroseconds(TIME); 
  SEND_HIGH();
  delayMicroseconds(TIME);
}

/**
 * \brief    Send logical "1" over RF
 * \details  a one bit be represented by an on-to-off transition
 * \         of the RF signal at the middle of a clock period.
 * \         Remenber, the Oregon v2.1 protocol add an inverted bit first 
 */
inline void sendOne(void)
{
   SEND_HIGH();
   delayMicroseconds(TIME);
   SEND_LOW();
   delayMicroseconds(TIME);
}


/**
 * \brief    Send a buffer over RF
 * \param    data   Data to send
 * \param    size   size of data to send
 */
void sendData(byte *data, byte size)
{
  for(byte i = 0; i < size; ++i)
  {
  (bitRead(data[i], 0)) ? sendOne() : sendZero();
  (bitRead(data[i], 1)) ? sendOne() : sendZero();
  (bitRead(data[i], 2)) ? sendOne() : sendZero();
  (bitRead(data[i], 3)) ? sendOne() : sendZero();
  (bitRead(data[i], 4)) ? sendOne() : sendZero();
  (bitRead(data[i], 5)) ? sendOne() : sendZero();
  (bitRead(data[i], 6)) ? sendOne() : sendZero();
  (bitRead(data[i], 7)) ? sendOne() : sendZero();    
  }
}

/**
 * \brief    Send an Oregon message
 * \param    data   The Oregon message
 */
void sendOregon(byte *data, byte size)
{

    digitalWrite(ALIM_TX_PIN, HIGH);// NEW ***************  alimente l'emetteur en 5V ***************   
    sendPreamble();
    sendData(data,size);   
    sendPostamble();
    digitalWrite(ALIM_TX_PIN, LOW); // NEW ***************  éteint l'emetteur pour économiser la batterie ******************
}

/**
 * \brief    Send preamble
 * \details  The preamble consists of 10 X "1" bits (minimum)
 */
inline void sendPreamble(void)
{
  for(byte i = 0; i < 10; ++i)   //OWL CM180
  {
    sendOne();
  }
}

/**
 * \brief    Send postamble
 */
inline void sendPostamble(void)
{

 for(byte i = 0; i <4 ; ++i)    //OWL CM180
  {
    sendZero() ;
  }
  SEND_LOW();
  delayMicroseconds(TIME);
}

//=================================================================================================================
// Basic constructor
//=================================================================================================================
void TeleInfo(String version)
{
  //  Serial.begin(1200,SERIAL_7E1);
  mySerial = new SoftwareSerial(8, 9); // RX, TX
  mySerial->begin(1200);
  pgmVersion = version;
  
  // variables initializations
  ADCO = "270622224349";
  OPTARIF = "----";
  ISOUSC = 0;
  HCHC = 0L;  // compteur Heures Creuses en W
  HCHP = 0L;  // compteur Heures Pleines en W
  PTEC = "----";    // Régime actuel : HPJB, HCJB, HPJW, HCJW, HPJR, HCJR
  HHPHC = '-';
  IINST = 0;        // intensité instantanée en A
  IMAX = 0;         // intensité maxi en A
  PAPP = -1;         // puissance apparente en VA
  MOTDETAT = "------";
}

//=================================================================================================================
// Capture des trames de Teleinfo
//=================================================================================================================
boolean readTeleInfo(boolean ethernetIsConnected)
{
#define startFrame 0x02
#define endFrame 0x03
#define startLine 0x0A
#define endLine 0x0D
#define maxFrameLen 280

  int comptChar=0; // variable de comptage des caractères reçus 
  char charIn=0; // variable de mémorisation du caractère courant en réception

  char bufferTeleinfo[21] = "";
  int bufferLen = 0;
  int checkSum;

  ethernetIsOK = ethernetIsConnected;

  int sequenceNumnber= 0;    // number of information group
   
   // ************ snips : pour ceux qui n'ont pas de PAPP on réinitialise pour tester une valeur PAPP est reçu ***************
   PAPP = -1;         // puissance apparente en VA
    // ************ snips : fin ajout***********************************************************

  //--- wait for starting frame character 
  nb_boucle1=0;
  while (charIn != startFrame)
  { // "Start Text" STX (002 h) is the beginning of the frame
    if (mySerial->available())
     charIn = mySerial->read()& 0x7F; // Serial.read() vide buffer au fur et à mesure
     nb_boucle1++; // ***********************test ****************************************
  } // fin while (tant que) pas caractère 0x02
//************* départ depuis interruption jusqu'à startframe : 1,45 à 1,52 sec
  //************************* pour trace debug a garder **********************************
  //digitalWrite(13, HIGH); // *********************************test TEST TEST TEST *******************************************
 if (first_boot)
   { 
     nb_boucle1=0;
     first_boot=false;
   }
  //*********top départ  jusqu'à la sortie "true" de la fonction : 2,00 à 2,04 secondes**************** 
  
  //  while (charIn != endFrame and comptChar<=maxFrameLen)
  while (charIn != endFrame)
  { // tant que des octets sont disponibles en lecture : on lit les caractères
    // if (Serial.available())
    if (mySerial->available())
    {
      charIn = mySerial->read()& 0x7F;
      // incrémente le compteur de caractère reçus
      comptChar++;
      if (charIn == startLine)
        bufferLen = 0;
      bufferTeleinfo[bufferLen] = charIn;
      // on utilise une limite max pour éviter String trop long en cas erreur réception
      // ajoute le caractère reçu au String pour les N premiers caractères
      if (charIn == endLine)
      {
        checkSum = bufferTeleinfo[bufferLen -1];
        if (chksum(bufferTeleinfo, bufferLen) == checkSum)
        {// we clear the 1st character
          strncpy(&bufferTeleinfo[0], &bufferTeleinfo[1], bufferLen -3);
          bufferTeleinfo[bufferLen -3] =  0x00;
          sequenceNumnber++;
          //Serial.println(bufferTeleinfo); // debug  
          //Serial.println(sequenceNumnber); //debug
          if (!handleBuffer(bufferTeleinfo, sequenceNumnber))
          {
            // Serial.println(F("Sequence error ...")); //debug original
            return false;
          }
        }
        else
        {
          // Serial.println(F("Checksum error ...")); //debug original
          return false;
        }
      }
      else
        bufferLen++;
    }
    if (comptChar > maxFrameLen)
    {
      //Serial.println(F("Overflow error ...")); ; //debug original
      return false;
    }
  }
      //************************* pour trace debug a garder **********************************
    // digitalWrite(13, LOW); // *********************************test TEST TEST TEST *******************************************
    //*********************** fin chrono DEPUIS STARTFRAME  : 2,00 à 2,04 secondes****************
  return true;
}

//=================================================================================================================
// Frame parsing
//=================================================================================================================
//void handleBuffer(char *bufferTeleinfo, uint8_t len)
boolean handleBuffer(char *bufferTeleinfo, int sequenceNumnber)
{
  // create a pointer to the first char after the space
  char* resultString = strchr(bufferTeleinfo,' ') + 1;
  boolean sequenceIsOK;

  switch(sequenceNumnber)
  {
  case 1:
    if (sequenceIsOK = bufferTeleinfo[0]=='A')
      ADCO = String(resultString);
    break;
  case 2:
    if (sequenceIsOK = bufferTeleinfo[0]=='O')
      OPTARIF = String(resultString);
    break;
  case 3:
    if (sequenceIsOK = bufferTeleinfo[1]=='S')
      ISOUSC = atol(resultString);
    break;
  default: 
      if (sequenceIsOK = (bufferTeleinfo[2]=='H' && bufferTeleinfo[3]=='C'))
          {
          HCHC = atol(resultString);
          break;
          }
 
      if (sequenceIsOK = (bufferTeleinfo[2]=='H' && bufferTeleinfo[3]=='P'))
          {
          HCHP = atol(resultString);
          break;
          }
    // *******snips : ajout pour gérer compteur de base *****************
    if (sequenceIsOK = bufferTeleinfo[0]=='B')
          {
          HCHP = atol(resultString);
          break;
          }
   // ******* fin ajout pour gérer compteur de base *****************
    
    if (sequenceIsOK = bufferTeleinfo[1]=='T')
          {
          PTEC = String(resultString);
          break;
          }
 
    if (sequenceIsOK = bufferTeleinfo[1]=='I')
          {
          IINST =atol(resultString);
          break;
          }
  
    if (sequenceIsOK = bufferTeleinfo[1]=='M')
          {
          IMAX =atol(resultString);
          break;
          }
  
    if (sequenceIsOK = (bufferTeleinfo[0]=='P' && bufferTeleinfo[1]=='A'))
          {
          PAPP =atol(resultString);
          break;
          }
    if (sequenceIsOK = bufferTeleinfo[1]=='H')
          {
          HHPHC = resultString[0];
          break;
          }
          
    if (sequenceIsOK = bufferTeleinfo[1]=='O')
          {
          MOTDETAT = String(resultString);
          break;
          }
  }
  
#ifdef debug
  if(!sequenceIsOK)
  {
    Serial.print(F("Out of sequence ..."));
    Serial.println(bufferTeleinfo);
  }
#endif
  return sequenceIsOK;
}

//=================================================================================================================
// Calculates teleinfo Checksum
//=================================================================================================================
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);
}


//=================================================================================================================
// This function displays the TeleInfo Internal counters
// It's usefull for debug purpose
//=================================================================================================================
void displayTeleInfo()
{  
/*
ADCO 270622224349 B
 OPTARIF HC.. <
 ISOUSC 30 9
 HCHC 014460852 $
 HCHP 012506372 -
 PTEC HP..  
 IINST 002 Y
 IMAX 035 G
 PAPP 00520 (
 HHPHC C .
 MOTDETAT 000000 B
 */
  
Serial.print(F(" "));
  Serial.println();
  Serial.print(F("ADCO "));
  Serial.println(ADCO);
  Serial.print(F("OPTARIF "));
  Serial.println(OPTARIF);
  Serial.print(F("ISOUSC "));
  Serial.println(ISOUSC);
  Serial.print(F("HCHC "));
  Serial.println(HCHC);
  Serial.print(F("HCHP "));
  Serial.println(HCHP);
  Serial.print(F("PTEC "));
  Serial.println(PTEC);
  Serial.print(F("IINST "));
  Serial.println(IINST);
  Serial.print(F("IMAX "));
  Serial.println(IMAX);
  Serial.print(F("PAPP "));
  Serial.println(PAPP);
  Serial.print(F("HHPHC "));
  Serial.println(HHPHC);
  Serial.print(F("MOTDETAT "));
  Serial.println(MOTDETAT);   
}



void encodeur_OWL_CM180()
{

if (PTEC.substring(1,2)=="C")
{
  HCP=(HCHC*223666LL)/1000LL;
}
if (PTEC.substring(1,2)=="P")
{
  HCP=(HCHP*223666LL)/1000LL;
}
// ********* snips : si tarif de base ******************* 
if (PTEC.substring(1,2)=="H")
{
  HCP=(HCHP*223666LL)/1000LL;
}
// ********* snips : fin tarif de base *******************

// ********* snips : si pas de PAPP reçu du compteur on approxime PAPP ******************* 
if (PAPP==-1)
{
  PAPP=IINST*230LL;
}
// ********* snips : fin pas de PAPP  *******************


OregonMessageBuffer[0] =0x62; // imposé
OregonMessageBuffer[1] =0x80; // GH   G= non décodé par RFXCOLM,  H = Count


//OregonMessageBuffer[2] =0x3C; // IJ  ID compteur : "L IJ 2" soit (L & 1110 )*16*16*16+I*16*16+J*16+2
// si heure creuse compteur 3D, si HP compteur 3C 
if (PTEC.substring(1,2)=="C")
{
  OregonMessageBuffer[2] =0x3D; 
  // Serial.print(F("HEURE CREUSE 0x3D"));  //débug *******************************
}
else
{
OregonMessageBuffer[2] =0x3C;
}

//OregonMessageBuffer[3] =0xE1; // KL  K sert pour puissance instantanée, L sert pour identifiant compteur 
PAPP_arrondi=long(long(PAPP)*497/500/16);

// améliore un peu la précision de la puissance apparente encodée (le CM180 transmet la PAPP * 497/500/16)
if ((float(PAPP)*497/500/16-PAPP_arrondi)>0.5)
{
++PAPP_arrondi;
}

OregonMessageBuffer[3]=(PAPP_arrondi&0x0F)<<4;

//OregonMessageBuffer[4] =0x00; // MN  puissance instantée = (P MN K)*16 soit : (P*16*16*16 + M*16*16 +N*16+K)*16*500/497. attention RFXCOM corrige cette valeur en multipliant par 16 puis 500/497.
OregonMessageBuffer[4]=(PAPP_arrondi>>4)&0xFF;

//OregonMessageBuffer[5] =0xCD; // OP  Total conso :  YZ WX UV ST QR O : Y*16^10 + Z*16^9..R*16 + O
OregonMessageBuffer[5] =((PAPP_arrondi>>12)&0X0F)+((HCP&0x0F)<<4);

//OregonMessageBuffer[6] =0x97; // QR sert total conso
OregonMessageBuffer[6] =(HCP>>4)&0xFF;

//OregonMessageBuffer[7] =0xCE; // ST sert total conso
OregonMessageBuffer[7] =(HCP>>12)&0xFF; // ST sert total conso

//OregonMessageBuffer[8] =0x12; // UV sert total conso
OregonMessageBuffer[8] =(HCP>>20)&0xFF; // UV sert total conso

//OregonMessageBuffer[9] =0x00; // WX sert total conso
OregonMessageBuffer[9] =(HCP>>28)&0xFF; 

//OregonMessageBuffer[10] =0x00; //YZ sert total conso
OregonMessageBuffer[10] =(HCP>>36)&0xFF; 


  chksum_CM180= 0;
  for (byte i=0; i<11; i++) 
  {
    chksum_CM180 += long(OregonMessageBuffer[i]&0x0F) + long(OregonMessageBuffer[i]>>4) ;
  }
  
chksum_CM180 -=2; // = =b*16^2 + d*16+ a ou [b d a]

//OregonMessageBuffer[11] =0xD0; //ab sert CHECKSUM  somme(nibbles ci-dessuus)=b*16^2 + d*16+ a + 2
OregonMessageBuffer[11] =((chksum_CM180&0x0F)<<4) + ((chksum_CM180>>8)&0x0F);

//OregonMessageBuffer[12] =0xF6; //cd  d sert checksum, a non décodé par RFXCOM
OregonMessageBuffer[12] =(int(chksum_CM180>>4)&0x0F);  //C = 0 mais inutilisé

}



void setup() {
  pinMode(ALIM_TX_PIN, OUTPUT); //************Broche 6 de l'arduino utilisée pour alimentée le VCC de l'émetteur 433 Mhz *************
  // pinMode(wakeUpPin, INPUT); //***************** Broche 2 de l'arduino utilisé pour sortir l'arduino du sommeil si 0 reçu (=1 téléinfo compteur)
  pinMode(13, OUTPUT); // A VIRER *********************************TEST A VIRER **********************************************
  Serial.begin(115200);   // pour la console, enlever les barres de commentaires ci dessous pour displayTeleInfo()
  TeleInfo(version); 
}

void loop() {
  
  ADCSRA=0;
  power_adc_disable();
  power_spi_disable(); 
  power_twi_disable();  
  power_timer1_disable();  
  power_timer2_disable();  
  power_usart0_disable();  //ATTENTION PLANTE SI DISABLE

teleInfoReceived=readTeleInfo(true);
if (teleInfoReceived)
  {
  //digitalWrite(13, LOW); // NEW *************** TEST TEST TEST  ******************  
  encodeur_OWL_CM180();
  mySerial->end(); //NECESSAIRE !! arrête les interruptions de softwareserial (lecture du port téléinfo) pour émission des trames OWL 
  sendOregon(OregonMessageBuffer, sizeof(OregonMessageBuffer));    // Send the Message over RF
  //**********snips : exemple de mise en veille : 8 secondes, dupliquez la ligne pour 8 secondes supplémentaires etc... ***************************
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
  // LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); // activer la ligne pour 8 secondes de sommeil supplémentaire
  // LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); // activer la ligne pour 8 secondes de sommeil supplémentaire etc...
  
  
// *************** fin chrono depuis teleinforeceived okys haut ! 8,57 à 8,67 secondes******************
/*   //**************************  pour trace DEBUG A GARDER***************************************************
digitalWrite(13, HIGH);// NEW *************** TEST TEST TEST  ******************
delay(100); // NEW *************** TEST TEST TEST  ******************
digitalWrite(13, LOW); // NEW *************** TEST TEST TEST  ******************
delay(100); // NEW *************** TEST TEST TEST  ******************
digitalWrite(13, HIGH); // NEW *************** TEST TEST TEST  ******************
*/  //**************************  pour trace DEBUG A GARDER***************************************************

if (!optimum)
{
  if (nb_boucle1>0)
  {
    if (nb_boucle0>0)
    {
      if (nb_boucle1<nb_boucle0)
        {
          sens_attente=true;
          if ((nb_boucle0-nb_boucle1)<nb_boucle1)
            {
            milli_temps_attente_startframe++;  
            nb_boucle0=nb_boucle1;
            }
          else 
            {
            optimum=true;
            nb_boucle_optimum=nb_boucle1; // stocke le nombre de boucle d'attente mini de startframe
            }
        }
      else
        {  
          if (sens_attente) 
            {
            milli_temps_attente_startframe--;
            optimum=true;
            nb_boucle_optimum=nb_boucle0; // stocke le nombre de boucle d'attente mini de startframe
            }
          else
            { 
            optimum=true;
            nb_boucle_optimum=0; // pas d'attente = optimum
            milli_temps_attente_startframe=0;
            }
          
        }
    }
    else
    {
    nb_boucle0=nb_boucle1;
    milli_temps_attente_startframe++; // on commence par introduire un petit temps d'attente en avant
    }
  }
}

if (!optimum) 
  {
  for (unsigned long i=1; i<= milli_temps_attente_startframe;i++)
    LowPower.powerDown(SLEEP_60MS, ADC_OFF, BOD_OFF);
  }
else
  {
  if (first_time)   // la premiere fois que c'est optimum, minimise le nombre de powerdown par les powerdown les plus longs
    {
    milli_temps_attente_startframe2=60*milli_temps_attente_startframe;// nbre de boucle de 60ms * 60 ms = temps attente en ms
    first_time=false;
    
     if (milli_temps_attente_startframe2>8000) 
     {
     flag_SLEEP_8S=true; 
     milli_temps_attente_startframe2-=8000;
     }
     else flag_SLEEP_8S=false;
   
   if (milli_temps_attente_startframe2>4000) 
     {
     flag_SLEEP_4S=true; 
     milli_temps_attente_startframe2-=4000;
     }
     else flag_SLEEP_4S=false;
  
   if (milli_temps_attente_startframe2>2000) 
     {
     flag_SLEEP_2S=true; 
     milli_temps_attente_startframe2-=2000;
     }
     else flag_SLEEP_2S=false;
   
     if (milli_temps_attente_startframe2>1000) 
     {
     flag_SLEEP_1S=true; 
     milli_temps_attente_startframe2-=1000;
     }
     else flag_SLEEP_1S=false;
   
     if (milli_temps_attente_startframe2>500) 
     {
     flag_SLEEP_500MS=true; 
     milli_temps_attente_startframe2-=500;
     }
     else flag_SLEEP_500MS=false;
   
    if (milli_temps_attente_startframe2>250) 
     {
     flag_SLEEP_250MS=true; 
     milli_temps_attente_startframe2-=250;
     }
     else flag_SLEEP_250MS=false;
    
    if (milli_temps_attente_startframe2>120) 
     {
     flag_SLEEP_120MS=true; 
     milli_temps_attente_startframe2-=120;
     }
     else flag_SLEEP_120MS=false;
    
    if (milli_temps_attente_startframe2>60) 
     {
     flag_SLEEP_60MS=true; 
     milli_temps_attente_startframe2-=60;
     }
     else flag_SLEEP_60MS=false;
     
     if (milli_temps_attente_startframe2>30) 
     {
     flag_SLEEP_30MS=true; 
     milli_temps_attente_startframe2-=30;
     }
     else flag_SLEEP_30MS=false;
     
     if (milli_temps_attente_startframe2>15) 
     {
     flag_SLEEP_15MS=true; 
     milli_temps_attente_startframe2-=15;
     }
     else flag_SLEEP_15MS=false;
    }
    
  if (flag_SLEEP_8S) LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
  if (flag_SLEEP_4S) LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF);
  if (flag_SLEEP_2S) LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF);
  if (flag_SLEEP_1S) LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF);
  if (flag_SLEEP_500MS) LowPower.powerDown(SLEEP_500MS, ADC_OFF, BOD_OFF);
  if (flag_SLEEP_250MS) LowPower.powerDown(SLEEP_250MS, ADC_OFF, BOD_OFF);
  if (flag_SLEEP_120MS) LowPower.powerDown(SLEEP_120MS, ADC_OFF, BOD_OFF);
  if (flag_SLEEP_60MS) LowPower.powerDown(SLEEP_60MS, ADC_OFF, BOD_OFF);
  if (flag_SLEEP_30MS) LowPower.powerDown(SLEEP_30MS, ADC_OFF, BOD_OFF);
  if (flag_SLEEP_15MS) LowPower.powerDown(SLEEP_15MS, ADC_OFF, BOD_OFF);
  
  }
  
  // digitalWrite(13, LOW); //**************************  pour trace DEBUG A GARDER***************************************************
  //**********snips : fin   exemple de mise en veille *****************************************************************************************
  mySerial->begin(1200);  //NECESSAIRE !! relance les interuptions pour la lecture du port téléinfo
  // displayTeleInfo();  // ****** console pour voir les trames téléinfo.. désactiver cette ligne pour économiser de l'énergie ******
  }

}

 
 
Dernière modification par snips le 29 déc. 2020, 02:27, modifié 1 fois.
snips
Messages : 272
Inscription : 18 mars 2015, 22:37

Re: Téléinfo radio

Message par snips »

J'ai mis à jour dans le post ci-dessus le code téléinforadio pour montage arduino pro mini alimenté en 5V par batterie.
il est mieux optimisé (les fonctions inutiles de l'Atmel sont désactivées pour économiser de l'énergie, un "powerdown" supplémentaire est ajouté : l'atmel sort du sommeil juste avant l'arrivée de la trame téléinformation du compteur ERDF).

Sur mon compteur électrique (jour/nuit), le montage ci-dessus alimenté par exemple avec 4 piles rechargeables NIMH AA en série (amazon basics 2500 mah noir, en tenant compte de l'autodécharge : perte de 20% de charge les 6 premiers mois, de 25% à 1 an et 30% à 2 ans) :

-avec une lecture des trames du compteur toutes le 12 secondes (5 fois par minute / soit un seul powerdown de 8 secondes dans le code) : le montage consomme 1,15 mah (valeur mesurée avec mon multimètre). Donc AUTONOMIE CALCULEE DE 2 Mois

-avec une lecture/réactualisation par minute (7 Powerdown de 8 secondes à mettre dans le code) : le montage consomme 0,23 mah (valeur mesurée avec mon multimètre). Donc AUTONOMIE CALCULEE DE 11 Mois.

-avec une lecture/réactualisation toutes les 2 minutes (15 Powerdown de 8 secondes à mettre dans le code) : le montage consomme 0,11 mah (valeur mesurée avec mon multimètre). Donc AUTONOMIE CALCULEE DE 21 Mois.

Bon, c'est théorique, il faut que je teste.

P.S. des améliorations sont encore possibles dans le code : l'arduino doit rester éveillé au moins 2 secondes pour lire une trame complète venant du compteur. Par ailleurs le programme utilise softwareserial pour lire les données du compteur. l'idée est de ne lire que certaines informations (puissance apparente, index compteur) pour garder l'arduino éveillé encore plus brièvement; utiliser les interruptions matérielles - ou optimiser énergétiquement le code softwareserial...
lebsana
Messages : 21
Inscription : 22 mars 2016, 15:58

Re: Téléinfo radio

Message par lebsana »

Bonjour à tous et bon 1er mai,

Je tiens à féliciter ce forum pour sa communauté active et ses partages.
J'ai réalisé le montage (Arduino,....) pour le relevé du Téléinformation. Je l'ai testé grâce au script de test de Snips (que je remercie au passage !) et celui-ci est bien reconnu par Domoticz donc coté montage harware c'est OK.
Ma config de base est un Raspberry 3 et un RFXcom USB.
J'ai téléversè le script de Snips pour le relevé du téléinfo et là pas de signe de vie dans Domoticz.
Voici ce que la console IDE m'affiche :

Code : Tout sélectionner

ADCO XXXXXXXXXXXX (en réalité il y a bien des chiffres mais ne sachant pas si cela était compromettant j'y ai mis des "X")
1
OPTARIF BBR+
2
ISOUSC 30
3
BBRHCJB 041848861
4
BBRHPJB 111751063
5
BBRHCJW 007280850
6
BBRHPJW 020697129
7
BBRHCJR 002421460
8
BBRHPJR 005128152
9
PTEC HPJB
10
DEMAIN ----
11
Sequence error ...
ADCO XXXXXXXXXXXX
1
Ça tourne en boucle...
Je pense que le problème viens de mon abonnement tarifaire.
En effet je suis avec l'Option Tempo en triphasé, ce qui explique mes différents relevés avec les BBRHP* et BBRHC* qui sont bien ceux affichés par le compteur.
Étant novice dans la prog, avez-vous une idée des modifs à réaliser :D :D :D .

Les codes trames de mon compteur, je pense sont dans le document que magdiblog renseigne page 19:
http://www.magdiblog.fr/wp-content/uplo ... PT_02E.pdf

J'aurais bien inséré une capture d'écran mais je n'y suis pas arrivé !
Bon dimanche enfin ensoleillé (dans le nooooooord, c'est la cata... le soleil et les températures étaient aux abonnées absent depuis des mois :x :x :x )

Lebsana
Des débuts en domotique avec une Zipabox "une vraie catastrophe !!!" Depuis début mars 2016 avec Domoticz "du bonheur" Zwave et rfxcom 433 mhz.
snips
Messages : 272
Inscription : 18 mars 2015, 22:37

Re: Téléinfo radio

Message par snips »

Bonjour,

Le code actuel ne gère pas la tarification tempo, mais je peux l'adapter pour que cela marche (cependant n'ayant pas l'option TEMPO je ne peux tester, vous allez devoir le faire et me faire un rapport en retour pour que je corrige les bugs....).

Je vois deux manière de faire cela :
-soit je somme les index des 6 compteurs (HC/HP X couleur jour bleu, blanc rouge...) pour faire un compteur unique avant d'envoyer tout cela à Domoticz....
-Soit on crée 6 compteurs dans domoticz, un pour chaque couleur/HC ou /HP. C'est un peu plus complexe pour la vision globale, mais on a un suivi tarifaire précis.

Je pourrai faire cela la semaine prochaine (pas sur d'avoir le temps aujourd'hui). Dites-moi si vous voulez 6 compteurs dans domoticz ou un seul.

snips
sirus
Messages : 131
Inscription : 05 mai 2015, 18:09
Contact :

Re: Téléinfo radio

Message par sirus »

Salut,
avez vous tester avec le script ici sur le site petitssuisses : Téléinfo ERDF sans fil pour compteur triphasé. ?

Edit : après relecture de l'article est des commentaire le script adapté ne semble pas encore fonctionné avec l'option tempo...


Bon dimanche et bon premier mai !!
Raspberry B+ & PI2 / Domoticz / RFXtrx433E / multiple homemade devices
My blog/tutos for domoticz / electronics stuff : domotique.web2diz.net
Répondre