Go Down

Topic: If-Switch-Array-Millis-For (Read 5850 times) previous topic - next topic

ratto93



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

Dovrebbe essere il quarzo standard da 4/8/16/20 Mhz che gli da il clock di "base" + questo quarzo applicato tra due pin del micro come negli MSP430....
Se corri veloce come un fulmine, ti schianterai come un tuono.

leo72

RTC sta per Real Timer Counter, non Real Time Clock.
Se imposti la fonte del clock per il timer 2 in modo asincrono, puoi attivare l'oscillatore interno per la CPU e puoi usare i pin esterni 9 e 10 (quelli a cui normalmente colleghi il quarzo) per attaccarci un cristallo a 32768 Hz, il contatore è calibrato proprio per questa frequenza.

Impostando un prescaler a 128, hai un overflow esattamente ogni secondo. E con poche righe di codice puoi metter su un piccolo orologio senza usare RTC esterni.

lesto



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


mi sa di sì, per questo suggerisco di leggere il quarzo con degli interrupt, così hai un quarzo a 16MHz per la parte logica e uno a 32kHz per la parte RTC. Arduino non dovrebbe aver problemi da questo punto di vista, essendo molto più veloce, e ci perdi solo uno o due pin (non so come funziona un quarzo, penso che da una parte gli dai vcc e dall'altra ti arriva un impulso ogni tot)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

leo72

Mi quoto

RTC sta per Real Timer Counter, non Real Time Clock.
Se imposti la fonte del clock per il timer 2 in modo asincrono, puoi attivare l'oscillatore interno per la CPU e puoi usare i pin esterni 9 e 10 (quelli a cui normalmente colleghi il quarzo) per attaccarci un cristallo a 32768 Hz, il contatore è calibrato proprio per questa frequenza.

Impostando un prescaler a 128, hai un overflow esattamente ogni secondo. E con poche righe di codice puoi metter su un piccolo orologio senza usare RTC esterni.

Quindi vai a 8 MHz: non sono molti ma se devi gestire solo un orologio sono anche troppi  :P

Testato

#34
Sep 26, 2011, 03:09 pm Last Edit: Sep 26, 2011, 03:15 pm by Testato Reason: 1
Ottimo, quindi non si usa millis per poi avere i secondi, e non c'e il problema di millis giusto ?.
In piu come precisione dovremmo stare meglio del risuonatore della Uno
Rimane il problema batteria, si deve fare in modo di consumare il meno possibile quando manca la 220v, trovare uno standby che non faccia perdere orario.
Purtroppo non posso usarlo nel mio nixie perché avrei problemi sulla velocità del multiplex
La mia idea e' di passare a 20 Mhz, +rtc esterno.
Ma in futuro userò questa tecnica. Grazie.
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Testato

#35
Sep 26, 2011, 09:10 pm Last Edit: Sep 26, 2011, 09:13 pm by Testato Reason: 1
Volendo allargare la visualizzazione anche ad un terzo elemento, la temperatura, e volendo gestire separatamente i tempi di visualizzazione di un dato rispetto ad un altro, devo cambiare la struttura dell'if

ho provato a fare da solo ma non funziona, c'e' per caso qualche altro asterisco da mettere :) ?

Code: [Select]
unsigned long intervallo=millis();

if (intervallo = 3000) {
  alterna = ClockArray;
  }
if (intervallo = 6000) {
  alterna = DateArray;
  }
if (intervallo = 9000) {
  intervallo = TempArray;
  }
if (intervallo = 12000) {
  intervallo = 0;
  }

   DisplayNumberString( alterna );
}


piu' precisamente viene visualizzata solo la data
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

lesto

stai usando un solo =, ovvero assegnazione, invece che il doppio ==, uguaglianza
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Testato

Errore banale grazie
Ma guardando meglio lo sketch credo che non funzioni lo stesso perché resetto a zero la var intervallo, ma poi intervallo ridiventa uguale a millis, quindi funziona solo al primo loop giusto ?
Non posso scrivere millis=0 perché sballerebbe tutte le altre funzioni basate su di esso
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Testato

Non ditemi nulla, forse ci sono arrivato, domani provo e vi dico :)
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

Testato

#39
Sep 27, 2011, 09:43 am Last Edit: Sep 27, 2011, 09:48 am by Testato Reason: 1
ci sono riuscito, avrei una domanda in merito:
Code: [Select]
 alterna = ClockArray;

 if(runTime>DATA+3000){
 alterna = DateArray;
 }
 
 if(runTime>reset_timer+8000){
 DATA=runTime;
 reset_timer=runTime;
 }

     // Display.
   DisplayNumberString( alterna );
}



a questo punto mi chiedo, come mai funziona ?
infatti non mi spiego una cosa:
- nei primi 3 secondi Alterna contiene solo l'orario
- tra i 3 secondi  e i 6 secondi alterna viene riempito dall'orario, ed immediatamente dopo dalla data, cioe' per 3 secondi guardando il listato mi aspetterei un lampeggio tra data e ora. Come mai invece funziona regolarmente ? il secondo dato prende il sopravvento sul primo ?
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

leo72

Premetto che non ho capito cosa il tuo sketch deve visualizzare né cosa tu ottieni, però la porzione di codice che hai postato dice di fare questo:

1) carica in alterna ClockArray
2) runTime è maggiore di DATA+3000?
2.Sì) assegna ad alterna il DateArray
2.No) prosegui
3) runTime è maggiore di reset_timer+8000?
3.Sì) assegna a DATA ed a reset_timer runTime
3.No) prosegui
4) visualizza alterna

