Lettura contatore GSE con arduino

Sistemi elettronici di controllo e monitoraggio, Arduino, Rasberry ecc.

Moderatori: gasala50, FabioR

FabioR
Messaggi: 125
Iscritto il: ven set 30, 2011 8:11 am

Lettura contatore GSE con arduino

Messaggioda FabioR » lun nov 07, 2011 1:45 pm

Allora, dopo essermi cimentato con successo nel monitoraggio del mio impianto solare termico con arduino, e in previsione di una futura installazione di impianto FV, ho configurato un arduino per la lettura automatica dei dati di produzione.
Mi sono basato su questo progetto http://enerduino.blogspot.com/2009/12/enerduino-italiano.html
che però salva i dati solo su sd
Ho realizzato il tutto usando un arduino ethernet con modulo poe, in modo da poter alimentare arduino attraverso il solo cavo di rete
http://www.ebay.it/itm/ARDUINO-UNO-ETHERNET-con-modulo-PoE-con-microcontrollore-ATmega328-/330636290287?pt=Componenti_elettronici_attivi&hash=item4cfb7568ef
alimentatore poe http://www.ebay.it/itm/160549197582?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1439.l2649
Usando un cavo di rete da esterni a doppia guaina non dovrebbero esserci problemi di coesistenza con le linee a 220V
http://www.ebay.it/itm/170716227871?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1439.l2649

Questo è il codice di arduino

Codice: Seleziona tutto

/*

 Save Enel production SD card and mysql database
 Use NTP time provider to sync internal time
 Fabio Roverso 5/11/11
 V 1.0
 
 */

#include <SPI.h>
#include <Ethernet.h>
#include <Udp.h>
#include <SD.h>
#include <Time.h>
#include <MsTimer2.h>

//Network stuff
byte mac[] = {
  0x90, 0xA2, 0xDA, 0x00, 0x76, 0xBE }; //Arduino MAC address
byte ip[] = {
  192, 168, 1, 178 }; //Arduino IP address
byte gateway[] = {
  192, 168, 1, 250 }; //Network gateway
byte subnet[] = {
  255, 255, 255, 0 }; //Network subnet mask

//NTP stuff
byte timeServer[] = {
  192, 168, 1, 8 }; //NTP server address
unsigned int localPort = 8888; //local port to listen for UDP packets
const int NTP_PACKET_SIZE = 48; //NTP time stamp
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
const unsigned long timeZoneOffset = 3600; //set this to the offset in seconds to your local time;

//Web client stuff
byte server[] = {
  192 ,168 ,12 ,8 }; //Web server address
unsigned int port = 82; //Web server http port (usually 80)
Client client(server, port); //Creates an http client handle

//led stuff
const byte ledPin = 9;
const byte HalfLed = 0;
const byte FullLed = 10;

// Analog input for photoresistor
#define PHOTO_IN 0

int threshold=450; // If photoresistor read more than this value, it count a flash
long timer=60000; // Log file is written every minute
long flash=0;
boolean writeLog=false;
byte i = 0;

// On the Ethernet Shield, CS is pin 4. Note that even if it"s not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 4;
boolean SDpresent = false;

boolean blndebug=true;

void setup(){

  // sets the digital pin as output
  pinMode(ledPin, OUTPUT);

  // Setup for photoresistor
  pinMode(PHOTO_IN,INPUT);

  //start Ethernet and UDP
  Ethernet.begin(mac, ip, gateway, subnet);
  Udp.begin(localPort);

  //start serial
  Serial.begin(9600);

  if (blndebug) Serial.print("Initializing SD card...");
  //make sure that the default chip select pin is set to
  //output, even if you don"t use it:
  pinMode(10, OUTPUT);
  //see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)){
    if (blndebug){
      Serial.println();
      Serial.println("Card failed, or not present");
    }
    SDpresent = false;
  }
  else {
    if (blndebug) Serial.println("OK");
    SDpresent = true;
  }

  //Sync time and date
  setSyncProvider(getNtpTime);
  setSyncInterval(86400); //24h
  if (blndebug) Serial.println("Synching Clock...");
  while(timeStatus() == timeNotSet){
    if (i > 100){
      if (blndebug) Serial.println("Time not set");
      break;
    }
    i++;
    delay(10);
  }

  // Initialize timer
  MsTimer2::set(timer, flushCounter);
  MsTimer2::start();

  if (blndebug){
    Serial.println();
    digitalClockDisplay();
    Serial.println("Arduino started");
    Serial.println("================================");
  }

  analogWrite(ledPin, HalfLed);
  delay(50);
}

