Follow focus con motore passo-passo

Buongiorno community, avrei bisogno di un piccolo aiuto sul codice da caricare in Arduino per la gestine del mio progetto. Descrivo brevemente cosa stò realizzando ed allego una parte di codice che ho testato fin’ora solo per movimentare il motore passp-passo in senso orario e antiorario, giusto per iniziare a prendere dimestichezza con la scheda e con il suo codice.

Il progetto è composto da 2 dispositivi:

  • il primo, è accoppiato alla ghiera di messa a fuoco dell’obiettivo e contiene il motore passo-passo 28BYJ-48 + il driver del motore ULN2003 + il potenziometro di posizione;

  • il secondo, è il dispositivo di controllo ed è costituito dal potenziometro di posizionamento + interruttore A + interruttore B + scheda Arduino nano.
    Tutto il sistema è alimentato dalla batteria della telecamera NP-F970 che fornisce una tensione di 7.2V.

Le specifiche del progetto sono 2:

  • la prima, il motore passo-passo deve azionare sia in senso orario sia in senso antiorario la ghiera di messa a fuoco e bloccarsi quando ha raggiunto il finecorsa meccanico della ghiera ovvero quando è terminata la rotazione disponibile per la messa a fuoco;

  • la seconda, con gli interruttori A e B bisogna impostare 2 punti all’interno del range di escursione della ghiera in modo tale da parzializzare il movimento solo da A verso B e viceversa, gli interruttori sono ON/OFF 2 posizioni quindi sulla posizione di OFF questi due punti verrebbero resettati permettendo così l’escursione massima della ghiera come descritto nella prima specifica.

//declare variables for the motor pins
int motorPin1 = 8; // Blue   - 28BYJ48 pin 1
int motorPin2 = 9; // Pink   - 28BYJ48 pin 2
int motorPin3 = 10; // Yellow - 28BYJ48 pin 3
int motorPin4 = 11; // Orange - 28BYJ48 pin 4
                       // Red    - 28BYJ48 pin 5 (VCC)

int motorSpeed = 0;     //variable to set stepper speed
int potPin = 2; //potentiometer connected to A2
int potValue = 0; //variable to read A0 input


//////////////////////////////////////////////////////////////////////////////
void setup() {
 //declare the motor pins as outputs
 pinMode(motorPin1, OUTPUT);
 pinMode(motorPin2, OUTPUT);
 pinMode(motorPin3, OUTPUT);
 pinMode(motorPin4, OUTPUT);
 Serial.begin(9600);
}

//////////////////////////////////////////////////////////////////////////////
void loop(){

 potValue = analogRead(potPin);     // read the value of the potentiometer
 Serial.println(potValue);          // View full range from 0 - 1024 in Serial Monitor
 if (potValue < 500){               // if potentiometer reads 0 to 499 do this
   motorSpeed = 1;  //scale potValue to be useful for motor
   clockwise();                     //go to the ccw rotation function
 }
 else if (potValue > 560) {         //value of the potentiometer is 561 - 1024
   motorSpeed = 1; //scale potValue for motor speed
   counterclockwise(); //go the the cw rotation function
 }
 else
   stopwise();
}

//////////////////////////////////////////////////////////////////////////////
//set pins to ULN2003 high in sequence from 1 to 4
//delay "motorSpeed" between each pin setting (to determine speed)

void counterclockwise (){
 // 1
 digitalWrite(motorPin1, HIGH);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, LOW);
 delay(motorSpeed);
 // 2
 digitalWrite(motorPin1, HIGH);
 digitalWrite(motorPin2, HIGH);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, LOW);
 delay (motorSpeed);
 // 3
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, HIGH);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, LOW);
 delay(motorSpeed);
 // 4
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, HIGH);
 digitalWrite(motorPin3, HIGH);
 digitalWrite(motorPin4, LOW);
 delay(motorSpeed);
 // 5
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, HIGH);
 digitalWrite(motorPin4, LOW);
 delay(motorSpeed);
 // 6
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, HIGH);
 digitalWrite(motorPin4, HIGH);
 delay (motorSpeed);
 // 7
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, HIGH);
 delay(motorSpeed);
 // 8
 digitalWrite(motorPin1, HIGH);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, HIGH);
 delay(motorSpeed);
}

