mardi 28 août 2012

Téléinformation 2/5 (Arduino SW)


#include <SoftwareSerial.h>
#include <SPI.h>
#include <Ethernet.h>

SoftwareSerial cptSerial(2,3);

//#define DebugL1        //envoie seulement pour le débug sur l'USB
//#define DebugL2        //envoie tout sur l'USB

//*****************************************************************************************
  byte inByte = 0 ;        // caractère entrant téléinfo
  char buffteleinfo[21] = "";
  byte bufflen = 0;
 
// declarations Teleinfo
  byte isousc = 0;        // Intensité souscrite, A
  unsigned int papp = 0;  // Puissance apparente, VA

  char ptec[4] = "";      // Période Tarifaire en cours, 4 alphanumériques (HC.. ou HP..)

  unsigned int iinst = 0;      // Monophasé - Intensité Instantanée, A  (intensité efficace instantanée)
   
  unsigned long hchc = 0;
  unsigned long hchp = 0;

#define debtrame 0x02
#define debligne 0x0A
#define finligne 0x0D


byte mac[] = {0x54,0x55,0x58,0x10,0x00,0x26};    // MAC address of Arduino
IPAddress ip(192,168,1, 202);                    // IP address of Arduino

EthernetServer server(80);

// ************** initialisation *******************************
void setup()
{
 // initialisation du port 0-1 lecture Téléinfo
    Serial.begin(1200);
    cptSerial.begin(1200);    // le mode 7 bit parité pair se fait plus loin

 // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();

#ifdef DebugL1
    Serial.print("-- Teleinfo Arduino UNO --");
#endif
}

// ************** boucle principale *******************************

void loop()                     // Programme en boucle
{

  read_teleinfo();
  read_web();

}

///////////////////////////////////////////////////////////////////
// Calcul Checksum teleinfo
///////////////////////////////////////////////////////////////////
char chksum(char *buff, int len)
{
  int i;
  char sum = 0;
    for (i=1; i<(len-2); i++) sum = sum + buff[i];
    sum = (sum & 0x3F) + 0x20;
    return(sum);
}

///////////////////////////////////////////////////////////////////
// Analyse de la ligne de Teleinfo
///////////////////////////////////////////////////////////////////
void traitbuf_cpt(char *buff, int len)
{

  if (strncmp("HCHP ", &buff[1] , 5)==0){
      hchp = atol(&buff[6]);
  #ifdef DebugL1
      Serial.print("- Index Heures Pleines: "); Serial.println(hchp,DEC);
  #endif       
  }

  else if (strncmp("HCHC ", &buff[1] , 5)==0){
      hchc = atol(&buff[6]);
  #ifdef DebugL1
      Serial.print("- Index Heures Creuses: ");Serial.println(hchc,DEC);
  #endif       
  }

  else if (strncmp("IINST ", &buff[1] , 6)==0){
      iinst = atol(&buff[7]);
  #ifdef DebugL1
      Serial.print("- I iNStantannee : "); Serial.println(iinst,DEC);    // valeur à l'ampère près donc à 240W près => pas terrible
  #endif    
  }

  else if (strncmp("PAPP ", &buff[1] , 5)==0){
      papp = atol(&buff[6]);
  #ifdef DebugL1
      Serial.print("- Puissance apparente : ");Serial.println(papp,DEC);
  #endif       
  }

  else if (strncmp("PTEC ", &buff[1] , 5)==0){
        strncpy(ptec, &buff[6], 4);
        ptec[4]='\0';
  #ifdef DebugL1
        Serial.print("- Periode Tarifaire En Cours : "); Serial.println(ptec);
  #endif       
  }
    
}

///////////////////////////////////////////////////////////////////
// Lecture trame teleinfo (ligne par ligne)
///////////////////////////////////////////////////////////////////
void read_teleinfo()
{
  // si une donnée est dispo sur le port série
  if (cptSerial.available() > 0)
  {
  // recupère le caractère dispo
    inByte = (cptSerial.read()& 0x7F);      // le 0X7F pour avoir en 7 bits au lieu de 8

#ifdef DebugL2   
    Serial.print(char(inByte));  // echo des trames sur l'USB (choisir entre les messages ou l'echo des trames)
#endif

    if (inByte == debtrame) bufflen = 0; // test le début de trame
    if (inByte == debligne) // test si c'est le caractère de début de ligne
    {
      bufflen = 0;
    } 
    buffteleinfo[bufflen] = inByte;
    bufflen++;
    if (bufflen > 21)bufflen=0;       // longueur max du buffer (21 pour lire trame ADCO)
    if (inByte == finligne && bufflen > 5) // si Fin de ligne trouvée
    {
      if (chksum(buffteleinfo,bufflen-1)== buffteleinfo[bufflen-2]) // Test du Checksum
      {
        traitbuf_cpt(buffteleinfo,bufflen-1); // ChekSum OK => Analyse de la Trame
      }
    }
  }
}

///////////////////////////////////////////////////////////////////
// Création page Web client
///////////////////////////////////////////////////////////////////
void read_web()
{
    // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    #ifdef DebugL1   
      Serial.println("new request");
    #endif
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        #ifdef DebugL1
          Serial.write(c);
        #endif
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n");
          client.println("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
      client.println("<ARDUINO>");
          client.print("<HCHC>");
          client.print(hchc,DEC);
          client.print("</HCHC>");
          client.print("<HCHP>");
          client.print(hchp,DEC);
          client.print("</HCHP>");
          client.print("<IINST>");
          client.print(iinst,DEC);
          client.print("</IINST>");   
          client.print("<PAPP>");
          client.print(papp,DEC);
          client.print("</PAPP>");
          client.print("<PTEC>");
          client.print(ptec);
          client.print("</PTEC>");
          client.println("</ARDUINO>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    #ifdef DebugL1
      Serial.println("client disonnected");
    #endif
  }
}

2 commentaires:

  1. Bonsoir
    j ai essayé le montage et copié collé le code mais j ai aucune donné qui sort , j ai un arduino atmega 1280, c est bien sur la broche n° 2 que l'on se connecte
    merci d'avance

    RépondreSupprimer
  2. Mon code donne les ports 0/1 pour le port série de débug par USB.
    Les port 2/3, le port série reliée à la carte d'interface téléinfo.
    Si tu enlève le commentaire sur la ligne //#define DebugL2 en supprimant le //, tu devrais voir ce qui arrive de la carte d'interface.

    Dans le cas ou tu aurais inversé les pin 2 et 3, au lieu de recabler, tu peux modifier le code comme ceci : SoftwareSerial cptSerial(3,2); pour modifier le RX et TX

    RépondreSupprimer