void loop(){

  // Read the photo sensor value
  if (analogRead(PHOTO_IN) > threshold){
    analogWrite(ledPin, FullLed);
    while (analogRead(PHOTO_IN) > threshold){
      // Just wait the flash to turn off (to avoid multiple counts)
      delay(10);
    }
    analogWrite(ledPin, HalfLed);
    flash++;
  }

  if (writeLog){
    WebClient(flash); //Save to db
    if(SDpresent){
      SDWrite(flash); //Save to SD
    }
    writeLog=false;
    flash=0;
  }
}

void WebClient(long conteggio){

  if (client.connect()){
    client.flush();
    client.print("GET ");
    client.print("/enel.php?user=username&password=password&data=");
    client.print(conteggio);
    client.println(" HTTP/1.0");
    client.println();
    while(!client.available()){
      delay(1);
    }
    while (client.available()){
      char c = client.read();
      if (blndebug) Serial.print(c);
    }
    if (blndebug) Serial.println();
  }
  else {
    if (blndebug) Serial.println("EXCEPTION: during HTTP GET. Could not connect");
    return;
  }
  while(client.connected()){
    if (blndebug) Serial.println("Waiting for server to disconnect");
  }
  client.stop();

}

void SDWrite(long conteggio){

  int digits;
  File dataFile = SD.open("enel.csv", FILE_WRITE); //define file handle
  //if the file is available, write to it:
  if (dataFile){

    if (blndebug) Serial.print("Writing to SD card...");

    dataFile.print(hour());
    dataFile.print(":");
    digits = minute();
    if (digits < 10) dataFile.print("0");
    dataFile.print(digits);
    dataFile.print(":");
    digits = second();
    if (digits < 10) dataFile.print("0");
    dataFile.print(digits);
    dataFile.print(" ");
    dataFile.print(day());
    dataFile.print("-");
    dataFile.print(month());
    dataFile.print("-");
    dataFile.print(year());
    dataFile.print(";");
    dataFile.println(conteggio);
    dataFile.close();
    if (blndebug) Serial.println("done");
  }
  else {
    if (blndebug) Serial.println("Error opening file.");
  }
}

// Routine executed by the timer interrupt. This flush the
// data to the log file
void flushCounter(void){
  if(flash>0) writeLog=true;
}

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print("0");
  Serial.print(digits);
}

/*******************************************************************************
 * Get NTP time function
 *******************************************************************************/
unsigned long getNtpTime(){
  sendNTPpacket(timeServer); //send an NTP packet to a time server
  delay(1000); //wait to see if a reply is available
  if (Udp.available()){
    Udp.readPacket(packetBuffer,NTP_PACKET_SIZE); //read the packet into the buffer

    //the timestamp starts at byte 40 of the received packet and is four bytes,
    //or two words, long. First, esxtract the two words:
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    //combine the four bytes (two words) into a long integer
    //this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;
    const unsigned long seventyYears = 2208988800UL - timeZoneOffset;
    //subtract seventy years:
    return secsSince1900 - seventyYears;
  }
  return 0; //return 0 if unable to get the time
}
/*******************************************************************************
 * send an NTP request to the time server at the given address
 *******************************************************************************/