//////////////////////////////////////////////////////////////////////////////
//set pins to ULN2003 high in sequence from 4 to 1
//delay "motorSpeed" between each pin setting (to determine speed)

void clockwise(){
 // 1
 digitalWrite(motorPin4, HIGH);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin1, LOW);
 delay(motorSpeed);
 // 2
 digitalWrite(motorPin4, HIGH);
 digitalWrite(motorPin3, HIGH);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin1, LOW);
 delay (motorSpeed);
 // 3
 digitalWrite(motorPin4, LOW);
 digitalWrite(motorPin3, HIGH);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin1, LOW);
 delay(motorSpeed);
 // 4
 digitalWrite(motorPin4, LOW);
 digitalWrite(motorPin3, HIGH);
 digitalWrite(motorPin2, HIGH);
 digitalWrite(motorPin1, LOW);
 delay(motorSpeed);
 // 5
 digitalWrite(motorPin4, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin2, HIGH);
 digitalWrite(motorPin1, LOW);
 delay(motorSpeed);
 // 6
 digitalWrite(motorPin4, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin2, HIGH);
 digitalWrite(motorPin1, HIGH);
 delay (motorSpeed);
 // 7
 digitalWrite(motorPin4, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin1, HIGH);
 delay(motorSpeed);
 // 8
 digitalWrite(motorPin4, HIGH);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin1, HIGH);
 delay(motorSpeed);
}

void stopwise (){
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, LOW);
}

Mi piacerebbe migliorare questo codice implementando la lettura del potenziometro di posizione + il controllo sugli interruttori A e B.

Ovviamente nei prossimi giorni metterò in condivisione altre immagini dello stato di avanzamento così se qualche appassionato di ripresa video volesse costruirsi un dispositivo simile già un pò di lavoro è fatto !!!

Grazie a tutti.

Francesco G.

Ciao! Il tuo programma non sembra fare quello che vorresti. Il programma come è adesso ruota in un senso o nell'altro un motore passo passo, il potenziometro funziona come una sorta di interruttore.

1)Per rilevare il finecorsa meccanico bisognerebbe che vi fosse un sensore e i sensori non ci sono.

  1. Dovresti leggere il potenziometro per darti dei valori analogici, con la funzione map() o direttamente con il valore analogico, dal valore analogico ottieni un valore minimo e un valore massimo, e con quello fare un certo numero di passi in senso orario o in senso antiorario. In pratica il potenziometro dovrebbe dirmi quanti passi fare in senso orario o in senso antiorario.

Ciao…infatti come dicevo il mio programma non è completo, è solo una bozza per iniziare a prendere dimestichezza con Arduino ed il motore passo-passo.

Per quanto riguarda il finecorsa meccanico, visto che i valori del potenziometro di posizione varierebbero tra 0 e 1024 (circa) ho pensato di usare 0 per il primo finecorsa, poi faccio ruotare la ghiera di messa a fuoco fino all’altra estremità e leggo il valore del potenziometro impostando in una variabile quel valore così facendo ho calibrato il campo d’azione del motore passo-passo. Credo che con una funzione IF inserita nella routine di loop posso cavarmela.

La parte di codice su cui cerco qualche suggerimento è quella che riguarda i 2 interruttori…se sono su OFF non succede nulla, però se li attivo vorrei 2 variabili che rappresentino i nuovi finecorsa all’interno dei quali muovermi con il motore passo-passo.

Allego 2 immagini sullo stato di avanzamento lavori giusto per far chiarezza sulla funzione del dispositivo che sto costruendo e sulla sua utilità.

Io procederei in modo differente e del tuo codice si potrebbe salvare solo le due funzione che fanno un passo in senso orario o antiorario.

  1. Devo sapere quanti passi del motore sono necessari per andare dalla posizione minima alla posizione
    massima.

  2. Nel programma ho una variabile globale "dichiarata fuori da ogni funzione" che memorizza la posizione
    attuale. All'accensione di arduino è a zero.

  3. Non ho sensori di fine corsa, allora pensavo a una sincronizzazione manuale del dispositivo.
    All'accensione di arduino io metto il fuoco in posizione minima e il potenziometro in posizione minima,
    in questo modo all'accensione di arduino sono in posizione minima e il potenziometro indica la posizione minima, il programma è sincronizzato con la meccanica.

  4. Agendo sul potenziometro ricavo la posizione da raggiungere, con la funzione map() valore massimo del potenziometro uguale a valore massimo passi, valore minimo potenziometro valore minimo dei passi.

  5. Con due if() se variabile posizione è minore di quella indicata dal potenziometro faccio con un ciclo for passi motore in un senso e incremento la variabile posizione, quando la variabile posizione è uguale a quella indicata dal potenziometro mi fermo. Se variabile posizione è minore ruoto in un senso e incremento, se variabile posizione è maggiore ruoto in un altro senso e decremento la variabile.

  6. Premendo i pulsanti posso memorizzare il valore della variabile posizione, se variabile posizione vale 1000, premendo il pulsante del minimo memorizzo 1000 in una variabile e ho la posizione minima, stessa cosa per la posizione massima.

  7. A questo punto posso muovere il sistema dai valori minimo e massimo, sapendo che il programma e la meccanica sono sincronizzati.

