Usare millis invece di delay

Salva a tutti, sto lavorando con un motore nema 17 con driver drv8825, siccome mentre gira il motore ho bisogno di lavorare con seriale ed lcd, invece di usare questo codice, che funziona (enable messo fisicamente a massa):

const int stepPin = 2; 
const int dirPin = 5; 
 
void setup() {
  // Sets the two pins as Outputs
  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);
}
void loop() {
  digitalWrite(dirPin,HIGH); // Enables the motor to move in a particular direction
  // Makes 200 pulses for making one full cycle rotation
  for(int x = 0; x < 400; x++) {
    digitalWrite(stepPin,HIGH); 
    delayMicroseconds(500); 
    digitalWrite(stepPin,LOW); 
    delayMicroseconds(500); 
  }
  delay(1000);
}

vorrei invece di usare il delay, usare la funzione millis(), che mi permetta di fare altro mentre “aspetto” il tempo del delay, avevo pensato a questo, che non va:

byte directionPin = 5;
byte stepPin = 2;

unsigned long times;
void setup(){
  pinMode(directionPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  digitalWrite(directionPin, HIGH);
}

void loop(){
  
  unsigned long current = 0;
  times = millis();
  digitalWrite(stepPin, HIGH);
  while(current - times > 500){
    current = millis(); 
  }
  current = 0;
  times = millis();
  digitalWrite(stepPin, LOW);
  while(current - times > 500){
    current = millis(); 
  }
}

avete consigli? Grazie in anticipo

boosterinolc:
times = millis();
digitalWrite(stepPin, HIGH);
while(current - times > 500){
current = millis();
}

Guarda che il tuo codice è equivalente a "delay(500);" ossia questo è il funzionamento del delay(), non hai mica risolto il problema! Ossia tu devi avere in loop() una serie di controlli per fare quello che devi fare (mi sembro Totò... :wink: ) solo quando millis()-start raggiunge il tempo prefissato, altrimenti devi lasciare libero il loop().

Per farti capire meglio, leggi QUI e QUI per iniziare, dovresti trovare gli spunti necessari.

appunto, dovrebbe essere uguale, peccato che il secondo non vada, ho provato apposta a fare le due soluzioni equivalenti

Veramente avevi detto "che mi permetta di fare altro mentre aspetto il tempo del delay", e questo è il motivo dell'uso del millis() al posto del delay(), non si capiva che stessi chiedendo come mai i due codici non risultino avere lo stesso comportamento.

Per cui se il tuo dubbio è questo (ma la prossima volta per favore scrivi più esplicitamente la tua domanda), dicci cosa intendi esattamente con "non va".

millis() è millisecondi
delayMicroseconds() è microsecondi

1000 micro= 1 millis

  unsigned long current = 0;
  times = millis();
  digitalWrite(stepPin, HIGH);
  while(current - times > 500){

mi pare che il controllo la prima volta sia finchè ( (0- millis()) >500 )....
quindi salta il while

comunque se lo scrivi così blocchi il programma dentro al while fino a che la condizione è vera quindi non puoi fare null'altro nel frattempo

Scusa, ma, a parte il fatto che appunto il codice non fa nulla durante il while(), noto ora che tu stai sostituendo "delaymicroseconds()" che è in microsecondi, con "millis()" che ragiona in millisecondi? In pratica hai una gestione dello stepper 1000 volte più lenta...

EDIT: Patrick mi ha preceduto... :wink:

Ma aggiungo: a mio avviso il problema non sono i delayMicroseconds() del ciclo, ma più che altro devi levare i delay(1000) esterni. Devi ripensare un pochino al codice, come negli esempi dei link che ti ho indicato.

boosterinolc:
avete consigli? Grazie in anticipo

Come usare il valore ritornato dalla funzione millis:

Come strutturare la logica:

grazie a tutti, adesso mi informo meglio, già ho poca esperienza ed ho sempre usato i delay, mi risulta molto astratta la funzione millis()

Per usare millis al posto di delay, devi "ripensare" l'intera struttura, non puoi semplicemente sostituire uno all'altro ... ad esempio, se devi accendere qualcosa, aspettare un secondo e spegnerla, con il delay ti basta fare delay(1000), ma con millis devi usare un paio di if consecutive (o un'if-else) ed una flag ... tipo, esempio al volo, la flag se non usata e' a zero ... quando devi accendere, la metti ad uno (nel punto del loop che ti serve) ... il primo if controlla se la flag e' ad 1, se si, accende l'uscita, mette il valore corrente di millis in una unsigned long, e mette la flag a 2 (cosi il primo if non verra' eseguito piu di una volta per ogni volta che metti la flag ad 1) ... il secondo if (oppure un'else), controlla se la flag e' a due (cosi verra' eseguito solo per il tempo necessario a controllare il ritardo), se si, confronta millis meno la unsigned long con 1000, e quando il tempo e' trascorso, spegne l'uscita e rimette la flag a zero (cosi i confronti non verranno piu eseguiti finche' non rimetterai la flag ad uno per riaccendere) ... e' un modo un po "grezzo" (io non sono un programmatore), e sono sicuro che ne esistono di migliori, ma in teoria dovrebbe funzionare ...

boosterinolc:
grazie a tutti, adesso mi informo meglio, già ho poca esperienza ed ho sempre usato i delay, mi risulta molto astratta la funzione millis()

Astratta direi di no (in fondo ti dà semplicemente un valore in millisecondi -più o meno- dall'accensione dell'MCU), ma che non sia immediato il suo utilizzo per avere una sorta di "multitasking" (non è multitasking in senso stretto, ma permette di fare più cose in tempi diversi diciamo) è vero.

Per questo però, scusa, ti avevo indicato due link dove si spiegano tutte le basi, non li hai visti?
Intendo questi:

http://www.leonardomiliani.com/2013/programmiamo-i-compiti-con-millis/

Dagli una letta e sperimenta, vedrai poi che in fondo una volta compreso il concetto, ti sarà più chiaro tutto.