Pages: 1 [2] 3 4 ... 9   Go Down
Author Topic: If-Switch-Array-Millis-For  (Read 4146 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Faraday Member
**
Karma: 38
Posts: 5604
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

non funziona ancora

Vado a mangiare, magari a pancia piena penso meglio smiley
Code:
// IF senza delay per alternare Ora/Data
  int AlternaArray[6]={0,0,0,0,0,0};
  
   if (millis() - previousMillis > interval)
   {
    previousMillis = millis();
    
      if (AlternaArray == ClockArray)
       {
       AlternaArray[6];
  DateArray[0] = upperDays;
  DateArray[1] = lowerDays;
  DateArray[2] = upperMonths;
  DateArray[3] = lowerMonths;
  DateArray[4] = upperYears;
  DateArray[5] = lowerYears;
  }
    else
     {
     AlternaArray[6];
       ClockArray[0] = upperHours;
  ClockArray[1] = lowerHours;
  ClockArray[2] = upperMins;
  ClockArray[3] = lowerMins;
  ClockArray[4] = upperSeconds;
  ClockArray[5] = lowerSeconds;
  
  
     // Display.
    DisplayNumberString( AlternaArray );
   }
}
}
« Last Edit: September 25, 2011, 11:39:46 am by Testato » Logged

- [GUIDA] IDE1.x - Nuove Funzioni - Sketch Standalone - Bootloader - VirtualBoard
http://arduino.cc/forum/index.php/topic,88546.0.html
- [LIBRERIA] ST7032i LCD I2C Controller Library
http://arduino.cc/forum/index.php/topic,96163.0.html

0
Online Online
Shannon Member
****
Karma: 117
Posts: 10102
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

allora, ci sono un pò di errori di base.
Se usi il nome di un array SENZA graffe, non stai utilizzando o confrontando TUTTI i suoi valori, ma l'indirizzo di memoria in cui è posizionato l'array (leggiti qualcosa sui puntatori in caso)

questo, a differenza di una copia, fa si che se ad uno dei due array vengono modificati dei valori, anche l'altro array avrà i valori modificati, perchè in realtà sono due "etichette" agli stessi dati, ovvero un'insieme di bit nella ram smiley


quindi dire:
Code:
if (alterna == ClockArray)
equivale a dire: l'array alterna, ha (o meglio punta) lo stesso indirizzo di memoria dell'array ClockArray? sintatticamente è corretto da fare

Code:
alterna = DateArray;
vuol dire, ora alterna dovrebbe puntare all'indirizzo della prima cella di DateArray, e anche questo è corretto (ricorda che modificando alterna, anche i valori contenuti in DateArray risulteranno modificati e viceversa)

Quindi cosa c'è di sbagliato?
molto probabilmente hai dichiarato alterna come un array. gli array sono dei puntatori alla prima cella di memoria di una serie di celle di memoria nella ram (l'array dal punto di vista fisico, appunto). Cambiare questo indirizzo senza prima lanciare una free() su quella zona di memoria vuol dire che finchè il programma è in esecuzione o non termina la visibilità della variabile (savo malloc manuale ma è un'altra storia), quell'aria di memoria viene considerata "in uso" e non può essere riassegnata, è un errore di programmazione. La zona di memoria si dice garbage, e quando il garbage riempie tutta la ram sia il programma, che il sistema operativo possono crashare.
Dunque per evitare problemi, gli array hanno l'indirizzo puntato costante, se non erro. Quindi dobbiamo usare un puntatore.
alterna sarà un puntatore alla prima cella dell'array:

int *alterna;

l'if e l'assegnazione rimangono uguali, persino il display:

Code:
if (alterna == ClockArray)
      alterna = DateArray;
    else
      alterna = ClockArray;
// Display.
    DisplayNumberString( alterna );

come puoi vedere un puntatore può essere tranquillamente sostituito ad un array, l'unica differenza è che l'array si prende da solo una zona memoria, mentre col puntatore devi allocarla manualmente con una malloc(), ma in questo caso non serve perchè usi delle aree di memoria già allicate dai 2 array

