Gestire velocità di stepper bipolari con la funzione millis() anzichè delay()

Buongiorno a tutti,
qui trovate una mia vecchia presentazione (il livello di conoscenza è pressochè il medesimo).

Dispongo di una scheda Arduino Uno, uno stepper bipolare tipo Nema17 (angolo step 1,8°), un integrato L293D. Partendo da questa idea, ho sviluppato un codice che -nelle mie intenzioni- mi doveva permettere di gestire la velocità di rotazione dello stepper intervenendo sui delay tra gli eccitamenti delle bobine. Impostato il valore delay come variabile “intervallo”, a questa ho assegnato i valori (debitamente scalati) rilevati analogicamente dal piedino A0, al quale ho collegato un potenziometro. Infine ho aggiunto un display lcd per visualizzare i valori dell’intervallo e il tempo totale necessario per effettuare un giro completo.

Siccome ho fatto scalare i valori del potenziometro su una scala 0-100000, perché tra uno step e l’altro avrò necessità di far passare una discreta quantità di tempo, tipo 50-100 secondi… mi sono imbattuto in un bel difetto. Quando vado a regolare il potenziometro, non ho una risposta immediata, perché il ciclo deve concludersi fino all’ultima delle 4 istruzioni di eccitamento delle bobine dello stepper. E ciò crea tempi lunghissimi tra una calibrazione e l’altra, soprattutto quando i valori dell’intervallo sono più alti (potenzialmente fino a 400 secondi). La domanda è: esiste un modo di interrompere il ciclo, non appena regolo il potenziometro, e avere così una risposta immediata del cambio di velocità?
Dopo aver sfrugulato in lungo e in largo i forum, ho dedotto che la soluzione non sono gli interrupts (che non mi farebbero uscire dai delay), ma la sostituzione della funzione delay con la millis, secondo modalità indicate nel tutorial https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay.

Qui purtroppo mi fermo e chiedo aiuto, perchè per miei limiti non sono riuscito a focalizzare come modificare il codice del mio progetto. In sostanza devo creare un codice che permetta di fare 4 istruzioni consecutive ad un intervallo variabile (ma ripetuto identico tra loro), utilizzando la funzione millis anzichè delay.
Ringrazio anticipatamente chi spenderà il suo tempo per me.

Qui di seguito trovate il codice. Il progetto è finalizzato a motorizzare un telescopio per l’inseguimento degli astri. Perdonate la lunga premessa con la descrizione del progetto: è stata fatta perchè eventuali altri suggerimenti su soluzioni totalmente alternative sono ben accetti.

Angelo

#include <LiquidCrystal.h>
LiquidCrystal lcd(13, 12, 5, 4, 3, 2);

const int PiedinoPotenziometro = A0;
int motorPin1 = 8;
int motorPin2 = 9;
int motorPin3 = 10;
int motorPin4 = 11;
int intervallo;


void setup() {
  // apri una porta seriale per il monitor seriale
  Serial.begin(9600);
    
  lcd.begin(16, 2);
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);
  
  lcd.setCursor(0,0);
  lcd.print("***TELESCOPIO***");
  lcd.setCursor(0,1);
  lcd.print("***MOTORIZZATO**");
  
  delay(3000);
}

void loop() {

  // leggi il valore sul piedino A0 collegato al sensore 
  // e memorizzalo come una variabile
  int ValorePotenziometro = analogRead(PiedinoPotenziometro);
   // manda le informazioni da Arduino al PC collegato
  Serial.print("Valore del Sensore: ");
  Serial.println(ValorePotenziometro); 
  
  intervallo = map(ValorePotenziometro, 0, 1023, 0, 10000);
  
  Serial.print(", intervallo: ");
  Serial.print(intervallo);
  Serial.println(" msec ");
  
  float h; //VARIABILE UTILIZZATA PER LE ORE
  float m; //VARIABILE UTILIZZATA PER I MINUTI
  float s; //VARIABILE UTILIZZATA PER I SECONDI
  float dp; //PARTE DECIMALE DELLE OPERAZIONI
  
  h = float(intervallo*200/1000) / 3600;//DIVIDO I SECONDI PER 3600 CHE SONO I SECONDI IN UN'ORA
   
  //CALCOLA I MINUTI
  dp = (h - int(h)); //I DECIMALI DELLA VARIABILE "H" SONO I MINUTI
  m = dp * 60; // TRASFORMO I MINUTI DA DECIMALE A SESSADECIAMALE
   
  //CALCOLA I SECONDI
  dp = (m - int(m));//I DECIMALI DELLA VARIABILE "M" SONO I SECONDI
  s =  dp * 60; // TRASFORMO I SECONDI DA DECIMALE A SESSADECIMALE
 
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("INT:");
      lcd.print(intervallo);
      lcd.print("ms");
      lcd.setCursor(0,1);
      lcd.print("1giro/");
      lcd.print(int(h)); //L' INTERO DELLA VARIABILE "H" SONO LE ORE
      lcd.print("h");
      lcd.print(int(m)); //L' INTERO DELLA VARIABILE "M" SONO I MINUTI
      lcd.print("m");
      lcd.print(int(s)); //L' INTERO DELLA VARIABILE "S SONO I SECONDI
      lcd.print("s");
      
  digitalWrite(motorPin1, HIGH); //ISTRUZIONI PER L'ECCITAMENTO DELLE BOBINE IN SUCCESSIONE
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  lcd.setCursor(12,0);
  lcd.print("BOB1");
  delay(intervallo);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  lcd.setCursor(12,0);
  lcd.print("BOB2");
  delay(intervallo);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
  lcd.setCursor(12,0);
  lcd.print("BOB3");
  delay(intervallo);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  lcd.setCursor(12,0);
  lcd.print("BOB4");
  delay(intervallo);
}

Prova a studiare millis() prima QUI, poi QUI ed infine leggi anche QUI ... spero che così ti sia più chiaro il suo uso.

Guglielmo