Controllo impianto fotovoltaico e "pseudo-domotico"...

Salve a tutti, mi chiamo Pierangelo, seguo questo forum da un po' ed ultimamente mi sono registrato... Premetto che non ho ancora per le mani un Arduino ma che lo acquisterò presto.

Sto progettando un sistema di controllo per il mio impianto fotovoltaico che abbia qualche funzione un po' più evoluta dei semplici datalogger di produzione che si trovano in commercio (a costi esagerati, aggiungo). Vi espongo cosa vorrei fare: 1) Monitoraggio potenza prodotta dall'impianto FV 2) Monitoraggio potenza assorbita dall'impianto domestico (e per differenza la potenza "disponibile", che immetto nella rete ENEL) 3) In base alle grandezze misurate, attivare il funzionamento di alcuni carichi elettrici (scaldino elettrico, lavatrice, condizionatori) 4) Intervenire in caso di superamento della potenza contrattuale con il distacco di alcuni carichi Questa è la base di ciò che mi occorre. A livello di hardware credo di avere le idee abbastanza chiare: Arduino Mega (potrebbe creare "problemi" rispetto all'Arduino Uno o 2009?) Arduino Uno Scheda Relè 8 canali (7x utilizzati) Trasduttori di corrente TA (2x oppure 9x) Trasduttore di tensione TV (un banale trasformatore AC) Contatori energia elettrica con uscita S0 DIN 43864 (6x) Pulsanti per attivazione manuale dei carichi disattivati e per la selezione della modalità operative (controllo carichi ON/OFF, controllo superamento potenza ON/OFF) LED di stato per uscite e modalità operative Opzionali: Display LCD RTC Ethernet shield

Potrebbe anche essere interessante, magari anche in un secondo momento come espansione del progetto, aggiungere un display LCD al posto dei LED ed una shield Ethernet per monitorare il tutto da postazione remota o www, ma al momento mi accontenterei anche di farne a meno. Il problema nasce da questo: non ho ben chiaro come realizzare l'algoritmo di gestione a livello software, nel senso che ci vuole prima di tutto una certa isteresi nelle decisioni prese per il distacco dei carichi (altrimenti magari si accende la lavatrice a minuti alterni!) e poi a priori è difficile sapere quanto consumano i vari carichi. Ad esempio se attivo lo scaldino, magari la il suo termostato non è attivo e per 10 minuti assorbe 0 e dopo assorbe 1,5Kw; oppure il condizionatore inverter che assorbe in funzione del carico da 1,2 a 0,3Kw. Secondo voi è indispensabile aggiungere un TA per ogni utenza per monitorare gli assorbimenti? Oppure si riesce a fare dei ragionamenti in base alla potenza assorbita totale che potrebbero evitarmi ulteriori TA? In caso servissero tutti quei TA, riuscirei ad effettuare 9 letture dai TA, decidere cosa fare coi carichi in base ad una tabella di priorità ed RTC, eventualmente rispondere ad interrogazioni da Ethernet shield con la potenza elaborativa a disposizione in tempi congrui? Vorrei avere almeno 10 letture per secondo per ogni TA per avere un valore di potenza reale abbastanza preciso. Oltre questo dovrei leggere lo stato di alcuni pulsanti che forzino l'attivazione dei carichi anche superando la potenza disponibile. Come optional sarebbe interessante visualizzare dei grafici giornalieri / mensili della potenza prodotta dall'impianto FV per visualizzazione su PC o www tramite Ethernet shield e scheda SD e magari anche gestire da remoto l'attivazione dei carichi.

C'è qualcuno di voi che ha voglia di buttare giu qualcosa insieme? Premetto che non ho alcuno scopo di lucro e voglio realizzare un progetto per risparmiare un po', facendo una cosa che mi piace e mi fa passare il tempo. Vi ringrazio fin d'ora e mi scuso per la lunghezza del post... In caso foste interessati potrei buttar giu qualche schema funzionale e raccogliere dei riferimenti di sketch da poter utilizzare. Ciao, Perangelo

Per prima cosa che inverter hai montato e che protocolli di comunicazione utilizza?

L'inverter è un SunWay M Plus 6400 di Elettronica Santerno che utilizza il protocollo ModBus RTU su RS485 a 3 fili.

http://www.google.it/url?sa=t&source=web&cd=4&ved=0CC8QFjAD&url=http%3A%2F%2Fwww.novaproject.it%2FLinkClick.aspx%3Ffileticket%3DXrtKUEp7nUA%253D%26tabid%3D76%26mid%3D431&ei=ec3TTdKNEY3ysgbGvYHfAg&usg=AFQjCNFj4oHBmKJ-7nEfRZsonty_Gz4Ntw

