Salve, sto facendo delle prove con L298N, vorrei comandare l' accensione di un motore tramite un telecomando infrarosso, riesco a farlo partire, il sensore legge il valore del telecomando riconosce il valore e il motore parte, quando il valore cambia dovrebbe fermarsi.
Per capirci meglio
/*
Codice Tasto
2728575039 1
2728534239 2
2728566879 3
2728550559 4
2728583199 5
2728530159 6
2728562799 7
2728546479 8
2728579119 9
2728570959 0
2728558719 OFF
2728542399 MUTE
2728554639 ENTER
2728538319 LAST
2728587279 RED
2728560759 GREEN
2728568919 YELLOW
2728585239 BLUE
2728544439 VOLUME -
2728536279 VOLUME +
2728528119 CANALE+
2728552599 CANALE-
2728577079 OK
*/
int ir_sensor = 2;
int input1 = 5;
int input2 = 7;
int enableA = 6;
#include <IRremote.h>
IRrecv irrecv(ir_sensor);
decode_results results;
void setup()
{
pinMode(ir_sensor, INPUT);
pinMode(input1, OUTPUT);
pinMode(input2, OUTPUT);
pinMode(enableA, OUTPUT);
Serial.begin(9600);
irrecv.enableIRIn(); // Start the ir receiver
}
void loop() {
int ir_sensor = 0;
if (irrecv.decode(&results)) {
Serial.println(results.value, DEC);
if(results.value == 2728528119) // Se il valore è uguale a 2728528119 fai partire il motore
analogWrite(enableA,255);//
digitalWrite(input1, HIGH);
digitalWrite(input2, LOW);
delay(2000); //
if (irrecv.decode(&results)) {
Serial.println(results.value, DEC);
}
{
if(results.value == 2728570959) // Se il valore è uguale a 2728570959 ferma il motore
analogWrite(enableA,255);
digitalWrite(input1, LOW);
digitalWrite(input2, LOW);
delay(2000);
if (irrecv.decode(&results)) {
Serial.println(results.value, DEC);
}
}
}
}
Il problema è che il sensore legge il valore, parte il motore, ma invece di aspettare il cambio della variabile dopo 2 secondi si spegne per altri 2 secondi ed il ciclo riparte.
Dove è l'errore?
Devi usare una variabile di stato che memorizzi lo stato (appunto) del motore, ossia se lo hai già azionato oppure no.
Gli if di controllo cambiano perché devi analizzare anche la variabile di stato.
Se ti arriva il comando di accensione, esegui il codice di accensione del motore solo se la variabile di stato indica che il motore è spento. Se la variabile di stato è falsa, quindi indica che il motore è spento, ed arriva il comando di accensione, accendi il motore e metti la variabile su vero. Se rispedisci di nuovo il comando di accensione, questa volta il tuo codice non farà nulla, perché il motore è già acceso.
Similarmente, per lo spengimento fai uguale. Spengi il motore solo se la variabile indica che il motore è acceso. Quando spengi il motore, metti anche la variabile su false, così da poter riaccendere il motore.
Controlla le parentesi {}
soprattutto dopo gli if result.value... devi racchiudere fra {} la parte di codice da eseguire se si verifica la condizione altrimenti te le esegue ad ogni loop indipendentemente dal result.value.
No, fare una prova senza farci vedere come hai sistemato il codice non serve a nulla, non abbiamo la palla di vetro
@Paulus ha ragione hai messo le graffe come capita. Ma sono importanti.
Se usi il tasto Ctrl+T hai la formattazione automatica.
Impara anche a mettere le graffe aperte e chiuse a inizio riga (lascia stare il mettere la { alla fine dell'if)
void loop()
{ int ir_sensor = 0;
if (irrecv.decode(&results))
{ Serial.println(results.value, DEC);
if(results.value == 2728528119) // Se il valore è uguale a 2728528119 fai partire il motore
analogWrite(enableA,255);//
digitalWrite(input1, HIGH);
digitalWrite(input2, LOW);
delay(2000); //
if (irrecv.decode(&results))
{ Serial.println(results.value, DEC);
}
{ // sta graffa NON serve
if(results.value == 2728570959) // Se il valore è uguale a 2728570959 ferma il motore
analogWrite(enableA,255);
digitalWrite(input1, LOW);
digitalWrite(input2, LOW);
delay(2000);
if (irrecv.decode(&results))
{ Serial.println(results.value, DEC);
}
} // e perciò NEPPURE questa graffa serve
}
}
Questo è il tuo codice. Nota che per le varie if() senza graffe solo l'istruzione successiva è eseguita su quella condizione.
Per ogni graffa aperta necessaria una chiusa (se le incolonni è più facile capire cosa contengono)
Nello specifico, solo la prima analogWrite viene eseguita alla condizione verificata Deve funzionare così ?
if(results.value == 2728528119) // Se il valore è uguale a 2728528119 fai partire il motore
analogWrite(enableA,255);//
digitalWrite(input1, HIGH);
digitalWrite(input2, LOW);
delay(2000);
Diverso se metti le graffe:
if(results.value == 2728528119) // Se il valore è uguale a 2728528119 fai partire il motore
{ analogWrite(enableA,255);//
digitalWrite(input1, HIGH);
digitalWrite(input2, LOW);
delay(2000);
}
Altro suggerimento, per rendere più leggibile il codice puoi creare dei nomi per quei valori dei stati. Mnemonici più semplici da leggere:
All'inizio devi mettere:
Grazie per i consigli.
Come puoi vedere ho messo le graffe come mi avete indicato ma il risultato è lo stesso, il motore parte quando premo il tasto CH+ ma non si spegne quando premo il tasto 0.
if(results.value == 2728528119) // Se il valore è uguale a 2728528119 fai partire il motore
{
analogWrite(enableA,255);//
digitalWrite(input1, HIGH);
digitalWrite(input2, LOW);
}
if(results.value == 2728570959 ) // Se il valore è uguale a 2728570959 ferma il motore
{
analogWrite(enableA,255);
digitalWrite(input1, LOW);
digitalWrite(input2, LOW);
} //
Per le altre modifiche prima vorrei capire come far funzionare il motore.
Per i nomi dei valori
ci avevo gia pensato ma tu mi hai anticipato, grazie per i consigli come ho detto nel primo post non sono molto pratico di programmazione , purtroppo non ho molto tempo disponibile da dedicarle.
if(results.value == 2728528119) // Se il valore è uguale a 2728528119 fai partire il motore
{
analogWrite(enableA,255);//
digitalWrite(input1, HIGH);
digitalWrite(input2, LOW);
}
if(results.value == 2728570959 ) // Se il valore è uguale a 2728570959 ferma il motore
{
analogWrite(enableA,255);
digitalWrite(input1, LOW);
digitalWrite(input2, LOW);
} //
Impara anche a debuggare da solo. Sei sicuro che quel pezzo di codice nel secondo if spegne il motore?
Vedo che su input2 metti sempre a LOW.
Io fossi in te farei un altro sketch con il pezzo che accende il motore, poi delay(2000) e poi il pezzo che spegne, poi altro delay()
Uno sketch che accende/spegne ogni 2 secondi. Per verificare se accendi/spegni funziona.
Il problema è che il sensore legge il valore, parte il motore, ma invece di aspettare il cambio della variabile dopo 2 secondi si spegne per altri 2 secondi ed il ciclo riparte.
Come puoi vedere ho già fatto la prova,
per quanto riguarda
paulus1969:
input2 che è sempre a LOW a cosa serve?
Non solo.
A che serve analogWrite(enableA,255); ??
La imposti nei due if a 255, da nessuna altra parte la cambi. Appena accendi il motore perciò lo metti a 255 e poi non viene mai cambiato. Secondo me nell'off del motore devi mettelo a 0 (sarebbe la velocità 0-255 ? )
Forse ho capito. Avevi messo due decode() inutili ma funzionavano perchè è obbligatorio mettere alla fine del loop() per la IrRemote un comando che ora non ricordo. Controllo i miei esempi e ti dico.
EDIT: ti manca alla fine del loop()
irrecv.resume(); //Attesa ricezione prossimo valore
Risolto . Ho inserito "irrecv.resume();" e miracolosamente funziona.
input2 che è sempre a LOW a cosa serve?
Vi spiego.
![](immagi10.png | Servimg.com - Free image hosting service]
L298N ha 6 pin input: EnA,In1,In2,In3,In4,EnB, EnA e EnB sono collegati ai pin PWM, nello specifico il 255 da sia il segnale di accensione che la velocità del motore, i pin In1-2 e 3-4 sono i collegamenti ai motori che possono essere o due normali cc o uno passo passo, la combinazione LOW ed HIGH da il senzo di rotazione :
LOW-HIGH rotazione
HIGH-LOW rotazione
LOW-LOW motore fermo
HIGH-HIGH motore fermo
Comunque Grazie infinite per l'aiuto e da tre notti che ci sbatto la testa e senza il vostro aiuto non ci sarei riuscito.