domanda semplice pwm

ciao
sono alle prese con i tutorial per principianti e lentamente inizio ad apprendere qualcosina.
Il tutorial sul pwm accende un led da 0 a 255 e viceversa, vorrei chiedere come posso fermare
il loop a 255 per un tempo desiderato (es. 4 ore) e poi riportarlo a 0 per poi riattivarlo un un tempo desiderato (es. dopo 8 ore)
Pensavo di inserire un orologio che attiva e disattiva il loop ma credo sia fuori dalla mia portata per ora.
grazie
Guido

La funzione millis() restituisce il valore in millisecondi dal momento in cui Arduino parte.

Essendo un contatore tipo unsigned long (4 byte = 32 bit), conta sino a 4.294.967.295 e poi riparte da zero.

Memorizzando il valore di questa funzione con una variabile unsigned long, è facile ricavare il numero di secondi trascorsi da quel momento operando la differenza tra il nuovo valore di millis() e quello memorizzato nella variabile.

GRAZIE Cyberhs
....facile, per ora non è per niente facile :stuck_out_tongue:
non ho ancora affrontato la funzione millis e sulle variabili mi sono un pò arenato.
Comunque gia sapere in che direzione andare è ok
ci lavorerò su, purtroppo ora ho poco tempo...non vedo i millis...ehm l'ora!

cyberhs:
La funzione millis() restituisce il valore in millisecondi dal momento in cui Arduino parte.

Essendo un contatore tipo unsigned long (4 byte = 32 bit), conta sino a 4.294.967.295 e poi riparte da zero.

Memorizzando il valore di questa funzione con una variabile unsigned long, è facile ricavare il numero di secondi trascorsi da quel momento operando la differenza tra il nuovo valore di millis() e quello memorizzato nella variabile.

mi sembra di capire che la millis dopo 49,7.. giorni però torna a zero. Ipotizzando di accendere un led tutti i giorni per un periodo
impostato nella millis, per esempio 3 ore al giorno...cosa succede dopo i 49,7.. giorni? Devo riprogrammare?

Se non sbaglio con leos puoi fare quello che ti.serve e non hai il problema dell overflow.dopo.49.giorni
Oppure puoi comprare un integrato rtc i2c io ne ho uno.costano pochissimo e sono semplici da usare

Se fai la differenza dei 2 tempi in modo corretto l'overflow non pregiudica la correttezza della differenza di tempo. Il problema si pone solo se la differenza di tempo é maggiore di 49,7 giorni.

Ciao Uwe

lucaleo:
Se non sbaglio con leos puoi fare quello che ti.serve e non hai il problema dell overflow.dopo.49.giorni
Oppure puoi comprare un integrato rtc i2c io ne ho uno.costano pochissimo e sono semplici da usare

Come ha detto Uwe, per non incorrere nei problemi dell'overflow di millis basta fare la differenza dei tempi in un certo modo:
http://www.leonardomiliani.com/2012/come-gestire-loverflow-di-millis/
http://www.leonardomiliani.com/2013/programmiamo-i-compiti-con-millis/

lucaleo:
Se non sbaglio con leos puoi fare quello che ti.serve e non hai il problema dell overflow.dopo.49.giorni
Oppure puoi comprare un integrato rtc i2c io ne ho uno.costano pochissimo e sono semplici da usare

cos'è leos? scusa la mia ignoranza...
ho un tiny rtc i2c e con un codice che riproduce un orologio, funziona. Ho possibilità di settare data e ora ed ho
aggiunto due sensori di temperatura che stampano a display.

Il leOS è uno scheduler software basato sui timer (leOS) oppure sul watchdog (leOS2) che permette di schedulare piccoli compiti da far eseguire in background in maniera del tutto indipendente dal codice principale.
C'è una grossa discussione su Megatopic, altro materiale sul mio sito (link in calce).

GRAZIE Leo!
l'ho messo gia nei preferiti e stasera approfondisco come agisce e le differenze fra leOS e leOS2, purtroppo ho bisogno di calma e tranquillità perchè sono argomenti a me nuovi e non proprio semplici.

mi pare di capire che leOS rispetto alla versione 2 tolga funzionalità ai pin 3 e 11.
Complimenti per il sito e per tutto il lavoro che c'è dentro!
Devo essere sincero che per ora non ho capito molto, piu che altro non sono in grado di applicare il concetto a quello che voglio provare.
Come primo progetto vorrei automatizzare l'acquario, so che qui si trova un mare di materiale ma mi piacerebbe realizzarlo con le
mie capacità in modo da aggiungere funzioni man mano che imparo.
Penso che elaborando un proprio codice passo passo si possa imparare, ho gia due temperature a display e per ora mi piacerebbe inserire
un effetto alba e tramonto senza possibilità di regolazioni se non cambiando il codice (per ora) perche vedo impresa difficile fare un menù
di gestione.
Come posso applicare i concetti leOS al mio uso?
GRAZIE
guido

La differenza sostanziale fra il leOS ed il leOS2 è sul "motore" che c'è dietro allo scheduler: nel primo è un timer, nel secondo è il watchdog.
A parte non far perdere le funzionalità di PWM, il leOS2 permette anche di implementare un sistema "antiblocco" molto raffinato per cui si può resettare il micro se un determinato task si è bloccato.

Per fare ciò che dici tu, ci sono tante strade.
Potresti fare un task che semplicemente fa l'incremento del PWM di 1 step ad intervalli regolari. Arrivato al max, potresti bloccare quel task, aspettare il tempo che la luce è on fissa e poi chiamare un altro task che scali il PWM fino a 0.
Oppure fare tutto in un unico task, se sei un pò più... bravino :sweat_smile:

