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

E' sbagliato il fatto che la pulseIn è una funzione che ferma l'esecuzione del codice in attesa del verificarsi dell'evento da misurare oppure per timeout della funzione stessa. Il timeout è impostato di default a 1 secondo, se non ricordo male, per cui con 4 pulseIn il tempo massimo di arresto dello sketch può, in teoria arrivare anche a 4 secondi se nessuno dei 4 segnali viene rilevato.

quindi se rileva tutti i segnali pulseIn anche se non della misura dell'if tutto il programma dovrebbe andare senza problemi?

allora collegati tutti i pulseIn e la situazione migliora molto, il lampeggio + o - va e cioè 1 led lampeggia come dovrebbe invece l'altro si perde i 50ms di pausa

alternativa a pulseIn che genera meno problemi?

Non so se la causa di tutti i tuoi problemi sia la pulseIn, io ti ho solo chiarito come la pulseIn interagisce col tuo codice.

Alternative alla pulseIn? Dipende.
La pulseIn serve a leggere l'intervallo di tempo che passa fra 2 fronti di un segnale. Ti serve proprio questa cosa?

devo leggere un segnale ppm di una ricevente da modellismo ed il pulseIn è l'unico strumento che conosco per leggere suddetto segnale

ma scusa tu alla fine dei conti non vuoi fare solo lampeggiare 2 led se spieghi che progetto è facciamo prima

cosa deve essere? una macchinina telecomandata tutta lampeggiante?

posta tutto il codice completo e una descrizione a grandi linee

e piu o meno quanto tempo dovrebbe durare un ciclo completo di tutte accensioni delle le luci

il codice completo l'ho postato qualche pagina fa

il progetto consiste nel fare l'impianto luci ad un modello radiocomandato da drift (se me la chiamate macchinina telecomandata mi arrabbio!!!!)

il fatto è che in commercio non c'è nulla di quel che voglio io e in + c'è più soddisfazione a farselo da soli

sommariamente
luci posizione PPM
lampeggio fari lunghi alternati PPM
fari lunghi on PPM fari lunghi flash es quando lampeggiate in autostrada per sorpassare mix da radio
4 frecce PPM
posizioni retro parzializzando i led degli stop mix arduino
segnale stop dai mosfet npn del regolatore elettronico digilatRead
retromarcia dal regolatore elettronico digitalRead

allora a quel codice ci sono da fare 2 modifiche
domani te le scrivo (ci va un po di tempo)

ti ringrazio, sei veramente molto gentile, cmq prima di scrivere ricontrolla quì che sto facendo 2 modifiche anche io, magari qualcosina di buono riesco a fare :slight_smile:

Riorganizziamo le idee:

  1. vuoi far lampeggiare dei led e contemporaneamente fare delle letture da dei pin con pulseIn

  2. hai un problema. Cito:

questo spezzone di codice andava da dio e poi da quando ho collegato tutto va solo 1 led a intervalli di 200 ms

  1. ti ho spiegato che la pulseIn rallenta il codice.

  2. Ora, siccome, il lampeggio lo basavi sulla lettura di intervalli temporali letti con millis, deduco che i 4 pulseIn introducano un ritardo tale che i tuoi controlli saltano alcuni if, per cui adesso hai solo determinate condizioni vere.

  3. per verificare che sia questa la causa, togli 1 pulseIn alla volta e guarda se cambia il tempo di lampeggio del led e/o se cambia quale dei 2 led lampeggia.

con il codice sistemato così funziona tutto bene apparte le posizioni in analogwrite su stopOut che si accende ma con una luce veramente troppo debole ma penso che domani risolvo....

int luciPosIn = 2;
int fariLungIn = 3;
int frecceIn = 4;
int lampIn = 5;
int stopIn = 6;
int retroIn = 7;


int luciPosOut = 8;
int faroLung1 = 9;
int faroLung2 = 10;
int stopOut = 11;
int retroOut = 12;
int frecceOut = 13;

int stopInS;
int retroInS;

int val1;
int val2;
int val3;
int val4; //Possibile non necessario!!
int val5 = LOW;

unsigned long previousMillis = 0;
unsigned long interval = 500;