a pag 64 si parla di comunicazione.

Il fatto è che dato che l'unica cosa che mi interessa monitorare è la potenza attiva prodotta, non volevo interfacciarmi direttamente all'inverter (penso si complichi la gestione) ma leggerla con un TA ed un TV per misurare lo sfasamento e la potenza reale. Dici che sbaglio? Grazie. Pierangelo

Si penso puoi anche utilizzare dei trasduttori, comandare pero molti elettrodomestici in base alla produzione di elettricità mi sembra però abbastanza complicato.

Proprio per questo chiedevo aiuto... :) A parte gli scherzi, capisco che non è semplice, anche perchè il tutto deve sottostare ad un sistema di priorità (e qui basta un definire un vettore in memoria) e magari anche cambiarle in base all'ora (disattiva il sistema quando il FV è spento)...

Mi ha sempre affascinato la casa intelligente ed ho seguito tutti i discorsi sul forum a riguardo, ciò che ne ho dedotto fino adesso è che benchè in teoria la cosa è fattibile poi ci si scontra con quello che non abbiamo fatto noi e non è pensato per funzionare come richiesto.

Hai detto bene riguardo la lavatrice o qualunqu altro elettrodomestico stupido, in quanto non c'è modo di sapere prima quando la scheda eccita il rele per fornire energia alla resistenza, ne tanto meno c'è modo di sapere quando il compressore del condizzionatore entra in funzione e non risolve avere condizionatori ad inverter aiuterebbe ma complicherebbe le cose.

Se tutti gli elettrodomestici comunicassere via wireless i loro parametri funzionali allora rimarrebbe da creare un'algoritmo molti simile al kernel di un pc, dove ogni carico è paragonabile ad un processo, con la sua priorità (nice) e modalità Realtime, softrealtime ecc., al livello software ci sarebbe da sbizzarrirsi, supportati da sensori presenza non dovresti neanche pensare ad accendere e spegnere il condizzionatore.

Io lascerei stare lo scollegamento del carico, ma implementerei la possibilità di vedere la condizzione di superamento e di poter sapere quale presa o carico ha comportato il superamento, poi registrati per un paio di settimane e analizzati ti potrebbero portare ad implementare il distacco di uno o due carichi a ragion veduta.

Il rischio che si corre è che il sistema venga visto come una complicazione più che agevolazione, dipende dalle persone che vivono nella casa. Es. Tua moglie ha messo avanti la lavatrice, si è calcolata che fra un'ora stende i panni, si prepara e scende a prendere i bambini, ma no il sistema ha staccato la lavatrice, questo potrebbe essere vissuto come un fastidio.

E non mi rispondere che sei tu che vai a prendere i bambini perchè era solo un'esempio.

Ora non voglio fare quello che dice non si può fare, non ti conviene, ma questi sono solo alcuni dei problemi che mi son venuti in mente, se ti metti all'opera stai tranquillo che di problemi da risolvere ne verrano fuori molti altri.

Ciao.

@MauroTec: Infatti io ho previsto anche un pulsante per ogni carico che mi dice se quel carico deve a) funzionare in automatismo; b) essere acceso; c) essere spento... Se mia moglie ha bisogno che la lavatrice finisca nei tempi previsti (tornando al tuo esempio) pigia il pulsante selezionando la modalità "sempre acceso" e la lavatrice va a prescindere dal consumo rilevato (viene esclusa dalla tabella di priorità). Comunque non credo che quello che ho in mente sia una complicazione, tutt'altro... Forse però non ho ben spiegato cosa voglio fare... Dovrei cercare un programmino per creare flowchart e mettervi su uno schemino in modo da rendere tutto più comprensibile. Nel mio caso poi non ho bisogno di moduli remoti che complicano le cose, dato che ho centralizzato e separato le utenze che mi occorrono in fase di realizzazione dell'impianto elettrico e mi basta installare tutto vicino al quadro elettrico principale. La cosa che più mi risulta difficile è creare un algoritmo che riesca a prendere delle decisioni che sia abbastanza intelligente e compatto da non richiedere troppe linee di codice o troppo consumo di risorse hardware. Questo week end mi metto a ragionarci su e cerco di postare qualcosa di organico. Ti ringrazio comunque per il tuo intervento! Ciao,

