Finecorsa e Motore passo passo

Salve sto lavorando ad un progetto (cancello scorrevole) ma mi sono bloccato e non so come fare:
COMPONENTI:
_relè
_pulsante
_scheda arduino mega
_finecorsa
_motore passo passo

Il problema è che il motore gira ma il finecorsa non si aziona,o meglio si aziona ma quando il motorino finisce i giri da me impostati…Come posso fare??
Aiutatemi
Qui sotto lo sketch di quello che ho fatto fino ad adesso

sketch_apr08e.ino (1.67 KB)

Un motore passo passo per un cancello scorrevole?

Credo sia poco potente per quello scopo, inoltre ti complichi la vita con il suo pilotaggio.

Meglio un motore DC con riduttore di giri ed applichi i finecorsa sulla cremagliera.

ciao

matteo41996: Il problema è che il motore gira ma il finecorsa non si aziona,o meglio si aziona ma quando il motorino finisce i giri da me impostati...Come posso fare??

Il controllo del finecorsa lo devi mettere all'interno della funzione che muove lo stepper.

cyberhs: Un motore passo passo per un cancello scorrevole?

credo (spero) sia un modellino... ;)

ciao pippo72

Cyberhs

cyberhs: Un motore passo passo per un cancello scorrevole?

Credo sia poco potente per quello scopo, inoltre ti complichi la vita con il suo pilotaggio.

Meglio un motore DC con riduttore di giri ed applichi i finecorsa sulla cremagliera.

Si quei motorini che ti danno nei kit Senno quale motorini mi consiglieresti?

pippo72: ciao

Il controllo del finecorsa lo devi mettere all'interno della funzione che muove lo stepper.

credo (spero) sia un modellino... ;)

ciao pippo72

Sisi è un plastico che sto realizzando per scuola Comunque come dovrei metterlo scusa? Ho provato in tutti i modi :O

questo è il programma che hai allegato:

const int IN1=2;
const int IN2=3;
const int IN3=4;
const int IN4=5;
const int finecorsa=8;
const int button=7;
const int rele=6;
const char tab1[] =
{
  0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08, 0x09
};
const char tab2[] =
{
  0x01, 0x09, 0x08, 0x0c, 0x04, 0x06, 0x02, 0x03
};