unsigned long sendNTPpacket(byte *address){
  //set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  //Initialize values needed to form NTP request
  //(see URL above for details on the packets)
  packetBuffer[0] = 0b11100011; //LI, Version, Mode
  packetBuffer[1] = 0; //Stratum, or type of clock
  packetBuffer[2] = 6; //Polling Interval
  packetBuffer[3] = 0xEC; //Peer Clock Precision
  //8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12] = 49;
  packetBuffer[13] = 0x4E;
  packetBuffer[14] = 49;
  packetBuffer[15] = 52;

  //all NTP fields have been given values, now
  //you can send a packet requesting a timestamp:
  Udp.sendPacket(packetBuffer, NTP_PACKET_SIZE, address, 123); //NTP requests are to port 123
}


In pratica conta i lampeggi del contatore gse (1 ogni Wh) e una volta al minuto invia i dati al database, via rete, e, se presente, li salva su scheda SD.
Un led aggiuntivo riproduce i lampeggi letti dalla fotoresistenza per avere un feedback immediato del funzionamento.
L'ora viene presa e sincronizzata tramite server NTP (anche pubblico)

il file php sul web server

Codice: Seleziona tutto

<?php
//Connect to database
$con = mysql_connect("localhost", $_GET['user'], $_GET['password']);
if(!$con)
    {
    die('Could not connect: ' .mysql_error());
    }

//Select database
mysql_select_db("rotex", $con);

$Impulsi=$_GET['data'];
//Execute the insert query
$result = mysql_query("INSERT INTO FV (Impulsi) VALUES ($Impulsi)");

if (!$result) {
    die('Invalid query: ' . mysql_error());
}

mysql_close($con);

print "OK";
?>


La tabella sul db contiene solo due campi: un timestamp e un numerico per i conteggio degli impulsi

Avatar utente
fcattaneo
Site Admin
Messaggi: 1579
Iscritto il: mar nov 27, 2007 7:44 pm
Contatta:

Re: Lettura contatore GSE con arduino

Messaggioda fcattaneo » mer nov 09, 2011 6:23 am

FabioR ha scritto:
La tabella sul db contiene solo due campi: un timestamp e un numerico per i conteggio degli impulsi


Molto interessante perche potrebbe essere la base per x realizzare un contacalorie..

Gli impulsi come li memorizza ?
Come N. di impulsi in un dato periodo ( per es. impulsi al minuto ) o come periodo di tempo tra un impulso e il successivo ?

Questo e' importante perche uno rappresenta l'energia consumata ( conteggi ) e uno la potenza assorbita ( periodo ).

Ciao,
F.

FabioR
Messaggi: 125
Iscritto il: ven set 30, 2011 8:11 am

Re: Lettura contatore GSE con arduino

Messaggioda FabioR » mer nov 09, 2011 8:37 am

attualmente conta gli impulsi e scarica il dato ogni minuto, quindi sul db si hanno gli impulsi al minuto
ho preferito questo approccio per evitare che eventuali ritardi sulla rete sballassero i risultati.
in questo modo ho una query che calcola l'energia prodotta al minuto e deriva la potenza istantanea per quel minuto

Codice: Seleziona tutto

select date_format(`FV`.`Data`,'%d-%m-%Y %H:%i:00') AS `minuto`,
  (sum(`FV`.`Impulsi`) / 1000) AS `Energia`,
  ((sum(`FV`.`Impulsi`) / 1000) / (60 / 3600)) AS `Potenza`
from `FV`
group by year(`FV`.`Data`),
  month(`FV`.`Data`),
  dayofmonth(`FV`.`Data`),
  hour(`FV`.`Data`),
  minute(`FV`.`Data`)
order by year(`FV`.`Data`) desc,
  month(`FV`.`Data`) desc,
  dayofmonth(`FV`.`Data`) desc,
  hour(`FV`.`Data`) desc,
  minute(`FV`.`Data`) desc;

