[Risolto] Blink con millis() lettura PPM con pulseIn() Ritardi e Problemi

Devo far lampeggiare 2 led come fossero i lampeggianti della polizia, quindi 2 impulsi 1° e poi 2 impulsi il secondo, ora col delay è semplicissimo da fare, ma tentando di farlo utilizzando millis() sono riuscito a far fare 2 lampeggi e poi si ferma, test fatto con un led singolo... AIUTO!!!!

int ledPin = 13;
int led = 0;
int value = LOW;
long previousMillis = 0;
long interval = 100;
long interval2 = 1000;
 
void setup()
{
  pinMode(ledPin, OUTPUT);
}
 
void loop()
{


 
  if(ledPin==HIGH)
  {
    led++;
    if(led<2)
      if (millis() - previousMillis > interval) {
        previousMillis = millis();
 
        if (value == LOW)
          value = HIGH;
        else
          value = LOW;
        digitalWrite(ledPin, value);
      }
      if (led == 2){
        if (millis() - previousMillis > interval2) {
          previousMillis = millis();     
          led = 0;  
        }
      }
    }  
}

Ricordando che sono un super ignorante in materia

cos'è sta roba if( ledPin=HIGH) ???e poi fa un assegnamento,NON un confronto :grin:

Hai visto negli esempi dell'IDE "Blink without delay"?

si ed è proprio da quell'esempio che nasce quel che ho scritto, il fatto è che in quell'esempio i tempi d'accensione e spegnimento sono di 1000, io invece devo fare 2 accensioni a 100 con pausa 100 fra loro e pausa lunga a 1000, e una volta fatto ciò devo fare la stessa condizione ad un secondo led che lampeggi nella pausa lunga del primo

Ho buttato giù 2 righe.
Fanno un lampeggio singolo a intervalli diversi.
Come spunto di partenza potrebbe andare.

int Led1 = 7;
int Led2 = 8;

long previousMillis1 = 0;
long previousMillis2 = 0;
long interval1 = 100;
long interval2 = 1000;

void setup()
{
  pinMode(Led1, OUTPUT);
  pinMode(Led2, OUTPUT);
  digitalWrite(Led1, LOW);
  digitalWrite(Led2, LOW);
  previousMillis1 = millis();
  previousMillis2 = millis();
}

void loop()
{
  if (millis() - previousMillis1 > interval1) {
    flash(Led1, 50);
    previousMillis1 = millis();
  }
  if (millis() - previousMillis2 > interval2) {
    flash(Led2, 50);
    previousMillis2 = millis();
  }
}

void flash( int pinled, int duration)
{
  digitalWrite(pinled, HIGH);
  delay(duration);
  digitalWrite(pinled, LOW);
}

ma così usi il delay, mi pare che lui non voglia usarlo...

ok.
La mia voleva essere solo una base di partenza per l'uso di due intervalli di lampeggio diversi.
Dovrebbe, infatti, sostituire alla funzione flash la parte della logica con gli stati HIGH e LOW e, in seguito inserire il secondo lampeggio.

in teoria potresti farlo con un solo millis visto che il tempo on è uguale a quello off assegnando a delle variabili i passaggi 1-2-3, di conseguenza anche il n° del led cambia a seconda del passaggio in cui si trova il prog, al passaggio n°2 il tempo diventa 1000 per poi ricominciare.

La strada è quella di Pablos, si tratta di una sequenza di accensioni/pause per cui è molto facile da gestire.
Ipotizzando che la luce di destra la chiamiamo L1 e la luce di sinistra L2, la sequenza è:
L1-ON-100
L1-OFF-100
L1-ON-100
L1-OFF-100
PAUSA-100
L2-ON-100
L2-OFF-100
L2-ON-10
L2-OFF-100
PAUSA-100

e ripartire da zero. Sono quindi 10 condizioni distanziate di 100 ms l'una dall'altra. Basta usare una variabile per indicare il punto della sequenza. Ogni 100 ms si incrementa questa variabile e poi si controlla quale azione si deve eseguire. Dopo la 10ma azione, si azzera la variabile così che la sequenza riparta.

