Purtroppo il progetto con il sensore ad ultrasuoni è fallito, nella teoria funziona ma in pratica non c'è abbastanza potenza per mandare avanti la macchina (circa 1kg).
Non mi sono arreso e facendo varie ricerche ho scoperto che il modulo "L293D" funge anche da amplificatore come un transistor e avendo 4 ingressi è risultato perfetto per 4 motori.
Ecco i materiali necessari:
Qui è come ho gestito il cablaggio:
Il motore 1 è stato collegato al pin 4, il motore 2 al pin 5, il motore 3 al pin 12 e il motore 4 al pin 8.
Per ogni motore il pin dell'Arduino viene collegato all'ingresso del modulo (secondo e penultimo dentino) mentre l'uscita (terzo e terzultimo dentino) va collegata al motore: al + se volete che il motore giri in senso orario mentre al - se volete che il motore giri in senso antiorario, l'altro filo va sempre collegato al GND dell'Arduino (-).
Il sensore a infrarossi è collegato al 2 pin all'uscita, il GND al GND dell'Arduino e l'alimentazione (VCC) ai 3.3V.
Nel codice all'inizio viene richiamata la libreria per il sensore IR: IRremote.h
.
int RECV_PIN = 2;
viene definita la variabile per il sensore e assegnato il pin 2, vengono anche definiti i pin per ogni motore.
Nella funzione setup()
: Serial.begin(9600)
inizializza la comunicazione a una velocità di 9600 baud per inviare dati alla console per il debug.
IrReceiver.begin(RECV_PIN, ENABLE_LED_FEEDBACK);
inizializza il ricevitore IR con il pin RECV_PIN definito all'inizio e abilita il LED del ricevitore infrarosso.
pinMode(motor1, OUTPUT); ecc...
configura i pin dei motori come pin di output per controllare l'alimentazione.
Nella funzione loop()
(cuore del programma): if (IrReceiver.decode())
controlla se è stato ricevuto un segnale IR valido.
unsigned long irCode = IrReceiver.decodedIRData.decodedRawData;
estrae il valore IR ricevuto e lo memorizza nella variabile irCode.
Il programma quindi verifica il valore di irCode e in base a questo valore esegue determinate azioni:
In questo caso, se è uguale a 0xF30CBF00 rileva che è stato premuto il tasto 0 quindi la macchina andrà avanti in trazione posteriore.
Se irCode è uguale a 0xEF10BF00 rileva che è stato premuto il tasto 1 quindi la macchina andrà in retromarcia in trazione anteriore.
Se irCode è uguale a 0xEE11BF00 rivela che è stato premuto il tasto 2 e la macchina viene configurata per "sterzare a sinistra". Entra in gioco il Motore2 (verso antiorario) e Motore3 (verso orario) che generano un meccanismo simile ad una coppia di forze che fa cambiare direzione alla macchina. Comportamento simile per il tasto 3 con irCode 0xED12BF00 altro che si usano i motori 1 e 4.
Dopo l'esecuzione di una delle condizioni, il programma riprende la ricezione dei segnali IR con IrReceiver.resume()
, in modo che possa ripetersi il ciclo per rispondere in continuazione ai comandi IR successivi.
Come detto in precedenza i codici esadecimali cambiano in base ai materiali che avete, vi consiglio di provare prima con quelli indicati nella spiegazione, se non vanno potete aggiungere queste righe di codice:
Serial.print("Codice IR ricevuto: 0x");
Serial.println(irCode, HEX);
Che vi restituiscono sulla console i risultati IR dopo aver premuto un tasto.
Ecco il codice completo:
#include <IRremote.h>
int RECV_PIN = 2;
int motor1 = 4;
int motor2 = 5;
int motor3 = 12;
int motor4 = 8;
void setup() {
Serial.begin(9600);
IrReceiver.begin(RECV_PIN, ENABLE_LED_FEEDBACK);
pinMode(motor1, OUTPUT);
pinMode(motor2, OUTPUT);
pinMode(motor3, OUTPUT);
pinMode(motor4, OUTPUT);
}
void loop() {
if (IrReceiver.decode()) {
unsigned long irCode = IrReceiver.decodedIRData.decodedRawData;
Serial.print("Codice IR ricevuto: 0x");
Serial.println(irCode, HEX); // IR esadecimale
if (irCode == 0xF30CBF00) { // "0"
// trazione posteriore
digitalWrite(motor1, HIGH);
digitalWrite(motor2, LOW);
digitalWrite(motor3, HIGH);
digitalWrite(motor4, LOW);
} else if (irCode == 0xEF10BF00) { // "1"
// trazione anteriore
digitalWrite(motor1, LOW);
digitalWrite(motor2, HIGH);
digitalWrite(motor3, LOW);
digitalWrite(motor4, HIGH);
} else if (irCode == 0xEE11BF00) { // "2"
// Sterza sx
digitalWrite(motor1, LOW);
digitalWrite(motor2, HIGH);
digitalWrite(motor3, HIGH);
digitalWrite(motor4, LOW);
} else if (irCode == 0xED12BF00) { // "3"
// Sterza dx
digitalWrite(motor1, HIGH);
digitalWrite(motor2, LOW);
digitalWrite(motor3, LOW);
digitalWrite(motor4, HIGH);
}
IrReceiver.resume(); // IR
}
}
Schema elettrico:
LINK TINKERCAD AL PROGETTO QUI