In pratica il tutto è un po più laborioso del codice che hai fatto, l'unica cosa che si può salvare del tuo codice è fare un passo in un senso o nell'altro, le due funzioni di rotazione.

//declare variables for the motor pins
int motorPin1 = 8; 	// Blue   - 28BYJ48 pin 1
int motorPin2 = 9; 	// Pink   - 28BYJ48 pin 2
int motorPin3 = 10; 	// Yellow - 28BYJ48 pin 3
int motorPin4 = 11; 	// Orange - 28BYJ48 pin 4
			// Red    - 28BYJ48 pin 5 (VCC)

int motorSpeed = 0;	//variable to set stepper speed
int potPin0 = 0;	//potentiometer connected to A0
int potValue = 0;	//variable to read A0 input
int potPin2 = 2;	//potentiometer connected to A2
int potValuePosiz = 0;	//variable to read A2 input

//////////////////////////////////////////////////////////////////////////////////////////

void setup() {
 pinMode(motorPin1, OUTPUT);
 pinMode(motorPin2, OUTPUT);
 pinMode(motorPin3, OUTPUT);
 pinMode(motorPin4, OUTPUT);
 Serial.begin(9600);
}

//////////////////////////////////////////////////////////////////////////////////////////

void loop(){
 potValue = analogRead(potPin0);	// read the value of the potentiometer
 potValuePosiz = analogRead(potPin2);	// read the value of the potentiometer

 Serial.println(potValue);		// View full range from 0 - 1023 in Serial Monitor
 Serial.println(potValuePosiz);		// View full range from 0 - 1023 in Serial Monitor

 if (potValue < 500){			// if potentiometer reads 0 to 499 do this
   motorSpeed = 1;			
   clockwise();				//go to the ccw rotation function
 }
 else if (potValue > 560) {		//value of the potentiometer is 561 - 1023
   motorSpeed = 1;			
   counterclockwise();			//go the the cw rotation function
 }
 else
   stopwise();
}

//////////////////////////////////////////////////////////////////////////////////////////

void counterclockwise (){
 // 1
 checkA();
 digitalWrite(motorPin1, HIGH);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, LOW);
 delay(motorSpeed);
 // 2
 checkA();
 digitalWrite(motorPin1, HIGH);
 digitalWrite(motorPin2, HIGH);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, LOW);
 delay (motorSpeed);
 // 3
 checkA();
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, HIGH);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, LOW);
 delay(motorSpeed);
 // 4
 checkA();
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, HIGH);
 digitalWrite(motorPin3, HIGH);
 digitalWrite(motorPin4, LOW);
 delay(motorSpeed);
 // 5
 checkA();
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, HIGH);
 digitalWrite(motorPin4, LOW);
 delay(motorSpeed);
 // 6
 checkA();
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, HIGH);
 digitalWrite(motorPin4, HIGH);
 delay (motorSpeed);
 // 7
 checkA();
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, HIGH);
 delay(motorSpeed);
 // 8
 checkA();
 digitalWrite(motorPin1, HIGH);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, HIGH);
 delay(motorSpeed);
}

//////////////////////////////////////////////////////////////////////////////////////////