spero sia chiaro e che la storia sull'indirizzo dell'array costante sia corretta, perchè non sono affatto sicuro smiley
Logged

my Arduino code: https://github.com/lestofante/arduinoSketch
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

0
Offline Offline
Faraday Member
**
Karma: 38
Posts: 5604
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

tutto qui ?
mi mancava un asterisco ?  smiley

grazie, avevo notato in altri codici quell'asterisco, credevo avesse il significato di carattere jolly  smiley

funziona alla grande, il codice finale e' questo, lo posto per chi si imbattesse in questa discussione:

Code:
  // serve per cambio Ora/Data
  long previousMillis = 0;
  long interval = 3000;
  int *alterna;

Code:
  // IF senza delay per alternare Ora/Data
   
   if (millis() - previousMillis > interval)
   {
    previousMillis = millis();
   
      if (alterna == ClockArray)
      alterna = DateArray;
    else
      alterna = ClockArray;
     
     // Display.
    DisplayNumberString( alterna );
    }
Logged

- [GUIDA] IDE1.x - Nuove Funzioni - Sketch Standalone - Bootloader - VirtualBoard
http://arduino.cc/forum/index.php/topic,88546.0.html
- [LIBRERIA] ST7032i LCD I2C Controller Library
http://arduino.cc/forum/index.php/topic,96163.0.html

0
Offline Offline
Faraday Member
**
Karma: 38
Posts: 5604
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ora devo affrontare la questone dellla gestione del mese, nel frattempo vi chiedo, il problema di overflow del millis, oltre a tutte le funzioni dell'orologio sara' presente anche su questa previousmillis che uso per lo switch, che succede dopo 2 mesi non switchera' piu' tra data e ora ?
Logged

- [GUIDA] IDE1.x - Nuove Funzioni - Sketch Standalone - Bootloader - VirtualBoard
http://arduino.cc/forum/index.php/topic,88546.0.html
- [LIBRERIA] ST7032i LCD I2C Controller Library
http://arduino.cc/forum/index.php/topic,96163.0.html

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

Certamente.
Logged


0
Offline Offline
Faraday Member
**
Karma: 38
Posts: 5604
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ma allora mi chiedo, se millis e' una funzione, ed anche importante e molto usata, perche' non viene aggiornata in modo da gestire automaticamente questo problema ?
Logged

- [GUIDA] IDE1.x - Nuove Funzioni - Sketch Standalone - Bootloader - VirtualBoard
http://arduino.cc/forum/index.php/topic,88546.0.html
- [LIBRERIA] ST7032i LCD I2C Controller Library
http://arduino.cc/forum/index.php/topic,96163.0.html

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

Chiedilo agli sviluppatori di Arduino  smiley-razz
Logged


0
Online Online
Shannon Member
****
Karma: 117
Posts: 10102
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

guardate che funziona lo stesso, credo smiley

millis() - previousMillis > interval

dove interval è una costante, ricordate che sia millis() che previousMillis sono unsigned, quindi NON assumono valori negativi.

lavoriamo con valori da 0 a 63 (6bit), con 64 che è l'overflow, quindi a 64 si ritorna a 0

se previusMillis vale 50, il timer si resetta(a 0), abbiamo:
0 - 50, ovvero -50? no! non ci sono numeri negativi! lavoriamo a bit

000000 -
110010 =
001110 ovvero 14... e guarda caso, è proprio il tempo trascorso tra 50 e 0... 50+14=64, ovvero overflow e si riparte da 0

quindi l'overflow non è gestito da arduino perchè fondamentalmete non necessario. Certo, se parti da 50, si resetta, e ritorni a 50 il tempo trascorso è pari a 0. Quindi in realtà questa cosa ti permette di avere SEMPRE un valore di massimo tempo pari alla grandezza della variabile (pensa sewnza questo trucco cosa succede a 2 secondi dall'overflow... al massimo hai 2 secondi di autonomia!)

