Monitoring d'une installation solaire photovoltaique

Bonjour,

j'ai pour projet de monitorer mon installation solaire, un peu dans le style de David Mercereau (Résultats de recherche pour « pvmonit » – David Mercereau) dont je me suis largement inspiré.
Je pars de la uno et de son atmega328p (mais sera t-elle suffisante ?) pour y connecter un capteur de température ds1820b, un capteur de gaz mq8 (H2), 2 capteurs de courant sct-013-030, un module rtc ds1307.
Les capteurs de température et de gaz enclencheront un ventilateur 12 V via un relais bistable ; un second relais pourra éventuellement démarrer un groupe électrogène (à l'étude).
Pour l'instant ce qui précède est déjà opérationnel sur une breadboard.
J'ai prévu deux shields maison : l'un pour les capteurs de courants, le capteur de température, le module rtc et le capteur MQ8, l'autre pour l'alimentation 12V DC et les relais.

Là où je pense coincer, c'est que je veux récupérer les données VE-direct (RS232) des appareils Victron, 3 en tout : un régulateur de charge MPPT, un onduleur et un module BMV 700.
Ces données ainsi que la consommation de courant, je veux les envoyer sur un site web. Il me faut donc un shield ethernet mais aussi un shield usb host pour récupérer les données Victron via un hub usb, car l'autre possibilité directement par RS232 demanderait autant de connexions série (Rxd,Txd) que d'appareils Victron, me trompe-je ?

Le shield ethernet et le shield USB Host utilisent tous les deux le même bus SPI. Voilà le problème. Alors faut-il 2 cartes Arduino ? Quelle solution ?
Merci de votre aide

Bonjour,
Je ne peux répondre qu’à la dernière question sur le SPI.
La réponse est évidente pour peu que tu te renseignes sur le bus SPI.
La documentation est abondante pour peu qu’on la recherche et sera mieux présentée qu’il ne sera possible de le faire sur ce forum.

Désolé d’être aussi raide mais quand je veux utiliser un nouveau bus je commence toujours par faire des recherches personnelles avant. Si je ne comprends pas certains points cela me permet de poser des questions précises et d’être plus efficace.

Pour le reste du message ne prend pas de DS1307 mais une DS3231 qui coûte le même prix et est bien plus précise.

Les règles de fonctionnement du forum demandent que des liens vers le matériel soient fournis.
Les capteurs de courant sct-013-30 je ne sais pas ce que c’est, pour te répondre il faudrait que je fasse des recherches, désolé mais je n’en ferai pas c’est à toi de fournir un lien cliquable de préférence → icone “chaine”.
Idem pour le Victron et autres.

Dis toi bien que tu n’es pas tout seul et que nous sommes des bénévoles qui avons d’autres activités.

A bientôt avec des précisions sur ton projet.

Vraiment désolé pour ma mauvaise présentation.

Déjà un lien cliquable vers la page de David Mercereau : Résultats de recherche pour « pvmonit » – David Mercereau

Ensuite, pour ce qui est des capteurs de courants, j'ai regardé du coté de Openenergymonitor : Learn | OpenEnergyMonitor

Les appareils Victron communiquent par le protocole RS232 (pas besoin d'expliquer ce que c'est, je pense), donc des câbles style FTDI et un hub usb conviendront.

Pour le module RTC DS1307, je n'ai que celui-ci et je n'ai pas vraiment besoin de plus de précision que ça, c'est juste pour avoir un repère temporel pour les mesures, un datalogger en fait.

Quant aux bus SPI, j'avoue que je n'avais pas vraiment cherché, étant "figé" par la configuration du port ICSP des cartes. Donc, il me faut un port avec autant de connexions SS que d'esclaves; soit dans mon cas : SCLK, MISO, MOSI, SS1, SS2. Et assigner SS1 et SS2 à des digital pins libres, par exemple Digital Pin 3 et Digital pin 10.
Est-ce cela ?

Donc, il me faut un port avec autant de connexions SS que d'esclaves; soit dans mon cas : SCLK, MISO, MOSI, SS1, SS2. Et assigner SS1 et SS2 à des digital pins libres, par exemple Digital Pin 3 et Digital pin 10.
Est-ce cela ?

Oui.

Victron et bus RS232.
Au cas où j'apporte une remarque.
De quel RS232 parles tu ? Il y a déjà eu de grosses confusions qui ont fait des dégâts.
Le vrai RS232 délivre des signaux pouvant être compris entre -18V et +18 V. Si tu applique ça sur une entrée de microcontrôleur ça fume instantanément.
Souvent, par abus de langage, on parle de rs232 pour le protocole mais en fait les signaux sont 0/+5V.
En sortie du Victron c'est quoi ?

Capteur de courant :
Pour le choisir il faut déjà définir la gamme de courant à mesurer.
Tu as deux limites :
Le courant max, il ne faut pas que le capteur sature.
Dans l'autre sens c'est moins évident. Tous les composants électroniques produisent du bruit électrique. Pour faire une mesure fiable il faut que le signal à mesurer soit grand devant le bruit sinon on ne sait pas si on mesure le signal ou si on mesure le bruit.

Une fois que tu as fixé des bornes "raisonnables" tu peux choisir un capteur.
Le courant est-il mesuré en sortie des panneaux solaire (courant continu) ou en sortie de l'onduleur (courant alternatif) ?

Pour la récupération sur un site Web je passe la main.

RS232 en 5V pour le régulateur de charge MPPT et l’onduleur et 3,3V pour le BMV700.

Pour les capteurs de courant, 30A suffisent largement, j’aurais pu prendre plus léger encore. C’est entre l’onduleur et le tableau de répartition et derrière le tableau, en 230V AC.

Mais tout ça fonctionne déjà bien sur la breadboard. C’est surtout la récupération des données Victron qui me posaient question et leur envoi sur un site web.

Salut

Si les sorties RS232 des appareils Victron sont en 5V ou 3.3V pourquoi ne pas les utiliser sans passer par de l'USB ?
Un ARDUINO MEGA possède plusieurs interfaces série.

Entre le traitement des capteurs de courant, qui sont des transformateurs de courant alternatifs, donc à raccorder sur des entrées analogiques, et le traitement des entrées série, plus l'envoi des données sur ethernet, j'aurais une crainte quant à la capacité d'un ATMEGA à traiter tout cela, y compris ARDUINO MEGA.

Personnellement, je suis producteur (revente EDF) et je fais le monitoring de mes 2 compteurs EDF avec une RAPBERRY PI.
Tout est sur la RASPBERRY PI : logiciel de récupération de données, base de données SQLITE, serveur WEB.
Une RASPBERRY PI 1B, pas besoin de plus.
La liaison ethernet ne sert qu'à la consultation.
Il me semble qu'une RASPBERRY, avec un logiciel multi-tâche sera certainement plus à même de mener à bien ce projet.

J'avais étudié la possibilité de produire une partie de mon énergie avec du stockage sur batterie l'année dernière.
A moins qu'il s'agisse d'un site isolé, le jeu n'en vaut pas la chandelle, du simple fait du prix des batteries cycliques et de leur durée de vie.

@+

Bonjour,

Justement, de rester en RS232 occuperait 3 interfaces série et même une Mega n'a que 2 interfaces série.

il semble qu'un atmega328 suffise car il y a 13 pins occupés :

MQ8 ==> A3

DS18B20 ==> D2

CT-Sensors ==> A0, A1

DS1307 ==> A5, A4

Relays ==> D5,D6

Ethernet shield ==> D13, D12, D11, D10

USB Host shield ==> D13, D12, D11, D3

En attendant, j'ai un raspberry qui tourne, sur la base du système de David Mercereau, avec un capteur de courant et la récolte de données du régulateur de charge solaire MPPT. Ça fonctionne à peu près correctement, sauf que le capteur de courant bégaye parfois sans explication. Il faut aussi prendre en compte la fréquence d'écriture sur la carte SD et son usure prématurée.
J'avais plutôt dans l'idée d'un système fait maison et réparable (sauf le shield USB host, mais je pourrais en faire un plus tard) et plus rustique que le raspberry qui de toute manière demandera de rajouter une ou des cartes supplémentaires pour brancher les capteurs.

Je suis en site isolé et c'est bien pour cela que je me donne cette peine pour mettre en place un système fiable de gestion de ma nouvelle installation photovoltaique, après avoir perdu plusieurs batteries par le passé et veillé pas mal de soirées à la bougie.

Salut

Il faut aussi prendre en compte la fréquence d'écriture sur la carte SD et son usure prématurée.

Ne pas hésiter à choisir de la SD de marque, et même industrielle.

Ces SD supportent jusqu'à 192 TBW (terra bytes écrits).

Justement, de rester en RS232 occuperait 3 interfaces série et même une Mega n'a que 2 interfaces série.

Il me semble que c'est plutôt 3

Mais encore une fois, un processeur à 16MHz aura du mal à surveiller 3 lignes série et interpréter les données, 2 capteurs de courant analogiques, calculer le courant efficace, récolter la température, etc.
Si ça bégaye déjà avec une RASPBERRY PI ...
A essayer toutefois.

Comment fais-tu actuellement pour lire les transformateurs de courant, la RASPBERRY PI n'ayant pas de GPIO analogiques il me semble ?

Autre solution : partager le travail.
Confier la partie analogique et température à un ARDUINO UNO ou NANO, relié par USB à la RASPBERRY PI.
La RASPBERRY PI se contenterait de récolter les données provenant des appareils Victron et de l'ARDUINO sur ses ports USB.
Avantage : tu conserves une bonne partie de ton hardware et de ton code.
Autre avantage : plus besoin de module RTC.

Ces données ainsi que la consommation de courant, je veux les envoyer sur un site web.

Un site interne à l'habitation ou externe ?
Dommage, la RASPBERRY PI peut héberger un serveur WEB pour quelques euros de consommation par an.

@+

Désolé @hbachetti, de ne t’avoir pas remercié de ta réponse aussitôt.

Une petite mise à jour concernant mon projet :

J’ai réalisé un shield équivalent à l’EmonTX d’openEnergyMonitor regroupant les 8 capteurs cités dans le premier message de ce fil et les 2 relais. 2 régulateurs de tension 5 V alimentent la carte, un spécialement pour le capteur de gaz MQ-8 et l’autre pour le reste dshield. Les relais sortent du 12 V.

Cette carte est en sandwich entre une Mega et un shield Ethernet/SD.

Il y a 3 câbles pour récupérer les données des appareils Victron avec connecteurs JST à chaque extrémités, le câble du BMV 700 étant relié à un convertisseur TTL 3,3V/5V.

Le code fonctionne bien pour la réception des données, leur traitement et l’envoi par requête HTTP format JSON sur mon site EMONCMS.
N’ayant pas de connexion internet permanente pour des raison d’économie d’électricité, les données sont stockées sur une carte SD en attendant la reconnexion.
Mon problème du moment est d’envoyer toutes les données inscrites dans un fichier sur la carte SD via client.print().
Elles passent par une chaîne String en mémoire vive avant l’envoi.
J’ai constaté sur Wireshark, le sniffeur de paquets ethernet, que client.print() n’envoie que la première requête alors qu’un Serial.print() de la chaîne affiche bien tout le contenu du fichier. J’ai horodaté les requêtes en temps Unix.

Comment faire lire toute la chaîne à client.print() ? Comment afficher en temps réel ce que client.print() envoie vraiment?
Ou bien me faut-il passer par de multiples fichiers contenant une seule requête par fichier ? Et donc une boucle d’écriture puis de lecture.

Ci-joint le code de test pour la lecture sur la carte et l’envoi des données sur mon serveur.

#include <Arduino.h>
#include "SdFat.h"
#include <SPI.h>
#include <RTClib.h>
#include <Wire.h>
#include <Ethernet.h>

RTC_DS1307 rtc;
SdFat sd;
File logFile;

const uint8_t chipSelect = 4;
const char fileName[] = "datalog.txt";

// Error messages stored in flash.
#define error(msg) sd.errorHalt(F(msg))


// this must be unique
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x59, 0x67 };

