Guest User

Untitled

a guest
Dec 29th, 2013
46
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. #include <SPI.h>         // needed for Arduino versionslater than 0018
  3. #include <Ethernet.h>
  4. #include <EthernetUdp.h>
  5. #include <SoftwareSerial.h>
  6.  
  7. // Arduino led
  8. #define LEDPIN 4
  9. /***************** Network configuration ********************/
  10.  
  11. /*
  12. ADCO 020928712433 @
  13.  
  14. OPTARIF HC.. <
  15.  
  16. ISOUSC 45 ?
  17.  
  18. HCHC 012750474 $
  19.  
  20. HCHP 019336969 A
  21.  
  22. PTEC HC.. S
  23.  
  24. IINST 018  
  25.  
  26. IMAX 047 J
  27.  
  28. PAPP 04130 )
  29.  
  30. HHPHC A ,
  31.  
  32. MOTDETAT 000000 B
  33. */
  34.  
  35.  
  36. // Mac address : a mac address must be unique
  37. byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
  38. // IP address : the value will depend on your network
  39. IPAddress ip(192, 168, 1, 165);
  40. char myIPAdress[]="192.168.1.165";
  41. // Broadcat address's first three elements should be the same than ip. The last should be 255.
  42. byte broadCastIp[] = {255, 255, 255, 255};
  43. // Udp local port used (any value you want between 1024 and 65536)
  44. unsigned int localPort = 3865;  
  45. // xPL protocol port (keep default value unless you know what you are doing)
  46. unsigned int xplPort = 3865;  
  47.  
  48. /***************** xPL configuration part *******************/
  49.  
  50. // Source. Format is <vendor id>-<device id>.<instance>
  51.  
  52. // Vendor id and device id should not be changed
  53. // Instance should be the location of your arduino and RGB led strip : living, bedroom, etc
  54. // Instance should only use letters or numbers! (no underscore, ...)
  55. #define MY_SOURCE "arduino-teleinfo.garage"
  56.  
  57. // Name of device in body of xpl message
  58. // This should be the same as previously defined instance
  59. #define MY_DEVICE "arduino"
  60.  
  61. // Maximal size of xPL messages that could be processed
  62. // This size should not be reduce unless you are sure of what you are doing
  63. #define MAX_XPL_MESSAGE_SIZE 200
  64.  
  65. // Heartbeat interval : time in minutes between 2 sends of a xpl hbeat message
  66. #define HBEAT_INTERVAL 5
  67.  
  68. // Duration of a minute in seconds (to allow shorter delay in dev)
  69. #define MINUTE 1
  70.  
  71. // Teleinfo interval : time in minutes between 2 sends of a xpl stat message
  72. #define TELEINFO_INTERVAL 1
  73.  
  74. /***************** Teleinfo configuration part *******************/
  75. char CaractereRecu ='\0';
  76. char Checksum[32] = "";
  77. char Ligne[32]="";
  78. char Etiquette[9] = "";
  79. char Donnee[13] = "";
  80. char Trame[512] ="";
  81. int i = 0;
  82. int j = 0;
  83.  
  84. unsigned long Chrono = 0;
  85. unsigned long LastChrono = 0;
  86.  
  87. char ADCO[12] ;      // Adresse du concentrateur de téléreport (numéro de série du compteur), 12 numériques + \0
  88. long HCHC = 0;      // Index option Heures Creuses - Heures Creuses, 8 numériques, Wh
  89. long HCHP = 0;      // Index option Heures Creuses - Heures Pleines, 8 numériques, Wh
  90. char PTEC[4] ;      // Période Tarifaire en cours, 4 alphanumériques
  91. char HHPHC[2] ; // Horaire Heures Pleines Heures Creuses, 1 alphanumérique (A, C, D, E ou Y selon programmation du compteur)
  92. int IINST = 0;     // Monophasé - Intensité Instantanée, 3 numériques, A  (intensité efficace instantanée)
  93. long PAPP = 0;      // Puissance apparente, 5 numérique, VA (arrondie à la dizaine la plus proche)
  94. long IMAX = 0;      // Monophasé - Intensité maximale appelée, 3 numériques, A
  95. char OPTARIF[4] ;    // Option tarifaire choisie, 4 alphanumériques (BASE => Option Base, HC.. => Option Heures Creuses, EJP. => Option EJP, BBRx => Option Tempo [x selon contacts auxiliaires])
  96. char MOTDETAT[10] = "";  // Mot d'état du compteur, 10 alphanumériques
  97. int ISOUSC = 0;    // Intensité souscrite, 2 numériques, A
  98.  
  99. int check[11];  // Checksum by etiquette
  100. int trame_ok = 1; // global trame checksum flag
  101. int finTrame=0;
  102. /******************* END OF CONFIGURATION *******************/
  103.  
  104.  
  105. /********************* time management **********************/
  106.  
  107. int second = 0;
  108. int lastTimeHbeat = 0;
  109. int lastTimeTeleinfo = 0;
  110.  
  111. /*********************** Global vars ************************/
  112.  
  113. // UDP related vars
  114. EthernetUDP Udp;
  115. SoftwareSerial cptSerial(2, 3);
  116.  
  117. int packetSize = 0;      // received packet's size
  118. byte remoteIp[4];        // received packet's IP
  119. unsigned int remotePort; // received packet's port
  120. byte packetBuffer[MAX_XPL_MESSAGE_SIZE];   // place to store received packet
  121.  
  122. // status
  123. int result;
  124.  
  125.  
  126. /********************* Set up arduino ***********************/
  127. void setup() {
  128.        
  129.    
  130.     pinMode(LEDPIN, OUTPUT);    
  131.    
  132.     // Serial to EDF cpt
  133.     cptSerial.begin(1200);
  134.     Serial.begin(115200);
  135.    
  136.     // Ethernet initialisation
  137.     Ethernet.begin(mac, ip);
  138.     Udp.begin(localPort);
  139.        
  140.     // Send a hbeat message on startup
  141.     sendHbeat();
  142.     digitalWrite(LEDPIN, LOW);
  143. }
  144.  
  145. void loop() {
  146.   // pulse management
  147.   pulse();
  148.  
  149.   if (second == 1) {
  150.            
  151.        // Hbeat action
  152.         lastTimeHbeat += 1;
  153.         // Each N minute, send a hbeat xpl message
  154.         if (lastTimeHbeat == (MINUTE*HBEAT_INTERVAL)) {
  155.             sendHbeat();
  156.             lastTimeHbeat = 0;
  157.         }
  158.  
  159.         // send teleinfo stat
  160.         lastTimeTeleinfo += 1;
  161.         // Each N minute, get teleinfo
  162.         if (lastTimeTeleinfo == (MINUTE*TELEINFO_INTERVAL)) {
  163.             digitalWrite(LEDPIN, HIGH);
  164.             getTeleinfo();
  165.             digitalWrite(LEDPIN, LOW);
  166.             sendTeleinfoBasic();
  167.             lastTimeTeleinfo = 0;
  168.         }        
  169.    }
  170.  
  171. }
  172.  
  173.  
  174. /*------------------------------------------------------------------------------*/
  175. /* Test checksum d'un message (Return 1 si checkum ok)              */
  176. /*------------------------------------------------------------------------------*/
  177. int checksum_ok(char *etiquette, char *valeur, char checksum)
  178. {
  179.     unsigned char sum = 32 ;        // Somme des codes ASCII du message + un espace
  180.     int i ;
  181.  
  182.     for (i=0; i < strlen(etiquette); i++) sum = sum + etiquette[i] ;
  183.     for (i=0; i < strlen(valeur); i++) sum = sum + valeur[i] ;
  184.     sum = (sum & 63) + 32 ;
  185.         Serial.print(etiquette);Serial.print(" ");
  186.         Serial.print(valeur);Serial.print(" ");
  187.     Serial.println(checksum);
  188.     Serial.print("Sum = "); Serial.println(sum);
  189.     Serial.print("Cheksum = "); Serial.println(int(checksum));
  190.     if ( sum == checksum) return 1 ;    // Return 1 si checkum ok.
  191.     return 0 ;
  192. }
  193.  
  194. /***********************************************
  195.    getTeleinfo
  196.    Decode Teleinfo from serial
  197.    Input : n/a
  198.    Output : n/a
  199. ***********************************************/
  200. void getTeleinfo() {
  201.  
  202.   /* vider les infos de la dernière trame lue */
  203.   memset(Ligne,'\0',32);
  204.   memset(Trame,'\0',512);
  205.   int trameComplete=0;
  206.  
  207.   memset(ADCO,'\0',12);
  208.   HCHC = 0;
  209.   HCHP = 0;
  210.   memset(PTEC,'\0',4);
  211.   memset(HHPHC,'\0',2);
  212.   IINST = 0;
  213.   PAPP = 0;
  214.   IMAX = 0;
  215.   memset(OPTARIF,'\0',4);
  216.   memset(MOTDETAT,'\0',10);
  217.   ISOUSC = 0;
  218.  
  219.  
  220.   while (!trameComplete){
  221.     while(CaractereRecu != 0x02) // boucle jusqu'a "Start Text 002" début de la trame
  222.     {
  223.        if (cptSerial.available()) {
  224.          CaractereRecu = cptSerial.read() & 0x7F;
  225.        }
  226.     }
  227.  
  228.     i=0;
  229.     while(CaractereRecu != 0x03) // || !trame_ok ) // Tant qu'on est pas arrivé à "EndText 003" Fin de trame ou que la trame est incomplète
  230.     {
  231.       if (cptSerial.available()) {
  232.           CaractereRecu = cptSerial.read() & 0x7F;
  233.       Trame[i++]=CaractereRecu;
  234.       }
  235.     }
  236.     finTrame = i;
  237.     Trame[i++]='\0';
  238.  
  239.     Serial.println(Trame);
  240.  
  241.     lireTrame(Trame);  
  242.  
  243.     // on vérifie si on a une trame complète ou non
  244.     for (i=0; i<11; i++) {
  245.       trameComplete+=check[i];
  246.     }
  247.     Serial.print("Nb lignes valides :"); Serial.println(trameComplete);
  248.     if (trameComplete < 11) trameComplete=0; // on a pas les 11 valeurs, il faut lire la trame suivante
  249.     else trameComplete = 1;
  250.   }
  251. }
  252.  
  253. void lireTrame(char *trame){
  254.     int i;
  255.     int j=0;
  256.     for (i=0; i < strlen(trame); i++){
  257.       if (trame[i] != 0x0D) { // Tant qu'on est pas au CR, c'est qu'on est sur une ligne du groupe
  258.           Ligne[j++]=trame[i];
  259.       }
  260.       else { //On vient de finir de lire une ligne, on la décode (récupération de l'etiquette + valeur + controle checksum
  261.           decodeLigne(Ligne);
  262.           memset(Ligne,'\0',32); // on vide la ligne pour la lecture suivante
  263.           j=0;
  264.       }
  265.  
  266.    }
  267. }
  268.  
  269. int decodeLigne(char *ligne){
  270.  
  271.  
  272.  
  273.   //Checksum='\0';
  274.  
  275.   int debutValeur;
  276.   int debutChecksum;
  277.   // Décomposer en fonction pour lire l'étiquette etc ...  
  278.   debutValeur=lireEtiquette(ligne);
  279.   debutChecksum=lireValeur(ligne, debutValeur);
  280.   lireChecksum(ligne,debutValeur + debutChecksum -1);
  281.  
  282.   if (checksum_ok(Etiquette, Donnee, Checksum[0])){ // si la ligne est correcte (checksum ok) on affecte la valeur à l'étiquette
  283.     return affecteEtiquette(Etiquette,Donnee);
  284.   }
  285.   else return 0;
  286.  
  287. }
  288.  
  289.  
  290. int lireEtiquette(char *ligne){
  291.     int i;
  292.     int j=0;
  293.     memset(Etiquette,'\0',9);
  294.     for (i=1; i < strlen(ligne); i++){
  295.       if (ligne[i] != 0x20) { // Tant qu'on est pas au SP, c'est qu'on est sur l'étiquette
  296.           Etiquette[j++]=ligne[i];
  297.       }
  298.       else { //On vient de finir de lire une etiquette
  299.     //  Serial.print("Etiquette : ");
  300.         //  Serial.println(Etiquette);
  301.           return j+2; // on est sur le dernier caractère de l'etiquette, il faut passer l'espace aussi (donc +2) pour arriver à la valeur
  302.       }
  303.  
  304.    }
  305. }
  306.  
  307.  
  308. int lireValeur(char *ligne, int offset){
  309.     int i;
  310.     int j=0;
  311.     memset(Donnee,'\0',13);
  312.     for (i=offset; i < strlen(ligne); i++){
  313.       if (ligne[i] != 0x20) { // Tant qu'on est pas au SP, c'est qu'on est sur l'étiquette
  314.           Donnee[j++]=ligne[i];
  315.       }
  316.       else { //On vient de finir de lire une etiquette
  317.     //  Serial.print("Valeur : ");
  318.         //  Serial.println(Donnee);
  319.           return j+2; // on est sur le dernier caractère de la valeur, il faut passer l'espace aussi (donc +2) pour arriver à la valeur
  320.       }
  321.  
  322.    }
  323. }
  324.  
  325.  
  326. void lireChecksum(char *ligne, int offset){
  327.     int i;
  328.     int j=0;
  329.     memset(Checksum,'\0',32);
  330.     for (i=offset; i < strlen(ligne); i++){
  331.           Checksum[j++]=ligne[i];
  332.     //  Serial.print("Chekcsum : ");
  333.         //  Serial.println(Checksum);
  334.       }
  335.  
  336. }
  337.  
  338.  
  339.  
  340.  
  341. int affecteEtiquette(char *etiquette, char *valeur){
  342.  
  343.  if(strcmp(etiquette,"ADCO") == 0) {
  344.    memset(ADCO,'\0',12); memcpy(ADCO, valeur,strlen(valeur)); check[1]=1;
  345.    Serial.print("ADCO="); Serial.println(ADCO);
  346.    Serial.print("valeur="); Serial.println(valeur);
  347.  }
  348.  else
  349.  if(strcmp(etiquette,"HCHC") == 0) { HCHC = atol(valeur); check[2]=1;
  350.    Serial.print("HCHC="); Serial.println(HCHC);
  351.    Serial.print("valeur="); Serial.println(valeur);
  352.  }
  353.  else
  354.  if(strcmp(etiquette,"HCHP") == 0) { HCHP = atol(valeur); check[3]=1;
  355.    Serial.print("HCHP="); Serial.println(HCHP);
  356.    Serial.print("valeur="); Serial.println(valeur);
  357.  }
  358.  else
  359.  if(strcmp(etiquette,"HHPHC") == 0) {
  360.    memset(HHPHC,'\0',2); strcpy(HHPHC, valeur); check[4]=1;
  361.    Serial.print("HHPHC="); Serial.println(HHPHC);
  362.    Serial.print("valeur="); Serial.println(valeur);
  363.  }
  364.  else
  365.  if(strcmp(etiquette,"PTEC") == 0) { memset(PTEC,'\0',4); memcpy(PTEC, valeur,strlen(valeur)); check[5]=1;
  366.    Serial.print("PTEC="); Serial.println(PTEC);
  367.    Serial.print("valeur="); Serial.println(valeur);
  368.  }
  369.  else
  370.  if(strcmp(Etiquette,"IINST") == 0) { IINST = atoi(valeur); check[6]=1;
  371.    Serial.print("IINST="); Serial.println(IINST);
  372.    Serial.print("valeur="); Serial.println(valeur);
  373.  }
  374.  else
  375.  if(strcmp(Etiquette,"PAPP") == 0) { PAPP = atol(valeur); check[7]=1;
  376.    Serial.print("PAPP="); Serial.println(PAPP);
  377.    Serial.print("valeur="); Serial.println(valeur);
  378.  }
  379.  else
  380.  if(strcmp(Etiquette,"IMAX") == 0) { IMAX = atol(valeur); check[8]=1;
  381.    Serial.print("IMAX="); Serial.println(IMAX);
  382.    Serial.print("valeur="); Serial.println(valeur);
  383.  }
  384.  else
  385.  if(strcmp(Etiquette,"OPTARIF") == 0) { memset(OPTARIF,'\0',4); memcpy(OPTARIF, valeur,strlen(valeur)); check[9]=1;
  386.    Serial.print("OPTARIF="); Serial.println(OPTARIF);
  387.    Serial.print("valeur="); Serial.println(valeur);
  388.  }
  389.  else
  390.  if(strcmp(Etiquette,"ISOUSC") == 0) { ISOUSC = atoi(valeur); check[10]=1;
  391.    Serial.print("ISOUSC="); Serial.println(ISOUSC);
  392.    Serial.print("valeur="); Serial.println(valeur);  
  393.  }
  394.  else
  395.  if(strcmp(Etiquette,"MOTDETAT") == 0) { memset(MOTDETAT,'\0',10); memcpy(MOTDETAT, valeur, strlen(valeur)); check[0]=1;
  396.    Serial.print("MOTDETAT="); Serial.println(MOTDETAT);
  397.    Serial.print("valeur="); Serial.println(valeur);  
  398.  }
  399.  else
  400.  return 0;
  401.  
  402.  return 1;
  403. }
RAW Paste Data