Salve a tutti, è da un paio di giorni che sto provando a cercare una soluzione al problema che vi sto per proporre. Premetto che non sono ferrato in elettronica e programmazione, anzi direi che sono soltanto alle primissime armi.
In ogni caso volevo sapere se è possibile controllare la rotazione e lo stop di un motore, collegato a un ponte h l298n, attraverso l'utilizzo di un solo switch.
Nello specifico il motore dovrebbe cominciare la rotazione non appena si avvia Arduino; quando poi viene schiacciato il pulsante, il motore dovrebbe fermarsi e restare fermo fino al rilascio di quest'ultimo, per poi cominciare a girare nella direzione opposta a quella di partenza.
Spero di essere stato chiaro
L'uso di un ponte H ha senso quando devi invertire il senso di rotazione e controllare la velocità tramite PWM.
Se, invece, ti interessa solo un senso di rotazione e magari la velocità, puoi usare un semplice transistor oppure un MOSFET.
Quanta fretta, mica ci paghi, non puoi pretendere che si risponda seduta stante ad ogni domanda!
Comunque certo che si può fare... Avvii il motore nel setup(), poi dai un'occhiata all'esempio Digital -> Debounce, che ti insegnerà a leggere la pressione di un tasto.
Fai una cosa alla volta, quindi se hai problemi torna qua e fai una domanda precisa sul problema che incontri,
Allora ho dato un'occhiata all'esempio Debounce è l'unico sketch "simil-funzionante" che sono riuscito a compilare è questo:
const int pulsanteDirezione = 13;
const int in1Pin = 7;
const int in2Pin = 8;
const int debounce = 50;
int stato = HIGH;
int reading;
int precedente = LOW;
long time = 0;
void setup() {
pinMode(pulsanteDirezione, INPUT);
pinMode(in1Pin, OUTPUT);
pinMode(in2Pin, OUTPUT);
digitalWrite (in1Pin, HIGH);
digitalWrite (in2Pin, LOW);
}
void loop() {
reading = digitalRead (pulsanteDirezione);
if (reading == LOW && precedente == HIGH && millis() - time > debounce){
if (stato == HIGH)
stato = LOW;
else stato = HIGH;
time = millis();
}
if (stato == HIGH){
digitalWrite(in1Pin, HIGH);
digitalWrite(in2Pin, LOW);
}
else {
digitalWrite(in1Pin, LOW);
digitalWrite(in2Pin, LOW);
}
precedente = reading;
}
L'unico problema è che ancora non fa quello che vorrei, nel senso che il motore dovrebbe fermarsi quando mantengo schiacciato lo switch, per poi ripartire nel senso contrario al precedente non appena lo rilascio...qualcuno può darmi una mano
qualcuno mi può dare una mano per favore?
Allora, intanto abbiamo bisogno di tenere traccia della direzione in cui stiamo andando. Usiamo una variabile globale di tipo int:
int direzione = 0; // 0 = Avanti, 1 = Indietro
Puoi metterla al posto di ledState, che non ci servirà più.
Nel setup() fai poi partire il tuo motore.
A questo punto prendi pari pari l'esempio Debounce e dove dice:
if (buttonState == HIGH) {
ledState = !ledState;
}
Fallo diventare qualcosa tipo:
if (buttonState == HIGH) {
// Pulsante premuto, spegnere motore
} else {
// Pulsante rilasciato, invertiamo direzione e riaccendiamo
if (direzione == 0) {
// Il motore stava andando avanti
} else {
// Il motore stava andando indietro
}
// Teniamo traccia del fatto che abbiamo invertito la direzione
direzione = !direzione;
}
Ovviamente lascio a te l'aggiunta dei comandi per azionare il motore.
Non ho testato niente ma potrebbe anche funzionare :D.
grazie mille lo provo subito :))
Allora il codice che ho compilato è questo:
const int pin1 = 7;
const int pin2 = 8;
const int buttonPin = 12;
int direzione = 0;
int buttonState;
int lastButtonState = LOW;
long lastDebounceTime = 0;
long debounceDelay = 50;
void setup() {
pinMode(buttonPin, INPUT);
pinMode(pin1, OUTPUT);
pinMode(pin2, OUTPUT);
digitalWrite (pin1, HIGH);
digitalWrite (pin2, LOW);
}
void loop() {
int reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == HIGH) {
digitalWrite (pin1, LOW);
digitalWrite (pin2, LOW);
}
else {
digitalWrite (pin1, LOW);
digitalWrite (pin2, HIGH);
}
if (direzione == 1){
digitalWrite (pin1, LOW);
digitalWrite (pin2, HIGH);
}
else {
digitalWrite (pin1, LOW);
digitalWrite (pin2, LOW);
}
direzione =! direzione;
}
}
lastButtonState = reading;
}
Il motore si avvia in senso orario, come scritto nel setup. Poi quando tengo premuto lo switch il motore si ferma, mentre quando rilascio, il motore comincia a girare in senso antiorario. E fin qui tutto ok.
Il problema è che da questo punto in poi ogni volta che schiaccio lo switch e lo rilascio, il motore ricomincia sempre a girare in senso antiorario, quando dovrebbe girare una volta in senso orario e una volta in senso antiorario.
Spero di essere stato chiaro..
Non hai "copiato" bene il mio sketch, hai gestito male un else. Riguardalo bene e riprova. Fai attenzione all'indentazione.
L'ho ricompilato così:
const int pin1 = 7;
const int pin2 = 8;
const int buttonPin = 12;
int direzione = 0;
int buttonState;
int lastButtonState = LOW;
long lastDebounceTime = 0;
long debounceDelay = 50;
void setup() {
pinMode(buttonPin, INPUT);
pinMode(pin1, OUTPUT);
pinMode(pin2, OUTPUT);
digitalWrite (pin1, HIGH);
digitalWrite (pin2, LOW);
}
void loop() {
int reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == HIGH) {
digitalWrite (pin1, LOW);
digitalWrite (pin2, LOW);
} else {
digitalWrite (pin1, LOW);
digitalWrite (pin2, HIGH);
}
if (direzione == 0){
digitalWrite (pin1, HIGH);
digitalWrite (pin2, LOW);
} else {
digitalWrite (pin1, LOW);
digitalWrite (pin2, HIGH);
}
direzione = !direzione;
}
}
lastButtonState = reading;
}
Ma così il motore si avvia in senso orario; la prima volta che schiaccio lo switch il motore cambia direzione, senza però fermarsi. Dopo di che, ogni volta che schiaccio lo switch, il motore torna a ruotare in senso antiorario, per poi ritornare al senso antiorario quando rilascio.
E' come se una volta schiacciato lo switch arduino non riuscisse più a ritornare alla situazione di partenza, ovvero con il motore che gira in senso orario, come era impostato nel setup..
Innanzitutto un consiglio (che ultimamente sto dando troppo spesso): evita di fare le cose a caso, cerca invece di capire il flusso di un programma e di seguirlo. Questo perché innanzitutto è una cosa che personalmente non sopporto, e poi perché cercare di capire ti porterà a qualche risultato in maniera sicuramente più veloce che andare a casaccio.
Come ti ho detto prima, hai sbagliato a copiare il mio suggerimento, in particolare:
if (buttonState == HIGH) {
digitalWrite (pin1, LOW);
digitalWrite (pin2, LOW);
} else {
digitalWrite (pin1, LOW); <-- Queste righe nel mio suggerimento non ci sono!
digitalWrite (pin2, HIGH);
}
if (direzione == 0){ <-- Questo if nel mio suggerimento sta dentro all'else precedente!
digitalWrite (pin1, HIGH);
digitalWrite (pin2, LOW);
} else {
digitalWrite (pin1, LOW);
digitalWrite (pin2, HIGH);
}
direzione = !direzione;
}
SukkoPera:
Innanzitutto un consiglio (che ultimamente sto dando troppo spesso): evita di fare le cose a caso, cerca invece di capire il flusso di un programma e di seguirlo.
@SukkoPera: ... e quindi concordi con il mio discorso , cento volte ripetuto, che, nella maggior parte dei casi, fornire il codice (... stile "pappa fatta" come molti fanno) è controproducente dato che gli utenti si limitano al solito copia/incolla senza mettersi a "studiare" e "capire" come e perché una cosa funziona :
Guglielmo
Come ho anche scritto altrove, concordo eccome! Infatti qua ho fornito uno "scheletro" del codice da implementare completandolo, in modo da dare uno spunto (visto che le prime raccomandazioni non erano state molto ben seguite) ma invitando a metterci del proprio.