// change to your network settings
byte ip[] = { 192, 168, 5, 53 };
byte gateway[] = { 192, 168, 5, 1 };
byte subnet[] = { 255, 255, 255, 0 };

char server[] = "192.168.5.50";

EthernetClient client;


String apikey = "aaaaabbbbbbccccccddddddddeeeee";  //localhost api key

unsigned long lastConnectionTime = 0;          // last time you connected to the server, in milliseconds
boolean lastConnected = false;                 // state of the connection last time through the main loop
const unsigned long postingInterval = 10 * 1000; // delay between updates, in milliseconds

//============================================================

int value1[17] = {25341, 440, 5879, 222478, 15, 48, 65, 95, 99, 75, 32, 147, 258, 963, 5789, 11, 28};
int value2[11] = {25341, 440, 5879, 222478, 15, 48, 65, 95, 99, 75, 32};

//=============================================================
void dateTime(uint16_t* date, uint16_t* time) {

  DateTime now = rtc.now();

  // return date using FAT_DATE macro to format fields
  *date = FAT_DATE(now.year(), now.month(), now.day());

  // return time using FAT_TIME macro to format fields
  *time = FAT_TIME(now.hour(), now.minute(), now.second());
}

//============================================================
void writeSD() {

  DateTime now = rtc.now();
  unsigned long currentTime = now.unixtime();

  SdFile::dateTimeCallback(dateTime);
  if (!logFile.open(fileName, O_CREAT | O_APPEND | O_WRITE )) {
    error("write_logFile.open");
  }

  logFile.print("GET /emoncms/input/bulk?data=[[");

   //(...)

  logFile.print(value1[12]);
  logFile.print("},{\"H22\":");
  logFile.print(value1[13]);
  logFile.print("},{\"H23\":");
  logFile.print(value1[14]);
  logFile.print("},{\"HSDS\":");
  logFile.print(value1[15]);
  logFile.print("}],[36,5,{\"MODE\":");

  //(...)

    logFile.print("},{\"H12\":");
    logFile.print(value3[24]);
    logFile.print("},{\"H17\":");
    logFile.print(value3[25]);
    logFile.print("},{\"H18\":");
    logFile.print(value3[26]); */
  logFile.print("}]]&time=");
  logFile.print(currentTime - 7200);
  logFile.print("&apikey=");
  logFile.println(apikey);
  logFile.println("HTTP/1.1");
  logFile.println("Host:localhost");
  logFile.println("User-Agent: Arduino-ethernet");
  logFile.println("Connection: close");
  logFile.println();
  // Force data to SD and update the directory entry to avoid data loss.
  if (!logFile.sync() || logFile.getWriteError()) {
    error("logFile write error");
  }
  logFile.close();
  Serial.println(F("Data writed"));
}
//============================================================
void readSD() {

  if (!logFile.open(fileName, O_READ)) {
    error("read_logFile.open");
  }
  if (logFile.available()) {
    while (logFile.position() < logFile.size()) {
      String dataBuff = logFile.readStringUntil('\0');
      client.print(dataBuff);
      //client.println();
      //debug
      //Serial.println(dataBuff);
    }
  }
  else {
    Serial.println(F("Nothing to send from SD card"));
  }

  logFile.close();
}

