Arduino nano lib linky LkyRx_06 + envoi en RF

Bonjour à tous, je post sur ce forum pour avoir de l'aide concernant un module arduino nano avec montage pour teleinfo linky + envoi RF en simulant une sonde oregon.

Voici le bout de code :slight_smile:

/***********************************************************************
                        Récepteur TIC Linky
                        Mode historique

V03  : External SoftwareSerial. Tested OK on 07/03/18.
V04  : Replaced available() by new(). Tested Ok on 08/03/18.
V05  : Internal SoftwareSerial. Cf special construction syntax.
V06  : Separate compilation version.

***********************************************************************/

/***************************** Includes *******************************/
#include <string.h>
#include <Streaming.h>
#include "LinkyHistTIC.h"
#include <SoftwareSerial.h>

/****************************** Defines *******************************/



/****************************** Constants *****************************/
const uint8_t pin_LkyRx = 8;
const uint8_t pin_LkyTx = 3;   /* !!! Not used but reserved !!! 
                                  * Do not use for anything else */
const byte TX_PIN = 3;         //emetteur 433 MHZ 
const unsigned long TIME = 488;
const unsigned long TWOTIME = TIME*2;


/************************* Global variables ***************************/
unsigned long chksum_CM180;
#define SEND_HIGH() digitalWrite(pin_LkyTx, HIGH)
#define SEND_LOW() digitalWrite(pin_LkyTx, LOW)
byte OregonMessageBuffer[13];  //  OWL180
unsigned long PAPP_arrondi;
int PAPP;
unsigned long long HCP; 

/************************* Object instanciation ***********************/
LinkyHistTIC Linky(pin_LkyRx, pin_LkyTx);

/****************************  Routines  ******************************/
/****************************  Functions  ******************************/
/**
 * \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)
{
    sendPreamble();
    sendData(data,size);   
    sendPostamble();
}

/**
 * \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);
}
void encodeur_OWL_CM180()
{

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


//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é

}



/******************************  Setup  *******************************/
void setup()
  {

  /* Initialise serial link */
  Serial.begin(9600);

  /* Initialise the Linky receiver */
  Linky.Init();

  Serial << F("Bonjour") << endl;

  }


/******************************* Loop *********************************/
void loop()
  {
  Linky.Update();

  if (Linky.baseIsNew())
    {
    Serial << F("Index base = ") << Linky.base() << F(" Wh") << endl;
    }

  if (Linky.iinstIsNew())
    {
    Serial << F("I instant. = ") << Linky.iinst() << F(" A") << endl;
    }

  if (Linky.pappIsNew())
    {
    Serial << F("Puis. app. = ") << Linky.papp() << F(" VA") << endl;
    PAPP = int(Linky.papp());
    Serial << F("Valeur = ")<< PAPP << endl;
    }

  encodeur_OWL_CM180();
  sendOregon(OregonMessageBuffer, sizeof(OregonMessageBuffer));    // Send the Message over RF
  };

Là où je commence à péter un câble c'est de coupler la reception des datas du linky et l'envoi du RF.

Je pense que j'ai une incompréhension dans la partie gestion des Serial. En effet, si dans la partie setup je commente le Linky.Init(); et en mettant une valeur de PAPP à la main, l'envoi en RF fonctionne parfaitement. Si je décommente Linky.Init(); pas d'envoi en RF.
J'ai bien remarqué également que d'activer l'encoding en OWL génére des erreurs dans la collecte des datas du linky. En jouant sur la variable TIME = 488 à 25 cela ne perturbe plus la récup des datas mais une valeur aussi faible ne permet pas l'envoi en RF. Bref je dois merd... sur la gestion des Serial. J'ai bien tenté de séparer avec des softwareserial différent mais avec une lib .cpp + un softwareserial dans le code direct cela ne fait pas bon ménage.... Une idée ? Merci à vous.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.