Problema sketch monitoraggio contatore Enel e fotovoltaico

Volevo chiedere aiuto per integrare lo sketch di un progetto che fa il monitoreggio della produzione di un impianto fotovoltaico. Fin qui ci son riuscito senza nessun problema. Vado a contare gli impulsi tramite una fotoresistenza sull' ingresso analogico A0 e una volta al minuto invio i dati al mio database.
Volevo fare la stessa cosa integrando sia il contatore del fotovoltaico che il contatore enel di consumo. Come posso fare? Ho provato ad integrare lo sketch con un altro ingresso ed un altra funzione nel void loop ma non funziona proprio. Ringrazio chi mi saprà aiutare ad integrare il codice sottostante.
Sotto copio il codice che ho usato. Come lo devo integrare per fare la lettura di 2 fotoresistenze quindi di 2 contatori?

Grazie mille
Ciao

/*
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
}

Una fotoresistenza non é il componente adatto per leggere gli impulsi di luce del contatore. Per primo perché la risposta in frequenza é molto bassa per secondo perché la lettura avviene con un analogRead.

È meglio usare un fototransistore in serie a una resistenza pullup.

La logia del sketch non permette una lettura di un secondo contatore perché resta nel ciclo while finche non smette di essere acceso il LED.

// 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++; 
  }

Devi via SW controllare il accendere espegenre del led oppure usare l' interrupt per la conta.

Ciao Uwe

Grazie per la risposta. Comunque con lo sketch postato il monitoraggio del contatore fotovoltaico avviene correttamente. Io utilizzo una fotoresistenza e una resistenza da 10 K.

Se non è possibile con questo sketch gestire il conteggio impulsi contemporaneo di 2 contatori c'è qualcuno che mi può aiutare a rivedere il codice per riuscire con un unico arduino a gestire 2 ingressi analogread invece di uno per la lettura impulsi di 2 fotoresistenze?

Grazie mille a tutti

Provare a scriverlo Tu?
Ciao Uwe

se fossi in grado lo avrei già scritto. Grazie comunque per l aiuto ciao

identifica il codice che legge un impuslo:

// 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++; 
  }

e duplicalo.
Poi come dice UWE quel delay() fa in modo che se i lampeggi avvengano insieme, ti accorga di solo uno dei due... per risolvere al posto del delay devifare come nell'esemio BlinkWithoutDelay.
Però ti vonviene scrivere un codice da 0 per leggere i due sensori e stampare il risultato via seriale, per avere un riscontro immediato

grazie mille lesto intanto proverò a rivedere il codice con il metodo che mi hai segnalato.. Blinkwithoutdelay.. Ti faccio sapere.. Grazie ancora

Volevo chiedere consiglio su come impostare il watchdog sullo sketch postato sopra. Funziona bene anche se dopo circa 2 giorni di monitoraggio si blocca e per farlo ripartire devo resettare l'arduino.
Mi è stato consigliato di impostare il watchdog. Secondo voi è corretto? All' inizio ho richiamato la libreria #include <avr/wdt.h> nel setup ho inserito //attivo wdt_enable(WDTO_8S); alla fine del loop resetto //resetto il watchdog wdt_reset();
Il conteggio degli impulsi viene inviato ogni minuto. Impostando il reset al massimo disponibile cioè a 8 secondi ci potrebbero essere problemi se ho un tempo tra un impulso e l'altro maggiore di 8 secondi? Come potrei impostare il watchdog per un tempo superiore ad esempio ? 2-3 minuti?

Grazie mille per la disponibilità

/*
V 1.0
*/

#include <SPI.h> 
#include <Ethernet.h>
#include <Udp.h>
#include <SD.h>
#include <Time.h>
#include <MsTimer2.h> 
#include <avr/wdt.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);

 wdt_enable(WDTO_8S);

}

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;
  }

//resetto il watchdog     wdt_reset(); 

}

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
}

ankamacha:
Mi è stato consigliato di impostare il watchdog. Secondo voi è corretto?

no.
Devi trovare il problema e risolverlo, altrimenti stai solo mettendo una pezza

Quoto lesto.

Ad esempio, potrebbe essere un problema di ram esaurita.
Prima di tutto metti tutti i print e println che contengono del testo fra virgolette con la funzione F().
Esempio:

client.print("/enel.php?user=username&password=password&data=");

diventa:

client.print(F("/enel.php?user=username&password=password&data="));

La butto lì.
E' possibile collegare il fotoresistore ad un ingresso digitale e realizzare un circuitino per impostare una soglia con un trimmer?
Risolverebbe il problema e permetterebbe l'uso dell'interrupt o di un ingresso digitale per incrementare il contatore.