//============================================================
void fileTruncate() {
  
  if (!logFile.open(fileName, O_WRITE)) {
    error("trunc_file.open");
  }
  if (logFile.size() > 0) {
    if (!logFile.truncate(0) == 0) {
      Serial.println(F("Effacement OK"));
    }
    else {
      error("echec effacement");
    }
  }

  logFile.close();
}

//============================================================
void sendData() {

  DateTime now = rtc.now();
  unsigned long currentTime = now.unixtime();
  //Serial.println(currentTime);

  client.print("GET /emoncms/input/bulk?data=[[");
  client.print("32,4"); // node MPPT-150_35
  client.print(",{\"V\":");
  client.print(value1[3]);

      //(....)

  client.print("},{\"AR\":");
  client.print(value2[8]);
  client.print("},{\"WARN\":");
  client.print(value2[9]);
  client.print("}]]&time=");
  client.print(currentTime - 7200);
  client.print("&apikey=");
  client.print(apikey);
  client.println(" HTTP/1.1");
  //client.println("Host:genatfab.ovh");
  client.println("Host:localhost");
  client.println("User-Agent: Arduino-ethernet");
  client.println("Connection: close");
  client.println();
}

//============================================================
void doHTTP() {

  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  if (!client.connected() && (lastConnected && (millis() - lastConnectionTime >= (postingInterval + 5000)))) {
    Serial.println(F("\r\n"));
    Serial.println(F("Disconnecting..."));
    client.stop();
  }

  if (!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    if (client.connect(server, 80)) {
      Serial.println(F("\r\n"));
      Serial.println(F("Connected"));
      //readSD();
      sendData();
      //fileTruncate();
      lastConnectionTime = millis();
    }

    // if the server's disconnected more than 2 min, stop the client and write data on sd card:
    if (!client.connected() && (millis() - (lastConnectionTime >=  (postingInterval * 12)))) {
      Serial.print(F("\r\n"));
      Serial.println(F("disconnecting from server."));
      client.stop();
      writeSD();
      Serial.println(F("Writing on SD card"));
      Serial.println(F("\r\n"));
      delay(30000);
    }
  }
  lastConnected = client.connected();
}
//============================================================
void setup() {
  Serial.begin(115200);

  // Mega
  pinMode(53, OUTPUT);
  // disable w5100 SPI while setting up SD
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  // enable SD SPI
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);

  rtc.begin();

  if (! rtc.isrunning()) {
    Serial.println("RTC ne fonctionne PAS!");
    // La ligne qui suit ajuste le RTC à la date et time du moment de compilation
    rtc.adjust(DateTime(__DATE__, __TIME__));
  }

  if (!sd.begin(chipSelect, SD_SCK_MHZ(50)))
  {
    sd.initErrorHalt();
  }

  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  digitalWrite(10, HIGH);

  Serial.println(Ethernet.localIP());

  //readSD();
  //fileTruncate();
  //writeSD();

}
//============================================================
void loop() {
  doHTTP();
}