Avatar utente
fcattaneo
Site Admin
Messaggi: 1579
Iscritto il: mar nov 27, 2007 7:44 pm
Contatta:

Re: Lettura contatore GSE con arduino

Messaggioda fcattaneo » mer nov 09, 2011 5:19 pm

FabioR ha scritto:attualmente conta gli impulsi e scarica il dato ogni minuto, quindi sul db si hanno gli impulsi al minuto
ho preferito questo approccio per evitare che eventuali ritardi sulla rete sballassero i risultati.
in questo modo ho una query che calcola l'energia prodotta al minuto e deriva la potenza istantanea per quel minuto



Fammi capire..

Supponiamo che hai un consumo costante di 40 Watt.. avresti un impulso ogni 90 secondi.
Quindi nel DB avrai un record con conteggio 1 e uno con conteggio 0 e cosi via..

Tracciando un grafico avresti quindi un minuto con consumo di 60 watt e uno con consumo di 0 .

Ho capito bene ?

Ciao,
F.

Jekterm
Messaggi: 906
Iscritto il: gio mag 27, 2010 3:05 pm

Re: Lettura contatore GSE con arduino

Messaggioda Jekterm » mer nov 09, 2011 8:30 pm

Domanda:
perchè vai a contare i lampeggi al contatore quando puoi leggere, con strumenti dotati di uscita analogica, direttamente Volt e Ampere?
Hai la potenza istantanea senza aspettare i lampeggi del contatore...

Ciao

FabioR
Messaggi: 125
Iscritto il: ven set 30, 2011 8:11 am

Re: Lettura contatore GSE con arduino

Messaggioda FabioR » mar nov 22, 2011 9:55 am

