Puoi ancora ottimizzare lo spazio in memoria ponendo const a molte variabili che non cambieranno valore.
Come le porte del server o i timeout o il valore soglia.
Ottimizza... ottimizza..
Puoi ancora ottimizzare lo spazio in memoria ponendo const a molte variabili che non cambieranno valore.
Come le porte del server o i timeout o il valore soglia.
Ottimizza... ottimizza..
ottimizzo più che posso.. spero di stabilizzare sto benedetto sketch...
grazie per le dritte...
grazie ancora Paolo
ankamacha:
ottimizzo più che posso.. spero di stabilizzare sto benedetto sketch...
Ecco, ottimizza
Ad esempio questo è uno spreco:
const unsigned long timeZoneOffset = 3600;
Usi 4 byte di RAM per immagazzinare un valore che sta tranquillamente in 2 byte.
Un unsigned int contiene numeri da 0 a 65535, più che sufficiente per contenere 3600.
Sono d'accordo sul problema RAM ma credo che il problema stia più nel fatto che da qualche parte sta creando ggarbage. Sicuramente passare all'ultima versione di ide risolve molti bug delle librerie
Io vedo un grosso problema qui:
#include <SPI.h>
#include <Ethernet.h>
#include <Udp.h>
#include <EthernetUdp.h> //new
#include <SD.h>
#include <Time.h>
#include <MsTimer2.h>
Sono tante librerie che vengono incluse, anche ingombranti, e chissà quanto consumano in termini di risorse...
Sarebbe curioso sapere la RAM libera una volta partito il programma.
il primo giorno di monitoraggio è andato perfettamente. Arduino non si è piantato.. spero di aver risolto grazie ai vostri preziosi consigli.
leo come faccio a conoscere la ram libera di arduino al momento dell' avvio dello sketch ?
se mi dici come fare ti faccio sapere...
grazie
Puoi usare avr-size per avere il consumo statico di RAM (prima dell'avvio dello sketch), oppure con una libreria da includere nel progetto.
Puoi leggere qui qualcosa in più.
Dopo 5 giorni di funzionamento senza blocchi posso dire che lo sketch è stato ottimizzato e funziona bene.
Ho notato un discostamento tra il rilevato da Arduino e il contatore Enel non trascurabile (circa il 5 %) . Come potrei fare per ridurre questo errore? Si parlava di usare al posto di una fotoresistenza un fototransistor. Con un fotodiodo potrei fare lo stesso? Se si, mi date qualche dritta per modificare lo sketch?
Grazie mille ragazzi
un fotodiodo (un led in pratica) può andare bene, i tempi di reazione sono nell'ordine dei nanosecondi. In pratica prendi un led (dello stesso colore, o megglio frequenza di luce, della luce da analizzare)e lo usi come pannello solare.. il - a GND e il + a un pin analogico, o ad un amplificatore che poi entra in un pin digitale
OK grazie quindi lo sketch resta invariato con il fotodiodo? Ma la R da 10 K per l'impostazione della soglia const int threshold=800; ci va lo stesso?
La fotoresistenza che tempo di risposta ha? Potrebbe essere che un errore del 5% nel conteggio degli impulsi sia dovuto proprio a un tempo di risposta troppo elevato? Fai conto che nelle ore di maggiore produzione dell' impianto vado nell'ordine dei 40-45 impulsi al minuto...
Di solito prendo i componenti di robotitaly... ho trovato questo http://www.robot-italy.com/it/siemens-sfh-205f-infrared-phododiode.html secondo te va bene?
grazie
Tempo di risposta elevato vuol dire 100/200ms come il tempo la lettura dell'analogRead. Se salti conteggi alla frequenza di 50 impulsi al minuto il problema è forse da un'altra parte.
Verifica la durata del ciclo loop e che non ci siano blocchi nelle funzioni della SD o della Ethernet.
qual'è il cavo migliore per collegare una fotoresistenza in un progetto di questo tipo? che sezione dovrebbe avere?
forse il cavo che utilizzo ha una sezione troppo grande, potrebbe essere questo la causa della perdita del 5% di impulsi?
PaoloP:
Tempo di risposta elevato vuol dire 100/200ms come il tempo la lettura dell'analogRead. Se salti conteggi alla frequenza di 50 impulsi al minuto il problema è forse da un'altra parte.
Verifica la durata del ciclo loop e che non ci siano blocchi nelle funzioni della SD o della Ethernet.
l'analog read dura circa 100 MICROsec(us), non MILLIsec(ms), quindi 0.1ms o 0.0001secondi
Ho notato un discostamento tra il rilevato da Arduino e il contatore Enel non trascurabile (circa il 5 %) . Come potrei fare per ridurre questo errore? Si parlava di usare al posto di una fotoresistenza un fototransistor. Con un fotodiodo potrei fare lo stesso? Se si, mi date qualche dritta per modificare lo sketch?
Ciao, come hai fatto a notare lo scostamento? Il contatore se non sbaglio segna solamente i KWh nelle varie fasce (F1,F2,F3) troncando i decimali, esempio se hai consumato 5.9kWh mostra a display ancora 5 kWh, sarà dura fare un confronto più preciso a meno che non azzecchi il momento preciso in cui parte il nuovo kWh.
I fototransistor sono principalmente per lo spettro IR (infra rosso) quindi non vanno bene a meno che non ne usi di speciali, i fotodiodi sono in genere per applicazioni dove veramente serve la velocità (fibra ottica, lettori CD, etc..), se hai 2-3 lampeggi al secondo non c'è bisogno di qualcosa di più veloce di una fotoresistenza con una soglia corretta. Più lampeggi non credo a meno che non hai un contratto particolare da più di 12 kWh ]
Ciao
Si hai ragione, le 3 fasce del contatore Enel non permettono di visualizzare la cifra dopo la virgola, però analizzando i dati su un arco di tempo di più giorni è possibile rendersi conto dello scostamento facendo un totale. Ho fatto 2 test sulla soglia: un giorno con theresold a 450, il giorno successivo con theresold 800 quindi meno sensibilità della fotoresistenza alla luce.. i discostamenti sembravano gli stessi anche confrontandoli con la lettura più precisa dell' inverter
Supponiamo che quando inizi la misura ti segni i numeri del contatore:
A1=A2=A3=999 kWH
Ma che in realtà sono tutti a 999.9 kWH, appena consumi 100W in tutte le tre fasce hai un errore di quasi 3kWH
Considerando che quando finisci la misura puoi avere una situazione analoga dove te hai segnato ad esempio 1200kWH mentre il contatore mostra 1199 (o 1201) su tutte e tre le fasce, hai un altro errore di 3kWH.
Sono situazioni limite ma puoi avere al massimo una misura precisa +-6kWH, valore che in % diminuisce all'aumentare dei consumi
La soglia non rende meno sensibile la fotoresistenza che continua a restituire i soliti valori, semplicemente consideri un lampeggio quando raggiunge certi limiti. Se hai una buona escursione tra led acceso o spento in tutte le condizioni esterne (es. di 500 valori su 1024, ma in realtà anche meno danno una buona certezza) allora puoi stare abbastanza tranquillo.
Dalla prova che hai fatto non hai avuto cambiamenti quindi la soglia direi che va bene e l'errore è da cercarsi nell'approssimazione del contatore.
Ciao
Se volessi utilizzare al posto della fotoresistenza un fototransistor e l'interrupt per il conteggio degli impulsi questo potrebbe andare bene?
http://www.robot-italy.com/it/phototransistor-fairchild-qrd1114.html
Sensore Fototransistor Fairchild QRD1114
Grazie
Ciao
No, come già detto il led del contatore non è infrarosso e non ci vuole un fototransistor per infrarossi
Ho risolto il problema dell'errore di monitoraggio rispetto al misurato Inverter e contatore GSE (5-8% di impulsi in meno). Nelle ore di maggiore produzione vale a dire a circa 40-50 impulsi al minuto, nel momento dell' invio del dato da Arduino al database (ogni minuto) perdevo qualche impulso. Questo errore moltiplicato per n minuti in una giornata mi dava il 5-8% di inpulsi in meno. Disabilitando la SD e inviando i dati solo al database la lettura è precisa. Probabilmente devo verificare la libreria della SD.
Adesso vorrei provare a sfruttare 2 fotoresistenze quindi 2 ingressi analogici per leggere in contemporanea 2 contatori:
quello Enel GSE bidirezionale
e quello Enel classico.
Lesto mi dicevi di modificare il codice di loop come nell’esempio BlinkWithoutDelay ma non ci capisco molto. Mi puoi dare qualche dritta?
Grazie mille
cosa succede:
nel momento in cui scrivi su SD e/o fai la richiesta GET, NON controlli i lampeggi, che vengono persi. In oltre anche quel delay(10) è molto grande, tempo che si somma al resto.
ciò è risolvibile usando un interrupt per leggere i lampeggi, che incrementa una variabile; poi dove ora fai la lettura del led, invece copierai il valore della variabile e la azzererai.
Quindi in pratica nel loop dove ora leggi il led invece leggerai il numero di volte che il led ha lampeggiato dall'ultima volta che l'hai letto; se ha lampeggiato almeno una volta fai il salvataggio su SD e su server.
edit: anche la scrittura via seriale è molto lenta. A 9600baud, impiegi un secondo per inviare al PC 960 lettere.
Può sembrare che non ti rallenti per via del buffer e del fatto che lavora con gli interrupt e quindi finchè il buffer non è pieno non rallenta più del solito. Ma se riempi il buffer più in fretta di quanto si svuota (ricordo 960 caratteri al secondo), allora quando il buffer è pieno vieni BLOCCATO in attesa di risposta.
Anche quando attendi la risposta dal server hai messo un while che ti blocca per un tempo indefinito. Per ora ti va di fortuna che il server risponde subito, ma quando il DB sarà un pò pieno o il pc impegnato a fare altro, e quindi la risposta impiegherà 10/15ms ad arrivare, saranno altri lampeggi persi (salvo sistema dell'interrupt eh)