Emoncms_SD_test.ino (9.74 KB)

le code corrigé avec une boucle d’écriture et de lecture lecture de la carte sd

#include <Arduino.h>
#include "SdFat.h"
#include <SPI.h>
#include <RTClib.h>
#include <Wire.h>
#include <Ethernet.h>

RTC_DS1307 rtc;

const uint8_t chipSelect = 4;
SdFat sd;

#define FILE_BASE_NAME "Data"

// Error messages stored in flash.
#define error(msg) sd.errorHalt(F(msg))


// this must be unique
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x59, 0x67 };

// change to your network settings
byte ip[] = { 192, 168, 5, 53 };
byte gateway[] = { 192, 168, 5, 1 };
byte subnet[] = { 255, 255, 255, 0 };

char server[] = "192.168.5.51";

EthernetClient client;


String apikey = "8bbd25e3b62b4245fea52c4534637ea8";  //localhost api key

unsigned long lastConnectionTime = 0;          // last time you connected to the server, in milliseconds
boolean lastConnected = false;                 // state of the connection last time through the main loop
const unsigned long postingInterval = 10 * 1000; // delay between updates, in milliseconds

//============================================================

int value1[17] = {25341, 440, 5879, 222478, 15, 48, 65, 95, 99, 75, 32, 147, 258, 963, 5789, 11, 28};
int value2[11] = {25341, 440, 5879, 222478, 15, 48, 65, 95, 99, 75, 32};

