Spettacolo!
Mi ci vorrà un pò di tempo per fare il tutto, non sono così sgamato ; d'altronde il progetto nasce lo scorso mese di agosto.
Domani proverò il tutto. a presto
ciao e grazie.
Claudio.
Spettacolo!
Mi ci vorrà un pò di tempo per fare il tutto, non sono così sgamato ; d'altronde il progetto nasce lo scorso mese di agosto.
Domani proverò il tutto. a presto
ciao e grazie.
Claudio.
Oltrealle cose che ti hanno giustamente indicato io ci aggiungerei:
adesso che sono tornato a casa e posso guardarlo bene da PC ci guardo bene col PC (scusa il mio solito gioco di parole)
ho imparato (e credo userò) il termine furbofono.
la prossima volta metterò il codice in chiaro.
aumenterò le identazioni, quelle che ci sono al momento erano più che altro per me.
a me non risulta nessun tipo di errore , tant'è che gira senza problemi.
adesso faccio il saputello e mi sbilancio (rischiando una figuraccia) magari è colpa della libreria?
perchè da qualche parte avevo letto che si consigliava la versione 1.5 anziché la 1.6 (time.lib)
ovviamente non posso sapere perché , ma se cancello la dichiarazione di v2 prima del for , la
formula "sballa". ad ogni restituzione del risultato corrisponde un incremento dello stesso.
Tipo sono "arrivato" a centinaia di volt.
Avevo capito la logica delle variabili globali e locali. Magari è inteso come un richiamo della globale piuttosto che una nuova definizione?
Comunque sia, posto il codice corretto e rivisto. Ovviamente funzionante.
A questo proposito penso di poter affermare (con una certa sicurezza e spavalderia) che più pulito
e magro di così , proprio non si può.
#include <TimeLib.h>
#include <Wire.h>
#include <DS3232RTC.h>
#include <LiquidCrystal.h>
#include <SD.h>
#include <SPI.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7); //pin di collegamento lcd
time_t t;
tmElements_t tm;
File filesd;
float temperatura = 0; // zona di memorizzazione della temperatura fornito da DS3231
float temp1 = 0; // zona di memorizzazione della temperatura in gradi celsius
int digits = 0; // zona di memorizzazione dei minuti e dei secondi da esporre
// sul display lcd
char tabmesi [37] = "genfebmaraprmaggiulugagosetottnovdic"; // tabella descr. mesi
int mese = 0; // zona di memorizzazione del mese corrente
int lavoro = 0; // zona di lavoro, utilizzata per calcoli intermedi
float ampere1 = 0;
float volt1 = 0;
float watt1 = 0;
float ampere2 = 0;
float volt2 = 0;
float watt2 = 0;
float Wt1 = 0;
float Wt2 = 0;
//
//********* routine di esposizione di data, ora e temperatura sul display lcd
//
void esponidati(void)
{
// esposizione dei dati provenienti dal timer di arduino
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.print(day());
lcd.print(' ');
mese = month(); // mememorizza il mese
mese = mese - 1; // diminuisce di 1 il valore del mese poiche'
// la descrizione del primo mese (gen) inizia
// all'indirizzo zero della tabella mesi
lcd.print (tabmesi [(mese * 3)]); // espone la prima lettera del mese
lcd.print (tabmesi [(mese * 3 + 1)]); // espone la seconda lettera del mese
lcd.print (tabmesi [(mese * 3 + 2)]); // espone la terza lettera del mese
lcd.print(' ');
lcd.print(year());
lcd.setCursor(0, 1);
lcd.print(hour());
digits = (minute()); // minute() da dove salta fuori? credo dalla libreria,giusto?
printDigits(); // routine esposizione zeri non significativi
digits = (second());
printDigits(); // routine esposizione zeri non significativi
lcd.print (" t:");
lcd.print (temp1);
}
//
//****routine visulazzazione minuti e secondi comprensivi di zeri non significativi********
//
void printDigits()
{
lcd.print(':');
if (digits < 10)
lcd.print('0');
lcd.print(digits);
}
void setup() {
Serial.begin(9600); //abilito porta seriale
pinMode (53, OUTPUT);
lcd.begin(16, 2); //inizializzo il diplay 1602
lcd.print (" buongiorno");
delay (1500);
lcd.clear ();
lcd.setCursor(0, 0); // posiziona il cursore all'inizio della prima riga
// (carattere 0 e riga 0)
setSyncProvider(RTC.get); // sincronizza il timer di Arduino con i dati presenti
// sul modulo RTC
lcd. clear ();
if (timeStatus() != timeSet) // verifica se la sincronizzazione e' andata a buon fine
lcd.print(" orologio non");
else
lcd.print(" orologio");
lcd.setCursor (0, 1);
lcd.print (" sincronizzato");
delay (1500);
temperatura = RTC.temperature(); // rileva per la prima volta la temperatura
lcd. clear ();
lcd.setCursor (6,1);
if (!SD.begin(10)) // verifica la presenza della secure digital
lcd.print ("SD KO");
else
lcd.print ("SD OK");
delay (1500);
}
void loop()
{
if (Serial.available() >= 17) // controlla se e' in arrivo una stringa da 17
// caratteri (aa,mm,gg,hh,mm,ss)
{ // acquisisce la stringa con data ed ora
int y = Serial.parseInt();
tm.Year = y2kYearToTm(y);
tm.Month = Serial.parseInt();
tm.Day = Serial.parseInt();
tm.Hour = Serial.parseInt();
tm.Minute = Serial.parseInt();
tm.Second = Serial.parseInt();
t = makeTime(tm);
RTC.set(t); // aggiorna (setta) il modulo RTC
setTime(t); // aggiorna (setta) il modulo RTC
} // fine del ciclo di acquisizione data ed ora
digits = (second()); // verifica se sono passati 10 secondi dal precedente
// rilevamento della temperatura
lavoro = digits % 10; // calcola il resto del secondo corrente diviso 10
if (lavoro == 9) // se si e' al nono secondo di ogni decade di minuto (se si e'
// al secondo 9, 19, 29, 39, 49 o 59) di ogni minuto
temperatura = RTC.temperature(); // rileva la temperatura
temp1 = temperatura / 4.0; // trasforma il valore rilevato in gradi celsius
esponidati(); // lancia la routine di esposizione dei dati
delay (1000); // aspetta un secondo prima di andare ad esporre nuovi dati, al fine di consentire al display una visualizzazione pulita
//****calcolo della corrente passante sul c.to1****//
float Acslettura1=0.0,campioni1=0.0,media1=0.0,ampere1=0.0;
for (int a1 = 0; a1 < 150; a1++){ //ricavo 150 valori
Acslettura1 = analogRead(A0) ; //leggo valore ritorno acs712 c.to 1
campioni1 = campioni1 + Acslettura1; //sommo i valori per calcolare la media
delay (1); }
media1=campioni1/150.0; //calcolo la media dei valori
ampere1 = (2.5 - (media1 * (5.0 / 1024.0)) )/0.10917; //formula per ottenere il valore definitivo
Serial.println(ampere1); //invio dati monitor seriale
delay(5);
//****calcolo della corrente passante sul c.to2****//
float Acslettura2=0.0,campioni2=0.0,media2=0.0,ampere2=0.0; //definisco DNS
for (int a2 = 0; a2 < 150; a2++){ //ricavo 150 valori
Acslettura2 = analogRead(A1) ; //leggo valore ritorno acs712 c.to 2
campioni2 = campioni2 + Acslettura2; //sommo i valori per calcolare la media
delay(1); }
media2=campioni2/150.0; //calcolo la media dei valori
ampere2 = (2.5 - (media2 * (5.0 / 1024.0)) )/0.10917; //formula per ottenere il valore definitivo
Serial.println(ampere2); //invio dati monitor seriale
delay(5);
//****calcolo della tensione sul c.to1****//
unsigned int v1= 0; //definisco variabile locale per calcoli intermedi
float volt1 =0; //RICHIAMO LA VARIABILE GLOBALE?
for (int v1 = 0; v1<1000; v1++) //ricavo 1000 valori
volt1 = volt1 + ((5.0/1024)*analogRead(A2))*((30+7.5)/7.5)/1000; //formula per risultato finale, con resistenze partitore.
delay(1);
Serial.println(volt1); //invio dati monitor seriale
delay(5);
//****calcolo della tensione sul c.to2****//
unsigned int v2= 0; //definisco variabile solo positiva tensione c.to1
float volt2 =0; //RICHIAMO LA VARIABILE GLOBALE?
for (int v2 = 0; v2<1000; v2++) //ricavo 1000 valori
volt2 = volt2 + ((5.0/1024)*analogRead(A3))*((30+7.5)/7.5)/1000; //formula per risultato finale, con resistenze partitore.
delay(1);
Serial.println(volt2); //invio dati al monitor seriale
delay(5);
//****calcolo della potenza in circolo sul c.to1****//
watt1 = (ampere1 * volt1); //formula risultato finale legge di omh
delay(1);
Serial.println(watt1); //invio dati monitor seriale
delay(5);
//****calcolo della potenza in circolo sul c.to2****//
watt2 = (ampere2 * volt2); //formula risultato finale legge di omh
delay(1);
Serial.println(watt2); //invio dati monitor seriale
delay(5);
//****routine ciclica dei dati su display lcd ****//
lcd.clear(); //PULISCO IL DISPLAY
lcd.begin(16, 2); //INIZIALIZZO IL DISPLAY LCD
delay(50); //PAUSA
lcd.setCursor(0, 0); //STABILISCO LA POSIZIONE DEL CURSORE
lcd.print("A1"); //SCRIVO corrente c.to1
lcd.setCursor(8, 0 ); //STABILISCO LA POSIZIONE DEL CURSORE
lcd.print("V1"); //SCRIVO tensione c.to1
lcd.setCursor(0, 1); //STABILISCO LA POSIZIONE DEL CURSORE
lcd.print("A2"); //SCRIVO corrente c.to2
lcd.setCursor(8, 1); //STABILISCO LA POSIZIONE DEL CURSORE
lcd.print("V2"); //SCRIVO tensione c.to2
lcd.setCursor(3,0);
lcd.print(ampere1);
lcd.print(" "); //ASSEGNO VALORI OTTENUTI
lcd.setCursor(11,0);
lcd.print(volt1);
lcd.print(" "); //ASSEGNO VALORI OTTENUTI
lcd.setCursor(3,1);
lcd.print(ampere2);
lcd.print(" "); //ASSEGNO VALORI OTTENUTI
lcd.setCursor(11,1);
lcd.print(volt2);
lcd.print(" "); //ASSEGNO VALORI OTTENUTI
delay(5000);
lcd.clear(); //PULISCO IL DISPLAY
lcd.begin(16, 2); //INIZIALIZZO IL DISPLAY LCD
delay(50);
lcd.setCursor(0, 0); //STABILISCO LA POSIZIONE DEL CURSORE
lcd.print("W1"); //SCRIVO corrente c.to1
lcd.setCursor(8, 0 ); //STABILISCO LA POSIZIONE DEL CURSORE
lcd.print("Wt1"); //SCRIVO tensione c.to1
lcd.setCursor(0, 1); //STABILISCO LA POSIZIONE DEL CURSORE
lcd.print("W2"); //SCRIVO corrente c.to2
lcd.setCursor(8, 1); //STABILISCO LA POSIZIONE DEL CURSORE
lcd.print("Wt2"); //SCRIVO tensione c.to2
lcd.setCursor(3,0);
lcd.print(watt1);
lcd.print(" "); //ASSEGNO VALORI OTTENUTI
lcd.setCursor(12,0);
lcd.print(Wt1);
lcd.print(" "); //ASSEGNO VALORI OTTENUTI
lcd.setCursor(3,1);
lcd.print(watt2);
lcd.print(" "); //ASSEGNO VALORI OTTENUTI
lcd.setCursor(12,1);
lcd.print(Wt2);
lcd.print(" "); //ASSEGNO VALORI OTTENUTI
delay(5000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.print(day());
lcd.print(' ');
mese = month(); // mememorizza il mese
mese = mese - 1; // diminuisce di 1 il valore del mese poiche' la descrizione del primo mese (gen) inizia all'indirizzo zero della tabella mesi
lcd.print (tabmesi [(mese * 3)]); // espone la prima lettera del mese
lcd.print (tabmesi [(mese * 3 + 1)]); // espone la seconda lettera del mese
lcd.print (tabmesi [(mese * 3 + 2)]); // espone la terza lettera del mese
lcd.print(' ');
lcd.print(year());
lcd.setCursor(0, 1);
lcd.print(hour());
digits = (minute());
printDigits(); // routine esposizione zeri non significativi
digits = (second());
printDigits(); // routine esposizione zeri non significativi
lcd.print (" t:");
lcd.print (temp1);
//****routine di scrittura su SD//****
filesd = SD.open("report.txt", FILE_WRITE); //File in scrittura
if (filesd) // Se il file è stato aperto correttamente
{
filesd.print (day());
filesd.print('-');
filesd.print (month());
filesd.print('-');
filesd.print(year());
filesd.print (',');
filesd.print(hour());
filesd.print (':');
filesd.print (minute ());
filesd.print (':');
filesd.print (second());
filesd.print (',');
filesd.print (ampere1);
filesd.print (',');
filesd.print (volt1);
filesd.print (',');
filesd.print (watt1);
filesd.print (',');
filesd.print (ampere2);
filesd.print (',');
filesd.print (volt2);
filesd.print (',');
filesd.print (watt2);
filesd.print (',');
filesd.println(" "); // Scrivo su file i dati ricevuti
filesd.close(); // Chiude il file su sd
}
}
tipo?
void StampaLcd(void) ? void StampaLcd() ? e dove li metto? fuori dal loop, no?
prima o dopo?
Questo è esattamente quello che non riesco a fare e capire bene.
grazie mille. e buona domenica.
ciao
Claudio
Hai voglia se si può
Comunque, fai una serie di azioni che andrebbero "raccolte" in blocchi funzionali omogenei per migliorare la leggibilità e che potresti eventualmente mettere anche in file diversi da includere nel progetto.
Ad esempio tutto quello che riguarda l'aggiornamento del display lo metti nella sua bella funzioncina, la scrittura della SD stessa cosa, i calcoli dei valori analogici etc etc.
E poi nel loop richiami le funzioni solo quando (e se) servono.
è esattamente quello che volevo fare. è proprio per questo che mi sono rivolto a voi.
cortesemente mi fai un esempio "mirato" e completo.
facciamo il blocco di scrittura?
void scrivi()
{filesd = SD.open("report.txt", FILE_WRITE); //File in scrittura
if (filesd) // Se il file è stato aperto correttamente
{
filesd.print (day());
filesd.print('-');
filesd.print (month());
filesd.print('-');
filesd.print(year());
filesd.print (',');
filesd.print(hour());
filesd.print (':');
filesd.print (minute ());
filesd.print (':');
filesd.print (second());
filesd.print (',');
filesd.print (ampere1);
filesd.print (',');
filesd.print (volt1);
filesd.print (',');
filesd.print (watt1);
filesd.print (',');
filesd.print (ampere2);
filesd.print (',');
filesd.print (volt2);
filesd.print (',');
filesd.print (watt2);
filesd.print (',');
filesd.println(" "); // Scrivo su file i dati ricevuti
filesd.close();
}
void loop()
{
scrivi();
}
io farei così, ho fatto così, ma non funziona. Ovvero , scrivere scrive ; ma solo data ora ed una
bella sequenza di 0,00
Ecco perché sono qua!
Non ti funziona perché per qualche oscuro mistero vai a ridefinire delle variabili locali dentro loop()
float volt1 =0; //RICHIAMO LA VARIABILE GLOBALE?
float volt2 =0; //RICHIAMO LA VARIABILE GLOBALE?
La risposta alla tua domanda nel commento è NO!
Stai definendo una nuova variabile locale che casualmente ha lo stesso nome di una variabile globale già definita.
Dentro loop()
verrà usata la variabile locale e quindi se lasci le istruzioni li ti ritrovi i valori che ti aspetti, ma se definisci una nuova funzione verrà usata la variabile globale a cui non hai mai assegnato alcun valore.
Quindi semplicemente cancella le righe dove ridefinisci le variabili locali.
Ho capito il concetto. Ma ci deve essere qualcos'altro che non quadra.
Ho appena provato.
Se elimino le due variabili locali in questione : la formula "sballa".
Se cambio nome alle globali (e derivanti) : il risultato è la solita sfilza di 0,00
Si dice che la notte porta consiglio...
grazie e buona serata.
Probabilmente perché ti porti dietro il vecchio valore calcolato precedentemente.
Invece di eliminare allora, semplicemente fai un "reset" a 0 del valore dove serve (senza ridichiarare).
volt1 = 0.0;
volt2 = 0.0;
etc
ok, proverò. nei prossimi giorni sono impegnato e avrò poco tempo, ma ci studierò meglio.
rinnovo il grazie.
aggiungo una domanda :
vorrei scrivere e registrare i dati con cadenza oraria/giornaliera (ecco perché ho messo un RTC) e avevo pensato di usare la libreria Time.alarm con una funzione detta alarm.AlarmRepeat
(se non altro perché ho trovato in rete un articolo che mi è parso chiaro , tant'è che riesco già
a giocarci discretamente). ecco, la domanda è questa : è un buon metodo o ce n'è di migliori?
a presto.
Claudio.
RISOLTO !
L' inghippo era tutto nella formula per il calcolo della tensione ; spinto dai vostri consigli e suggerimenti ho fatto un bel respiro e ripreso in mano tutto il codice , stavolta con diverse nozioni e idee più chiare ; ho persino dipanato qualche altra nube nel mio cielo.!
RINGRAZIO TUTTI. GRAZIE DAVVERO.
Ciao
Claudio.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.