void clockwise(){
 // 1
 checkB();
 digitalWrite(motorPin4, HIGH);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin1, LOW);
 delay(motorSpeed);
 // 2
 checkB();
 digitalWrite(motorPin4, HIGH);
 digitalWrite(motorPin3, HIGH);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin1, LOW);
 delay (motorSpeed);
 // 3
 checkB();
 digitalWrite(motorPin4, LOW);
 digitalWrite(motorPin3, HIGH);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin1, LOW);
 delay(motorSpeed);
 // 4
 checkB();
 digitalWrite(motorPin4, LOW);
 digitalWrite(motorPin3, HIGH);
 digitalWrite(motorPin2, HIGH);
 digitalWrite(motorPin1, LOW);
 delay(motorSpeed);
 // 5
 checkB();
 digitalWrite(motorPin4, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin2, HIGH);
 digitalWrite(motorPin1, LOW);
 delay(motorSpeed);
 // 6
 checkB();
 digitalWrite(motorPin4, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin2, HIGH);
 digitalWrite(motorPin1, HIGH);
 delay (motorSpeed);
 // 7
 checkB();
 digitalWrite(motorPin4, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin1, HIGH);
 delay(motorSpeed);
 // 8
 checkB();
 digitalWrite(motorPin4, HIGH);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin1, HIGH);
 delay(motorSpeed);
}

//////////////////////////////////////////////////////////////////////////////////////////

void stopwise (){
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, LOW);
}

//////////////////////////////////////////////////////////////////////////////////////////

void checkA (){
if (potValuePosiz = 0){			// se il potenziometro di posizione è = 0
   stopwise ();				// ferma il motore passo-passo
}

//////////////////////////////////////////////////////////////////////////////////////////

void checkB (){
if (potValuePosiz = 1023){		// se il potenziometro di posizione è = 1023
   stopwise ();				// ferma il motore passo-passo
}

Grazie mille per i suggerimenti, però prima di prendere una strada diversa, ho pensato a questa ipotetica soluzione:

ho asseganto al pin0 analogico il potenziometro di comando ed al pin2 analogico il potenziometro di posizione. Ho pensato che, se prima di ogni movimento step by step effettuo un controllo mediante 2 sub-routine (checkA e chekB) quando raggiungo i valori di finecorsa impostati nelle 2 sub-routine, il motore dovrebbe arrestarsi…mi sembra una soluzione semplice.

Però sugli interruttori ho ancora qualche dubbio…porto l’interruttore su ON e memorizzo il valore del potenziometro di posizione in una variabile…muovo la ghiera di messa a fuoco e analogamente il potenziometro cambia valore…la variabile che ho memorizzato precedentemente continuerà a cambiare il valore memorizzato ? La variabile dovrebbe mantenere un solo valore così posso spostarmi in un’altra posizione e su un’altra variabile memorizzare un secondo valore.

Non funziona e ti spiego perché tu richiami checkA la quale verifica il valore che hai memorizzato all'inizio del loop, se ciò non bastasse a rendere la logica fallace anche ammettendo di rileggere il valore del potenziometro dentro checkA e nel caso sia il suo valore zero richiamare la funzioen che ferma il motore, non appena esci dalla checkA il loop continuerebbe ri azionando il motore.
fossi in te darei retta a @torn24, è difficile mentalmente da fare ma necessario, butta tutto il codice e rivedi interamente la logica che deve seguire. Se non sei pratico di programmazione aggiungo anche che ti conviene prima buttare giù la logica che deve seguire in italiano e poi codificare:
Es.
Se sto cuocendo la torta
controllo se il tempo impostato è finito
spengo il forno
altrimenti
verifico la temperatura
....
Quandola logica da seguire sarà chiara ed esatta allora aproccerei a codificarla.
E ti dico già che i delay sono tuoi accerrimi nemici perché se metti un delay per far muovere il motore per un certo tempo, in quel tempo non puoi controllare se sei arrivato a fine corsa e via di seguito. A mio avviso il delay lo puoi usare per lo stretto tempo necessario affinché il motore esegua un passo ed uno soltanto (che è l'unità minima e quindi non può essere interrotta), per tutto il resto millis come se non ci fosse un domani

Grazie a tutti per i suggerimenti...sto rivedendo la logica di azionamento del motore e credo che con la libreria Stepper.h riesco a cavarmela con poche righe di codice.

Mi sono arenato su un concetto: metto nel loop il controllo di un pin digtale e se il suo stato è high memorizzo in una variabile il valore analogico di un potenziometro, successivamente il potenziometro cambia il suo valore ed il pin digitale è sempre sullo stato high, credo che il valore memorizzato nella variabile continuerà a cambiare in virtù del loop nel quale la funzione è inserita, invece vorrei che fosse memorizzato solo il primo valore del potenziometro ovvero quando il pin digitale passa da low a high senza cambiare fin quando il pin digitale non torna sullo stato low...non so se son stato chiaro...c'è un modo per farlo ?

int interruttore = 10;
int potPin0 = 0;
int potValue = 0;

void setup() { 
 pinMode(interruttore, INPUT);
}

void loop() {
 int stato_interruttore = digitalRead(interruttore); 
 if (stato_interruttore == HIGH){
  potValue = analogRead(potPin0);	
 } 
}

Questo codice dovrebbe memorizzare in potValue il valore letto sul pin0 quando il digital pin10 è high però durante il loop cambierà di continuo man mano che il valore del potenziometro cambia.
Ovviamente non posso portare allo stato low il pin digitale, perderei visivamente il fatto che è impostato un valore personalizzato.

Grazie :wink:

Certo che puoi, una bella variabile bool. Quando il pulsante viene premuto verifiche se tale variabile non è settata, nel caso memorizzi il valore del potenziometrom, setti la variabile in modo da non aggiornare in seguito il valore del potenziometro.
Quando il pulsante viene rilasciato, resetti la variabile

Forse la procedura non mi è del tutto chiara, perdona la mia inesperienza...una variabile booleana dovrebbe funzionare come lo stato di un pin digitale (low, high) il problema è che non utilizzo un pulsante ma un interruttore on-off quindi vorrei che un dato evento si verificasse solo sul fronte di salita cioè solamente nel passaggio da low a high...l'interruttore resta su on per un tempo indefinito.

Appunto interruttore va HIGH, variabile vera (o falsa dipende da come ti torna) allora memorizza il valore del potenziometro e variabile falsa (o vera in base a com ti torna :slight_smile: ).
Interrutore va a LOW variabile torna al valore precedente.
Tradotto è una variabile ed un if da aggiungere

Indendevi in questo modo ?

boolean variabile = false
int interruttore = 10;
int potPin0 = 0;
int potValue = 0;

void setup() { 
 pinMode(interruttore, INPUT);
}

void loop() {
 int stato_interruttore = digitalRead(interruttore); 
 if (stato_interruttore == HIGH){
  variabile = true;
 }
 if (variabile == true){
  potValue = analogRead(potPin0);
  variabile = false;
 } 
}

No, in quel modo non cambia nulla, lo stato interruttore valorizzerà sempre la variabile e il successivo if continua a rilvalorizzare potValue di continuo e tu non vuoi questo.
Prova a pensarci, tutto parte che stato_interruttore è LOW, ad un certo punto va HIGH, quindi quando questa condizione è vera tu devi fare una cosa solo una volta, ovvero il loop farà si che ad ogni giro tu entrerai in quell'if ma con la variabile e un altro if dentro questo devi far leggere il potenziometro solo una volta, ovvero SE premuto allora Se è la prima volta leggo e faccio in modo che le altre volte non sia più la prima volta :slight_smile: . SE il pulsante non è più premuto allora reimposto la variabile in mdoo che quando sarà premuto di nuovo sarà di nuovo la prima volta.

Forse ci sono :sweat_smile: speriamo bene !

boolean variabile = false
int interruttore = 10;
int potPin0 = 0;
int potValue = 0;

void setup()
{ 
pinMode(interruttore, INPUT);
}

void loop()
{
int stato_interruttore = digitalRead(interruttore); 

if (stato_interruttore == LOW){
 variabile = false;
}

if (stato_interruttore == HIGH && variabile == false){
 potValue = analogRead(potPin0);
 variabile = true;
}
}

Esatto! quello che stavo descrivendo io a parole era così:

void setup()
{
pinMode(interruttore, INPUT);
variabile = false;
}

void loop()
{
    int stato_interruttore = digitalRead(interruttore);


    if (stato_interruttore == HIGH)
    {
        if(variabile == false)
        {
          potValue = analogRead(potPin0);
          variabile = true;
        }
    }
    else
    {
       variabile = false;
    }
}

che poi essendo entrambe le condizioni booleane e quindi direttamente valutabili nell'espressione può divenire:

void setup()
{
pinMode(interruttore, INPUT);
variabile = false;
}

void loop()
{
    if (digitalRead(interruttore))
    {
        if(!variabile)
        {
          potValue = analogRead(potPin0);
          variabile = true;
        }
    }
    else
    {
       variabile = false;
    }
}

La tua soluzione funziona benissimo, la mia l'ho messa solo per permetterti di fare un parallelo tra il testo in italico idioma e relativa codifica.
Entrambe funzionano benissimo se l'interruttore è dotato di adeguato circuito di debounce hardware (che andrebbe sempre messo per ogni pulsante :wink: )

Grazie mille davvero tantissimo !!! Sei stato super professionale.

Ho implementato tutta la logica di gestione del mio progetto in questo codice

#include <Stepper.h>
const int stepsPerRevolution = 4096;
Stepper myStepper = Stepper(stepsPerRevolution, 8, 9, 10, 11);

int motorPin1 = 8; 	// Blue   - 28BYJ48 pin 1
int motorPin2 = 9; 	// Pink   - 28BYJ48 pin 2
int motorPin3 = 10; 	// Yellow - 28BYJ48 pin 3
int motorPin4 = 11; 	// Orange - 28BYJ48 pin 4
			// Red    - 28BYJ48 pin 5 (VCC)

int potPin0 = 0;	// potentiometer connected to A0
int potValue = 0;	// variable to read A0 input
int potPin2 = 2;	// potentiometer connected to A2
int potValuePosiz = 0;	// variable to read A2 input
int interruttoreA = 1;	// pin digitale 1
int interruttoreB = 2;	// pin digitale 2
int finecorsaX = 0;
int finecorsaY = 1000;
int finecorsaA = 0;
int finecorsaB = 0;

boolean variabileA = false;
boolean variabileB = false;

void setup()
{
 pinMode(interruttoreA, INPUT);
 pinMode(interruttoreB, INPUT);
 pinMode(motorPin1, OUTPUT);
 pinMode(motorPin2, OUTPUT);
 pinMode(motorPin3, OUTPUT);
 pinMode(motorPin4, OUTPUT);
 myStepper.setSpeed(50);			// imposta la velocità in giri al minuto (rpm)
 Serial.begin(9600);
 Serial.println("Pot_Comando\tPot_Posizione\tFinecorsa_X\tFinecorsa_Y\tFinecorsa_A\tFinecorsa_B");
}



void loop()
{
 int stato_interruttoreA = digitalRead(interruttoreA);
 int stato_interruttoreB = digitalRead(interruttoreB);
 
 potValue = analogRead(potPin0);	// leggi sul pin0 il valore del potenziometro di comando
 potValuePosiz = analogRead(potPin2);	// leggi sul pin2 il valore del potenziometro di posizione

 if(stato_interruttoreA == HIGH)
 {
  if(variabileA == false)
  {
   finecorsaA = analogRead(potPin2);
   finecorsaX = finecorsaA;
   variabileA = true;
  }
 }
 else
 {
  variabileA = false;
  finecorsaX = 0;
 }

 if(stato_interruttoreB == HIGH)
 {
  if(variabileB == false)
  {
   finecorsaB = analogRead(potPin2);
   finecorsaY = finecorsaB;
   variabileB = true;
  }
 }
 else
 {
  variabileB = false;
  finecorsaY = 1000;
 }

 void monitor()

 if (potValue <=500 && potValuePosiz != finecorsaX)	// valore potenz.comando <=500 e valore potenz.posizione diverso da 0
 {
  myStepper.step(1);					// esegui 1 step in senso orario
 }
 if (potValue <=500 && potValuePosiz = finecorsaX)	// valore potenz.comando <=500 e valore potenz.posizione diverso da 0
 {
  stopwise();						// ferma il motore
 }
 if (potValue >=560 && potValuePosiz != finecorsaY)	// valore potenz.comando >=560 e valore potenz.posizione diverso da 1000
 {
  myStepper.step(-1);					// esegui 1 step in senso antiorario
 }
 if (potValue >=560 && potValuePosiz = finecorsaY)	// valore potenz.comando >=560 e valore potenz.posizione diverso da 1000
 {
  stopwise();						// ferma il motore
 }
 if (potValue && >500 && <560)				// valore potenz.comando compreso tra 501 e 559
 {
  stopwise();						// ferma il motore
 }
}

void stopwise ()
{
 digitalWrite(motorPin1, LOW);
 digitalWrite(motorPin2, LOW);
 digitalWrite(motorPin3, LOW);
 digitalWrite(motorPin4, LOW);
}

void monitor ()
{
 Serial.print(potValue);		// scrivi sul monitor il valore del potenziometro di comando
 Serial.print("\t");
 Serial.print(potValuePosiz);		// scrivi sul monitor il valore del potenziometro di posizione
 Serial.print("\t");
 Serial.print(finecorsaX);		// scrivi sul monitor il valore del finecorsa X
 Serial.print("\t");
 Serial.print(finecorsaY);		// scrivi sul monitor il valore del finecorsa Y
 Serial.print("\t");
 Serial.print(finecorsaA);		// scrivi sul monitor il valore del finecorsa A
 Serial.print("\t");
 Serial.print(finecorsaB);		// scrivi sul monitor il valore del finecorsa B
}

però nel momento in cui verifico il codice, il compilatore mi visualizza questi errori:

prova:80:2: error: expected initializer before ‘if’

if (potValue <=500 && potValuePosiz != finecorsaX) // valore potenz.comando <=500 e valore potenz.posizione diverso da 0

^~

prova:84:40: error: lvalue required as left operand of assignment

if (potValue <=500 && potValuePosiz = finecorsaX) // valore potenz.comando <=500 e valore potenz.posizione diverso da 0

^~~~~~~~~~

prova:92:40: error: lvalue required as left operand of assignment

if (potValue >=560 && potValuePosiz = finecorsaY) // valore potenz.comando >=560 e valore potenz.posizione diverso da 1000

^~~~~~~~~~

prova:96:18: error: expected primary-expression before ‘>’ token

if (potValue && >500 && <560) // valore potenz.comando compreso tra 501 e 559

^

prova:96:26: error: expected primary-expression before ‘<’ token

if (potValue && >500 && <560) // valore potenz.comando compreso tra 501 e 559

^

Più di una libreria trovata per “Stepper.h”
Usata: C:\Program
exit status 1
expected initializer before ‘if’

Quelle righe di if dove c’è la gestione del potenziometro di comando, hanno qualcosa che non funziona a dovere però mi sembra che la condizione AND l’ho implementata bene.

Se usassi la funzione di "formattazione automatica" messa a disposizione dal IDE, non solo avresti un sorgente meglio formattato, ma ... scopriresti che ... c'è una riga, messa li così, che non c'entra nulla ...
... magari volevi fare un'altra cosa o magari ti è rimasto sporco un copia/incolla.

Guglielmo

Grazie Guglielmo

const int stepsPerRevolution = 2048;

Stepper myStepper = Stepper(stepsPerRevolution, 8, 10, 9, 11);

int motorPin1 = 8;  // Blue   - 28BYJ48 pin 1
int motorPin2 = 9;  // Pink   - 28BYJ48 pin 2
int motorPin3 = 10; // Yellow - 28BYJ48 pin 3
int motorPin4 = 11; // Orange - 28BYJ48 pin 4

void setup()
{
  myStepper.setSpeed(10);
}

void loop()
{
  myStepper.step(10);
}

Il codice che ho allegato racchiude le classiche istruzioni per indirizzare i pin digitali di Arduino e pilotare uno stepper, nel mio caso si tratta di un 28BYJ48.

Ovviamente il codice che gestisce il mio dispositivo è molto più articolato.

Dopo tante prove fatte prove fatte, cambiando il SetSpeed ed il numero di step, al fine di aumentare la velocità di rotazione dello stepper, ho notato che oltre un limite non riesce ad andare e probabilmente non riesce ad esprimere neanche la coppia tipica per cui è progettato...mi è venuto in mente un discorso che ho sperimentato con i segnali pwm...se collego lo stepper sui pin 3,9,10,11 ed riduco la frequenza di clock a 122Hz è possibile che riesca ad ottenere il massimo ? (come specificato nel data sheet dello stepper).

Grazie.

Forse devo procedere in modo diverso:

utilizzando myStepper.step(1) muovo lo stepper di un solo step ed utilizzando un delay(8) avrei un intervallo di 8 ms prima che venga inviato il secondo step vale a dire (1/0,008s) = 125Hz. In questo modo potrei riuscire ad usare un valore maggiore di 10rpm nel funzione myStepper.setSpeed(10) senza perdere troppa coppia. E’ giusto il ragionamento ?