Diverse routine void()

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. :wink:
Domani proverò il tutto. a presto

ciao e grazie.
Claudio.

Oltrealle cose che ti hanno giustamente indicato io ci aggiungerei:

  1. posta il programma in chiaro sul forum, possibilmente
    perché chi usa spesso il furbofono ha difficoltà ad aprire un file.ino
  2. indenta, indenta e poi indenta
    che il tuo programma non è male indentato, complimenti, molto meglio della media, ma si può fare di più
  3. possibilmente posta un programma che compili, almeno a me da :
    'RTC' was not declared in this scope
    all'interno della loop

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ò :laughing:

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! :kissing_heart::blush:

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
1 Like

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 ! :heart_eyes::heart_eyes:
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.