//=============================================================
void dateTime(uint16_t* date, uint16_t* time) {

  DateTime now = rtc.now();

  // return date using FAT_DATE macro to format fields
  *date = FAT_DATE(now.year(), now.month(), now.day());

  // return time using FAT_TIME macro to format fields
  *time = FAT_TIME(now.hour(), now.minute(), now.second());
}

//============================================================
void readSD() {

  File logFile;
  char fileName;
  sd.ls();

  sd.vwd()->rewind();
  while (logFile.openNext(sd.vwd(), O_READ | O_WRITE)) {
    String dataBuff = logFile.readStringUntil('\0');
    client.print(dataBuff);
    client.println(" HTTP/1.1");
    //client.println("Host:genatfab.ovh");
    client.println("Host:localhost");
    client.println("User-Agent: Arduino-ethernet");
    client.println("Connection: close");
    client.println();
    //delay(10000);
    //Serial.println(dataBuff);
    if (!logFile.remove()) Serial.println(F("Error logFile.remove"));
  }

  if (!sd.exists(fileName)) {
    Serial.println(F("Nothing to send from SD card"));
  }
}

//============================================================
void sendData() {

  DateTime now = rtc.now();
  unsigned long currentTime = now.unixtime();
  //Serial.println(currentTime);

  client.print("GET /emoncms/input/bulk?data=[[");
  client.print("32,4"); // node MPPT-150_35
  client.print(",{\"V\":");
  client.print(value1[3]);
  client.print("},{\"I\":");
  client.print(value1[4]);
  client.print("},{\"VPV\":");
  client.print(value1[5]);
  client.print("},{\"PPV\":");
  client.print(value1[6]);
  client.print("},{\"CS\":");
  client.print(value1[7]);
  client.print("},{\"ERR\":");
  client.print(value1[8]);
  client.print("},{\"H19\":");
  client.print(value1[10]);
  client.print("},{\"H20\":");
  client.print(value1[11]);
  client.print("},{\"H21\":");
  client.print(value1[12]);
  client.print("},{\"H22\":");
  client.print(value1[13]);
  client.print("},{\"H23\":");
  client.print(value1[14]);
  client.print("},{\"HSDS\":");
  client.print(value1[15]);
  client.print("}],[");
  client.print("34,5"); // node Inverter_24V_500VA
  client.print(",{\"MODE\":");
  client.print(value2[3]);
  client.print("},{\"CS\":");
  client.print(value2[4]);
  client.print("},{\"AC_OUT_V\":");
  client.print(value2[5]);
  client.print("},{\"AC_OUT_I\":");
  client.print(value2[6]);
  client.print("},{\"V\":");
  client.print(value2[7]);
  client.print("},{\"AR\":");
  client.print(value2[8]);
  client.print("},{\"WARN\":");
  client.print(value2[9]);
  client.print("}]]&time=");
  client.print(currentTime - 7200);
  client.print("&apikey=");
  client.print(apikey);
  client.println(" HTTP/1.1");
  //client.println("Host:genatfab.ovh");
  client.println("Host:localhost");
  client.println("User-Agent: Arduino-ethernet");
  client.println("Connection: close");
  client.println();
}
//============================================================
void writeSD() {

  File logFile;
  char fileName[13] = FILE_BASE_NAME "0000";
  const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1; //taille en octet de nom fichier -1

  // Find an unused file name.
  if (BASE_NAME_SIZE > 8) {
    error("FILE_BASE_NAME too long");
  }
  while (sd.exists(fileName)) {
    if (fileName[BASE_NAME_SIZE + 3] != '9') {
      fileName[BASE_NAME_SIZE + 3]++;
    } else if (fileName[BASE_NAME_SIZE + 2] != '9') {
      fileName[BASE_NAME_SIZE + 3] = '0';
      fileName[BASE_NAME_SIZE + 2]++;
    } else if (fileName[BASE_NAME_SIZE + 1] != '9') {
      fileName[BASE_NAME_SIZE + 2] = '0';
      fileName[BASE_NAME_SIZE + 1]++;
    } else if (fileName[BASE_NAME_SIZE] != '9') {
      fileName[BASE_NAME_SIZE + 1] = '0';
      fileName[BASE_NAME_SIZE]++;
    } else {
      error("Can't create file name");
    }
  }


  DateTime now = rtc.now();
  unsigned long currentTime = now.unixtime();

  SdFile::dateTimeCallback(dateTime);
  if (!logFile.open(fileName, O_CREAT | O_WRITE | O_EXCL )) {
    error("write_logFile.open");
  }

  logFile.print("GET /emoncms/input/bulk?data=[[");
  /*logFile.print("34,0,{\"temp\":");
    logFile.print(temperature);
    logFile.print("}],[34,1,{\"H2\":");
    logFile.print(MQGetGasPercentage(MQRead(MQ_PIN\) / Ro, GAS_H2));
    logFile.print("}],[34,2,{\"power1\":");
    logFile.print(Irms1 * volt);
    logFile.print("}],[34,3,{\"power2\":");
    logFile.print(Irms2 * volt);
    logFile.print("}],[");*/
  logFile.print("34,4,{\"V\":");
  logFile.print(value1[3]);
  logFile.print("},{\"I\":");
  logFile.print(value1[4]);
  logFile.print("},{\"VPV\":");
  logFile.print(value1[5]);
  logFile.print("},{\"PPV\":");
  logFile.print(value1[6]);
  logFile.print("},{\"CS\":");
  logFile.print(value1[7]);
  logFile.print("},{\"ERR\":");
  logFile.print(value1[8]);
  logFile.print("},{\"H19\":");
  logFile.print(value1[10]);
  logFile.print("},{\"H20\":");
  logFile.print(value1[11]);
  logFile.print("},{\"H21\":");
  logFile.print(value1[12]);
  logFile.print("},{\"H22\":");
  logFile.print(value1[13]);
  logFile.print("},{\"H23\":");
  logFile.print(value1[14]);
  logFile.print("},{\"HSDS\":");
  logFile.print(value1[15]);
  logFile.print("}],[36,5,{\"MODE\":");
  logFile.print(value2[3]);
  logFile.print("},{\"CS\":");
  logFile.print(value2[4]);
  logFile.print("},{\"AC_OUT_V\":");
  logFile.print(value2[5]);
  logFile.print("},{\"AC_OUT_I\":");
  logFile.print(value2[6]);
  logFile.print("},{\"V\":");
  logFile.print(value2[7]);
  logFile.print("},{\"AR\":");
  logFile.print(value2[8]);
  logFile.print("},{\"WARN\":");
  logFile.print(value2[9]);
  /*logFile.print("}],[34,6,{\"V\":");
    logFile.print(value3[1]);
    logFile.print("},{\"I\":");
    logFile.print(value3[2]);
    logFile.print("},{\"P\":");
    logFile.print(value3[3]);
    logFile.print("}, {\"CE\":");
    logFile.print(value3[4]);
    logFile.print("},{\"SOC\":");
    logFile.print(value3[5]);
    logFile.print("},{\"TTG\":");
    logFile.print(value3[6]);
    logFile.print("},{\"AR\":");
    logFile.print(value3[9]);
    logFile.print("},{\"BMV\":");
    logFile.print(value3[10]);
    logFile.print("},{\"H1\":");
    logFile.print(value3[13]);
    logFile.print("},{\"H2\":");
    logFile.print(value3[14]);
    logFile.print("},{\"H3\":");
    logFile.print(value3[15]);
    logFile.print("},{\"H4\":");
    logFile.print(value3[16]);
    logFile.print("},{\"H5\":");
    logFile.print(value3[17]);
    logFile.print("},{\"H6\":");
    logFile.print(value3[18]);
    logFile.print("},{\"H7\":");
    logFile.print(value3[19]);
    logFile.print("},{\"H8\":");
    logFile.print(value3[20]);
    logFile.print("},{\"H9\":");
    logFile.print(value3[21]);
    logFile.print("},{\"H10\":");
    logFile.print(value3[22]);
    logFile.print("},{\"H11\":");
    logFile.print(value3[23]);
    logFile.print("},{\"H12\":");
    logFile.print(value3[24]);
    logFile.print("},{\"H17\":");
    logFile.print(value3[25]);
    logFile.print("},{\"H18\":");
    logFile.print(value3[26]); */
  logFile.print("}]]&time=");
  logFile.print(currentTime - 7200);
  logFile.print("&apikey=");
  logFile.println(apikey);

  // Force data to SD and update the directory entry to avoid data loss.
  if (!logFile.sync() || logFile.getWriteError()) {
    error("logFile write error");
  }
  logFile.close();
  Serial.print(F("Writing "));
  Serial.print(fileName);
  Serial.println(F(" on SD card"));

  Serial.print(F("\r\n"));
}

