Posizione stepper senza encoder

Salve a tutti,
ho costruito una siringa dosatrice, tutto funziona correttamente ma ora vorrei implementare il software aggiungendo la possibilità di controllare l’esatta quantità di liquido elargito.
Sò che il numero di step totali tra il finecorsa (a siringa estesa) al punto in cui la siringa è vuota (cioé compressa) è di 24000 impulsi (240 impulsi ogni 0,1ml di prodotto).
Ecco… ora dovrei contare ogni quante volte “accadono” 240 impulsi prima che io prema un ipotetico pulsante di Stop.

Lo sketch riportato è quello che uso per i test.

// Definisco i Pin
  const int stepPin = 6;       // Impulso per il movimento
  const int dirPin = 7;          // Direzione di rotazione
  const int drvPin = 2;         // Pin DRV8825 sempre HIGH
        int switchPin = 3;        // Pin del finecorsa

  
void setup() {
  
      digitalWrite(drvPin, HIGH);   // Attivo il Pin su DRV8825
      digitalWrite(dirPin, HIGH);    // Abilito la rotazione
      while(digitalRead(switchPin)==HIGH)  // La siringa và al finecorsa
      {
      
            digitalWrite(stepPin, HIGH);
            delayMicroseconds(100);
            digitalWrite(stepPin, LOW);
            delayMicroseconds(50);
            digitalRead(switchPin==LOW);
      }
       delay(10); // Pausa di 0,1 secondi
  
      digitalWrite(dirPin,LOW); //Cambia il senso di rotazione
      // 3200 Pulsazioni per un giro completo
      for(int x = 0; x < 24000; x++) { // Siringa vuota a 24000 step
            digitalWrite(stepPin,HIGH);
            delayMicroseconds(100);
            digitalWrite(stepPin,LOW);
            delayMicroseconds(50);
      }
           
           
    
}

void loop() {

   delay(2000); // Pausa di 2 secondi
  
  digitalWrite(dirPin,HIGH); //Cambia il senso di rotazione
  // 3200 Pulsazioni per un giro completo
  for(int x = 0; x < 24000; x++) { // siringa piena a 0 step
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(1000);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(50);
  }
   delay(2000); // Pausa di 2 secondi
  
  digitalWrite(dirPin,LOW); //Cambia il senso di rotazione
  // 3200 Pulsazioni per un giro completo
  for(int x = 0; x < 24000; x++) { // siringa piena a 24000 step
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(1000);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(50);
  }
}

Il tuo sketch fa andare avanti e indietro il pistone della siringa.

Se ho capito bene quello che vorresti fare è riempire completamente la siringa, invertire il senso di rotazione e, quando un contatore raggiunge il valore che tu vuoi, premere un pulsante di STOP.

Una domanda: non sarebbe meglio predisporre un valore in millilitri (ad es con il Serial Monitor) e il sistema si ferma da solo? Magari fornendo (sempre ad es attraverso serial monitor) il quantitativo erogato e quello rimanente?

Ciao, P.

Ciao!
Ho risolto in questo modo, anche se il trigger che dice al pistone di fermarsi, ancora non c’è.
Per il momento, tramite il monitor seriale ho la visualizazione di quanto è stato espirato dal totale.

// Definisco i Pin
  const int stepPin = 6;        // Impulso per il movimento
  const int dirPin = 7;         // Direzione di rotazione
  const int drvPin = 2;         // Pin DRV8825 sempre HIGH
        int switchPin = 3;      // Pin del finecorsa
      float measureVal = 0;      // Valore misurazione (con virgola)
  const float sirConst = 0.208342;
void setup() {

     Serial.begin(115200);
      Serial.println("INIZIO TEST SIRINGA");
      delay(1000);
      digitalWrite(drvPin, HIGH);   // Attivo il Pin su DRV8825
      digitalWrite(dirPin, HIGH);   // Abilito la rotazione
      while(digitalRead(switchPin)==HIGH)  // La siringa và al finecorsa
      {
      
            digitalWrite(stepPin, HIGH);
            delayMicroseconds(150);
            digitalWrite(stepPin, LOW);
            delayMicroseconds(50);
            digitalRead(switchPin==LOW);
      }
       delay(1000);
       Serial.println("FINECORSA OK");
       delay(1000); // Pausa di 1 secondo
  
      digitalWrite(dirPin,LOW); //Cambia il senso di rotazione
      // 3200 Pulsazioni per un giro completo
      for(int x = 0; x < 24000; x++) { // Siringa vuota a 24000 step
            digitalWrite(stepPin,HIGH);
            delayMicroseconds(150);
            digitalWrite(stepPin,LOW);
            delayMicroseconds(50);
      }
         delay(1000);
         Serial.println("INIZIO ASPIRAZIONE");  
         delay(2000); // Pausa di 2 secondi
  
      digitalWrite(dirPin, HIGH);   // Abilito la rotazione
      while(digitalRead(switchPin)==HIGH)  // La siringa và al finecorsa
      {
      
            digitalWrite(stepPin, HIGH);
            delayMicroseconds(500);
            digitalWrite(stepPin, LOW);
            delayMicroseconds(50);
            digitalRead(switchPin==LOW);
      }
   
   delay(1000);
   Serial.println("INIZIO ESPIRAZIONE");
   delay(2000); // Pausa di 2 secondi
  
  digitalWrite(dirPin,LOW); //Cambia il senso di rotazione
  // 3200 Pulsazioni per un giro completo
  for(int x = 0; x < 24000; x++) { // siringa piena a 24000 step
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(150);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(50);
   Serial.println(((measureVal + (measureVal++))/1000) * sirConst);
  }     
    delay(1000);
    Serial.println("FINE TEST SIRINGA");
}