EDIT: Una delle difficoltà maggiori, non avendo l'hardware a disposizione al momento, è capire quanto tempo ci vuole ad eseguire un certo compito e quindi capire quanto complesso possa essere il software di gestione... Ma a questo rimedierò in fretta con l'acquisto della scheda! ;) Pierangelo

Ciao CH1980, già si può dire che il sistema ha una interfaccia utente con la quale escludere un utenza dal calcolo e quindi dal controllo. Con utenza mi riferisco a qualunque carico elettrico cehe deve essere gestito.

Quindi già a livello software c'è di bisogno di un'oggetto nel quale potere inserire un oggetto utenza: Pseudocode

Class Consumer(const String &name, int id) Consumer::setPriority(int priority) int Consumer::priority() Consumer::setEnabled( bool ) bool Consumer::enabled()

Class ConsumersSchedule() ConsumersSchedule::addConsumers(Consumers * users) ConsumersSchedule::removeConsumers(int index) Consumers *ConsumersSchedule::GetNext()

Poi una classe gestore crea o usa l'oggetto di classe ConsumersSchedule per iterare su tutti gli oggetti di tipo Consumers.

una cose del tipo: while (true) { Consumer * user = schedule->getNext() user->setPriority(10) }

Ok spero di averti dato una idea e non averti messo fuori strada.

Ciao.

Ciao a tutti…
Finalmente son riuscito a buttar giu uno schemino del circuito con MCP23008 in Fritzing…
Ho fatto una modifica nella scelta del metodo per la lettura della potenza attiva: ho deciso di utilizzare dei contatori di kWh con uscita S0 (1 impulso ogni 0,5kWh). Avevo pensato a questa configurazione:
S0-1: energia prodotta da FV (appena dopo l’inverter)
S0-2: energia consumata da tutto l’impianto domestico (sull’ingresso del quadro elettrico generale)
S0-3: energia consumata dal boyler
S0-4: energia consumata dalla lavatrice
S0-5: energia consumata dalla PdC piano terra
S0-6: energia consumata dalla PdC piano primo
S0-7 e S0-8: futuri utilizzi
Un impulso su uno di questi ingressi mi genera un Interrupt al pin D2, a quel punto mi leggo il registro INTF del MCP23008 (mi dice quale/i pin ha generato l’interrupt) e salvo il valore di millis() in un vettore (?) alla posizione relativa al / ai pin che ha generato l’interrupt; quando ad un ulteriore richiamo dell’interrupt routine mi accorgo di avere un valore precedente di millis() per un dato pin, mi calcolo la differenza in ms tra due impulsi su una stessa linea S0 e su un altro vettore (?) metto la potenza in kWh calcolata per quel pin. Potrebbe funzionare? Sarebbe troppo complicato da eseguire all’interno della routine di interrupt?

Il secondo MCP23008 si occuperebbe di gestire i pulsanti che escludono un utenza dal controllo tramite Arduino. Pensavo di utilizzare le R di pull-up interne e collegarlo al pin D3 per l’interrupt, che semplicemente dovrebbe eseguire il toggle di una variabile booleana (il solito array di 8 variabili?) ad ogni pressione del relativo pulsante. Se la variabile è true Arduino attiva e disattiva l’utenza in base alla sua logica, se è false allora la relativa uscita è sempre attiva (utenza alimentata permanentemente).

Il terzo MCP23008 dovrebbe pilotare i rele’ di comando delle utenze in base ad una tabella di priorità ed alla differenza di potenza tra la linea S0-1 ed S0-2 (che dovrebbe tendere a 0 o essere leggermente positiva in favore dell’energia prodotta dallimpianto FV).

In sostanza i primi due MCP23008 producono interrupt differenti, mentre nel main loop leggo le potenze calcolate all’interno dell’interrupt routine associata al pin D2, controllo di poter pilotare i vari carichi (leggo il vettore relativo impostato all’interno dell’interrupt routine associata al pin D3) e cerco di mantenere la potenza letta sulla linea S0-2 appena minore o uguale a quella letta sulla linea S0-1.
Potrebbe funzionare?
Purtroppo sono ancora al palo col software, anche perchè aspetto l’Arduino Uno dal Regno Unito che ci sta mettendo una vita ad arrivare! :frowning:
Saluti a tutti!

Aggiornato lo schema su bread board:
ho aggiunto il quarto MCP23008 per la visualizzazione dello stato del byte di controllo delle uscite rele’, che viene impostato tramite dei pulsanti collegati al secondo MCP23008
ho anche aggiunto le resistenze di pull-up del bus I2C (4,7kOhm vanno bene?)