il fatto per cui non posso utilizzare il delay è xkè devo in contemporanea leggere 8 ingressi ppm e restituire 10 uscite derivate, di conseguenza il delay mi blocca tutto il resto del programma... ora la cosa folle è che riesco a lavorare con i ppm e non riesco a far lampeggiare 2 led senza che rompano i così detti....

scrivi l'esatta sequenza dei lampeggi es led 1 acceso 100 millisecondi spento 200 millisecodi , acceso ect
scrivi anche se millis () e usato anche da qualcos'altro nel programma

GINGARDU:
scrivi l'esatta sequenza dei lampeggi es led 1 acceso 100 millisecondi spento 200 millisecodi , acceso ect
scrivi anche se millis () e usato anche da qualcos'altro nel programma

l'ha scritta LEO.

Led 1 Led 2 Tempo
off off 0
on off 100
off off 200
on off 300
off off 400
off on 500
off off 600
off on 700

nessun altro utilizzo per millis
il resto è tutto ricezione ppm ed esecuzione

sto facendo varie prove, ma ogni cosa faccio non riesco ad uscire dalla prima istruzione, nel senso che se gli dico di lampeggiare ogni 100 ms non riesco a fargli fare una pausa di 1000 ms e poi ricominciare il ciclo di 100

google ricerca "Arduino police led millis"
http://www.cmiyc.com/tutorials/arduino-example-police-lights-with-millis/
http://www.cmiyc.com/blog/2011/01/06/millis-tutorial/

DriftBoy:
Led 1 Led 2 Tempo
off off 0
on off 100
off off 200
on off 300
off off 400
off on 500
off off 600
off on 700

nessun altro utilizzo per millis
il resto è tutto ricezione ppm ed esecuzione

sto facendo varie prove, ma ogni cosa faccio non riesco ad uscire dalla prima istruzione, nel senso che se gli dico di lampeggiare ogni 100 ms non riesco a fargli fare una pausa di 1000 ms e poi ricominciare il ciclo di 100

hai scritto una sequenza di 700 millisecondi
e poi parli di riritardare un secondo,

scrivila completa con le pause complete che vuoi usa la stesso schemino che hai fatto ma scrivila tutta

scrivi anche su che pin hai i due led

pablos:
google ricerca "Arduino police led millis"
http://www.cmiyc.com/tutorials/arduino-example-police-lights-with-millis/
http://www.cmiyc.com/blog/2011/01/06/millis-tutorial/
Arduino Police Strobe (w/ millis()) - Pastebin.com

Direi perfetto :wink:

DriftBoy:
Led 1 Led 2 Tempo
off off 0
on off 100
off off 200
on off 300
off off 400
off on 500
off off 600
off on 700

nessun altro utilizzo per millis
il resto è tutto ricezione ppm ed esecuzione

sto facendo varie prove, ma ogni cosa faccio non riesco ad uscire dalla prima istruzione, nel senso che se gli dico di lampeggiare ogni 100 ms non riesco a fargli fare una pausa di 1000 ms e poi ricominciare il ciclo di 100

un sistema abbastanza comprensibile per chi è nuovo e questo,
non c'e molto da spiegare (anche se millis non l'ho capito bene nemmeno io)

se millis() si trova entro un determinato tempo accende o spegne il led

ovviamente se vuoi modificare il tempo di accensione mettiv quello che vuoi,
l'importante che alla fine del ciclo metti

if (millis()>1400) timer0_millis = 0;
questa riga appena millis () arriva a 1400 (1,4 sec) porta a zero millis ()
e tutto ricomincia da capo

(ovviamente al posto di 1400 devi mettere il tempo totale del ciclo se lo modifichi i parametri di lampeggio)

ps:
sicuramente ci saranno anche altri sistemi per ottenere lo stesso risultato

extern unsigned long timer0_millis; 

void setup() { 

  pinMode(12, OUTPUT); 
  pinMode(13, OUTPUT); 
digitalWrite(13,LOW); 
digitalWrite(12,LOW);
} 