void setup() 
{
  pinMode(finecorsa, INPUT);
  pinMode(button, INPUT);
  pinMode(rele, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
}

void loop() {
  if(digitalRead(button)==HIGH)
  {
    ctlStepMotor(720,1);
    
  }
  if(digitalRead(finecorsa)==HIGH)
  {
    digitalWrite(rele, HIGH);
    delay(5000);
    digitalWrite(rele,LOW);
    ctlStepMotor(-720,1);
    StepMotorStop();
    
  }
}

void ctlStepMotor(int angle,char speeds )
{
  for (int j = 0; j < abs(angle) ; j++)
  {
    if (angle > 0)
    {
      for (int i = 0; i < 8; i++)
      {
        digitalWrite(IN1, ((tab1[i] & 0x01) == 0x01 ? true : false));
        digitalWrite(IN2, ((tab1[i] & 0x02) == 0x02 ? true : false));
        digitalWrite(IN3, ((tab1[i] & 0x04) == 0x04 ? true : false));
        digitalWrite(IN4, ((tab1[i] & 0x08) == 0x08 ? true : false));
        delay(speeds);
      }
    }
    else
    {
      for (int i = 0; i < 8 ; i++)
      {
        digitalWrite(IN1, ((tab2[i] & 0x01) == 0x01 ? true : false));
        digitalWrite(IN2, ((tab2[i] & 0x02) == 0x02 ? true : false));
        digitalWrite(IN3, ((tab2[i] & 0x04) == 0x04 ? true : false));
        digitalWrite(IN4, ((tab2[i] & 0x08) == 0x08 ? true : false));
        delay(speeds);
      }
    }
  }
}
void StepMotorStop()
{
  digitalWrite(IN1, 0);
  digitalWrite(IN2, 0);
  digitalWrite(IN3, 0);
  digitalWrite(IN4, 0);
}

All’intero del loop tu hai messo 2 if: il primo verifica se un pulsante viene premuto e si comporta di conseguenza (richiami la funzione ctlStepMotor) e il secondo controlla se interviene il finecorsa ecc.

C’è un piccolo problema: arduino esegue sempre e solo un comando (o una funzione) alla volta quindi se si verifica il primo if (button == HIGH) questo chiama (o esegue,come preferisci) la funzione ctlStepMotor fino alla fine della stessa senza mai verificare se interviene il finecorsa.

Se vuoi che mentre il motore si muove venga anche “letto” il finecorsa devi mettere questo controllo all’interno della funzione ctlStepMotor.

esempio:

void ctlStepMotor(int angle,char speeds )
{
  for (int j = 0; j < abs(angle) ; j++)
  {
    if (angle > 0)
    {
      OMISSIS...
    }
    else
    {
    OMISSIS...
    }
    if(digitalRead(finecorsa)==HIGH)  //<==============aggiunto controllo
  {
    OMISSIS...
     }
}

Naturalmente non puoi solo spostare il tuo controllo finecorsa così come è scritto, va adattato alla situazione.

ciao
pippo72

pippo72:
questo è il programma che hai allegato:

const int IN1=2;

const int IN2=3;
const int IN3=4;
const int IN4=5;
const int finecorsa=8;
const int button=7;
const int rele=6;
const char tab1 =
{
  0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08, 0x09
};
const char tab2 =
{
  0x01, 0x09, 0x08, 0x0c, 0x04, 0x06, 0x02, 0x03
};

void setup()
{
  pinMode(finecorsa, INPUT);
  pinMode(button, INPUT);
  pinMode(rele, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
}

void loop() {
  if(digitalRead(button)==HIGH)
  {
    ctlStepMotor(720,1);
   
  }
  if(digitalRead(finecorsa)==HIGH)
  {
    digitalWrite(rele, HIGH);
    delay(5000);
    digitalWrite(rele,LOW);
    ctlStepMotor(-720,1);
    StepMotorStop();
   
  }
}

void ctlStepMotor(int angle,char speeds )
{
  for (int j = 0; j < abs(angle) ; j++)
  {
    if (angle > 0)
    {
      for (int i = 0; i < 8; i++)
      {
        digitalWrite(IN1, ((tab1[i] & 0x01) == 0x01 ? true : false));
        digitalWrite(IN2, ((tab1[i] & 0x02) == 0x02 ? true : false));
        digitalWrite(IN3, ((tab1[i] & 0x04) == 0x04 ? true : false));
        digitalWrite(IN4, ((tab1[i] & 0x08) == 0x08 ? true : false));
        delay(speeds);
      }
    }
    else
    {
      for (int i = 0; i < 8 ; i++)
      {
        digitalWrite(IN1, ((tab2[i] & 0x01) == 0x01 ? true : false));
        digitalWrite(IN2, ((tab2[i] & 0x02) == 0x02 ? true : false));
        digitalWrite(IN3, ((tab2[i] & 0x04) == 0x04 ? true : false));
        digitalWrite(IN4, ((tab2[i] & 0x08) == 0x08 ? true : false));
        delay(speeds);
      }
    }
  }
}
void StepMotorStop()
{
  digitalWrite(IN1, 0);
  digitalWrite(IN2, 0);
  digitalWrite(IN3, 0);
  digitalWrite(IN4, 0);
}




All'intero del loop tu hai messo 2 if: il primo verifica se un pulsante viene premuto e si comporta di conseguenza (richiami la funzione ctlStepMotor) e il secondo controlla se interviene il finecorsa ecc.

C'è un piccolo problema: arduino esegue sempre e solo un comando (o una funzione) alla volta quindi se si verifica il primo if (button == HIGH) questo chiama (o esegue,come preferisci) la funzione ctlStepMotor fino alla fine della stessa senza mai verificare se interviene il finecorsa.

Se vuoi che mentre il motore si muove venga anche "letto" il finecorsa devi mettere questo controllo all'interno della funzione ctlStepMotor.

esempio:


void ctlStepMotor(int angle,char speeds )
{
  for (int j = 0; j < abs(angle) ; j++)
  {
    if (angle > 0)
    {
      OMISSIS…
    }
    else
    {
    OMISSIS…
    }
    if(digitalRead(finecorsa)==HIGH)  //<==============aggiunto controllo
  {
    OMISSIS…
    }
}




Naturalmente non puoi solo spostare il tuo controllo finecorsa così come è scritto, va adattato alla situazione.

ciao
pippo72

Grande ora funziona mettevo il codice nella posizione sbagliata dello sketch

Altro problema…ho modificato lo sketch ma quando attivo il finecorsa si attiva il rele(e fin qui tutto bene) gli do due secondi per spegnere il rele ma avendo il finecorsa ancora attivo va in loop

const int IN1=2;
const int IN2=3;
const int IN3=4;
const int IN4=5;
const int pulsante=10;
const int rele=8;
const int finecorsa=12;
const char tab1 =
{
0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08, 0x09
};
const char tab2 =
{
0x01, 0x09, 0x08, 0x0c, 0x04, 0x06, 0x02, 0x03
};

void setup()
{
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(rele, OUTPUT);
pinMode(pulsante, INPUT);
pinMode(finecorsa, INPUT);
}

void loop() {
if(digitalRead(pulsante)==HIGH)
{
ctlStepMotor(-720,1);
}
if(digitalRead(finecorsa)==HIGH)
{
digitalWrite(rele, HIGH);
delay(5000);
digitalWrite(rele,LOW);
ctlStepMotor(720,1);
StepMotorStop();
}
}

void ctlStepMotor(int angle, char speeds )
{
for (int j = 0; j < abs(angle) ; j++)
{
if (angle > 0)
{
for (int i = 0; i < 8; i++)
{
digitalWrite(IN1, ((tab1 & 0x01) == 0x01 ? true : false));
_ digitalWrite(IN2, ((tab1 & 0x02) == 0x02 ? true : false));_
_ digitalWrite(IN3, ((tab1 & 0x04) == 0x04 ? true : false));
digitalWrite(IN4, ((tab1 & 0x08) == 0x08 ? true : false));
* delay(speeds);
}
}
else*

* {
for (int i = 0; i < 8 ; i++)
{
digitalWrite(IN1, ((tab2 & 0x01) == 0x01 ? true : false));
digitalWrite(IN2, ((tab2 & 0x02) == 0x02 ? true : false));
digitalWrite(IN3, ((tab2 & 0x04) == 0x04 ? true : false));
digitalWrite(IN4, ((tab2 & 0x08) == 0x08 ? true : false));
delay(speeds);
}
}
if(digitalRead(finecorsa)==HIGH)
{
digitalWrite(rele, HIGH);
delay(5000);
digitalWrite(rele,LOW);
}
}
}
void StepMotorStop()
{
digitalWrite(IN1, 0);
digitalWrite(IN2, 0);
digitalWrite(IN3, 0);
digitalWrite(IN4, 0);
}*_

ciao

quando alleghi un codice mettilo all’interno dei tag CODE ( bottone </> in alto a sx).

Non è che va in loop, semplicemente stai controllando il finecorsa all’interno del ciclo for che non è ancora finito (e che tu non interrompi).
Ti avevo comunque “quasi” avvertito:

pippo72:
Naturalmente non puoi solo spostare il tuo controllo finecorsa così come è scritto, va adattato alla situazione.

Devi interrompere il ciclo for:

    if(digitalRead(finecorsa)==HIGH)
  {
    digitalWrite(rele, HIGH);
    delay(5000);
    digitalWrite(rele,LOW);
    break; //<============== 
  }
  }

così da uscire subito da quel ciclo for.

ciao
pippo72

 const int IN1=2;
const int IN2=3;
const int IN3=4;
const int IN4=5;
const int pulsante=10;
const int rele=8;
const int finecorsa=12;
const char tab1[] =
{
  0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08, 0x09
};
const char tab2[] =
{
  0x01, 0x09, 0x08, 0x0c, 0x04, 0x06, 0x02, 0x03
};

void setup() 
{
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(rele, OUTPUT);
  pinMode(pulsante, INPUT);
  pinMode(finecorsa, INPUT);
}

void loop() {
  if(digitalRead(pulsante)==HIGH)
  {
    ctlStepMotor(-720,1);
   
  }
  if(digitalRead(finecorsa)==HIGH)
  {
    
    digitalWrite(rele, HIGH);
    delay(5000);   
    digitalWrite(rele,LOW);
    ctlStepMotor(720,1);
    StepMotorStop();
  }
  }

void ctlStepMotor(int angle, char speeds )
{
  for (int j = 0; j < abs(angle) ; j++)
  {
    if (angle > 0)
    {
      for (int i = 0; i < 8; i++)
      {
        digitalWrite(IN1, ((tab1[i] & 0x01) == 0x01 ? true : false));
        digitalWrite(IN2, ((tab1[i] & 0x02) == 0x02 ? true : false));
        digitalWrite(IN3, ((tab1[i] & 0x04) == 0x04 ? true : false));
        digitalWrite(IN4, ((tab1[i] & 0x08) == 0x08 ? true : false));
        delay(speeds);
      }
    }
    else
    {
      for (int i = 0; i < 8 ; i++)
      {
        digitalWrite(IN1, ((tab2[i] & 0x01) == 0x01 ? true : false));
        digitalWrite(IN2, ((tab2[i] & 0x02) == 0x02 ? true : false));
        digitalWrite(IN3, ((tab2[i] & 0x04) == 0x04 ? true : false));
        digitalWrite(IN4, ((tab2[i] & 0x08) == 0x08 ? true : false));
        delay(speeds);
      }
    }
    if(digitalRead(finecorsa)==HIGH)
  {
    digitalWrite(rele, HIGH);
    delay(5000);   
    digitalWrite(rele,LOW);
    break;
  }
  }
  }
void StepMotorStop()
{
  digitalWrite(IN1, 0);
  digitalWrite(IN2, 0);
  digitalWrite(IN3, 0);
  digitalWrite(IN4, 0);
}

ho fatto cosi ma forse non mi sono spiegato bene…
praticamente quando il finecorsa si attiva si attiva anche il rele (il rele interrompe il - del motore o il + è uguale) poi aspetta 5 secondi e si spegne il rele ma il finecorsa comunque rimane attivo…e quindi al motore gli arriva tensione ma contemporaneamente il finecorsa essendo rimasto attivo risvolge il comando…
Forse non mi ero spiegato bene prima ma avendo comprato da poco arduino non so benissimo programmare ma sto imparando

a che ti serve un rele’ per spegnere il motore, visto che usi uno stepper ?

Anche ammettendo che il relè possa servire, devi cambiare l'approccio. Il fine corsa lo devi interrogare solo quando stai muovendo il motore per sapere quando arrivi - appunto - alla fine della corsa. Lo puoi anche interrogare prima di iniziare un nuovo movimento se vuoi portare il sistema in una posizione note: verifica se sei in quella posizione, altrimenti mettiti a fine corsa e poi esegui le fasi successive, così sei sicuro di partire sempre dal fine corsa (nel caso si fosse spostato per interventi esterni). Tu invece lo verifichi ad ogni loop quindi continuamente, indipendentemente dal fatto che il cancello sia aperto, chiuso... Metti una variabile che ti dice se il cancello è aperto e casomai imposta un timer usando millis() che se è aperto te lo chiude dopo xxx secondi o anche prima, se viene premuto il pulsante.

Chiuso + il pulsante non è premuto : non fare nulla. Chiuso + il pulsante è stato premuto: aprilo. Aperto + pulsante non premuto ed xxx secondi ancora non trascorsi: non fare nulla. Aperto + pulsante premuto: chiudilo. Aperto + sono trascorsi xxx secondi: chiudilo.

Brunello:
a che ti serve un rele’ per spegnere il motore, visto che usi uno stepper ?

Pensavo servisse per interrompere una fase ma ho provato senza e funziona uguale, però c’è sempre il problema che se il finecorsa rimane premuto ripete comunque il comando

paulus1969:
Anche ammettendo che il relè possa servire, devi cambiare l’approccio.
Il fine corsa lo devi interrogare solo quando stai muovendo il motore per sapere quando arrivi - appunto - alla fine della corsa. Lo puoi anche interrogare prima di iniziare un nuovo movimento se vuoi portare il sistema in una posizione note: verifica se sei in quella posizione, altrimenti mettiti a fine corsa e poi esegui le fasi successive, così sei sicuro di partire sempre dal fine corsa (nel caso si fosse spostato per interventi esterni).
Tu invece lo verifichi ad ogni loop quindi continuamente, indipendentemente dal fatto che il cancello sia aperto, chiuso…
Metti una variabile che ti dice se il cancello è aperto e casomai imposta un timer usando millis() che se è aperto te lo chiude dopo xxx secondi o anche prima, se viene premuto il pulsante.

Chiuso + il pulsante non è premuto : non fare nulla.
Chiuso + il pulsante è stato premuto: aprilo.
Aperto + pulsante non premuto ed xxx secondi ancora non trascorsi: non fare nulla.
Aperto + pulsante premuto: chiudilo.
Aperto + sono trascorsi xxx secondi: chiudilo.

se puoi spiegati meglio ripeto che sono nuovo e non so bene come funziona ancora arduino
Il mio progetto consiste in un cancello scorrevole.
_se premo il pulsante il cancello si apre,
_tocca il finecorsa
_ dopo 5 secondi si deve chiudere
solo non riesco a capire dove sbaglio e sto impazzendo… quando tocco il finecorsa come faccio a dirgli di tornare indietro nella posizione iniziale?perchè il finecorsa mi rimane acceso?

const int IN1=2;
const int IN2=3;
const int IN3=4;
const int IN4=5;
const int pulsante=10;

const int finecorsa=12;
const char tab1[] =
{
  0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08, 0x09
};
const char tab2[] =
{
  0x01, 0x09, 0x08, 0x0c, 0x04, 0x06, 0x02, 0x03
};

void setup() 
{
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
 
  pinMode(pulsante, INPUT);
  pinMode(finecorsa, INPUT);
}

void loop() {
  if(digitalRead(pulsante)==HIGH)
  {
    ctlStepMotor(-720,1);
   
  }
  if(digitalRead(finecorsa)==HIGH)
  {
    delay(2000);
    ctlStepMotor(720,1);
   }
  }

void ctlStepMotor(int angle, char speeds )
{
  for (int j = 0; j < abs(angle) ; j++)
  {
    if (angle > 0)
    {
      for (int i = 0; i < 8; i++)
      {
        digitalWrite(IN1, ((tab1[i] & 0x01) == 0x01 ? true : false));
        digitalWrite(IN2, ((tab1[i] & 0x02) == 0x02 ? true : false));
        digitalWrite(IN3, ((tab1[i] & 0x04) == 0x04 ? true : false));
        digitalWrite(IN4, ((tab1[i] & 0x08) == 0x08 ? true : false));
        delay(speeds);
      }
    }
    else
    {
      for (int i = 0; i < 8 ; i++)
      {
        digitalWrite(IN1, ((tab2[i] & 0x01) == 0x01 ? true : false));
        digitalWrite(IN2, ((tab2[i] & 0x02) == 0x02 ? true : false));
        digitalWrite(IN3, ((tab2[i] & 0x04) == 0x04 ? true : false));
        digitalWrite(IN4, ((tab2[i] & 0x08) == 0x08 ? true : false));
        delay(speeds);
      }
    }
    if(digitalRead(finecorsa)==HIGH)
  {
    break;
    digitalWrite(finecorsa,LOW);
  }
  }
}
void StepMotorStop()
{
  digitalWrite(IN1, 0);
  digitalWrite(IN2, 0);
  digitalWrite(IN3, 0);
  digitalWrite(IN4, 0);
}

Ho modificato lo sketch con le variabili ora però il motore appena tocca il finecorsa non si stoppa …
come posso fare?

const int IN1=2;
const int IN2=3;
const int IN3=4;
const int IN4=5;
const int pulsante=10;
const int finecorsa=12;
const int finecorsa1=16;
const char tab1[] =
{
  0x01, 0x03, 0x02, 0x06, 0x04, 0x0c, 0x08, 0x09
};
const char tab2[] =
{
  0x01, 0x09, 0x08, 0x0c, 0x04, 0x06, 0x02, 0x03
};
enum tipo_stato {iniziale=0, aperto=1, chiuso=2};
tipo_stato stato=iniziale; 
void setup() 
{
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(pulsante, INPUT);
  pinMode(finecorsa, INPUT);
  pinMode(finecorsa, INPUT);
  
}
void Motoreacceso(int angle, char speeds )
{
  for (int j = 0; j < abs(angle) ; j++)
  {
    if (angle > 0)
    {
      for (int i = 0; i < 8; i++)
      {
        digitalWrite(IN1, ((tab1[i] & 0x01) == 0x01 ? true : false));
        digitalWrite(IN2, ((tab1[i] & 0x02) == 0x02 ? true : false));
        digitalWrite(IN3, ((tab1[i] & 0x04) == 0x04 ? true : false));
        digitalWrite(IN4, ((tab1[i] & 0x08) == 0x08 ? true : false));
        delay(speeds);
        }
      }
    
    else
    {
      for (int i = 0; i < 8 ; i++)
      {
        digitalWrite(IN1, ((tab2[i] & 0x01) == 0x01 ? true : false));
        digitalWrite(IN2, ((tab2[i] & 0x02) == 0x02 ? true : false));
        digitalWrite(IN3, ((tab2[i] & 0x04) == 0x04 ? true : false));
        digitalWrite(IN4, ((tab2[i] & 0x08) == 0x08 ? true : false));
        delay(speeds);
     }        
    }
    if(digitalRead(finecorsa)==HIGH)
    {
    }
   }
}
void Motorefermo()
{
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
}

void loop() {
  switch(stato)
  {
    case iniziale:
    if(digitalRead(pulsante)==HIGH)
    {
      stato=aperto;
      Motoreacceso(720,1);
    }
    break;
    case aperto:
   if(digitalRead(finecorsa)==HIGH)
   {
    stato=iniziale;
    delay(2000);
    Motoreacceso(-720,1);
        }
    break;
    case chiuso:
    break;
  }
}

Ti indico un piccolo schema da seguire.

Ammettiamo che tu abbia già alcune funzioni

apri()     apre il cancello

chiudi()  chiude il cancello

finecorsa()   che ti restituisce true se sei a fine corsa o false altrimenti

pulsante()    che ti restituisce true se il pulsante è premuto o false altrimenti

queste le sai sicuramente fare

e poi un'altra

temposcaduto() che ti restituisce true se sono passati i 5 secondi da quando lo hai aperto

che devi costruire con millis(), vediamo se questa riesci a farla, altrimenti ti diamo suggerimenti

Una volta costruite queste funzioni, ti verrà tutto immediato Partiamo da queste. Dicci se le sai costruire tutte e cinque. Poi andiamo avanti.

Alla fine ci sono riuscito grazie mille :smiley:

Bene

Allora metti la versione finale, così potrà essere una utile ispirazione per qualcuno che volesse realizzare qualcosa di simile.