extern unsigned long timer0_millis;

void setup() {
  pinMode(luciPosIn, INPUT); //Input PPM ricevente radio (luciPosIn)
  pinMode(fariLungIn, INPUT); //Input PPM ricevente radio (fariLungIn) Possibile anche lampeggio!!!
  pinMode(frecceIn, INPUT); //Input PPM ricevente radio (frecceIn)
  pinMode(stopIn, INPUT); //Input mosfet regolatore (stopIn)
  pinMode(retroIn, INPUT); //Input mosfet regolatore (retroIn)
  pinMode(lampIn, INPUT); //Input PPM ricevente radio (lampIn) Possibile non necessario!!!
  
  pinMode(luciPosOut, OUTPUT); //Accensione luci posizione
  pinMode(faroLung1, OUTPUT); //Accensione luce profondità !! o lampeggio strobo
  pinMode(faroLung2, OUTPUT); //Accensione luce profondità !! o lampeggio strobo
  pinMode(frecceOut, OUTPUT); //Accensione 4 frecce
  pinMode(stopOut, OUTPUT); //Accensione Stop e posizione posteriore 1/2 potenza
  pinMode(retroOut, OUTPUT); //Accensione retro
  
  digitalWrite(luciPosOut,LOW);
  digitalWrite(faroLung1,LOW);
  digitalWrite(faroLung2,LOW);
  digitalWrite(stopOut,LOW);
  digitalWrite(retroOut,LOW);
  
}

void loop() {
  
  val1 = pulseIn(luciPosIn, HIGH);
  val2 = pulseIn(fariLungIn, HIGH);
  val3 = pulseIn(frecceIn, HIGH);
  val4 = pulseIn(lampIn, HIGH); //Possibile non necessario!!
  
  stopInS = digitalRead(stopIn);
  retroInS = digitalRead(retroIn);
  
  
  if (val1 > 1600) digitalWrite(luciPosOut, HIGH);
  if (val1 < 1600) digitalWrite(luciPosOut, LOW);
  if (val1 > 1600) analogWrite(stopOut, 255);
  if (val1 < 1600) analogWrite(stopOut, 0);
  //if (val1 > 1600 && stopInS == LOW) analogWrite(stopOut, 255);
  //if (val1 < 1600 || stopInS == HIGH) analogWrite(stopOut, 0);
  if (val2 > 1600) digitalWrite(faroLung1, HIGH);
  if (val2 < 1600) digitalWrite(faroLung1, LOW);
  if (val2 > 1600) digitalWrite(faroLung2, HIGH);
  if (val2 < 1600) digitalWrite(faroLung2, LOW);
  if (val3 > 1600) {
    
    if (millis() - previousMillis > interval) {
      
      previousMillis = millis();
      
      if (val5 == LOW)
        val5 = HIGH;
      else 
        val5 = LOW;
      
      digitalWrite(frecceOut, val5);
    }
  }
  if (val3 < 1600) digitalWrite(frecceOut, LOW);
        
  if (val4 > 1600 && val2 < 1600) {
  
    if (millis()>50 && millis()<100) digitalWrite(faroLung1, HIGH);     
    if (millis()>100 && millis()<150) digitalWrite(faroLung1, LOW);
  
    if (millis()>150 && millis()<200) digitalWrite(faroLung1, HIGH);   
    if (millis()>200 && millis()<250) digitalWrite(faroLung1, LOW);
  
    if (millis()>750 && millis()<800) digitalWrite(faroLung2,HIGH);
    if (millis()>800 && millis()<850) digitalWrite(faroLung2, LOW);
  
    if (millis()>850 && millis()<900) digitalWrite(faroLung2,HIGH);
    if (millis()>900 && millis()<950) digitalWrite(faroLung2, LOW); 

    if (millis()>1400) {
      cli();
      timer0_millis = 0;
      sei();  
    }  
  }
  
  if (stopInS == HIGH) digitalWrite(stopOut, HIGH);
  if (stopInS == LOW) digitalWrite(stopOut, LOW);
  if (retroInS == HIGH) digitalWrite(retroOut, HIGH);
  if (retroInS == LOW) digitalWrite(retroOut, LOW);
  
}

