(RISOLTO) millis per invio a seriale cambia tempo

Ciao a tutti,
ho fatto un controllo per cancello scorrevole con motore brushless, nella funzione che apre o chiude c'è il controllo assorbimento del motore, quindi invio a seriale il valore di un ingresso analogico ogni 200 ms, utilizzando millis; succede che casualmente il tempo non viene più rispettato e l'invio a seriale è a massima velocità, come se il tempo dalla funzione di millis non venisse contato. Magari una svista oppure ho scritto male qualcosa...
Vi allego solo la funzione, se poi serve tutto il prgramma, allego tutto.

void apre()
{
  digitalWrite(REVERSE, LOW);       // se 1 gira per chiudere
  aprendo = true;                   // avviso che sto aprendo

  while (puls == LOW)               // attende il rilascio del pulsante
  {
    puls = digitalRead(PULS);       // leggo lo stato del pin pulsante
  }

  digitalWrite(ON_OFF, HIGH);       // se 1 abilita il controller brushless
  tempo_ana = millis();             // azzero tempo per lettura amper

  while (puls == HIGH && fine_ap == HIGH) // attendo puls o fine corsa
  {
    puls = digitalRead(PULS);       // leggo lo stato del pin pulsante
    fine_ap = digitalRead(FINE_AP);
    rall = digitalRead(RALL);       // leggo se devo rallentare

    if (rall == LOW)
    {
      pwm = 100;                    // abbasso velocità motore
      analogWrite(COM_GIRI, pwm);   // invio il pwm al motore
    }
    else
    {
      pwm = 180;                    // aumento velocità motore
      analogWrite(COM_GIRI, pwm);   // invio il pwm al motore
    }

    if ((millis() - tempo_ana) >= 200)  // tempo lettura sensore amper
    {
      volt_amper = analogRead(SENSOR);  // leggo il sensore amper
      Serial.println(volt_amper);       // scrive su seriale il valore assorbimento
      if (volt_amper > 1020)            // controllo se supero assorbimento
      {
        break;                          // esco dal ciclo while
      }
      tempo_ana = millis();             // azzero tempo per lettura amper
    }
  }

  digitalWrite(ON_OFF, LOW);        // fermo il motore

  while (puls == LOW)               // attende il rilascio del pulsante
  {
    puls = digitalRead(PULS);       // leggo lo stato del pin pulsante
  }
}

è un modellino ?

si, è roba funzionante a 12V

Se nell'if

if ((millis() - tempo_ana) >= 200)

metti

tempo_ana = millis();

subito, prima dell'altro if voltampere...

vedi cosa succede

Dal solo spezzone di codice non si evince nessuna problematica particolare, l'unica cosa che mi può venire in mente è che la variabile tempo_ana è stata definita con un tipo errato, avendo a che fare con millis() deve essere definita come unsigned long, se ha un tipo tale da non contenere correttamente i valori (Es. byte, int) quando millis supera il valore massimo possibile per tale tipo va in overflow assegnado un numero negativo o comunque non corretto e il test diviene positivo ad ogni ciclo di loop.

paulus1969:
Se nell'if

if ((millis() - tempo_ana) >= 200)

metti

tempo_ana = millis();

subito, prima dell'altro if voltampere...

vedi cosa succede

Ciao,
ho provato, ma non cambia niente, anche perchè quell'if se viene eseguito, va a spegnere il motore causa superamento dell'assorbimento, e se non viene eseguito subito dopo c'è l'azzeramento della variabile.....

Allego tutto il codice, anche se la variabile è stata correttamente definita...
Potrebbe essere un disturbo dato dal motore brushless? Però in tal caso, al ciclo successivo, tutto dovrebbe comunque rifunzionare... Preciso che sto utilizzando arduino nano.
Grazie

Scheda_cancello_elettrico.ino (8.18 KB)

Definita bene non direi è unsigend int e non unsigned long

fabpolli:
Definita bene non direi è unsigend int e non unsigned long

Oh cavolo, hai ragione, scusami, ero talmente sicuro che nemmeno ho verificato :-[
Ho copiato da un'altro codice, che stranamente è corretto, chissà cos'ho combinato...
Più tardi provo se funziona :wink:
Grazie e scusa ancora, la sicurezza ci frega sempre....

Poi la parte:

 while (puls == LOW)               // attende il rilascio del pulsante
 {
   puls = digitalRead(PULS);       // leggo lo stato del pin pulsante
 }

si può semplificare in:while(digitalRead(PULS)==0){}
o, ancora più semplicemente:while(!digitalRead(PULS)); // attende il rilascio del pulsante

Ciao, thedrifter :slight_smile:
Apprezzo i tuoi ringraziamenti, ma se non riporti la mia risposta nella tua si capisce ugualmente, poiché ti riferisci al messaggio precedente. Per semplificare la lettura, tanto più da telefono cellulare, è bene riportare, se indispensabile, solo il minimo indispensabile per la comprensione.

Grazie per la collaborazione! :slight_smile:

Ciao, ho rimosso il commento, ne aggiungo un'altro :stuck_out_tongue:
Ho provato entrambe le istruzioni che hai suggerito, ma non funzionano, eppure mi tornano...
:slight_smile:

Cioè
while(!digitalRead(PULS));
non blocca il ciclo in attesa che venga lasciato il pulsante?...
Hai messo un condensatore da circa 100nF in parallelo al pulsante? Se non c'è, al primo falso contatto del pulsante premuto il ciclo prosegue!

Si, blocca il ciclo, non esce mai da li, c'è condensatore e resistenza hardware, condensatore da 0,47 e resistenza da 10k, mi serviva abbastanza duro... Più resistenza da 4,7k di pullup

condensatore da 0,47 e resistenza da 10k, mi serviva abbastanza duro... Più resistenza da 4,7k di pullup

Uh?... Dove sta la 10k?

Condensatore fra pin e massa, resistenza fra pin e tasto...

Per forza il tasto non fa più nulla! :slight_smile:
Togli la resistenza in serie al tasto, o metti 100 Ohm.

??? Il condensatore senza resistenza serve proprio a poco, sempre fatto così, e mai avuto un problema di rimbalzo e spurie..... Farò per curiosità la prova che dici, ma il problema non è quello... Preciso che non uso la pullup interna al processore, ma diretta sul tasto

Eccomi, ho fatto come hai detto tu, ho tolto completamente la resistenza, ma il problema, come sapevo, è rimasto, il programma non esce più dal ciclo while...

Perché mai?...
C'è la resistenza verso il positivo, il condensatore verso massa e il pulsante un parallelo al condensatore?
Premendo il pulsante, la tensione sul pin PULS va da 5V a 0V?
Stai usando il pin giusto?