sì, in teoira con op-amp usato come amplificatore.. che poi non è altro che un transistor o un mosfet con la base al segnale analogico, collettore ed emettitore a 5V e al pin digitale. C'è da fare 4 conti sulla resistenza da usare e fare attenzione che la base sia abbastanza sensibile.

Ho trovato questo --> SENSORI
Usa un LM741.

COMPONENTI: R1 (10k), R2 (trimmer 47k), R3 (1k), U1 (741), LDR (fotoresistenza).

ancora più easy: 2 resistenze e un transistor:

(in alto a sinistra, usa il BSS138 per portare un TX_LV a TX_HV)

anche se è scritto 3,3v e 5v, il sistema dovrebbe funzionare fino a 1.8v.

Notare che questo sistema è anche BIDIREZIONALE, quindi puoi usarlo sia per passare da HV(alto voltaggio) a LV (basso voltaggio) che viceversa.
Have fun!

edit: ah, non hai il trimmer, però setti la tensione di partenza e di arrivo con LV e HV

ankamacha:
Se non è possibile con questo sketch gestire il conteggio impulsi contemporaneo di 2 contatori c'è qualcuno che mi può aiutare a rivedere il codice per riuscire con un unico arduino a gestire 2 ingressi analogread invece di uno per la lettura impulsi di 2 fotoresistenze?

Anche io sono del parere che è meglio un fototransistor.

Dopodiché userei 2 interrupt.

ok grazie provo intanto ad ottimizzare il codice con la funzione f(). Questa funziona solo da IDE Arduino 1.0 o superiore vero?
Lo sketch sopra è compatibile fino alla versione 023. Può essere che adattando il codice alla versione più recente e usando il consiglio di leo funzone f() la scheda non si pianti più dopo 2 giorni di perfetto funzionamento?

Grazie intanto faccio dei test

ankamacha:
ok grazie provo intanto ad ottimizzare il codice con la funzione f(). Questa funziona solo da IDE Arduino 1.0 o superiore vero?

Sì.

Lo sketch sopra è compatibile fino alla versione 023. Può essere che adattando il codice alla versione più recente e usando il consiglio di leo funzone f() la scheda non si pianti più dopo 2 giorni di perfetto funzionamento?

Grazie intanto faccio dei test

E' probabile. Controlla prima che lo sketch e tutte le lib siano compatibili con l'IDE 1.0.

in effetti ho provato con Arduino 1.0.3 ci sono un pò di errori nelle librerie... la funzione f() che mi dicevi non funziona su Arduino 023 vero?
ho cercato di adattare il codice con IDE 1.0.3 mi sono usciti un pò di errori sulla configurazione Ethernernet... che ho cercato di risolvere. Lo sketch viene compilato correttamente ma non manda il dato al database... dopo poco si disconnette e esce a video l'errore EXCEPTION: during HTTP GET. Could not connect..cosa potrebbe essere di sbagliato? nella versione 023 funziona perfettamente la scheda di rete la vedo correttamente

Grazie per l'aiuto

/*

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 <EthernetUdp.h>  //new
#include <SD.h>
#include <Time.h>
#include <MsTimer2.h> 

//Network stuff
byte mac[] = { 
  0x90, 0xA2, 0xDA, 0x0D, 0x1E, 0x21 }; //Arduino MAC address   new 0x90, 0xA2, 0xDA, 0x0D, 0x6C, 0xEF
byte ip[] = { 
  192, 168, 0, 25 }; //Arduino IP address
byte gateway[] = { 
  192, 168, 0, 1 }; //Network gateway
byte subnet[] = { 
  255, 255, 255, 0 }; //Network subnet mask

//NTP stuff
byte timeServer[] = { 
  193, 204, 114, 232
  }; //NTP server address http://www.inrim.it/ntp/index_i.shtml
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
IPAddress server(5,9,145,245); // Google //Web server address google  5,9,145,245
unsigned int port = 80; //Web server http port (usually 80)
//Client client(server, port); //Creates an http client handle   originale
EthernetClient client;  //new


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

// Analog input for photoresistor 
#define PHOTO_IN 0 

int threshold=800; // 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;
EthernetUDP Udp;  //new
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(server, 80)){
    client.flush();
    client.print("GET ");
    client.print("http://www.prova.altervista.org/enel.php?enel=");
    client.print(conteggio);
    Serial.println(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
}
*/

L'inizializzazione corretta è

Ethernet.begin(mac, ip, gateway, gateway, subnet);

adesso funziona perfettamente!
grazie mille Paolo!

lo skech manda i dati al database!
ora posso testare la funzione f() sui testi. collego la scheda e vi faccio sapere se arduino lavora bene senza piantarsi dopo 1 giorno di monitoraggio