Pages: [1] 2 3 ... 5   Go Down
Author Topic: Loop nel Loop  (Read 3989 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
God Member
*****
Karma: 0
Posts: 589
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ma c'è forse una legge di murphy per cui, più si va avanti con il progetto più iniziano a dare problemi anche le cose semplici? smiley
La frustrazione qua incombe...

Ho il void loop che mostra i dati dei sensori e fa il logging.
Se il loop principale è a 2 secondi, vorrei che il logging fosse ogni 30secondi.

Ho scritto una robina semplicissima ed innocente con un if(now.unixtime() >= ecc e va tutto in palla.
Prima di stare ad ammorbarvi con pagine di codice, mi dite semplicemente come fareste voi?
La cosa più semplice in assoluto smiley

Poi se volete farvi del male le pagine di codice ve le posto pure :\
Help.
Logged

Monselice PD Italy
Offline Offline
Faraday Member
**
Karma: 28
Posts: 5515
фон Крыса
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Il modo più semplice per creare un loop è while(1){ tuo codice } oppure for( ; ; ){ non so se questo va in C }
poi per uscire dal ciclo infinito poni una variabile che quando assume un dato valore trmite un if ti fa fare un salto alla posizione del programma che vuoi te smiley
Logged

Se corri veloce come un fulmine, ti schianterai come un tuono.

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22966
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
unsigned long contatore;

void setup() {
  ...
  contatore=millis()+30000; //30000 ms -> 30 s
}

void loop() {
  ....
  if (millis()>contatore) { //sono passati 30 s
    contatore=millis()+30000;
    fai_quel_che_devi_fare;
  }
}

Inizializzi una variabile unsigned long. Nel setup, cioè nel primo avvio gli dai il valore di millis+30000, ossia metti un "fermo" temporale a 30s.
Nel loop, in fondo, controlli se millis è maggiore di contatore: se sì, vuol dire che sono passati i tuoi 30 s. Quindi reimposti il fermo temporale e poi esegui il codice che devi eseguire.
Logged


Offline Offline
God Member
*****
Karma: 0
Posts: 589
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Leo, dammi una martellata in testa, ti prego smiley
Il codice che avevo scritto io era simile al tuo (usavo unixtime al posto dei mills)... tuttavia grazie a te adesso ho scoperto che cose crea il problema.
Non ho la più pallida idea del perché però, tu lo sai?

Con questo codice, funziona tutto.
Code:
if (millis()>contatore) { //sono passati 55 s
    contatore=millis()+55000;
    Serial.println ("Dati Loggati.");

    //DataLogging
    myFile = SD.open(filename, FILE_WRITE);
    myFile.print(now.unixtime()); // seconds since 2000
    myFile.print(", ");
    myFile.print(now.year(), DEC);
    myFile.print("/");
    myFile.print(now.month(), DEC);
    myFile.print("/");
    myFile.print(now.day(), DEC);
    myFile.print(" ");
    myFile.print(now.hour(), DEC);
    myFile.print(":");
    myFile.print(now.minute(), DEC);
    myFile.print(":");
    myFile.print(now.second(), DEC);
    myFile.print(", ");
    myFile.print(tout); // tout DHT
    myFile.print(", ");
    myFile.print(hout); // rh out DHT
    myFile.print(", ");
    myFile.print(tin); // tin DHT
    myFile.print(", ");
    myFile.print(hin); // rh in DHT
    myFile.print(", ");
    myFile.print(T1); // h20
    myFile.print(", ");
    myFile.print(T2); // hot
    myFile.print(", ");
    myFile.print(frq); // light
    myFile.print(", ");
    if (A3 == HIGH) { //status pin A3 - SSR
      myFile.println("1");
    }
    else {
      myFile.println("0");

    }
    myFile.close();
  }

Però, se a seguire aggiungo queste due righe, che volevo mettere solo per debug e sapere che il ciclo if era stato eseguito... tutto si pianta!. Schermo vuoto, seriale bloccata al debug della sd nel setup.

 
Code:
else {
    Serial.println ( "File non loggati" );
  }

Erano SOLO queste due righe che mi hanno bloccato tutto per ore! Perché??
Logged

BZ (I)
Offline Offline
Brattain Member
*****
Karma: 270
Posts: 21863
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Il modo più semplice per creare un loop è while(1){ tuo codice } oppure for( ; ; ){ non so se questo va in C }
poi per uscire dal ciclo infinito poni una variabile che quando assume un dato valore trmite un if ti fa fare un salto alla posizione del programma che vuoi te smiley

@ratto93
Questo é un stile di programazione brutto. Sia while (1) che for ( ; ; ) funzionano come cicli infiniti. Ma come delay() bloccano il codice. A quel punto é meglio usare delay();
 
@Daniela
Non credo che now.unixtime() esiste su Arduino. La funzione corrispondente é millis()
PS: non credo che Leo picchia delle ragazze.

Ciao Uwe
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22966
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@Daniela:
non so da cosa possa dipendere. Non avendo pubblicato il tuo codice interamente, non so dirti se c'era qualcos'altro a bloccare i cicli.

@Uwe:
now.unixtime appartiene a questa libreria e restituisce l'orario in formato timestamp unix-like
Logged


BZ (I)
Offline Offline
Brattain Member
*****
Karma: 270
Posts: 21863
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@Uwe:
now.unixtime appartiene a questa libreria e restituisce l'orario in formato timestamp unix-like
Se non ho capito male, per quella libreria serve un RTC  DS1307 nel sitema. Ma Daniela ce l'ha?
Ciao Uwe
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22966
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Dovrebbe avercelo perché nell'altro thread, quello dove parlava dei problemi nello scrivere su una SD, diceva appunto che voleva fare un logging dei dati con ora/data di rilevazione.
Logged


BZ (I)
Offline Offline
Brattain Member
*****
Karma: 270
Posts: 21863
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

in quello hai ragione, ma non dice ancora niente su quale modello di RTC.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mi erano capitati dei problemi con un RTC perché lo bombardavo di richieste. A ogni main loop controllavo se l'ora era maggiore di un tot, e tutto andava in malora.

Per avere sempre il tempo ma non chiederlo compulsivamente all'RTC chiedevo a quest'ultimo l'ora, per un secondo nel loop principale la facevo aumentare usando millis() e dopo questo tempo tornavo a sincare l'ora con l'RTC per non perdere definizione.
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22966
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Anch'io suggerivo sul thread relativo alla swRTC di sincronizzarsi con un RTC ogni tot e poi tenere il tempo sul micro con un contatore agganciato a millis. Anche secondo me bombardare di richieste l'RTC non è salutare.
Logged


Offline Offline
God Member
*****
Karma: 0
Posts: 589
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Eccomi qua smiley
Si ho un RTC DS1307, Lib adafruit.
Probabilmente sono un po' confusiva quando cerco aiuto, quindi provo a fare chiarezza.

Il codice di leo  if (millis()>contatore)... funziona.
Il mio codice  if (now.unixtime()>contatore)... funziona. // questo mi fa pensare che non sia un problema di RTC

Se aggiungo un else a seguire del if.
Il codice di leo smette di funzionare e l'arduino si blocca.
Il mio codice smette di funzionare e l'arduino si blocca.

L'else incriminato è:
Code:
else {
    Serial.print("Log non aggiornato");
  }

Due banalissime righe che, se sono presenti, bloccano tutto il codice. Se vengono tolte, tutto funziona alla perfezione, sia con mills che unixtime.
Per bloccare intendo: l'arduino sembra incastrato in un loop infinito nel setup dove inizializza, con apparente successo ("done"), l'SD card.
Ho scoperto questa cosa perché il mio codice unixtime lo scrivevo sempre con l'else (per il debug) mentre quello di leo la prima volta l'ho messo dentro senza else.

Ora, se volete posso pure postarvi tutto il codice, ma sono 400righe, non credo abbiate voglia di leggerlo :\
In più la compilazione avviene senza problemi, quindi senza arduino e sensori c'è poco da vedere.
Tuttavia se siete masochisti come me... ben venga smiley-grin datemi il permesso e ve lo posto.

Inizio veramente a pensare che sia un bug, oggi mi è successo in un altro ciclo if... stesso blocco dell'arduino in loop nel setup. Ho tolto due righe di Serial.print e tutto funziona che è una meraviglia.

Per una ossessiva come me sarebbe bellissimo capire perché ... ma forse devo solo abituarmi che certe risposte non le avrò mai smiley-razz

Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22966
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

A me basterebbe vedere la routine che contiene quel blocco di codice if-then-else. Potresti mettere quella?
Logged


Offline Offline
God Member
*****
Karma: 0
Posts: 589
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A me basterebbe vedere la routine che contiene quel blocco di codice if-then-else. Potresti mettere quella?

Per te questo ed altro smiley

Code:
 
void loop () {
...
...

Serial.println (contatore);
  if (millis()>contatore) { //sono passati 55 s
    contatore=millis()+55000;
    Serial.println ("Dati Loggati.");

    //DataLogging
    myFile = SD.open(nomefilelog, FILE_WRITE);
    myFile.print(now.unixtime()); // seconds since 2000
    myFile.print(", ");
    myFile.print(now.year(), DEC);
    myFile.print("/");
    myFile.print(now.month(), DEC);
    myFile.print("/");
    myFile.print(now.day(), DEC);
    myFile.print(" ");
    myFile.print(now.hour(), DEC);
    myFile.print(":");
    myFile.print(now.minute(), DEC);
    myFile.print(":");
    myFile.print(now.second(), DEC);
    myFile.print(", ");
    myFile.print(tout); // tout DHT
    myFile.print(", ");
    myFile.print(hout); // rh out DHT
    myFile.print(", ");
    myFile.print(tin); // tin DHT
    myFile.print(", ");
    myFile.print(hin); // rh in DHT
    myFile.print(", ");
    myFile.print(T1); // h20
    myFile.print(", ");
    myFile.print(T2); // hot
    myFile.print(", ");
    myFile.print(frq); // light
    myFile.print(", ");
    if (A3 == HIGH) { //status pin A3 - SSR
      myFile.println("1");
    }
    else {
      myFile.println("0");

    }
    myFile.close();
  }

 else {                     
    Serial.println("Log non aggiornato");  //con else tutto si blocca, senza tutto funziona
  }

  delay(1000); // Attendo 1 secondi per ricominciare

}

Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22966
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Non può essere un bug di Arduino. Il seguente codice riproduce ciò che vuoi fare tu:

Code:
unsigned long contatore;

void setup() {
    delay(2000);
    Serial.begin(19200);
    contatore=millis()+5000;
}

void loop() {
    if (millis()>contatore) {
        contatore=millis()+5000;
        Serial.println("Ciao");
    } else {
        Serial.println("Oh...");
    }
    delay(1000);
}
E funziona perfettamente. Quindi è qualcos'altro nel tuo programma, qualcosa che magari hai tralasciato di esaminare.
Logged


Pages: [1] 2 3 ... 5   Go Up
Jump to: