millis()....maledetto millis()

Salve a tutti

Il progetto che ho intenzione di realizzare è un semplice azionamento di un motore passo passo senza
usare le librerie.

Premesso che sono alle prime armi con la programmazione,ma ho gia affrontato millis(),
il mio problema è durante la programmazione .....millis() in pratica non fà quel che vorrei.

metto i pezzi di schetc......il problema è all'ultimo

int pulsante=2;
int bobina1=8;
int bobina2=9;
int bobina3=10;
int bobina4=11;
int bob1=0;
int bob2=0;
int bob3=0;
int bob4=0;
int conteggiopassi=0;
int girocompleto=512;
int partenza=0;
int rotazione;

fin quì tutto OK

void setup()
{
Serial.begin(9600);
pinMode(pulsante,INPUT);  
pinMode(bobina1,OUTPUT);
pinMode(bobina2,OUTPUT);
pinMode(bobina3,OUTPUT);
pinMode(bobina4,OUTPUT);
}

anche qui tutto ok

void loop()
{
 if(bob1==1){digitalWrite(bobina1,HIGH);}else{digitalWrite(bobina1,LOW);}
 if(bob2==1){digitalWrite(bobina2,HIGH);}else{digitalWrite(bobina2,LOW);}
 if(bob3==1){digitalWrite(bobina3,HIGH);}else{digitalWrite(bobina3,LOW);}
 if(bob4==1){digitalWrite(bobina4,HIGH);}else{digitalWrite(bobina4,LOW);}
 if(partenza==0){bob1=0;bob2=0;bob3=0;bob4=0;Serial.println("Motore Fermo");}
 Serial.print(bob1);
 Serial.print(bob2);
 Serial.print(bob3);
 Serial.print(bob4);
 Serial.println("");
  
 if(digitalRead(pulsante))
  {
  while(digitalRead(pulsante)){Serial.println("Senso Orario Via");}
  partenza=1;
  rotazione=0;
  Serial.print(partenza);
  Serial.print(rotazione); 
  Serial.println("");
  }

anche qui tutto OK

i problemi cominciano QUI

if((partenza==1)&&(rotazione==0))
  {
  int velocita(1000);
  unsigned TEMPO=0;
  
  if(millis()>=TEMPO+velocita){bob1=1;bob2=0;bob3=0;bob4=0;}
  TEMPO=millis();
  if(millis()>=TEMPO+2000){bob1=1;bob2=1;bob3=0;bob4=0;}
  TEMPO=millis();
  if(millis()>=TEMPO+velocita){bob1=0;bob2=1;bob3=0;bob4=0;}
  TEMPO=millis();
  if(millis()>=TEMPO+velocita){bob1=0;bob2=1;bob3=1;bob4=0;}
  
  if(millis()>=TEMPO+velocita){bob1=0;bob2=0;bob3=1;bob4=0;}
  
  if(millis()>=TEMPO+velocita){bob1=0;bob2=0;bob3=1;bob4=1;}
  
  if(millis()>=TEMPO+velocita){bob1=0;bob2=0;bob3=0;bob4=1;}
  
  if(millis()>=TEMPO+velocita){bob1=1;bob2=0;bob3=0;bob4=1;} 
  }         

}

In pratica "partenza e rotazione" li legge correttamente,
credo che il problema stia nel "TEMPO=millis()", oppure nella Variabile "velocita".

Ovunque sposto "TEMPO=millis()" mi legge solo la riga sopra poi si blocca ho provato pure ad a mettere 2000 millisecondi al posto di"velocita", ma niente da fare.

Non so più cosa provare per saltarci fuori....mi sono arenato nuovamente sto "millis()" e utilissimo,ma mi fà dannare.

Hai le idee molto poco chiare su come si usa millis ...
... studiati (... e NON leggiti) bene come si usa prima QUI, poi QUI ed infine leggi anche QUI e QUI ... ti si dovrebbero chiarire le idee :wink:

Guglielmo

docsavage:
Ci guardo dopo cena

... c'è poco da guardare, NON usa la millis() nel modo corretto ::slight_smile:

Guglielmo

Che colpa ha millis() perché la maledici solo perché non la capisci?

Grazie a tutti

Nessun errore di compilazione in nessun caso provato.

solo non capisco perchè mi legge la prima volta "TEMPO=millis()" poi si blocca.

nel caso riportato è una delle tante prove ed il monitor mi legge prima "partenza==1 e rotazione==0"
e subito dopo le "bob== 0000" poi legge nel caso riportato prima le "bob==1000".

se sposto"TEMPO=millis()" come in questo caso

 if((partenza==1)&&(rotazione==0))
  {
  if(millis()>=TEMPO+velocita){bob1=1;bob2=0;bob3=0;bob4=0;}
 
  if(millis()>=TEMPO+2000){bob1=1;bob2=1;bob3=0;bob4=0;}
  
  if(millis()>=TEMPO+velocita){bob1=0;bob2=1;bob3=0;bob4=0;}
  TEMPO=millis();
  if(millis()>=TEMPO+velocita){bob1=0;bob2=1;bob3=1;bob4=0;}
  
  if(millis()>=TEMPO+velocita){bob1=0;bob2=0;bob3=1;bob4=0;}
  
  if(millis()>=TEMPO+velocita){bob1=0;bob2=0;bob3=1;bob4=1;}
  
  if(millis()>=TEMPO+velocita){bob1=0;bob2=0;bob3=0;bob4=1;}
  
  if(millis()>=TEMPO+velocita){bob1=1;bob2=0;bob3=0;bob4=1;} 
  }         

}

il monitor legge giustamente 0100

se lo sposto mi legge le "bob" sopra........poi si blocca

se ne metto altri d i"TEMPO=millis()"...utilizza solo il primo che legge,,,,,,poi si blocca.

docsavage:
... rimettere il tempo uguale a millis durate l'esecuzione del ciclo principale NON è una buona maniera per far scattare il timer

ad ogni esecuzione del ciclo TEMPO diventa uguale a millis() e quindi millis()>TEMPO+qualunque_numero non sarà mai vero

Glie l'ho detto che NON ha capito come si usa millis() e che quel confronto NON è corretto, ma ...
... pare non abbia tempo di andare a STUDIARE i link che gli ho messo :smiling_imp:

Guglielmo

ho capito DOC che mi sto complicando la vita e sarebbe più facile fare dei digitalWrite e dei delay per il tempo.......ma tosrniamo alla situazione del "vecchietto"....se intanto che il motore passopasso gira.....il vecchio decide di fare altro?????

per questo sto tentando di untilizzare l'orologio millis().

PS

i primi motori PP li ho fatti funzionare senza Arduino....con un seplice NE555....un contatore decennale che ora non riesco a leggere il codice...ed un L293D

Ok ragazzi ci provo
per il momento grazie a tutti.

Il fatto che un Sketch compili senza dare errori non vuol dire che funziona o che fa quello hai voluto scrivendolo.

Puso:
tosrniamo alla situazione del "vecchietto"....se intanto che il motore passopasso gira.....il vecchio decide di fare altro?????

Infatti il "problema" è sempre quello. E per quello avevo scritto tre vecchietti che camminano ciascuno alla propria velocità indipendente dagli altri in fondo a questo post.

La funzione 'millis' è usata come indicato in quest'altro post.

Invece continuare ad usare la forma seguente:

millis() >= xyz

è errato per quanto detto in quest'altro post ancora.

Tra l'altro in questa ultima pagina c'è anche un mini esempio su come fare due cose contemporaneamente (un'attesa lunga e leggere periodicamente un pulsante) usando solo un piccolo delay. Un programma totalmente multitasking è solo l'estensione di questo concetto.


millis() in pratica non fà quel che vorrei

Quando il codice o un'istruzione non fanno quello che "si vorrebbe" significa che non si è ben compreso come usare quell'istruzione o come implementare la logica "che si vorrebbe" con lo specifico codice.

In particolare in questo caso la logica è cambiare uno stato/fase ogni tot millisecondi, e quindi servirà una variabile di fase/stato per ricordare a che punto siamo arrivati, e una di tempo per controllare quando è passato tot tempo dall'inizio della fase precedente ed è ora di passare a quella nuova.

Ad esempio se volessi una variabile 'fase' che cicla continuamente da 1 a 8 finché una variabile 'comando' vale 1, e rimane a 0 finché 'comando' vale 0, nel loop principale potrei scrivere qualcosa del genere:

   tempoAttuale = millis();

    if (fase==0  &&  comando==1)  // avviare sequenza fasi
        { tInizio = tempoAttuale;  fase = 1; }
    else if (fase>0  &&  comando==0)  // stop sequenza fasi
        fase = 0;
    if (fase>0  &&  tempoAttuale - tInizio >= DURATA_FASE) 
        { tInizio += DURATA_FASE;  fase = 1 + (fase % 8); }

Naturalmente 'tempoAttuale' e 'tInizio' sono variabili di tipo unsigned long, mentre 'fase' e 'comando' sono due variabili di tipo byte. 'DURATA_FASE' sono i millisecondi che passano tra un valore e l'altro della variabile 'fase', se 'DURATA_FASE' vale 125, allora l'intero ciclo di otto fasi avviene in un secondo.

Comunque col semaforo ci sono riuscito.......lo schecth che ho postato funziona anche se non è scritto come lo scriverebbe un programmatore e funziona anche su bredboard

ed il vostro è stato un grande aiuto.

In quanto al studiare, se fosse sufficente leggere per capire, tutti saprebbero fare tutto.

Io prima di iscrivermi al forum non sapevo neppure la differenza tra le parentesi tonde,quelle quadre e quelle graffe.

Adesso almeno riesco a compilare da solo senza copiare un minimo di schetc (anche se in maniera preistorica).

Ora mi rileggo con calma i vari precedenti post con i consigli che mi avete dato, almeno per capire dove sto sbagliando

Secondo me', stai sbagliando l'approccio al problema ...

millis() e' un contatore interno che tu puoi leggere, e che continua a cambiare (ogni millisecondo) ... consideralo un'orologio, da cui prendere il tempo ogni volta che inizia un determinato ciclo da controllare (tempo che quindi metterai in una variabile segnatempo nel momentio in cui INIZIA il possibile intervallo di tempo da controllare), variabile che poi confronterai con i nuovi valori di millis finche' ti accorgi che il tot di tempo che ti serve e' trascorso ... e che rimetterai uguale a millis ogni volta che devi ricontrollare di nuovo quell'intervallo ...

Ovviamente, se ci sono piu intervalli di tempo diversi da controllare e che iniziano o terminano in momenti diversi, ti servira' una variabile segnatempo diversa per ogni intervallo ... e naturalmente ogni diversa variabile andra' rimessa uguale a millis nel momento in cui il SUO intervallo di tempo da controllare ricomincia ...

senza polemiche

se avessi seguito subito i consigli.....li avrei semplicemente copiati.....invece di tentare di capire.

Qundi mi sono posto sperimentando i vari consigli.

Sto provando di capire anche gli array e credo di aver inteso di cosa parli.

Solo che preferisco affrontare un problema alla volta, se comincio a girovagare su tutte le cose che mi dite ....va a finire che mi perdo e non ci salto fuori.

Per ora comprendere il millis() fino a fondo è la mia bestia nera, ma ci sto lavorando....e l'infarinatura degli array,e interessante, e se ho compreso bene mi toglierebbe un sacco di righe nello schetc.

se guardi bene nel mio schetch è chiaro che i passaggi sulle bobine sono 8......il mio problema (per ora)è solo sul millis() tra un passaggio e l'altro.

non posso semplificare qualkosa se prima non l'ho compresa perfettamente.

docsavage:
vedo che molti qui non sono d'accordo, ma scrivere
if(condizione){azione;azione;azione;}

è secondo me sbagliato, sbagliatissimo

if(condizione)
{
azione;
azione;
azione;
}
azione;

è la maniera consigliata dal K&R, che ti consiglio vivamente di leggere

Vero, tra l'altro è un suggerimento valido in qualsiasi linguaggio imperativo (per i linguaggi funzionali forse è un po' diverso).

Tuttavia mi sono spesso trovato a dover mediare tra funzioni troppo lunghe da seguire (necessità di scrollare) e "logica a colpo d'occhio", esattamente come i nomi troppo lunghi o troppo corti.

Il C per sua natura porta ad occupare una grande quantità di righe (20..40% di righe composte solo da spazi e parentesi), come dire, su cento fogli stampati venti sono solo di parentesi...

Inutile dire che non ho mai trovato una regola universalmente valida... cerco di volta in volta quello che "distrae di meno" o "evidenzia di più"... ancora non ho capito quale sia la forma più comprensibile di parentesi prima e dopo un else...

Puso:
Salve a tutti

Il progetto che ho intenzione di realizzare è un semplice azionamento di un motore passo passo senza
usare le librerie.

Premesso che sono alle prime armi con la programmazione,ma ho gia affrontato millis(),
il mio problema è durante la programmazione .....millis() in pratica non fà quel che vorrei.

metto i pezzi di schetc......il problema è all'ultimo

int pulsante=2;

int bobina1=8;
int bobina2=9;
int bobina3=10;
int bobina4=11;
int bob1=0;
int bob2=0;
int bob3=0;
int bob4=0;
int conteggiopassi=0;
int girocompleto=512;
int partenza=0;
int rotazione;




fin quì tutto OK



void setup()
{
Serial.begin(9600);
pinMode(pulsante,INPUT);  
pinMode(bobina1,OUTPUT);
pinMode(bobina2,OUTPUT);
pinMode(bobina3,OUTPUT);
pinMode(bobina4,OUTPUT);
}




anche qui tutto ok



void loop()
{
if(bob1==1){digitalWrite(bobina1,HIGH);}else{digitalWrite(bobina1,LOW);}
if(bob2==1){digitalWrite(bobina2,HIGH);}else{digitalWrite(bobina2,LOW);}
if(bob3==1){digitalWrite(bobina3,HIGH);}else{digitalWrite(bobina3,LOW);}
if(bob4==1){digitalWrite(bobina4,HIGH);}else{digitalWrite(bobina4,LOW);}
if(partenza==0){bob1=0;bob2=0;bob3=0;bob4=0;Serial.println("Motore Fermo");}
Serial.print(bob1);
Serial.print(bob2);
Serial.print(bob3);
Serial.print(bob4);
Serial.println("");
 
if(digitalRead(pulsante))
 {
 while(digitalRead(pulsante)){Serial.println("Senso Orario Via");}
 partenza=1;
 rotazione=0;
 Serial.print(partenza);
 Serial.print(rotazione);
 Serial.println("");
 }




anche qui tutto OK



i problemi cominciano QUI


if((partenza==1)&&(rotazione==0))
 {
 int velocita(1000);
 unsigned TEMPO=0;
 
 if(millis()>=TEMPO+velocita){bob1=1;bob2=0;bob3=0;bob4=0;}
 TEMPO=millis();
 if(millis()>=TEMPO+2000){bob1=1;bob2=1;bob3=0;bob4=0;}
 TEMPO=millis();
 if(millis()>=TEMPO+velocita){bob1=0;bob2=1;bob3=0;bob4=0;}
 TEMPO=millis();
 if(millis()>=TEMPO+velocita){bob1=0;bob2=1;bob3=1;bob4=0;}
 
 if(millis()>=TEMPO+velocita){bob1=0;bob2=0;bob3=1;bob4=0;}
 
 if(millis()>=TEMPO+velocita){bob1=0;bob2=0;bob3=1;bob4=1;}
 
 if(millis()>=TEMPO+velocita){bob1=0;bob2=0;bob3=0;bob4=1;}
 
 if(millis()>=TEMPO+velocita){bob1=1;bob2=0;bob3=0;bob4=1;}
 }

}





In pratica "partenza e rotazione" li legge correttamente,
credo che il problema stia nel "TEMPO=millis()", oppure nella Variabile "velocita".

Ovunque sposto "TEMPO=millis()" mi legge solo la riga sopra poi si blocca ho provato pure ad a mettere 2000 millisecondi al posto di"velocita", ma niente da fare.

Non so più cosa provare per saltarci fuori....mi sono arenato nuovamente sto "millis()" e utilissimo,ma mi fà dannare.

che senso ha reinventare la ruota? se devi muovere uno stepper devi avere il motore e e devi avere il driver che ti costa 30 volte meno che fartelo da solo
ci sono talmente tanti "parametri" che mette in atto un driver che quello che stai cercando di fare tu e solo una piccola parte,
con un driver stepper solo con i comandi dir & step fai già girare il motore

:confused: e mi pare che non ci sono stepper pilotabili direttamente dalle uscite di arduino
per ultimo scrivere software senza ardware collegato è una gran vaccata (il 99.9% delle volte)

OK OK

intanto scusate il ritardo nelle risposte,ma questa settimana è stata impegnativa nella vita personale e non ho avuto tempo per la parte hobbistica.

Appena riesco ci riprovo ( ho capito la scrittura da ominide....sto comprendendo le variabili e ringrazio per i consigli che appena riesco provo a tentare di risolvere).

PS

Reinventare la ruota......ha senso......almeno per capire il perchè gira.
il mio problema non è far girare un motore passo passo...il mio problema è farlo senza librerie o schede elettroniche gia fatte.......voglio solo comprendere( in questo caso, la programmazione).

Leggendo i vostri consigli ho capito che mi state insegnando e ne faccio tesoro.......ammetto che caratterialmente a volte faccio come i bambini......finche non cado e mi sbuccio un ginocchio, non mi rendo conto di quato faccia male.

;D ;D ;D
Ok
ci sono riuscito sia su seriale sia con i led al posto delle bobine,
sia attaccandoci un passo passo direttamente su arduino(anche se non come vorrei,ma credo che il problema sia che non do il negativo alle bobine) infatti va lentissimo anche se abbasso il tempo od inverto le bobine....appena riesco ci metto in mezzo un L293D, teoricamente dopo dovrebbe funzionare bene.

Comunque credo di aver capito il mio errore con millis(). praticamente mi servono 2 variabili.

A meno che non me lo chiedete per autolesionismo,,,,,evito di postare lo schetc che ho fatto,,,,,se no mi sgridate.

Comunque funziona.

Prossimo passo comprendere le variabili e le funzioni void cavallo()

e provare a riscrivere lo schetch usandole.

cavallo per dare un nome a caso

intendo quelle tipo "void mostra" e "void avanti"e che hai richiamato dopo nel loop.

ma un passo alla volta.

prima voglio fare altre cose utilizzando il millis()......per ora era questo il mio problema.....nella speranza di averlo capito come si deve ora lo devo provare e riprovare e spremerlo finche non mi diventa automatico........come fare uno starnuto.