Questo articolo è il proseguimento del precedente e consentirà di pilotare un robot a due ruote tramite la tastiera del computer; i comandi verranno inseriti nel monitor seriale dello sketch di arduino. Verranno utilizzati alcuni elementi presenti in SparkFun Inventor’s Kit for Arduino UNO:
- 1 INTERRUTTORE (SWITCH): apre/chiude un circuito; se l’interruttore è chiuso il circuito si attiverà;
- 2 MOTORI DC, 2 RUOTE e 1 CHIP MOTOR DRIVER (TB6612FNG) : tale chip
- 1 BREADBOARD
- 1 ARDUINO UNO R3
- 1 TAVOLETTA NERA
- 1 CAVO USB
- 1 clip
- 1 pezzo di nastro biadesivo “Dual Lock 3M”
Dopo aver fatto tutti i collegamenti previsti nel precedente articolo, tagliare 3 – 3,5 cm di “Dual Lock 3M” ed incollarlo una parte sulla ruota ed una parte sulla struttura portante. Fare lo stesso per l’altra ruota:
Si osservi che, per comodità di montaggio, un motore è stato montato al contrario. Ciò vuol dire che quando il robot a due ruote dovrà andare dritto, un motore dovrà essere pilotato in un verso e l’altro in verso opposto.
Il robot, avendo solo due ruote, penderà nella parte posteriore dove verrà collegata una clip:
Per controllare il robot a due ruote, bisognerà inserire un comando tramite il monitor seriale. Scrivendo
- a 20: il robot andrà avanti di 20 cm
- i 30: il robot andrà indietro di 30 cm
- d 45: il robot ruoterà di 45°
- s 90: il robot ruoterà a sinistra di 90°
Il codice da utilizzare sarà il eseguente:
/*SparkFun Inventor’s Kit
Circuit 5B – Remote Control Robot
Questo sketch consente di controllare il robot a due ruote inviando
dei comandi di movimento e di direzione attraverso il monitor seriale*/
// La ruota sinistra è controllata dal canale A, la ruota destra dal canale B
// Controllare i collegamenti delle ruote
const int AIN1 = 13; // pin1 di controllo del motore A (ruota sinistra)
const int AIN2 = 12; // pin2 di controllo del motore A
const int PWMA = 11; // controlla la velocità del motore A
const int BIN1 = 8; // pin1 di controllo del motore B (ruota destra)
const int BIN2 = 9; // pin1 di controllo del motore B
const int PWMB = 10; // controlla la velocità del motore B
int switchPin = 7; // interruttore per accendere e spegnere il robot
// numero di millisecondi che il robot impiega a fare circa 1 cm; dipende dall’attrito delle ruote con il pavimento.
const int driveTime = 26;
// Questo valore va settato sperimentalmente. Si scrive “a 100” nel Monitor seriale, si misura la distanza percorsa dal robot e si fa la proporzione:
// 26 : misura = x : 100 => x = 2600/misura. Tale valore si setta in driveTime
const int turnTime = 3; // numero di millisecondi necessario per ruotare di 1 grado;
// se nella porta seriale si indica d 45, il robot ruota di 45° a destra;
// tale valore va settato sperimentalmente, dipende dall’attrito con il pavimento.
String botDirection; // verso di spostamento del robot;
String distance; // distanza da percorrere
/**************************************/
void setup()
{
pinMode(switchPin, INPUT_PULLUP); //set this as a pullup to sense whether the switch is flipped // setta i pin come output
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(PWMA, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);
pinMode(PWMB, OUTPUT);
Serial.begin(9600); //inizializza la comunicazione con la porta seriale
//prompt the user to enter a command
Serial.println(“Scrivi il tipo di movimento, spazio, distanza da percorrere (cm) e premi invio.”);
Serial.println(“a = avanti, i = indietro”);
Serial.println(“Esempio: a 50”);
Serial.println(“va avanti di 50 cm”);
Serial.println(“Oppure scrivi il tipo di rotazione e l’angolo di rotazione.”);
Serial.println(“d = ruota a destra, s = ruota a sinistra”);
Serial.println(“Esempio: d 90”);
Serial.println(“ruota a destra di 90°”);
Serial.println(“—————————————“);
}
/*******************************************/
void loop()
{
// legge l’interruttore sullo switchPin e se è basso (interruttore chiuso)
if(digitalRead(7) == LOW)
{ // cioè l’interruttore è ON
if (Serial.available() > 0) // se l’utente ha inserito un comando
{
// legge il primo comando (prima dello spazio) cioè il verso del robot : a avanti, i indietro
botDirection = Serial.readStringUntil(‘ ‘);
// legge il secondo comando sulla distanza/rotazione: d destra, s sinistra
distance = Serial.readString();
// stampa il comando ricevuto
Serial.print(botDirection);
Serial.print(” “);
Serial.println(distance.toInt());
if(botDirection == “a”) // se l’utente inserisce a (avanti)
{
rightMotor(200); // setta la velocità del motore destro
leftMotor(-200); // setta la velocità del motore sinistro
// la distanza viene trasformata in un tempo e i motori proseguono per il tempo indicato
delay(driveTime * distance.toInt());
}
else if(botDirection == “i”) // se l’utente inserisce i (indietro)
{
rightMotor(-200); // setta la velocità del motore destro
leftMotor(+200); // setta la velocità del motore sinistro
// la distanza viene trasformata in un tempo e i motori proseguono per il tempo indicato
delay(driveTime * distance.toInt());
}
else if(botDirection == “d”) // se si deve ruotare a destra
{
rightMotor(-255); // setta la velocità del motore destro
leftMotor(-255); // setta la velocità del motore sinistro
delay(turnTime * distance.toInt());
}
else if(botDirection == “s”) // se si deve ruotare a sinistra
{
rightMotor(255); // setta la velocità del motore destro
leftMotor(+255); // setta la velocità del motore sinistro
delay(turnTime * distance.toInt());
}
rightMotor(0); // ferma il motore destro
leftMotor(0); // ferma il motore sinistro
}
}
else // l’interruttore è OFF
{
rightMotor(0); // ferma il motore destro
leftMotor(0); // ferma il motore sinistro
}
}
/***********************************/
void rightMotor(int motorSpeed) // funzione che guida il motore destro
{
if (motorSpeed > 0) // se il motore destro deve andare avanti
{
digitalWrite(BIN1, HIGH); //set pin 1 to high
digitalWrite(BIN2, LOW); //set pin 2 to low
}
else if (motorSpeed < 0) // se il motore destro deve andare indietro
{
digitalWrite(BIN1, LOW); //set pin 1 to low
digitalWrite(BIN2, HIGH); //set pin 2 to high
}
else // se il motore va fermato
{
digitalWrite(BIN1, LOW); //set pin 1 to low
digitalWrite(BIN2, LOW); //set pin 2 to low
}
analogWrite(PWMA, abs(motorSpeed)); // avvia il motore (se motorSpeed è diverso da 0)
}
/*********************************/
void leftMotor(int motorSpeed) // funzione che guida il motore sinistro
{
if (motorSpeed > 0) // se il motore sinistro deve andare avanti
{
digitalWrite(AIN1, HIGH); //set pin 1 to high
digitalWrite(AIN2, LOW); //set pin 2 to low
}
else if (motorSpeed < 0) // se il motore sinistro deve andare indietro
{
digitalWrite(AIN1, LOW); //set pin 1 to low
digitalWrite(AIN2, HIGH); //set pin 2 to high
}
else // se il motore va fermato
{
digitalWrite(AIN1, LOW); //set pin 1 to low
digitalWrite(AIN2, LOW); //set pin 2 to low
}
analogWrite(PWMB, abs(motorSpeed)); // avvia il motore
}