di sicuro la prima soluzione mi sembra la piu probabile...
pensavo a qualcosa del genere, l'esempio fade di arduino

int led = 9;           
int brightness = 0;   
int fadeAmount = 5;    

void setup()  { 
 
  pinMode(led, OUTPUT);
} 
void loop()  { 

  analogWrite(led, brightness);    
  brightness = brightness + fadeAmount;

  if (brightness == 0 || brightness == 255) {
  ////////////  fadeAmount = -fadeAmount ; 
  }        
  delay(30);                            
}

devo però capire come applicare leOS2

tu metti dentro a un task quello che vuoi fare e leos si occupa di farlo al momento giusto :smiley:
non l'ho mai usato ma ho letto più volte i vari articoli e questo è il sunto che faccio da principiante :smiley:
dovrebbe essere giusto :wink:

leOS2 differisce da leOS per un altro aspetto: esso usando il watchdog ha intervalli minimi, o tick, di 16 ms.
Per cui nel tuo esempio, 30 ms diventano su per giù 2 tick.

Una possibile riscrittura del tuo codice con il leOS2 sarebbe la seguente:

#include "leOS2.h"
int led = 9;           
int brightness = 0;   
int fadeAmount = 5;    
leOS2 myOS;

void setup()  { 
  myOS.begin();
  myOS.addTask(doFading, 2, SCHEDULED_IMMEDIATESTART); //2 tick, partenza immediata
  pinMode(led, OUTPUT);
} 
void loop()  { 
}

void doFading() {
  analogWrite(led, brightness);    
  brightness += fadeAmount;

  if (brightness == 0 || brightness == 255) {
  ////////////  fadeAmount = -fadeAmount ; 
  }                                
}

non ho ancora provato ma leggendo il codice c'è una cosa che non capisco
come faccio a mantenere 255 per x periodo?
il codice mi sembra che regola il fade in però a quel punto dovrei bloccarlo per il periodo desiderato.
potrei poi ripetere il codice in maniera opposta così da chiudere il fade

ok posto sottoforma di codice quello che ho in mente:

#define LED 9 /////////////////// definisco pin
int i = 0;    /////////////////// uso per contare su e giu

void setup() {
  pinMode(LED, OUTPUT); ///////// dico che il pin è output
}

void loop(){
  delay(3000);   //////////////// imposto tempo spento
  

  for (i = 0; i < 255; i++) { // fade in
    analogWrite(LED, i);      // set the LED brightness
    delay(10);     ///////////// imposto tempo acceso
  }

  for (i = 255; i > 0; i--) { // fade out

    analogWrite(LED, i);      // set
    delay(10);          //////// imposto tempo alba, tramonto
    pinMode(LED,LOW);         // spengo completamente il led
  }
}

così mi sembra che sia ok, l'ho provato velocemente e funziona, ora si tratta di applicare leOS per inserirlo all'interno del codice di base che è l'orologio con le temperature

gutty:
ok posto sottoforma di codice quello che ho in mente:

#define LED 9 /////////////////// definisco pin

int i = 0;    /////////////////// uso per contare su e giu

void setup() {
 pinMode(LED, OUTPUT); ///////// dico che il pin è output
}

void loop(){
 delay(3000);   //////////////// imposto tempo spento

for (i = 0; i < 255; i++) { // fade in
   analogWrite(LED, i);      // set the LED brightness
   delay(10);     ///////////// imposto tempo acceso
 }

for (i = 255; i > 0; i--) { // fade out

analogWrite(LED, i);      // set
   delay(10);          //////// imposto tempo alba, tramonto
   pinMode(LED,LOW);         // spengo completamente il led
 }
}




così mi sembra che sia ok, l'ho provato velocemente e funziona, ora si tratta di applicare leOS per inserirlo all'interno del codice di base che è l'orologio con le temperature

È leos a farti da orologio
Tu devi.fare vari task con i pezzi di codice che ti servono e poi dici a leos quando e come eseguirli :wink:

EDIT
@leo72 una domanda
ma se io voglio che leos mi esegua un task per 5 ore per accendere qualcosa (un led dai)
mi conviene fare un task non bloccante con millis che gira per 5 ore e viene fatto partire da leos al momento giusto oppure fare un task accensione led e poi dire a leos dopo 5 ore di eseguire un task spegnimento led?
la seconda opzione mi sembra più pulita e leggera...

Puoi fare in 2 modi:

  1. usare un task usa-e-getta, o one-time task, ossia un task che, una volta eseguito, viene cancellato e rimosso dallo scheduler.
  2. usare un task che, se gli intervalli sono uguali (come nel tuo caso, 5 ore), cambi funzione ogni volta che viene eseguito. La prima volta accende il led, la seconda lo spenge, la terza lo accende, la quarta lo accende ecc..

leo72:
Puoi fare in 2 modi:

  1. usare un task usa-e-getta, o one-time task, ossia un task che, una volta eseguito, viene cancellato e rimosso dallo scheduler.
  2. usare un task che, se gli intervalli sono uguali (come nel tuo caso, 5 ore), cambi funzione ogni volta che viene eseguito. La prima volta accende il led, la seconda lo spenge, la terza lo accende, la quarta lo accende ecc..

giustissimo hai ragione basta
statoLed =! statoLed ogni 5 ore :smiley: