J’ai commencé le développement de régulations basées sur un Arduino. Pourquoi je n’acquière pas un produit du commerce: Les solution commerciales ne répondent pas à mes attentes en particulier la possibilité de dépannage en cas de problèmes. D’autres part, bien qu’équipée de bus, la communication est souvent un protocole fermé, il est plus simple de développer un système de communication que comprendre et surtout arriver à utiliser celui mis en place par le constructeur. Je partage donc mon travail sur une régulation « loi d’eau » et une régulation pour chaudière bois ou poêle bouilleur.
Le sketch est inspiré des anciennes régulations Landys & Gyr qui pilotaient une vanne trois voies motorisée. La courbe de chauffe était déterminée par des potentiomètre. Dans cette version, tout les paramètres sont accessibles et modifiable via le modbus. Il sont mémorisés via une commande modbus dans l’eeprom. Le sketch tourne sur un arduino nano. la t° de départ est soit 4° (antigel) soit fixe soit loi d’eau. Un mode booster temporisé permet de forcer la t° à 40°. Le système fonctionne depuis fin 2022. suite a un orage, destruction des MAX31865 -> remplacement
Bonjour, Dans l’idée de limiter au maximum la consommation électrique (alimentation panneau solaire) la régulation veille à garder un delta de 10° dans l’échangeur. Une vanne thermostatique 3 voies maintient de façon autonome la température d’entrée de l’échangeur à 55°. L’alimentation du circulateur Grundfoss Alpha1L se fait via un thermostat mécanique dont la sonde est dans un doigt de gant dans l’échangeur. Sans électronique le système est autonome.
L’algorithme gếre la mise en route, l’arrêt et la vitesse via le pwm. Le fonctionnement peut être suivit avec le modbus. Tous les paramètres sont stockés dans l’eeprom et peuvent être modifiés via le modbus. Un script python cgi permet le lire le modbus et d’afficher les valeurs sur une page web. Le bootloader de l’Atmega 328 est modifié pour pouvoir le reprogrammer au travers du modbus avec l’ide arduino. schema_atmega_bouilleur L’algorithme gếre la mise en route, l’arrêt et la vitesse via le pwm. Le fonctionnement peut être suivit avec le modbus. Tous les paramètres sont stockés dans l’eeprom et peuvent être modifiés via le modbus. Un script python cgi permet le lire le modbus et d’afficher les valeurs sur une page web. Le bootloader de l’Atmega 328 est modifié pour pouvoir le reprogrammer au travers du modbus avec l’ide arduino. schema_atmega_bouilleur code source: code.ino
Bonjour, Dans cet article je propose le partage du développement que j’ai réalisé pour décoder les trames Vbus. toutes les spécification se trouvent ici: https://danielwippermann.github.io/resol-vbus/vbus-specification.html tout à disparu de son site. Je ne l’ai hélas pas téléchargé…… Le code ci-après est dérivé du travail de M. Wipperman. Vous pouvez échanger sur le sujet en me contactant via formulaire contact Version raspberry pi: vbus_decode
Version arduino:
/*
nouvelle version de Vbusread
* permet de selectionner un DFA
* serveur web fichiers json
* Prise en compte du CRC
* version ok pas toucher
*
* Legal Notices
* RESOL, VBus, VBus.net and others are trademarks or registered trademarks of RESOL - Elektronische Regelungen GmbH.
* Le sketch d'origine provient de M. Wiperman, http://danielwippermann.github.io
*
* Vbus 9600 bauds 8 bits pas de parité un stop bit
* Vbus ttl avec un opto coupleur SFH6206 une resistance de 4,7k en série avec led, coté transistor, collecteur sur +5V,emeteur une résistance pulldown de 3,3K vers la masse
* | C E | 40 @ Ic/Iin Iin 1mA
* | |
* .| in in|
* si pas de vbus -> affiche timeout -> ok
* sonde dht22 pour température et humidité local
* test: curl http://192.168.1.140/vbus.json
* switch debug rs232: curl http://192.168.1.141/disp_rs232.json
http://192.168.1.141/temperatures.json
modif ligne 230 inversion poid fort et faible et _ manquant
*/
#include <SoftwareSerial.h>
#include <EtherCard.h> //doc: https://www.aelius.com/njh/ethercard/
#include <DHT.h>
#define VERSION "0.1.04"
#define DHTPIN 7
#define soft_rxd_pin 8
#define LED 2
#define DHTTYPE DHT22 // DHT 22
DHT dht(DHTPIN, DHTTYPE);
#define FLength 6 // Framelength
#define FOffset 10 // Offset start of Frames
#define FSeptet 4 // Septet byte in Frame
#define LED 2
#define timerInterval 1500
SoftwareSerial Soft_serial(soft_rxd_pin, 9,false);
#define debug 1
//ENC28J60 ethernet
// Ethernet uses 10,11,12,13
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x34 };
#define STATIC 1 // DHCP=0 , static=1
#define version 0.1.0
#if STATIC
static byte myip[] = { 192,168,1,141 }; // static ip address
#endif
byte Ethernet::buffer[400]; // tcp ip send and receive buffer
BufferFiller bfill;
#define FLOATEMIT
const char header_json[] PROGMEM =
"HTTP/1.0 200 OK\r\n"
"content-Type: application/json;charset=utf-8\r\n"
"\r\n";
const char header_json2[] PROGMEM =
"HTTP/1.0 200 OK\r\n"
"content-Type: application/json;charset=utf-8\r\n"
"Refresh: 5\r\n"
"\r\n";
const char header_refresh[] PROGMEM = "Refresh: 5\r\n";
const char page_help[] PROGMEM =
"HTTP/1.0 200 OK\r\n"
"content-Type: application/json;charset=utf-8\r\n"
"\r\n"
"{\"help\":{ "
"\"compil_date\": \"" __DATE__"\","
"\"compil_time\": \"" __TIME__"\","
"\"src_file\": \"" __FILE__"\","
"\"version\": \""VERSION"\""
"}}\r\n";
const char error_json[] PROGMEM =
"HTTP/1.0 404 Not Found\r\n"
"content-Type: application/json;charset=utf-8\r\n"
"\r\n"
"{\"vbus\":{ \"error\": 404}}"
"\r\n";
bool all;
bool disp_rs232 = false;
bool refresh = false;
unsigned char Buffer[75];
char char_buffer[80];
long lastTimeTimer;
//long timerInterval =600;
//int temp;
byte i;
uint16_t networkaddress;
byte nb_crc_error;
char sensor1_tempc [6];
char sensor2_tempc [6];
char sensor3_tempc [6];
char sensor4_tempc [6];
char refresh_string [] = "false";
//char * refresh_string ;
char temp_VFD [6];
char PumpSpeed1; // in %
char PumpSpeed2; // in %
char RelaisMask;
char ErrorMask;
char Scheme;
uint16_t OperatingHoursRelais1;
uint16_t OperatingHoursRelais2;
uint32_t HeatQuantity;
uint16_t Version;
uint16_t OperatingHoursRelais1Today;
uint16_t SystemTime;
uint16_t flow_VFD;
unsigned int Destination_address;
unsigned int Source_address;
unsigned char ProtocolVersion;
unsigned int Command;
unsigned char Framecnt;
unsigned char Septet;
unsigned char Checksum;
unsigned char calc_Checksum;
unsigned char tot_crc_error =0;
void setup() {
pinMode(LED, OUTPUT);
digitalWrite(LED, HIGH);
dht.begin();
Serial.println("Arduino debugging started");
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("Go!");
// set the data rate for the SoftwareSerial port
Soft_serial.begin(9600);
//ether.begin(sizeof Ethernet::buffer, mymac);
if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
Serial.println( "Failed to access Ethernet controller");
#if STATIC
ether.staticSetup(myip);
Serial.println("Static IP");
#else
if (!ether.dhcpSetup())
Serial.println("DHCP failed");
#endif
ether.printIp("IP: ", ether.myip);
digitalWrite(LED, LOW);
}
void loop() {
//String refresh_string = " ";
word pos = ether.packetLoop(ether.packetReceive());
// check if valid tcp data is received
if (pos) {
char* data = (char *) Ethernet::buffer + pos;
#if debug
Serial.println(data);
#endif
if (strncmp("GET / ", data, 6) == 0) {
//Serial.println("http Get /");
ether.httpServerReplyAck(); // send ack to the request
memcpy_P(ether.tcpOffset(), page_help, sizeof page_help);//only the first part will sended
ether.httpServerReply_with_flags(sizeof page_help - 1,TCP_FLAGS_ACK_V|TCP_FLAGS_FIN_V);
}
else
if (strncmp("GET /vbus.json", data, 14) == 0) {
//Serial.println("http GET /vbus.json");
//digitalWrite(LED, HIGH);
if (VBusRead(0x10)){
//Serial.println(temp);
nb_crc_error = extract_septep();
tot_crc_error += nb_crc_error;
bfill = ether.tcpOffset();
if (refresh) {
bfill.emit_p(PSTR("$F"),header_json2);
strcpy(refresh_string, "true");
}
else {
bfill.emit_p(PSTR("$F"),header_json);
strcpy(refresh_string, "false");
}
bfill.emit_p(PSTR(
"{\"Vbus\":{"
"\"src_address\":\"0x$H$H\","
"\"t_1\":$S,"
"\"t_2\":$S,"
"\"t_3\":$S,"
"\"t_4\":$S,"
"\"t_VFD\":$S,"
"\"VFD_flow\":$D,"
"\"Vpump1\":$D,"
"\"heures_P1\":$D,"
"\"Vpump2\":$D,"
"\"heures_P2\":$D,"
"\"heure\":\"$D:$D\","
"\"P_tot\":$L,"
"\"ErrorMask\":\"0x$H\","
"\"nb_crc_error\":$D,"
"\"tot_crc_error\":$D,"
"\"refresh\":\"$S\""
"}}"
),Buffer[4],Buffer[3],sensor1_tempc,sensor2_tempc,sensor3_tempc,sensor4_tempc,temp_VFD,flow_VFD,
PumpSpeed1,OperatingHoursRelais1,PumpSpeed2,OperatingHoursRelais2, SystemTime/60,SystemTime%60,
HeatQuantity, ErrorMask,nb_crc_error, tot_crc_error,refresh_string);
ether.httpServerReply(bfill.position());
}
else {
bfill = ether.tcpOffset();
bfill.emit_p(PSTR("{\"Vbus\":{\"error\" :\"timeout\" }}"));
ether.httpServerReply(bfill.position());
}
}
else
if (strncmp("GET /infos_10.json", data, 17) == 0) {
//Serial.println("GET /infos_15.json");
byte vbusread_code;
vbusread_code = VBusRead(0x10);
if (vbusread_code){
extract_septep();
bfill = ether.tcpOffset();
bfill.emit_p(PSTR(
"$F{\"Vbus\":{"
"\"vbusread code\":$D,"
"\"sync\":\"0x$H\","
"\"Src address\":\"0x$H$H\","
"\"Dst address\":\"0x$H$H\","
"\"22\":$D,"
"\"23\":$D,"
"\"24\":$D,"
"\"25\":$D,"
"\"28\":$D,"
"\"29\":$D,"
"\"30\":$D,"
"\"31\":$D,"
"\"34\":$D,"
"\"35\":$D,"
"\"35\":$D,"
"\"37\":$D"
"}}"
),header_json,vbusread_code,Buffer[0],Buffer[2],Buffer[1],Buffer[3],Buffer[4],
Buffer[22],Buffer[23],Buffer[24],Buffer[25],
Buffer[28],Buffer[29],Buffer[30],Buffer[31],
Buffer[34],Buffer[35],Buffer[36],Buffer[37]
);
ether.httpServerReply(bfill.position());
}
}
else
if (strncmp("GET /infos.json", data, 14) == 0) {
byte vbusread_code;
vbusread_code = VBusRead(0x10);
if (vbusread_code){
//Serial.println(temp);
bfill = ether.tcpOffset();
bfill.emit_p(PSTR(
"$F{\"Vbus\":{"
"\"vbusread code\":$D,"
"\"sync\":\"0x$H\","
"\"Src address\":\"0x$H$H\","
"\"Dst address\":\"0x$H$H\","
"\"Protocol Version\":\"0x$H\","
"\"Command:=\":\"0x$H$H\","
"\"Framecount\":$D,"
"\"Checksum\":\"0x$H\","
"\"calc Checksum\":\"0x$H\""
"}}"
),header_json,vbusread_code,Buffer[0],Buffer[2],Buffer[1],Buffer[3],Buffer[4],ProtocolVersion,Buffer[6],Buffer[7],Framecnt,temp_VFD,Buffer[9],VBus_CalcCrc(Buffer, 1, 8));
ether.httpServerReply(bfill.position());
}
}
else
if (strncmp("GET /temperatures.json", data, 22) == 0) {
bfill = ether.tcpOffset();
char char_value[5];
bfill.emit_p(PSTR("$F{\"dht22\":"),header_json);
dtostrf(dht.readHumidity(),5,1 ,char_value);
bfill.emit_p(PSTR("{\"humidity\":$S,"),char_value);
dtostrf(dht.readTemperature(),5,1 ,char_value);
bfill.emit_p(PSTR("\"temperature\":$S"), char_value);
bfill.emit_p(PSTR("}}"));
ether.httpServerReply(bfill.position());
}
else
if (strncmp("GET /disp_rs232.json", data, 20) == 0) {
bfill = ether.tcpOffset();
bfill.emit_p(PSTR("$F{\"disprs232\":"),header_json);
disp_rs232 = (! disp_rs232);
if (disp_rs232)
bfill.emit_p(PSTR("\"true\"}"));
else
bfill.emit_p(PSTR("\"false\"}"));
ether.httpServerReply(bfill.position());
}
else
if (strncmp("GET /refresh.json", data, 17) == 0) {
bfill = ether.tcpOffset();
bfill.emit_p(PSTR("$F{\"refresh\":"),header_json);
refresh = (! refresh);
if (refresh)
bfill.emit_p(PSTR("\"true\"}"));
else
bfill.emit_p(PSTR("\"false\"}"));
ether.httpServerReply(bfill.position());
}
else {
ether.httpServerReplyAck(); // send ack to the request
memcpy_P(ether.tcpOffset(), error_json, sizeof error_json);//only the first part will sended
ether.httpServerReply_with_flags(sizeof error_json - 1,TCP_FLAGS_ACK_V|TCP_FLAGS_FIN_V);
}
} //if (strncmp("GET /vbus.json"
}
byte VBusRead (byte DFA) {
/*code sortie 0 no data
* 3 sortie sur deuxieme Sync
* 2 trop de données
*/
byte c;
bool start;
bool DFA_ok = false;
lastTimeTimer = millis();
int index;
index = 0;
while (index < 73) {
if (Soft_serial.available()) {
c= (byte) Soft_serial.read();
lastTimeTimer = millis();
if (c == 0xAA) {
if (DFA_ok) {
digitalWrite(LED, HIGH);
return 3;
}
index = 0;
Buffer[0]=c;
#if debug
Serial.println("Sync found");
#endif
digitalWrite(LED, LOW);
}
else
if (index == 1){
if (c == DFA)
DFA_ok = true;
}
if (DFA_ok) {
Buffer[index]=c;
#if debug
char s[7];
sprintf(s, "%02X ",c);
Serial.print(s);
#endif
}
index ++;
}
if ((timerInterval > 0) && (millis() - lastTimeTimer > timerInterval ) ) {
if (disp_rs232) {
Serial.print("time_out ");
Serial.println(lastTimeTimer);
}
return 0;
}
}
digitalWrite(LED, LOW);
return 2;
} //byte VBusRead (byte DFA)
byte extract_septep () {
byte F;
byte nb_crc_error =0;
//0 SYNC byte 0XAA
//1 2 dest address
//3 4 source address
//5 protocol verion
//6 7 command
//8 Number of payload frames
//9 Checksum for offset 1-8
Destination_address = Buffer[2] << 8 | Buffer[1];
Source_address = Buffer[4] << 8 | Buffer[3];
Command = Buffer[7] << 8 | Buffer[6];
ProtocolVersion = (Buffer[5]>>4) + (Buffer[5] &(1<<15));
Framecnt = Buffer[8];
Checksum = Buffer[9];
calc_Checksum = VBus_CalcCrc(Buffer, 1, 8);
///******************* Frame 1 *******************
F=FOffset;
calc_Checksum = VBus_CalcCrc(Buffer, F, 5);
if (Buffer[F+5] != calc_Checksum)
nb_crc_error ++;
else {
Septet=Buffer[F+FSeptet];
InjectSeptet(Buffer,F,4);
dtostrf(CalcTemp(Buffer[F+1], Buffer[F]) ,5,1 ,sensor1_tempc);
dtostrf(CalcTemp(Buffer[F+3], Buffer[F+2]),5,1 ,sensor2_tempc);
}
///******************* Frame 2 *******************
F=FOffset+FLength;
calc_Checksum = VBus_CalcCrc(Buffer, F, 5);
if (Buffer[F+5] != calc_Checksum)
nb_crc_error ++;
else {
Septet=Buffer[F+FSeptet];
InjectSeptet(Buffer,F,4);
dtostrf(CalcTemp(Buffer[F+1], Buffer[F]) ,5,1 ,sensor3_tempc);
dtostrf(CalcTemp(Buffer[F+3], Buffer[F+2]),5,1 ,sensor4_tempc);
}
///******************* Frame 3 *******************
F=FOffset+FLength*2;
calc_Checksum = VBus_CalcCrc(Buffer, F, 5);
if (Buffer[F+5] != calc_Checksum) {
nb_crc_error ++;
PumpSpeed1 =255;
}
else {
Septet=Buffer[F+FSeptet];
InjectSeptet(Buffer,F,4);
PumpSpeed1 = ((Buffer[F] & 0X7F));
OperatingHoursRelais1=Buffer[F+3] << 8 | Buffer[F+2];
}
///******************* Frame 4 *******************
F=FOffset+FLength*3;
calc_Checksum = VBus_CalcCrc(Buffer, F, 5);
if (Buffer[F+5] != calc_Checksum) {
nb_crc_error ++;
PumpSpeed2 =255;
}
else {
Septet=Buffer[F+FSeptet];
InjectSeptet(Buffer,F,4);
PumpSpeed2 = (Buffer[F+0] & 0X7F);
OperatingHoursRelais2=Buffer[F+3] << 8| Buffer[F+2];
}
///******************* Frame 5 *******************
F=FOffset+FLength*4;
calc_Checksum = VBus_CalcCrc(Buffer, F, 5);
if (Buffer[F+5] != calc_Checksum)
nb_crc_error ++;
Septet=Buffer[F+FSeptet];
InjectSeptet(Buffer,F,4);
Scheme = Buffer[F+1];
///******************* Frame 6 *******************
F=FOffset+FLength*5;
calc_Checksum = VBus_CalcCrc(Buffer, F, 5);
if (Buffer[F+5] != calc_Checksum)
nb_crc_error ++;
Septet=Buffer[F+FSeptet];
InjectSeptet(Buffer,F,4);
ErrorMask= Buffer[F];
SystemTime = Buffer[F+3] << 8 | Buffer[F+2];
///******************* Frame 7 *******************
F=FOffset+FLength*6;
calc_Checksum = VBus_CalcCrc(Buffer, F, 5);
if (Buffer[F+5] != calc_Checksum)
nb_crc_error ++;
Septet=Buffer[F+FSeptet];
InjectSeptet(Buffer,F,4);
///******************* Frame 8 *******************
F=FOffset+FLength*7;
calc_Checksum = VBus_CalcCrc(Buffer, F, 5);
if (Buffer[F+5] != calc_Checksum)
nb_crc_error ++;
Septet=Buffer[F+FSeptet];
InjectSeptet(Buffer,F,4);
//HeatQuantity = (Buffer[F + 3] << 24| Buffer[F+2] << 16 | Buffer[F + 1] << 8 | Buffer[F]);
HeatQuantity = (Buffer[F+2] * 65535) + word ((Buffer[F + 1] << 8 | Buffer[F]));
//HeatQuantity = (Buffer[F + 3] << 8 | Buffer[F+2]) + word ((Buffer[F + 1] << 8 | Buffer[F]));
///******************* Frame 9 *******************
F=FOffset+FLength*8;
calc_Checksum = VBus_CalcCrc(Buffer, F, 5);
if (Buffer[F+5] != calc_Checksum)
nb_crc_error ++;
Septet=Buffer[F+FSeptet];
InjectSeptet(Buffer,F,4);
Version=Buffer[F+1] << 8| Buffer[F];
///******************* Frame 10 *******************
F=FOffset+FLength*9;
calc_Checksum = VBus_CalcCrc(Buffer, F, 5);
if (Buffer[F+5] != calc_Checksum)
nb_crc_error ++;
Septet=Buffer[F+FSeptet];
InjectSeptet(Buffer,F,4);
dtostrf(CalcTemp(Buffer[F+1], Buffer[F]) ,5,1 ,temp_VFD);
flow_VFD=Buffer[F+3] << 8| Buffer[F+2];
///******************* End of frames ****************
if (disp_rs232) {
for (int i = 0; i < 10; i++) {
F=FOffset+FLength * i;
serial_print_buffer(Buffer,F,i);
}
}
return nb_crc_error;
} //byte extract_septep ()
// This function converts 2 data bytes to a temperature value.
float CalcTemp(int Byte1, int Byte2) {
int v;
v = Byte1 << 8 | Byte2; //bit shift 8 to left, bitwise OR
if (Byte1 == 0x00)
v= v & 0xFF;
if (Byte1 == 0xFF)
v = v - 0x10000;
return (float)((float) v * 0.1);
}
unsigned char VBus_CalcCrc(const unsigned char *Buffer, int Offset, int Length) {
//source: VBus Protocol Specification page 9
unsigned char Crc = 0x7F;
for (int i = 0; i < Length; i++) {
Crc = (Crc - Buffer [Offset + i]) & 0x7F;
}
return Crc;
}
// The following is needed for decoding the data
void InjectSeptet(unsigned char *Buffer, int Offset, int Length) {
for (unsigned int i = 0; i < Length; i++) {
if (Septet & (1 << i)) {
Buffer [Offset + i] |= 0x80;
}
}
}
void serial_print_buffer (unsigned char *Buffer,int F, int i) {
byte calc_Checksum;
calc_Checksum = VBus_CalcCrc(Buffer, F, 5);
sprintf(char_buffer,"frame %02d: %03d %03d %03d %03d",i,Buffer[F],Buffer[F+1],Buffer[F+2],Buffer[F+3]);
Serial.print(char_buffer);
if (Buffer[F+5] == calc_Checksum)
Serial.println(" checksum: OK");
else {
Serial.print(Buffer[F+5]);
Serial.print(" ");
Serial.println(calc_Checksum);
}
}
// Frame info for the Resol resol CS4 and CS plus
// modidied by Dimi
// voir doc deltasol bs+ id: 2211
// http://danielwippermann.github.io/resol-vbus/#/#0010_1122_0100
// protocole: les bits de poids forts sont à zéro, il sont contenus dans le 5 e octet
// T° exemple 19,9° 199 D 0 D 28,6° 30 D 1 D 30 * 0.1 + 2.26 * 30
//-1,2° 244D 255D
//Offset Size Mask Name Factor Unit
//frame 0
//0 SYNC byte 0xAA
//1 LSB dest address appelé DFA valeur 0x10 ou 0x15
//2 MSB dest address
//3 LSB src address
//4 MSB src address
//5 protocol version
//6 LSB command
//7 MSB command
// 0x0100 Packet contains data for slave
// 0x0100 Packet contains data for slave
// 0x0300 Request answer of slave
//Frame 1 pour dest adress 0x0010
//10 1 Temperature sensor 1 0.1 C°
//11 1 Temperature sensor 1 25.6 C°
//12 1 Temperature sensor 2 0.1 C°
//13 1 Temperature sensor 2 25.6 C°
//frame 2
//16 1 Temperature sensor 3 0.1 C°
//17 1 Temperature sensor 3 25.6 C°
//18 1 Temperature sensor 4 0.1 C°
//19 1 Temperature sensor 4 25.6 C°
//frame 3
//22 1 Pump speed pump %
//23 1 ?
//24 1 heure relai 1 1h
//25 1 heure relai 1 256
//frame 4
//28 2 vitesse relai 2 %
//29 ?
//30 1 heure relai 2 1
//31 1 heure relai 2 256
//frame 5
//34 1 unit type 1
//35 1 system 1
//37
//37
//frame 6
//40 0x01 sensor 1 defekt 1
//40 0x02 sensor 2 defekt 1
//40 0x04 sensor 3 defekt 1
//40 0x08 sensor 4 defekt 1
//40 0x10 sensor GFD 1
//41 error mask 256
//42 temps en minutes 1
//43 temps 256
//frame 7
//46 status mask 1
//47 status mask 256
//48 status mask 65536
//49 status mask 16777216
//frame 8
//52 compteur energie 1 wh
//53 compteur energie 256 wh
//54 compteur energie 65536 wh
//55 compteur energie 1 wh
//frame 9
//58 sw version 0.01
//59 sw version 2.56
//60
//61
//frame 10 a verifier -> ok
//64 Temp GFD 0.1
//65 temp GFD 2.56
//66 debit1 1 l/h
//67 debit1 256 l/h
// Each frame has 6 bytes
// byte 1 to 4 are data bytes -> MSB of each bytes
// byte 5 is a septet and contains MSB of bytes 1 to 4
// byte 6 is a checksum