Per ora ho lasciato le cose in sospeso
@fcattaneo
devo ancora ragionarci meglio, era una prova
certo che sarebbe più preciso calcolare una potenza media integrata su un tempo più lungo di quello di campionamento, ma vedrò in seguito come proseguire (per ora non ho ancora l'impianto installato)
@Jekterm
devo capire se posso e come interfacciamri con l'inverter, che sarà un solar edge
sul suo sito ho visto che ha un sistema di controllo molto bello che indica lo stato di ogni singolo pannello, ma deve vedere se posso anche estrarre i dati indipendentemente dal portale della solaredge (che mi sembra di aver capito diventa un servizio a pagamento dopo il primo anno).

Ho due figli in arrivo quindi il mio tempo libero è a termine e giò ora parecchio incostante :wink:

gborgo
Messaggi: 45
Iscritto il: mar set 07, 2010 8:07 am

Re: Lettura contatore GSE con arduino

Messaggioda gborgo » mar nov 22, 2011 5:55 pm

devo capire se posso e come interfacciamri con l'inverter, che sarà un solar edge
sul suo sito ho visto che ha un sistema di controllo molto bello che indica lo stato di ogni singolo pannello, ma deve vedere se posso anche estrarre i dati indipendentemente dal portale della solaredge (che mi sembra di aver capito diventa un servizio a pagamento dopo il primo anno).[/i]
Ho due figli in arrivo quindi il mio tempo libero è a termine e giò ora parecchio incostante


Ciao Fabio,
Io ho un SolarEdge, installato da circa un anno.
Ho trovato anch'io in rete commenti riguardo al fatto che il servizio di monitoraggio online di SolarEdge fosse gratis solo per 1-3 anni, ma l'unico riferimento esplicito al riguardo che ho trovato sul loro sito è nel documento di licenza d'uso del servizio, che dice solo che il servizio al momento è gratuito, "currently free of charge".

Stavo per scrivere -questa settimana- in Israele per chiedere lumi riguardo a come accedere ai dati che l'inverter manda automaticamente all'indirizzo IP del loro server.
Ti farò sapere cosa mi rispondono.
Ciao,

Giorgio

FabioR
Messaggi: 125
Iscritto il: ven set 30, 2011 8:11 am

Re: Lettura contatore GSE con arduino

Messaggioda FabioR » mer nov 23, 2011 8:20 am

gborgo ha scritto:...
Stavo per scrivere -questa settimana- in Israele per chiedere lumi riguardo a come accedere ai dati che l'inverter manda automaticamente all'indirizzo IP del loro server.
Ti farò sapere cosa mi rispondono.
Ciao,

Giorgio

interessante
forse nel giro di un paio di settimane ho l'impianto anche io, quindi posso cominciare a giocare un po' con l'inverter
Intanto predispongo un punto rete vicino all'inverter.
Se trovo il tempo potrei anche provare a sniffare un po' di traffico fra inveter e casa madre, per capire come comunica, ma non prometto niente (soprattutto se il traffico è cifrato).

FabioR
Messaggi: 125
Iscritto il: ven set 30, 2011 8:11 am

Re: Lettura contatore GSE con arduino

Messaggioda FabioR » mer nov 23, 2011 9:35 am

cercando in rete ho trovato questa discussione
http://forums.whirlpool.net.au/archive/1788256
le risposte da parte di solaredge non sono incoraggianti...

FabioR
Messaggi: 125
Iscritto il: ven set 30, 2011 8:11 am

Re: Lettura contatore GSE con arduino

Messaggioda FabioR » mer nov 23, 2011 3:49 pm

fcattaneo ha scritto:
FabioR ha scritto:attualmente conta gli impulsi e scarica il dato ogni minuto, quindi sul db si hanno gli impulsi al minuto
ho preferito questo approccio per evitare che eventuali ritardi sulla rete sballassero i risultati.
in questo modo ho una query che calcola l'energia prodotta al minuto e deriva la potenza istantanea per quel minuto



Fammi capire..

Supponiamo che hai un consumo costante di 40 Watt.. avresti un impulso ogni 90 secondi.
Quindi nel DB avrai un record con conteggio 1 e uno con conteggio 0 e cosi via..

Tracciando un grafico avresti quindi un minuto con consumo di 60 watt e uno con consumo di 0 .

Ho capito bene ?

Ciao,
F.



sto pensando che potrei far calcore ad arduino i millisecondi fra un lampeggio e l'altro, facendoli calcolare la potenza istantanea ad ogni lampeggio
poi integro il dato facendo la media sul minuto e lo scrivo su db
in questo modo avrei la potenza media al minuto in modo più preciso, e come risoluzione temporale mi basterebbe per i miei scopi

gborgo
Messaggi: 45
Iscritto il: mar set 07, 2010 8:07 am

Re: Lettura contatore GSE con arduino

Messaggioda gborgo » gio nov 24, 2011 6:17 pm

FabioR ha scritto:cercando in rete ho trovato questa discussione
http://forums.whirlpool.net.au/archive/1788256
le risposte da parte di solaredge non sono incoraggianti...


Ciao Fabio,

Si, avevo visto anch'io questo post.

La prima risposta del supporto technico di primo livello di SolarEdge è stata ignorare la mia domanda di accedere ai dati di produzione del mio inverter, mettendo invece il mio impianto accessibile a tutti sul loro sito :?

Ho scritto ancora :) , chiedendo di nuovo indicazioni su come leggere i dati di produzione del mio impianto localmente.

Vedremo se riuscirò a convincerli.
Intanto, se qualcuno vuole dare un'occhiata al mio impianto sul loro web portal:
1) http://www.solaredge.com
2) in alto nella pagina di ingresso, fare click su: Monitoring Login
3) nella finestra di log-in che si apre, in basso a sinistra selezionare: Public sites
4) il mio impianto è "GBORGO's"

Ciao,

Giorgio

FabioR
Messaggi: 125
Iscritto il: ven set 30, 2011 8:11 am

Re: Lettura contatore GSE con arduino