void loop(){ 

  if (millis()>100 && millis()<200) digitalWrite(13,HIGH); 
  if (millis()>200  && millis()<300) digitalWrite(13,LOW); 
  
  if (millis()>400 && millis()<500) digitalWrite(13,HIGH); 
  if (millis()>600  && millis()<700) digitalWrite(13,LOW); 
  
  if (millis()>700 && millis()<800) digitalWrite(12,HIGH); 
  if (millis()>900  && millis()<1000) digitalWrite(12,LOW); 
  
  if (millis()>1100 && millis()<1200) digitalWrite(12,HIGH); 
  if (millis()>1300  && millis()<1400) digitalWrite(12,LOW); 

  

  if (millis()>1400) timer0_millis = 0;
}

GINGARDU:
anche se millis non l'ho capito bene nemmeno io

Cos'è che non ti è chiaro?
Cerco di riassumerti brevemente.
Millis() altro non è che una funzione che restituisce il numero di millisecondi dall'avvio dell'Arduino. E' un contatore a 32 bit che viene incrementato da una porzione di codice inserita all'interno della ISR che gestisce l'overflow del timer 0.
Chiamando millis() hai indietro un valore numerico, un contatore temporale. E' come "leggere" l'orario su un orologio che ha solo un'unità di misura, i millisecondi appunto.

Quando si fa un controllo tipo con un if sul valore di millis non si fa altro che fare un check sul valore che assume una variabile. Se tu leggi una porta analogica e devi compiere una certa operazione se la lettura è superiore ad X, fai un semplice:
if (analogRead(porta) > X) { .... }

Con millis() fai lo stesso. Chiedi a millis() il valore del contatore di millisecondi ed agisci di conseguenza. Esempio:
if (millis() > 1000) { .... }
Ovviamente questo codice ha poco senso perché verrà usato solo 1 volta, esattamente 1 secondo dopo l'avvio dell'Arduino. Questo perché il valore del contatore di millisecondi cresce continuamente e tu saresti un mago se tu potessi sapere in ogni istante che valore assume. Perciò si ricorre al semplice trucco di fissare una specie di "istante zero" e calcolare il tempo a partire da quell'istante. Come si fissa l'istante zero? Facendo una semplice lettura di millis() e poi aggiungengo l'intervallo desiderato. Se ad esempio vogliamo che una data azione sia eseguita ogni 5 secondi, si farà un qualcosa del genere:

unsigned long temporizzatore; //creo una variabile per contenere il valore di millis()
void setup() {
  temporizzatore = millis(); //assegno a temporizzatore il valore attuale di millis() - creo cioè l'istante zero
}

void loop() {
  if (millis() > (temporizzatore + 5000)) { //controllo se sono passati 5 secondi dal mio istante zero
    ..... //eseguo il mio codice
    temporizzatore = millis(); //ricreo nuovamente l'istante zero
  }
  ....... //altro codice
}

Così ad ogni loop controllo se sono passati 5 secondi dall'istante zero. Se sono passati, eseguo il mio compito e poi ricreo l'istante zero da cui ricontare altri 5 secondi. E così via.

IL fatto è che, chi è nuovo all'argomento ha sempre tanta confuzione chi invece ha capito una volta per tutte una certa cosa poi avra sempre piu dimistichezza,

millis() e una cosa che inizia e poi "scappa" all'infinito (mai si ferma),
millis () nudo e crudo lo si puo adoperare quasi per niente

come hai scritto tu bisogna sempre costruirgli un programmino attorno
che da solo non si puo "guardare"

GINGARDU:
IL fatto è che, chi è nuovo all'argomento ha sempre tanta confuzione chi invece ha capito una volta per tutte una certa cosa poi avra sempre piu dimistichezza,

millis() e una cosa che inizia e poi "scappa" all'infinito (mai si ferma),
millis () nudo e crudo lo si puo adoperare quasi per niente

come hai scritto tu bisogna sempre costruirgli un programmino attorno
che da solo non si puo "guardare"

è il prezzo (piccolo) da pagare per non bloccare il processore, a volte non serve a nulla, a volte è indispensabile :slight_smile: millis si ferma, anche se gli servono un bel po' di giorni....