Salve avrei di bisogno di un aiuto per fare fermare il motore stepper (Step motor 28BYj-48) con finecorsa inizio e fine, lo sketch che sto usando è il seguente.
Volendo inserire i fine corsa in A0 e A1 e comune con +5V.
il cancello posizionato in A0 al comando ir apre il cancello finché non raggiunge il finecorsa A1, attente 2 sec e ritorna alla posizione iniziale di A0.
Grazie anticipatamente dell aiuto.
stepper.ino (1.51 KB)
Cominciamo con due domande:
Quanto tempo hai?
Sai far fare UN SINGOLO passo allo stepper?
lo stepper funziona benissimo con ir controllo il senso orario e antiorario , il problema è dovrei fermarlo all'arrivo al ponto da me stabilito . Tipo cancello scorrevole .
Qualcuno mi ha consigliato di mettere il comune dei due finecorsa al +5V e il NO in A0 e A1 , ma non riesco nella programmazione . Aiutatemi se potete vorrei riuscirci prima di Martedì 3 Luglio .
Tu sai fargli fare un passo?
Se si allora é molto facile:
Stabilita la direzione contolli in continuo il finecorsa che dovrà fermare il motore, e se non é premuto fai fare al motore stesso un passo.
Se non lo sai fare guarda bene la libreria, DEVE esserci un modo
Ti mostro lo schema che per il momento funziona con il telecomando -
dovrei inserire solo i finecorsa e programmare il tutto
Quindi i finecorsa sono uno o due? non ho ben capito. Nel codice ne vedo definito solo uno. Ti dò un paio di dritte:
- se vuoi collegare direttamente i finecorsa agli ingressi di Arduino, volendo evitare di collegare resistenze esterne, si possono utilizzare le resistenze di pull-up integrate in Arduino. Esse sono abilitabili via software nella funzione di setup:
pinMode(A0, INPUT_PULLUP); //finecorsa di posizione UP associato all'ingresso A0
pinMode(A1, INPUT_PULLUP); //finecorsa di posizione DOWN associato all'ingresso A1
- All'inzio del loop leggi il loro stato:
//lettura stato finecorsa
int finecorsaUP = digitalRead(A0);
int finecorsaDOWN = digitalRead(A1);
- Nei case invece determini cosa deve succedere quando un finecorsa è azionato/disazionato a seconda di come imposti la condizione di test. Esempio:
case 0xFF629D: // UP button pressed
if(finecorsaUP) { //se finecorsa UP è disazionato, porto cancello verso UP
... tue istruzioni ...
}
break;
Tieni presente che il collegamento pull-up comporta quanto segue:
finecorsa azionato ==> arduino legge "0"
finecorsa disazionato ==> arduino legge "1"
Nota bene: questo è valido nel caso in cui il contatto del finecorsa è normalmente aperto (NO), se è normalmente chiuso (NC) vale l'opposto. Che io sappia dovrebbero essere quasi tutti normalmente aperti.
Puoi leggere l'intera istruzione in questi termini: "SE ho a 1 finecorsaUP (finecorsa disazionato) ALLORA esegui le istruzioni ALTRIMENTI non fare nulla perché finecorsa UP è a 0 (finecorsa azionato)".
A te il lavoro di ricomporre i pezzi di codice in maniera sensata e di implementarli nel tuo sketch.
edit: se fai le pinMode, cancella queste righe:
#define finecorsa1 A0
RPM = analogRead(A0);
Serial.println(RPM,DEC);
if (RPM == 1)
{break ;}
else
I fine corsa sono due uno all'inizio e uno alla fine -
Francesco2-1963:
I fine corsa sono due uno all'inizio e uno alla fine -
Attenzione che ho modificato la mia precedente risposta, mi ero sbagliato a descrivere lo stato di azionamento/disazionamento del finecorsa.
edit:
Se avessi voluto testare lo stato di azionamento del finecorsa avrei scritto:
if(!finecorsaUP)
L'operatore ! è detto di negazione logica. Quindi con quell'istruzione che letteralmente si legge "SE NON ho finecorsaUP a 1", di fatto il programma controlla se il finecorsa è a 0 (finecorsa azionato).
Ho una domanda: a cosa ti servono i finecorsa? I motori stepper fanno esattamente i passo che tu dici, e poi si fermano da soli, quindi decidi: O li comandi in passi O li comandi con i finecorsa un passo per volta. Se provi a fare tutti e due non ne vedo utilità
Immagino che la movimentazione del cancello dovrà essere automatica in ambo le direzioni comandate, giusto? Oggi mi sento particolarmente buono e ti dò un altro aiuto :D.
Prima di cominciare, i codici dei comandi non si possono vedere scritti in quel modo, sono un pugno in un occhio :D. Uno che li legge dall'esterno non può capire a colpo d'occhio a cosa servono e cosa fanno.
Definisci due costanti globali con nomi leggibili da un essere umano, scrivile a parte nella prima riga del programma fuori da setup e loop. Esempio:
const long ComandoUP = 0xFF629D;
const long ComandoDOWN = 0xFFA857;
Se la velocità di rotazione nelle due direzioni è la stessa, questa riga la puoi spostare nella funzione di setup:
small_stepper.setSpeed(300); //Max seems to be 700
Invece nello switch puoi fare una cosa del genere:
void loop() {
//leggo e salvo su variabile di appoggio codice del tasto premtuto
long CodiceRicevuto = results.value;
switch (CodiceRicevuto) {
case ComandoUP: //premuto tasto di comando direzione UP?
while(digitalRead(A0)) small_stepper.step(Steps2Take);
//finché finecorsaUP non è premuto comando stepper in direzione UP
break;
case ComandoDOWN: //premuto tasto di comando direzione DOWN?
while(digitalRead(A1)) small_stepper.step(-Steps2Take);
//finché finecorsaDOWN non è premuto comando stepper in direzione DOWN
break;
}
if (CodiceRicevuto == ComandoUP || CodiceRicevuto == ComandoDOWN) delay(2000);
/*attesa di due secondi prima di accettare altri comandi dal telecomando IR dopo la movimentazione del motore in una delle due direzioni*/
}
L'istruzione while, dice al motore di muoversi dell'entità di passi impostata in Steps2Take finché il finecorsa della direzione comandata è disazionato.
Mi raccomando prova a velocità bassa, cioè scrivi per esempio small_stepper.setSpeed(50) invece di small_stepper.setSpeed(300), non vorrei che a velocità troppo alta il cancello si porti via i finecorsa :D.
edit1: ho modificato il tipo di dato delle variabili da int a long
edit2: ahi ahi, c'era un errore grosso come una casa nei while, non rileggevano mai lo stato aggiornato dei finecorsa. A sto punto non ha più senso farne una lettura appoggiata su variabili all'inizio del loop. E' chiaro che se i finecorsa si guastano o non leggono, il motore non si ferma più. A voler fare le cose fatte bene bisognerebbe introdurre dei timeout: se entro x secondi non si raggiunge la posizione, fermata del motore dove si trova.
Kryton18 grazie , il tuo aiuto e stato fondamentale .
Se vieni nelle parti di Catania una bella granita con brioss è già pagata .
Grazie
Francesco2-1963:
Kryton18 grazie , il tuo aiuto e stato fondamentale .
Ottimo e abbondante :D. Quindi hai già provato e funziona tutto?
Sei riuscito a implementare anche la funzionalità di ritorno automatico del cancello alla posizione di riposo, finecorsa A0 azionato, dopo due secondi che era stata raggiunta la posizione di lavoro, finecorsa A1 azionato?
Ti chiedo se per favore puoi allegare lo sketch che hai realizzato nella tua risposta successiva, così se qualcuno dovrà realizzare un'applicazione simile alla tua avrà una traccia già delineata.
Se vieni nelle parti di Catania una bella granita con brioss è già pagata.
E' da anni che dovrei fare un giro in Sicilia, ho in parte origini siciliane e non ci sono mai stato, mi dai una valida motivazione per rimediare al più presto :D.