Messaggioda FabioR » ven nov 25, 2011 1:09 pm

non sembra andare l'apostrofo nel nome

il portale è interessante, per tenere sotto controllo l'impianto

Diciamo che per me, che sono un addetto ai lavori, mandare i miei dati a Tel Aviv per poter monitorare il mio impianto mi fa storcere un po' il naso. Inoltre anche se posso generare report, non riesco ad ottenere i dati in tempo reale in forma usabile.

Mi sa che userò comunque arduino sul contatore GSE usando un dato di potenza media sui 5 minuti, per pilotare l'accensione del clima/pompa di calore

Ho gli installatori sul tetto adesso :mrgreen:

Jekterm
Messaggi: 906
Iscritto il: gio mag 27, 2010 3:05 pm

Re: Lettura contatore GSE con arduino

Messaggioda Jekterm » sab nov 26, 2011 2:03 pm

FabioR ha scritto:Mi sa che userò comunque arduino sul contatore GSE usando un dato di potenza media sui 5 minuti, per pilotare l'accensione del clima/pompa di calore


Ma perchè non usi un amperometro e un volmetro con uscita analogica?
Leggi le analogiche e ti trovi la potenza istantanea disponibile

Ciao

FabioR
Messaggi: 125
Iscritto il: ven set 30, 2011 8:11 am

Re: Lettura contatore GSE con arduino

Messaggioda FabioR » mer dic 07, 2011 1:45 pm

Stavo guardando questo progetto
http://openenergymonitor.org/emon/node/58
e ho anche visto questo bel prodotto
http://www.diykyoto.com/uk/aboutus/wattson-renewables

stavo pensando di unire le due cose e farmelo da me.
In pratica arduino legge la corrente sulla fase che arriva dall'inverter e dal contatore GSE e ottiene la potenza istantanea di produzione
Poi legge la corrente sulla fase fra il parallelo Enel e il generale di casa mia e ottiene la potenza istantanea consumata
Dalla differenza ottengo la potenza consumata (o inviata) a enel, quindi un numero con segno positivo o negativo a seconda del verso.

Su un display lcd seriale indico i numeri raw.
Inoltre integro i dati per un minuto, facendo la media, e li invio con quella cadenza al database, per il logging.
Infine piloto una barra led, messa nel centralino al piano principale, in modo che dia un'indicazione immediata della situazione:

led tutto verde -> produco 3kW e non consumo nulla
led giallo -> autoconsumo tutto il prodotto, o non consumo e non produco nulla
led tutto rosso -> consumo 3kW, oppure produco 3kW ma ne consumo 6 e quindi sono al limite del distacco.

FabioR
Messaggi: 125
Iscritto il: ven set 30, 2011 8:11 am

Re: Lettura contatore GSE con arduino

Messaggioda FabioR » lun dic 12, 2011 9:34 am

penso di utilizzare questa barra da 30 led, controllabile in seriale in modo da passare un semplice cavetto dal locale tecnico al centralino al piano terra, dove integrerò il pannellino
Immagine

L'idea è di accendere sempre 3 led, in modo da avere una scala decimale che va da +3kW a -3kW
Nel caso ci sia più di 3kW di prelievo da enel farei anche lampeggiare i led rossi

Stavo anche pensando di alimentare arduino tramite un semplice trasformatore toroidale, in modo da poter campionare anche la tensione per calcolare la potenza in modo più preciso.
Purtroppo non riesco a discriminare fra potenza attiva e reattiva, quindi dovrò impostare un cosfi medio per avere almeno una indicazione qualitativa della potenza (che è il mio scopo)
La barra colorata dovrebbe servire a capire a colpo d'occhio il bilancio energetico, in modo da capire se è possibile accendere altri elettrodomestici


Torna a “Domotica, monitoraggio e controllo.”



Chi c’è in linea

Visitano il forum: Nessuno e 3 ospiti