Vi posto anche una primissima release del software (manca la parte che controlla i carichi, per ora visualizzo solo i consumi e la produzione sul monitor seriale ed ho inserito delle linee, marcate con //DEBUG, per monitorare il tempo di esecuzione del codice che poi eliminerò).
Vorrei chiedervi una mano per modificare la funzione S0_Count() e la funzione Pulse() della classe PulseIn per utilizzare il registro INTF del MCP23008 anzichè la porta GPIO. Al momento la classe controlla se lo stato letto è diverso dal precedente e, se così è, conteggia un impulso. Il registro INTF del MCP23008 ha la stessa funzione della classe in oggetto, quindi vorrei modificarla per conteggiare un impulso ogni volta che viene chiamata e richiamare la giusta classe nella funzione S0_Count (anzichè chiamarle tutte e 8, chiamare solo quella/e che sono relative ai pin che hanno cambiato stato). Vorrei che S0_Count() sia più rapida possibile perchè viene richiamata in seguito ad interrupt. Sarà il caldo ma stò diventando matto a fare questa modifica…
Vi posto qui la S0_Count() e la PulseIn::Pulse() per referenza, mentre vi allego il file completo zippato.
Grazie in anticipo!

void S0_Count() {
  Time = micros();
  Wire.beginTransmission(S0_ADDR);   // start talking to the device
  Wire.send(MCP_GPIO);               // select the GPIO register for reading
  Wire.endTransmission();            // stop talking to the device
  Wire.requestFrom(S0_ADDR, 1);      // connect to device and request one byte from GPIO register
  if (!Wire.available());            // do nothing until data arrives
  S0_Val = Wire.receive();           // read GPIO register value
  Wire.endTransmission();

  //--------------------------------------------------------------------
  // Detect pulses from GPIO register
  //--------------------------------------------------------------------
  S0_Pulse[0].Pulse(0, S0_Val, Time);       // GPIO GP0
  S0_Pulse[1].Pulse(1, S0_Val, Time);       //  ''  GP1
  S0_Pulse[2].Pulse(2, S0_Val, Time);       //  ''  etc
  S0_Pulse[3].Pulse(3, S0_Val, Time);
  S0_Pulse[4].Pulse(4, S0_Val, Time);
  S0_Pulse[5].Pulse(5, S0_Val, Time);
  S0_Pulse[6].Pulse(6, S0_Val, Time);
  S0_Pulse[7].Pulse(7, S0_Val, Time);
}
#define BIT_TST(REG, bit, val)( ( (REG & (1UL << (bit) ) ) == ( (val) << (bit) ) ) )

boolean PulseIn::Pulse(int Pin, int S0_Val, unsigned long TimeIn) {
  PrevState = State;                                        // previous digital state = digital state
  if (BIT_TST(S0_Val, Pin, 1)) State = 1; else State = 0;   // get current digital state
  if (PrevState == 1 && State == 0) {                       // if state changed from 1 to 0:
    Count++;                                                // count the pulse
    PrevTime = Time;                                        // rate calculation begins
    Time = TimeIn;
    PRate = Time - PrevTime;                                // rate based on last 2 pulses
    PRateAcc += PRate;                                      // accumulate rate for average calculation
    return 1;
  }
  return 0;
}

PVControl.zip (3.32 KB)

Ho modificato il software ma per ora non ho possibilità di testarlo, intanto ha compilato correttamente che è già qualcosa! :wink:
Secondo voi è corretto?

#define BIT_TST(REG, bit, val)( ( (REG & (1UL << (bit) ) ) == ( (val) << (bit) ) ) )

void S0_Count() {
  Time = micros();
  Wire.beginTransmission(S0_ADDR);   // start talking to the device
  Wire.send(MCP_INTF);               // select the INTF register for reading
  Wire.endTransmission();            // stop talking to the device
  Wire.requestFrom(S0_ADDR, 1);      // connect to device and request one byte from INTF register
  if (!Wire.available());            // do nothing until data arrives
  S0_Val = Wire.receive();           // read INTF register value
  Wire.endTransmission();

  //--------------------------------------------------------------------
  // Detect pulses from INTF register
  //--------------------------------------------------------------------
  for (int Pin=0; Pin<=7; Pin++) {   // for all inputs:
    if (BIT_TST(S0_Val, Pin, 1))     // if digital state changed and caused interrupt
      S0_Pulse[Pin].Pulse(Time);     // count pulse for relative input pin
    }
}
boolean PulseIn::Pulse(unsigned long TimeIn) {
    Count++;                                                // count the pulse
    PrevTime = Time;                                        // rate calculation begins
    Time = TimeIn;
    PRate = Time - PrevTime;                                // rate based on last 2 pulses
    PRateAcc += PRate;                                      // accumulate rate for average calculation
    return 1;
}

PVControl_INTF.zip (3.36 KB)

Inizio ad avere seri dubbi che questo progetto interessi a qualcuno (magari è troppo specifico o c’è di meglio in giro :~ ) comunque vi rendo partecipi dell’ultimo aggiornamento:
mi sono aggiudicato un display 20x4 con controller I2C a prezzo modico sulla baia che utilizzerò come interfaccia utente nel mio progetto, quindi spariranno i due MCP23008 relativi ai pulsanti (è presente a bordo del controller display anche un controller per tastiera a matrice o 8 ingressi digitali separati con interrupt) e quello relativo ai LEDs (lo stato verrà visualizzato direttamente sul display). Ho anche buttato giù uno schemino di ciò che sarà la visualizzazione a display, che vi allego.
Suggerimenti? Consigli? (anche in merito ai post precedenti)
Ciao!

Ognuno segue i suoi progetti. Certo, quando si pubblica qualcosa fa piacere ricedere dei commenti, giusto per autostima :smiley:
Però non prendertela, dai. Anch’io sto seguendo un mio progettino e metto i progressi online: ovviamente mi fa piacere se qualcuno mi dice “ooooohhhh ma quanto sei bravo” oppure “il tuo circuito è trooooppo figo” ma non mi arrabbio se nessuno dice nulla, magari ha altro da fare oppure ha già espresso il suo parere.

Cmq, ti volevo chiedere un’informazione. Stavo anch’io cercando lo stesso tipo di display (20x4 I2C). Ma è testuale? A me interessa di questo tipo.
Mi sono accorto che le info estrapolabili dalla stazioncina meteo sono molte e visualizzarle con i led è un po’… primitivo :sweat_smile:

Ciao Leo! Figurati, non me la prendo assolutamente e non è un discorso di autostima: diciamo che non posso ancora fisicamente fare delle prove complete perchè mi mancano dei componenti (almeno l'Arduino Uno è arrivato!) quindi non sono sicuro che tutto funzioni perfettamente. Non ho nemmeno mai utilizzato i chip MCP23008 o il bus I2C (anche se in questi giorni ho fatto un po' di pratica con lo shield SD card + RTC) ed ho qualche dubbio su tutti quei Wire.beginTransmission() e Wire.endTransmission() ad ogni invio, per esempio...

Per quanto riguarda il display, questo è il manuale: http://www.web4robot.com/files/SerialLCDCtrl.pdf E' un display testuale che ha una utile funzione aggiuntiva per disegnare grafici a barre verticali od orizzontali con risoluzione di 1 pixel per riga o per colonna a seconda della funzione. Ciao!

Il bus I2C è un bus che può essere usato da più dispositivi contemporaneamente. Ogni dispositivo può essere Master (inviare richieste di dati) oppure Slave (inviare dati su richiesta). Per far sì che un dispositivo possa comunicare con un altro, deve inviare la richiesta a quel particolare dispositivo, specificando il suo indirizzo. Ecco il Wire.beginTransmission(indirizzo): il dispositivo Master (in questo caso l'Arduino) esegue una richiesta di comunicazione con "indirizzo", che diverrà il dispositivo Slave. Dopo la trasmissione, si chiude il canale per liberare i dispositivi.

Riguardo al display, volevo se possibile il prezzo che hai pagato ed il link del venditore, così che se ne ha un altro lo prendo anch'io.

Ti ho inviato un messaggio privato col link. Posso approfittare a chiederti una cosa? Se io devo mandare vari byte sempre allo stesso indirizzo devo chiudere ogni volta la trasmissione?

  Wire.beginTransmission(S0_ADDR);   // start talking to the device
  Wire.send(MCP_GPIO);               // select the GPIO register for reading
  Wire.endTransmission();            // stop talking to the device
  Wire.requestFrom(S0_ADDR, 1);      // connect to device and request one byte from GPIO register
  if (!Wire.available());            // do nothing until data arrives
  S0_Val = Wire.receive();           // read GPIO register value
  Wire.endTransmission();

O posso fare così:

  Wire.beginTransmission(S0_ADDR);   // start talking to the device
  Wire.send(MCP_GPIO);               // select the GPIO register for reading
  Wire.requestFrom(S0_ADDR, 1);      // connect to device and request one byte from GPIO register
  if (!Wire.available());            // do nothing until data arrives
  S0_Val = Wire.receive();           // read GPIO register value
  Wire.endTransmission();

Inoltre ho letto che prima di un Wire.requestFrom() non è necessario il Wire.beginTransmission(): confermi?

Meglio la prima. Così dai modo allo Slave di passare dalla modalità ricezione a quella di trasmissione.

nizio ad avere seri dubbi che questo progetto interessi a qualcuno (magari è troppo specifico o c'è di meglio in giro smiley-confuse ) comunque vi rendo partecipi dell'ultimo aggiornamento:

E che qui chi più chi meno lavora a testa bassa sul suo progetto e molte volte si iniziano post che poi non portano a nulla (capita e capitato anche a me). Io ad esempio sono rimasto indietro, i progressi che hai fatto per me sono cosa totalmente nuova, quindi me li devo studiare.

Non realizzero niente di quello che stai sviluppando per mancanza di tempo e $$. Però come ti ho detto mi affascina e li seguo volentieri questi post e li "uso" per distrarmi e spesso stuzzicano la fantasia.

Sono poco presente perchè faccio estenuanti sessioni di programmazione, ora mi rilasso un pò e mi rimetto in pari con il progetto.

Ciao.

Non ho ancora guardato tutto il codice, anche perchè ancora non ho le idee chiare o almeno vorrei una conferma a quello che ho capito io, cioè sfrutti i port expander che generano dei segnali che all'interno del 328 scatenano un IR (interrupt request). Domani do uno sguardo al sorgente.

Un impulso su uno di questi ingressi mi genera un Interrupt al pin D2, a quel punto mi leggo il registro INTF del MCP23008 (mi dice quale/i pin ha generato l'interrupt) e salvo il valore di millis() in un vettore (?) alla posizione relativa al / ai pin che ha generato l'interrupt; quando ad un ulteriore richiamo dell'interrupt routine mi accorgo di avere un valore precedente di millis() per un dato pin, mi calcolo la differenza in ms tra due impulsi su una stessa linea S0 e su un altro vettore (?) metto la potenza in kWh calcolata per quel pin. Potrebbe funzionare? Sarebbe troppo complicato da eseguire all'interno della routine di interrupt?

Ecco appunto mi sembra di aver capito. Osservazioni utili: All'interno delle ISR (Interrupt service routine) si dovrebbe far eseguire codice che impegna il minor tempo in termine di cicli di clock. Il motivo è che se il puntatore PC esegue codice ISR non può eseguire altro codice e per di più il micro non esegue una richiesta di interrupt ( e possibile manipolare i registri per modificare questo comportamento ), tuttavia da una discussione con Astrobeed è uscito fuori che la IR viene comunque presa in considerazione ed eseguita quando termina ISR corrente. Alla fine il tempo impiegato per eseguire codice in una ISR può anche essere di 1 o 2 secondi o anche più, sempre che la logica dell'intero progetto lo permetta.

Se il tempo dovesse essere troppo alto si deve: ottimizzare o salvare le operazioni da compiere e calcolare il tutto nel loop.

Ciao.

Grazie per le risposte, Mauro! Effettivamente anche io seguo vari post che mi interessano "come diversivo" ma non rispondo quasi mai (anche perchè non sono in grado, altrimenti lo faccio volentieri)... Comunque posso dire che questo sarà un progetto che andrà ad essere realizzato al 100% (ci ho investito abbastanza in tempo e denari! $) ) quindi alla fine realizzerò un post di riepilogo con un tutorial dettagliato per replicare quello che farò. Come tempistica vorrei finire in tempo per l'inverno... Tornando al codice, hai capito perfettamente il meccanismo. Le ISR che ho programmato (e postato qualche messaggio più indietro con la funzione codice) dovrebbero essere abbastanza svelte, comunque tra una settimana al massimo dovrei riuscire ad assemblare il tutto su breadboard e vedere esattamente quanto tempo impiegano per l'esecuzione (l'unica cosa lunga sono le transazioni su bus I2C ma dovrebbero comunque richiedere poco tempo). Male che vada dovrò modificare le ISR per salvare il valore millis() e settare un flag che mi faccia fare i calcoli all'interno del main loop, solo che così il codice diventerebbe più fumoso e meno leggibile. Farò delle prove. Ciao!