Quindi, prima che il controllo al punto 2) sia vero, alterna contiene clockArray. Dopo che il controllo al punto 2) è vero, alterna contiene DateArray. Se poi il controllo al punto 3) è vero, viene ripristinato tutto.

Tu dici:
Quote
guardando il listato mi aspetterei un lampeggio tra data e ora

Immagino che tu voglia visualizzare alternativamente le info. Se è così, immagino che in un punto del codice prima di quello che hai postato tu visualizzi qualcos'altro. Ma se non scrivi un sistema per far sì che l'informazione precedente rimanga un po' sullo schermo, vedrai solo sovrapporsi le 2 scritte quasi istantaneamente.

lesto


- nei primi 3 secondi Alterna contiene solo l'orario
- tra i 3 secondi  e i 6 secondi alterna viene riempito dall'orario, ed immediatamente dopo dalla data, cioe' per 3 secondi guardando il listato mi aspetterei un lampeggio tra data e ora. Come mai invece funziona regolarmente ? il secondo dato prende il sopravvento sul primo ?


tu il dato lo invii al led solo DOPO aver fatto questo doppio passaggio, attraverso DisplayNumberString. Quindi in alterna puoi metterci quello che vuoi, finchè non lo dai un pasto al display esso non cambierà la scritta.

se anche fosse che il display non avesse bisogno di essere "alimentato", ma si autosettasse in base al valore di Alterna (cosa direi impossibile da fare in C, dovresti gestire un'interrupt sull'assegnazione della variabile, con il C++ e le classi si può fare), il tempo di settaggio, un if, e un secondo settaggio, vedrai la prima scritta apparire e scomparire talmente in fretta che difficilmente la noterai.
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Testato

mi ero perso una graffa :)
credevo di spedire al display i valori in continuazione, fuori dalla sezione degli if, invece l'ho messa dentro e quindi ora mi e' chiaro.
Come giustamente detto da entrambi funziona perche i dati li invio solo alla fine di tutti gli if.

altra domanda,
(e ringrazio che mi stiate seguendo in domande facili, spero di fare altrettante in ambito elettronico se necessario)

E normale ragionare cosi' ? mi spiego:
Nel pezzo di codice di cui sopra (per leo, e' proprio questo il pezzo dicodice che uso per far apparire 3 secondi l'orologio sulle nixie mie , quelle dell'avatar, e per 5 secondi la data, ed in futuro per 4 secondi la temperatura, in alterna spedisco i vari array di dati)

Guardando il codice, per i primi 3 secondi inseriamo l'orario in ALTERNA e poi direttamente al display, mentre al 4 secondo PRIMA ci mettiamo l'orario, e DOPO ci mettiamo la data. Per 5 secondi interi, che a 16MHz sono una marea di volte, scriviamo prima l'orario e poi subito dopo la data. Questo e' normale ? non sarebbe piu' pulito, che cosi' come nei primi 3 secondi in ALTERNA mettiamo solo l'orario, anche nei successivi 5 ci mettessimo solo la data ?

Immaginiamo voler visualizzare 10 parametri, quando dovremo scrivere a display il 10, PRIMA metto in ALTERNA i precedenti 9 valor, inutilmente, e solo al decimo ci metto quello che mi serve.

In poche parole, se anche non comporta problemi di visualizzazione mi sembra uno spreco computazionale, forse ragiono troppo da elettronico, ma mai mi immaginerei di fare un circuito che prima di accendere la decima lucetta, che mi interessa, accendesse prima le altre 9 che non mi servono, anche se questo non comporterebbe problemi non lo farei.

grazie in anticipo

vi ho segnato a credito 10 TEST gratuiti a testa  :)

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

lesto

ahah spero di farteli usare presto i test gratuiti :-)

comunque non è stilisticamente sbagliato assegnarne un valore ad una variabile, per poi assegnarne un altro.
Ti spiego. all'inizio in ALTERNA io metterei il valore NULL, poi fai la serie di if o uno switch (se la logica lo permette) per assegnarci i vari valori da stampare. Se alla fine degli if ALTERNA è ancora NULL allora c'è stato un errore. Problema: se lasci il null sai dell'errore, ma se non lo gestisci rischi di impallare il micro. Quindi per ora il tuo metodo va più che bene. tanto la RAM non ha problemi di riscritture (e meno male!)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

leo72

Basta che tu metta un doppio controllo nell'if.

Code: [Select]
if((runTime>DATA+3000) && (runTime<reset_timer+8000)) {
  alterna = DateArray;


Così assegni DateArray ad alterna solo quando runTime è compreso nell'intervallo.
Un altro metodo è invertire gli if, mettendo come primo il controllo sul valore più alto e poi a scalare fino a quello col valore più basso usando gli else. In questo modo, a cascata, gli assegnamenti vengono fatti solo 1 volta.

Code: [Select]
a=0;
if (b>100) {
  a=50;
} else if (b>50) {
  a=25;
} else if (b>25) {
  a=12;
} else {
  a=6;
}


In questo modo l'assegnamento viene fatto solo 1 volta. Nel tuo caso può diventare così:

Code: [Select]
  if (runTime>reset_timer+8000) {
    DATA=runTime;
    reset_timer=runTime;
  } else if(runTime>DATA+3000) {
    alterna = DateArray;
  }


Go Up