//============================================================
void doHTTP() {

  if (!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    if (client.connect(server, 80)) {
      Serial.print(F("\r\n"));
      Serial.println(F("Connected"));
      readSD();
      //sendData();
      lastConnectionTime = millis();
    }
    lastConnected = client.connected();
  }
  
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  if (!client.connected() && lastConnected) {
    Serial.println(F("\r\n"));
    Serial.println(F("Disconnecting..."));
    client.stop();
  }
  // if the server's disconnected more than 2 min, stop the client and write data on sd card:
  if (!client.connected() && (millis() - lastConnectionTime >=  postingInterval * 12)) {
    Serial.println(F("disconnecting from server more than 2 min."));
    client.stop();
    writeSD();
    //delay(30000);
    delay(3000);
  }
}
//============================================================
void setup() {
  Serial.begin(115200);

  // Mega
  pinMode(53, OUTPUT);
  // disable w5100 SPI while setting up SD
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  // enable SD SPI
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);

  rtc.begin();

  if (! rtc.isrunning()) {
    Serial.println("RTC ne fonctionne PAS!");
    // La ligne qui suit ajuste le RTC à la date et time du moment de compilation
    rtc.adjust(DateTime(__DATE__, __TIME__));
  }

  if (!sd.begin(chipSelect, SPI_FULL_SPEED))
  {
    sd.initErrorHalt();
  }

  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  digitalWrite(10, HIGH);
  delay(2000);

  Serial.println(Ethernet.localIP());

  //readSD();
  //writeSD();

}
//============================================================
void loop() {
  doHTTP();
}