leo72:
Riorganizziamo le idee:

  1. vuoi far lampeggiare dei led e contemporaneamente fare delle letture da dei pin con pulseIn

  2. hai un problema. Cito:

questo spezzone di codice andava da dio e poi da quando ho collegato tutto va solo 1 led a intervalli di 200 ms

  1. ti ho spiegato che la pulseIn rallenta il codice.

  2. Ora, siccome, il lampeggio lo basavi sulla lettura di intervalli temporali letti con millis, deduco che i 4 pulseIn introducano un ritardo tale che i tuoi controlli saltano alcuni if, per cui adesso hai solo determinate condizioni vere.

  3. per verificare che sia questa la causa, togli 1 pulseIn alla volta e guarda se cambia il tempo di lampeggio del led e/o se cambia quale dei 2 led lampeggia.

allora si il problema erano i pulseIn ma solo perchè collegavo solo 1 porta alla ricevente quindi gli altri pulsein non leggendo nulla determinavano il rallentamento di tutto il codice generando i problemi sopracitati, collegando il tutto invece (quindi tutti i pulseIn con segnali ppm) la situazione è migliorata, ho riaggiustato un pochino il codice e risulta al 99% tutto ok

grazie mille a tutti per l'aiuto, se vi viene un idea per l'1% mancante ne sarei felice

Che ti avevo detto? :wink:

leo72:
E' sbagliato il fatto che la pulseIn è una funzione che ferma l'esecuzione del codice in attesa del verificarsi dell'evento da misurare oppure per timeout della funzione stessa. Il timeout è impostato di default a 1 secondo, se non ricordo male, per cui con 4 pulseIn il tempo massimo di arresto dello sketch può, in teoria arrivare anche a 4 secondi se nessuno dei 4 segnali viene rilevato.

ok risolto tutto, domani posto il codice e modifico il titolo!!!!!

Codice Perfettamente funzionante (con tutti i pulseIn collegati "fonte leo72")

int luciPosIn = 2;
int fariLungIn = 3;
int frecceIn = 4;
int lampIn = 5;
int stopIn = 6;
int retroIn = 7;


int luciPosOut = 8;
int faroLung1 = 9;
int faroLung2 = 10;
int stopOut = 11;
int retroOut = 12;
int frecceOut = 13;

int stopInS;
int retroInS;

int val1;
int val2;
int val3;
int val4; //Possibile non necessario!!
int val5 = LOW;

unsigned long previousMillis = 0;
unsigned long interval = 500;

extern unsigned long timer0_millis;

void setup() {
  pinMode(luciPosIn, INPUT); //Input PPM ricevente radio (luciPosIn)
  pinMode(fariLungIn, INPUT); //Input PPM ricevente radio (fariLungIn) Possibile anche lampeggio!!!
  pinMode(frecceIn, INPUT); //Input PPM ricevente radio (frecceIn)
  pinMode(stopIn, INPUT); //Input mosfet regolatore (stopIn)
  pinMode(retroIn, INPUT); //Input mosfet regolatore (retroIn)
  pinMode(lampIn, INPUT); //Input PPM ricevente radio (lampIn) Possibile non necessario!!!
  
  pinMode(luciPosOut, OUTPUT); //Accensione luci posizione
  pinMode(faroLung1, OUTPUT); //Accensione luce profondità !! o lampeggio strobo
  pinMode(faroLung2, OUTPUT); //Accensione luce profondità !! o lampeggio strobo
  pinMode(frecceOut, OUTPUT); //Accensione 4 frecce
  pinMode(stopOut, OUTPUT); //Accensione Stop e posizione posteriore 1/2 potenza
  pinMode(retroOut, OUTPUT); //Accensione retro
  
  digitalWrite(luciPosOut,LOW);
  digitalWrite(faroLung1,LOW);
  digitalWrite(faroLung2,LOW);
  digitalWrite(stopOut,LOW);
  digitalWrite(retroOut,LOW);
  
}

void loop() {
  
  val1 = pulseIn(luciPosIn, HIGH);
  val2 = pulseIn(fariLungIn, HIGH);
  val3 = pulseIn(frecceIn, HIGH);
  val4 = pulseIn(lampIn, HIGH); //Possibile non necessario!!
  
  stopInS = digitalRead(stopIn);
  retroInS = digitalRead(retroIn);
  
  
  if (val1 > 1600) digitalWrite(luciPosOut, HIGH);
  if (val1 < 1600) digitalWrite(luciPosOut, LOW);
  if (val1 > 1600 && stopInS == LOW) analogWrite(stopOut, 10);
  if (val1 > 1600 && stopInS == HIGH) analogWrite(stopOut, 255);
  if (val1 < 1600 && stopInS == HIGH) analogWrite(stopOut, 255);
  if (val1 < 1600 && stopInS == LOW) analogWrite(stopOut, 0);  
  if (val2 > 1600) digitalWrite(faroLung1, HIGH);
  if (val2 < 1600) digitalWrite(faroLung1, LOW);
  if (val2 > 1600) digitalWrite(faroLung2, HIGH);
  if (val2 < 1600) digitalWrite(faroLung2, LOW);
  if (val3 > 1600) {
    
    if (millis() - previousMillis > interval) {
      
      previousMillis = millis();
      
      if (val5 == LOW)
        val5 = HIGH;
      else 
        val5 = LOW;
      
      digitalWrite(frecceOut, val5);
    }
  }
  if (val3 < 1600) digitalWrite(frecceOut, LOW);
        
  if (val4 > 1600 && val2 < 1600) {
  
    if (millis()>50 && millis()<100) digitalWrite(faroLung1, HIGH);     
    if (millis()>100 && millis()<150) digitalWrite(faroLung1, LOW);
  
    if (millis()>150 && millis()<200) digitalWrite(faroLung1, HIGH);   
    if (millis()>200 && millis()<250) digitalWrite(faroLung1, LOW);
  
    if (millis()>750 && millis()<800) digitalWrite(faroLung2,HIGH);
    if (millis()>800 && millis()<850) digitalWrite(faroLung2, LOW);
  
    if (millis()>850 && millis()<900) digitalWrite(faroLung2,HIGH);
    if (millis()>900 && millis()<950) digitalWrite(faroLung2, LOW); 

    if (millis()>1400) {
      cli();
      timer0_millis = 0;
      sei();  
    }  
  }
  
  if (retroInS == HIGH) digitalWrite(retroOut, HIGH);
  if (retroInS == LOW) digitalWrite(retroOut, LOW);
  
}

ringrazio tutti per l'aiuto datomi
specialmente per avermi spiegato il millis()
e le preziose informazioni sui tempi di pulseIn

magari se a qualcuno venisse in mente un alternativa al pulseIn sarebbe molto gradita

prova questo codice forse "zoppica" meno, alle righe modificate ho aggiunto // modifica GINGARDU
con una breve spiegazione,

int luciPosIn = 2;
int fariLungIn = 3;
int frecceIn = 4;
int lampIn = 5;
int stopIn = 6;
int retroIn = 7;


int luciPosOut = 8;
int faroLung1 = 9;
int faroLung2 = 10;
int stopOut = 11;
int retroOut = 12;
int frecceOut = 13;

int stopInS;
int retroInS;

int val1;
int val2;
int val3;
int val4; //Possibile non necessario!!
int val5 = LOW;

unsigned long previousMillis = 0;
unsigned long interval = 500000;  //   modifica GINGARDU aggiunto 3 zeri perche il timer mocros va a microsecondo

extern unsigned long timer0_millis;

void setup() {
  pinMode(luciPosIn, INPUT); //Input PPM ricevente radio (luciPosIn)
  pinMode(fariLungIn, INPUT); //Input PPM ricevente radio (fariLungIn) Possibile anche lampeggio!!!
  pinMode(frecceIn, INPUT); //Input PPM ricevente radio (frecceIn)
  pinMode(stopIn, INPUT); //Input mosfet regolatore (stopIn)
  pinMode(retroIn, INPUT); //Input mosfet regolatore (retroIn)
  pinMode(lampIn, INPUT); //Input PPM ricevente radio (lampIn) Possibile non necessario!!!
  
  pinMode(luciPosOut, OUTPUT); //Accensione luci posizione
  pinMode(faroLung1, OUTPUT); //Accensione luce profondità !! o lampeggio strobo
  pinMode(faroLung2, OUTPUT); //Accensione luce profondità !! o lampeggio strobo
  pinMode(frecceOut, OUTPUT); //Accensione 4 frecce
  pinMode(stopOut, OUTPUT); //Accensione Stop e posizione posteriore 1/2 potenza
  pinMode(retroOut, OUTPUT); //Accensione retro
  
  digitalWrite(luciPosOut,LOW);
  digitalWrite(faroLung1,LOW);
  digitalWrite(faroLung2,LOW);
  digitalWrite(stopOut,LOW);
  digitalWrite(retroOut,LOW);
  
}

void loop() {
  
  val1 = pulseIn(luciPosIn, HIGH);
  val2 = pulseIn(fariLungIn, HIGH);
  val3 = pulseIn(frecceIn, HIGH);
  val4 = pulseIn(lampIn, HIGH); //Possibile non necessario!!
  
  stopInS = digitalRead(stopIn);
  retroInS = digitalRead(retroIn);
  
  
  if (val1 > 1600) digitalWrite(luciPosOut, HIGH);
  if (val1 < 1600) digitalWrite(luciPosOut, LOW);
  if (val1 > 1600 && stopInS == LOW) analogWrite(stopOut, 10);
  if (val1 > 1600 && stopInS == HIGH) analogWrite(stopOut, 255);
  if (val1 < 1600 && stopInS == HIGH) analogWrite(stopOut, 255);
  if (val1 < 1600 && stopInS == LOW) analogWrite(stopOut, 0);  
  if (val2 > 1600) digitalWrite(faroLung1, HIGH);
  if (val2 < 1600) digitalWrite(faroLung1, LOW);
  if (val2 > 1600) digitalWrite(faroLung2, HIGH);
  if (val2 < 1600) digitalWrite(faroLung2, LOW);
  if (val3 > 1600) {
    
    if (millis() - previousMillis > interval) {
      
      previousMillis = micros();  // modifica GINGARDU   sostituito il timer millis com micros  
                                   //per evitare che dia fastiadio al timer  timer0_millis = 0;  o voceversa
    
    
      if (val5 == LOW)
        val5 = HIGH;
      else 
        val5 = LOW;
      
      digitalWrite(frecceOut, val5);
    }
  }
  if (val3 < 1600) digitalWrite(frecceOut, LOW);
        
  if (val4 > 1600 && val2 < 1600) {
  
    if (millis()>50 && millis()<100) digitalWrite(faroLung1, HIGH);     
    if (millis()>100 && millis()<150) digitalWrite(faroLung1, LOW);
  
    if (millis()>150 && millis()<200) digitalWrite(faroLung1, HIGH);   
    if (millis()>200 && millis()<250) digitalWrite(faroLung1, LOW);
  
    if (millis()>750 && millis()<800) digitalWrite(faroLung2,HIGH);
    if (millis()>800 && millis()<850) digitalWrite(faroLung2, LOW);
  
    if (millis()>850 && millis()<900) digitalWrite(faroLung2,HIGH);
    if (millis()>900 && millis()<950) digitalWrite(faroLung2, LOW); 
    
    if (millis()>1050 && millis()<1100) digitalWrite(faroLung1, HIGH);     
    if (millis()>1100 && millis()<1150) digitalWrite(faroLung1, LOW);
  
    if (millis()>1150 && millis()<1200) digitalWrite(faroLung1, HIGH);   
    if (millis()>1200 && millis()<1250) digitalWrite(faroLung1, LOW);
  
    if (millis()>1750 && millis()<1800) digitalWrite(faroLung2,HIGH);
    if (millis()>1800 && millis()<1850) digitalWrite(faroLung2, LOW);
  
    if (millis()>1850 && millis()<1900) digitalWrite(faroLung2,HIGH);
    if (millis()>1900 && millis()<1950) digitalWrite(faroLung2, LOW); 
    
    if (millis()>2050 && millis()<2100) digitalWrite(faroLung1, HIGH);     
    if (millis()>100 && millis()<150) digitalWrite(faroLung1, LOW);
  
    if (millis()>2150 && millis()<2200) digitalWrite(faroLung1, HIGH);   
    if (millis()>2200 && millis()<2250) digitalWrite(faroLung1, LOW);
  
    if (millis()>2750 && millis()<2800) digitalWrite(faroLung2,HIGH);
    if (millis()>2800 && millis()<2850) digitalWrite(faroLung2, LOW);
  
    if (millis()>2850 && millis()<2900) digitalWrite(faroLung2,HIGH);
    if (millis()>2900 && millis()<2950) digitalWrite(faroLung2, LOW); 
    
    if (millis()>3000) {  // modifica GINGARDU  ho triplicato il codice sopra e modificato  millis()>3000  cosi timer millis si resetta ogni 3 secondi
      cli();
      timer0_millis = 0;
      sei();  
    }  
  }
  
  if (retroInS == HIGH) digitalWrite(retroOut, HIGH);
  if (retroInS == LOW) digitalWrite(retroOut, LOW);
  
}