void loop() {

 
}

Allora…
Ho aggiunto un pulsante di STOP al PIN 52 del Mega. Il sistema funziona, la siringa smette di erogare nel momento in cui premo il pulsante ad a monitor mi viene visualizzato la quantità erogata. Purtroppo, se io non premo alcun pulsante, quando arrivo ad espirare tutto il contenuto, il motore continua la sua corsa.
Come posso fare per limitare gli step ed allo stesso modo fare il check del pulsante?

// Definisco i Pin
  const int stepPin = 6;        // Impulso per il movimento
  const int dirPin = 7;         // Direzione di rotazione
  const int drvPin = 2;         // Pin DRV8825 sempre HIGH
        int switchPin = 3;      // Pin del finecorsa
        int cellPin = 52;     
      float serialVal = 0;
      float measureVal = 0;      // Valore misurazione (con virgola)
  const float sirConst = 0.208342;

void setup() {

     Serial.begin(115200);
      Serial.println("INIZIO TEST SIRINGA");
      delay(1000);
      digitalWrite(drvPin, HIGH);   // Attivo il Pin su DRV8825
      digitalWrite(dirPin, HIGH);   // Abilito la rotazione
      while(digitalRead(switchPin)==HIGH)  // La siringa và al finecorsa
      {
      
            digitalWrite(stepPin, HIGH);
            delayMicroseconds(150);
            digitalWrite(stepPin, LOW);
            delayMicroseconds(50);
            digitalRead(switchPin==LOW);
      }
       delay(1000);
       Serial.println("FINECORSA OK");
       delay(1000); // Pausa di 1 secondo
  
      digitalWrite(dirPin,LOW); //Cambia il senso di rotazione
      // 3200 Pulsazioni per un giro completo
      for(int x = 0; x < 24000; x++) { // Siringa vuota a 24000 step
            digitalWrite(stepPin,HIGH);
            delayMicroseconds(150);
            digitalWrite(stepPin,LOW);
            delayMicroseconds(50);
      }
         delay(1000);
         Serial.println("INIZIO ASPIRAZIONE");  
         delay(2000); // Pausa di 2 secondi
  
      digitalWrite(dirPin, HIGH);   // Abilito la rotazione
      while(digitalRead(switchPin)==HIGH)  // La siringa và al finecorsa
      {
      
            digitalWrite(stepPin, HIGH);
            delayMicroseconds(500);
            digitalWrite(stepPin, LOW);
            delayMicroseconds(50);
            digitalRead(switchPin==LOW);
      }
   
   delay(1000);
   Serial.println("INIZIO ESPIRAZIONE");
   delay(2000); // Pausa di 2 secondi
  
  digitalWrite(dirPin,LOW); //Cambia il senso di rotazione
  // 3200 Pulsazioni per un giro completo
   
  
   while(digitalRead(cellPin)==LOW)  
      
      {
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(150);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(50);
    serialVal = (((measureVal + (measureVal++))/1000) * sirConst);
    Serial.println(serialVal);
    

    digitalRead(cellPin==HIGH);  //
      }

 
      
    
    
    delay(1000);
    Serial.println("FINE TEST SIRINGA");
}

void loop() {

 
}

Vorrei capire a cosa servono righe come questa

digitalRead(switchPin==LOW);

Detto questo, se tu ogni volta che invii al motore la sequenza high-low fai aumentare di 1 il valore di una variabile se vai in una direzione e lo fai diminuire di 1 se vai nell'altra direzione, saprai dove si trova il motore. Ovviamente ti conviene mettere = 0 questa variabile quando sei sul fine corsa. Dal titolo credo che sia questa la richiesta.

Ehm... Righe come quella dovrebbero fermare il ciclo while quando accade qualcosa... Nel primo caso, è il finecorsa a massima estensione, nel secondo, è il finecorsa di massima compressione. Il mio problema nasce dal fatto che la siringa deve fermarsi dopo aver ricevuto l'ordine di fermarsi da parte di un'altro trigger. Come se dovessi cortocircuitare il microswitch di finecorsa in compressione con il Pin trigger, in modo tale che se non ricevo l'impulso a fermarsi dal trigger, la siringa si fermerà comunque all'attivarsi del finecorsa.

Per quello basta la condizione del while

 while(digitalRead(switchPin)==HIGH)

io mi riferivo a quelle righe isolate messe dopo gli impulsi inviati al motore.

Per conoscere la posizione puoi usare il metodo che ti ho precedentemente indicato. Per uscire dal while e quindi fermare il motore quando si verifica un'altra condizione basta mettere questa condizione fra le condizioni del while, ovviamente negata e con un and.

 while((digitalRead(switchPin)==HIGH) && (altracosa == quacosaltro))

in questo modo appena altracosa diventa diversa da qualcosaltro hai l'uscita dal while che hai anche se il digitalread della condizione che avevi già messo tu se ne va a LOW.

Ho capito. Sono riuscito a risolvere il problema. Grazie a tutti coloro che hanno avuto la pazienza ed il tempo di darmi una mano.