Puoi usare un trucco per andare oltre: ogni volta che millis si riazzera, aumenti una variabile. A questo punto il massimo valore memorizzabile è (valori unsigned long)*(valori variabile). con un int mi sa che arrivi tranquillamente fino a fine del sole smiley
ovviamente quando salvi un tempo, non prendi più solo la millis, ma ti salvi anche il numero di reset attuali. A questo punto si complica un poco la matematica: al valore 14 che prima abbiamo trovato, devi aggiungere il valore massimo dell'overflow moltiplicato per il numero di reset di differenza -1. Dato che è un valore non memorizzabile in una variabile standard, è un poco difficile da computare ma credo tu abbia capito cosa intendo, e spero non ti debba mai inbattere in calcoli del genere (che poi in realtà noi tra giorni, mesi e anni bisestili complichiamo la storia mooooolto di più) smiley
Logged

my Arduino code: https://github.com/lestofante/arduinoSketch
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

0
Offline Offline
Faraday Member
**
Karma: 38
Posts: 5604
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

quindi se ho capito potremmo riassumere cosi',

se con millis mi faccio un orologio e quindi la uso per rimpilzare la variabile SECONDI il problema esiste, perche' quando SECONDI ripartira' da Zero l'orario sara' da correggere

mentre se uso millis per altre cose, ad esempio far lampeggiare un led, o nel mio caso switchare diversi dati perso un display non ci interessa l'azzeramento, perche' non ci interessa il valore in se' di millis.

L'unico rpoblema che vedo e' che ad esempio se io voglio far blincare il led 3sec on e 3sec off, se capita che l'overflow accade quando manca un secondo dallo spegnimento, ripartendo da zero sbagliera' i twempi del blink, ma sbagliera' solo la prima volta.

cioe' ogni due mese (unsigned long) capitera' che per un istante il led sbaglia il tempo di blincaggio, ma poi sara' regolare per altri due mesi ?
Logged

- [GUIDA] IDE1.x - Nuove Funzioni - Sketch Standalone - Bootloader - VirtualBoard
http://arduino.cc/forum/index.php/topic,88546.0.html
- [LIBRERIA] ST7032i LCD I2C Controller Library
http://arduino.cc/forum/index.php/topic,96163.0.html

0
Online Online
Shannon Member
****
Karma: 117
Posts: 10102
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

no, con un overflow della variabile tutta la matematica torna perfettamente e non sbaglia mai, a meno che non misuri tempi superiori al tempo di overflow(due mesi), allora devi usare il metodo della variabile esterna che conta gli overflow.

Se conti i secondi invece sbagli, perchè non esiste l'overflow a 60 in binario, al massimo ti avvicini usando 6bit che da 64, ma dato che la alu del atmega pensa in 8bit, sei comunque in una simulazione, quindi tanto vale gestire il tutto con if eccetera. (per le variabili che sono multiple del byte la matematica è più semplice, perchè lunica cosa di cui ti devi preoccupare è il riporto, la matematica avviene via hw spezzando la variabile nei byte)
Logged

my Arduino code: https://github.com/lestofante/arduinoSketch
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

0
Offline Offline
Faraday Member
**
Karma: 38
Posts: 5604
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

sei insostituibile  smiley

permettimi di ricapitolare il ricapitolo:

1- il problema dell'overflow di millis, seppur esistente, non influisce sull'uso che si fa della tecnica BlinkWithoutDelay, i led blinkeranno all'infinito senza sbagliare mai

2- non ha senso scriversi il codice di un orologio perche' ci si imbatte in:
- questo problema di millis(),
- nel rpoblema della gestione dei mesi,
- nel problema della batteria di backup,
- e non so se ce ne siano altri.

 Quindi un bel RTC i2c e via
« Last Edit: September 25, 2011, 12:37:19 pm by Testato » Logged

- [GUIDA] IDE1.x - Nuove Funzioni - Sketch Standalone - Bootloader - VirtualBoard
http://arduino.cc/forum/index.php/topic,88546.0.html
- [LIBRERIA] ST7032i LCD I2C Controller Library
http://arduino.cc/forum/index.php/topic,96163.0.html

0
Online Online
Shannon Member
****
Karma: 117
Posts: 10102
:(){:|:&};: TOX id: fcb8e918bef08581e23f6ddf9d4dba77697c25b217bf372736ed959a95fde36df5b8c5b90fbb
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

2- non ha senso scriversi il codice di un orologio perche' ci si imbatte in:
- questo problema di millis(),
- nel rpoblema della gestione dei mesi,
- nel problema della batteria di backup,
- e non so se ce ne siano altri.

il problema millis può essere aggirato facilmente. per esempio gli RTC NON memorizzano data e ora, ma il numero di secondi trascordi dal 1/1/1900, il faomoso timestamp (da non confondere con lo unix time del 1970 e che non è lineare).
l'overflow di un unsigned long, usato per i secondi anzichè per i millisecondi vuol dire che ha un ordine di magnitudo in più:

un unsigned long conserva come valore massimo 2^32 = 4.2949673 * 10^9, ovvero 4.294.967.300, se sono millisecondi,  si resettano ogni 4294967.3 secondi, ovvero 71582.788 minuti, ovvero 1193.0465 ore, ovvero 49.710271 giorni (circa un mese e mezzo)

se invece sono secondi... 71582788 minuti, o 1193046.5 ore, o 49710.271 giorni, circa 136 anni.....

a partire dai secondi, e con un paio di tabelle in memoria (la durata in giorni dei mesi secondo il calendario gregoriano, e un valore di riferimento che va da 0 a 3 per gli anni bisestili) è una baggianata estrarre giorno ora e data, si tratta di divisioni e resto delle stesse.

La batteria di backup è un problema anche per gli RTC, più che altro che ogni volta che riprogrammi l'atmega devi reinviare anche l'ora perchè cancelli la sua memoria.

PERCHÈ quindi NON si può fare?
questo me l'ha detto uwe le prime volte che bazzicavo nel forum, stupito dal fatto di usare un RTC quando si poteva benissimo fare una cosa simile con 2 calcoli, o al massimo per i più svogliati una libreria.

Il problema è che i quarzi o gli oscillatori che usiamo sono troppo poco precisi! Esistono ovviamente dei clock, ma se non ho capito bene sono intorno ai 30kHz, e non so se si possano settare i fuse o leggere il clock con degli interrupt, teoricamente è meno sbattimento usare un RTC esterno.

edit: avevo sbagliato il calcolo dei secondi conteggiando due volte le ore
« Last Edit: September 25, 2011, 02:59:28 pm by lesto » Logged

my Arduino code: https://github.com/lestofante/arduinoSketch
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

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

Scusa, permettimi di correggerti un calcolo:
Quote
2^32 = 4.2949673 * 10^9
Non è corretto.
2^32 = 4294967296, quello che hai messo tu è un numero in virgola mobile, oltretutto approssimato  smiley-razz
4 byte (32 bit) variano da 0 a 4294967295. Il resto dei tuoi calcoli è giusto.

Infine, i quarzi a cui ti riferisci sono quelli classici da orologio, 32768 Hz o 32.768 kHz

PS:
piccola info, non so se lo sai. L'Atmega328 ha un modulo RTC. Se usi un quarzo da 32768 Hz puoi implementare un orologio RTC in hardware. Resta comunque la scelta migliore l'uso di un RTC esterno con la sua batteria di backup.
Logged


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

PS:
piccola info, non so se lo sai. L'Atmega328 ha un modulo RTC. Se usi un quarzo da 32768 Hz puoi implementare un orologio RTC in hardware. Resta comunque la scelta migliore l'uso di un RTC esterno con la sua batteria di backup.

Ma se lo usi con un quarzo da 32kHz anche il clock va cosí lento?
Ciao Uwe
Logged

0
Offline Offline
Faraday Member
**
Karma: 38
Posts: 5604
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Il discorso della precisione dei quarzo parco l' avevo dimenticato.
Leo per il discorso del timer rtc dei nostri atmega, non si puo usare in contemporanea al quarzo da 16 giusto? cioe tutto lo sketch deve andare a 32k giusto?
Logged

- [GUIDA] IDE1.x - Nuove Funzioni - Sketch Standalone - Bootloader - VirtualBoard
http://arduino.cc/forum/index.php/topic,88546.0.html
- [LIBRERIA] ST7032i LCD I2C Controller Library
http://arduino.cc/forum/index.php/topic,96163.0.html

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