grazie GINGARDU della tua disponibilità (ma ti avevo scritto ieri di dare una letta prima sul forum che magari riuscivo a risolvere) e infatti ho già risolto tutte le rotture

cmq ti ringrazio nuovamente per avermi regalato la conoscienza dell'istruzione micros()
ma piccolo appunto (mo me a tiro)

hai sbagliatoooooooooooooooooooooo!!!!!!!!!!!!!!!!!!!!!!!!

if (millis() - previousMillis > interval) {

previousMillis = micros(); // modifica GINGARDU sostituito il timer millis com micros
//per evitare che dia fastiadio al timer timer0_millis = 0; o voceversa

if (val5 == LOW)
val5 = HIGH;
else
val5 = LOW;

digitalWrite(frecceOut, val5);
}

nell'if hai lasciato millis() cmq sarà sicuramente utilissimo nei prossimi progetti

intanto per studiare il millis ho scritto uno spezzone di codice per far accendere e spegnere un led in modo proporzionale utilizzando millis() e sono veramente molto soddisfatto!!!

int value = 0;
int value2;
long previousMillis = 0;
long interval = 10;
 
void setup()
{
  pinMode(ledPin, OUTPUT);
}
 
void loop()
{
  if (value == 150) value2 = 1;
  if (value == 0) value2 = 2;

  if (millis() - previousMillis > interval) {
    previousMillis = millis();
 
    if (value2 == 2) value = value+1;


    analogWrite(ledPin, value);
  }
  if (millis() - previousMillis > interval) {
    previousMillis = millis();
 
    if (value2 == 1) value = value-1;


    analogWrite(ledPin, value);
  }
}

ok dai l'importante che hai capito quello che volevo fare se avevo l'ardware che hai tu me ne sarei accorto ,
nella compilazione non ha dato errori perche millis() e micros () sono entrambi validi,

se ti servono ancora una decina di timer puoi farteli, cosi evitiamo di bastonare sempre millis () :stuck_out_tongue:

long DriftBoy1;
long DriftBoy2;
long DriftBoy3;
long DriftBoy4;
long DriftBoy5;
long DriftBoy6;
long DriftBoy7;
long DriftBoy8;
long DriftBoy9;
long DriftBoy10;

void setup() {

DriftBoy1 = micros()/1000;
DriftBoy2 = micros()/1000;
DriftBoy3 = micros()/1000;
DriftBoy4 = micros()/1000;
DriftBoy5 = micros()/1000;
DriftBoy6 = micros()/1000;
DriftBoy7 = micros()/1000;
DriftBoy8 = micros()/1000;
DriftBoy9 = micros()/1000;
DriftBoy10 = micros()/1000;

}

void loop()
{

}

grazie mille utilissimo

prossimo passo sarà inserire un solo pulseIn e un contatore che in base alle volte che viene raggiunto il valore di 1600 abilita le variabili da 0 a 5
me diverto troppo a crearmi problemi

sto già pensando ad implementarlo in macchina e gestire tutto da cellulare :smiley: