Guide · 18 min di lettura

Macchinina robot Arduino: costruzione e controllo Bluetooth

Macchinina robot Arduino passo passo: materiali e costi, collegamenti L298N e HC-05, batterie 18650, codice, controllo da smartphone, deriva e reset risolti.

Costruire una macchinina con Arduino è uno dei modi più divertenti per imparare elettronica e programmazione in un unico progetto. Con due motoriduttori, un driver per motori L298N, due batterie 18650, un modulo Bluetooth HC-05 e un Arduino Uno puoi realizzare in un fine settimana una macchinina robot da guidare con lo smartphone. Lungo la strada vedrai di persona perché i motori non si collegano direttamente ad Arduino, perché la scelta della batteria è così importante e come poche righe di codice muovono un vero veicolo.

In questa guida costruiamo insieme una macchinina robot 2WD (a due motori) dall'inizio alla fine: elenco dei materiali e voci di costo, montaggio del telaio, tabelle dei collegamenti, codice per avanti, indietro e sterzate e controllo Bluetooth dallo smartphone. I due problemi su cui i principianti si bloccano più spesso, la macchinina che non va dritta e Arduino che si resetta quando partono i motori, hanno ciascuno una sezione dedicata con soluzioni concrete. Nelle ultime sezioni troverai come guidare la stessa macchinina con un ESP32 o un Raspberry Pi Pico e come trasformarla in un robot che evita gli ostacoli o segue una linea.

Arduino Uno
Arduino Uno
L298N
L298N
HC-05
HC-05
18650 Li-ion
18650 Li-ion

Come funziona una macchinina robot con Arduino?

Una macchinina robot si può dividere in quattro parti. Arduino è il cervello: legge il comando che arriva dallo smartphone e decide quale motore gira, in che verso e a che velocità. Il driver L298N è il muscolo: trasforma i deboli segnali a 5 V di Arduino nella corrente elevata che serve ai motori. I motoriduttori fanno girare le ruote e il pacco batterie alimenta tutto. Queste macchinine non hanno sterzo: girano facendo ruotare le due ruote a velocità o in versi diversi. Si chiama trazione differenziale: se la ruota sinistra gira in avanti e la destra all'indietro, la macchinina ruota su se stessa verso destra. Una piccola ruota pivottante davanti o dietro tiene in equilibrio il telaio.

Motoriduttore TT giallo con ruota da 65 mm
Il motore standard delle macchinine robot: un motore TT con riduttore in plastica gialla e una ruota da 65 mm. Il riduttore divide per 48 la velocità del motore e ne aumenta la coppia.
CaratteristicaMotore TT giallo (1:48)
Tensione di lavoro3–6 V
Rapporto di riduzione1:48 (ingranaggi in plastica)
Velocità a vuotoCirca 90–120 giri/min a 3 V, 200–250 giri/min a 6 V
Corrente a vuotoCirca 150–160 mA
Corrente di stalloCirca 1,1–1,5 A
Diametro ruota (nei kit)65 mm
Velocità della macchinina a 6 VCirca 0,7 m/s (π × 0,065 m × 200 / 60)

La riga più importante della tabella è la corrente di stallo: quando una ruota spinge contro un ostacolo o la macchinina parte, ogni motore assorbe per un istante più di 1 ampere. Un pin di Arduino invece fornisce al massimo 20–40 mA, per questo i motori si collegano sempre tramite un driver. Nel farlo, l'L298N perde circa 1,5–2,5 V; con un pacco da 7,4 V ai motori restano 5–6 V, proprio l'intervallo ideale per i motori TT. Spieghiamo in dettaglio il funzionamento del driver e del ponte H in Controllo di un motore DC con l'L298N.

Elenco dei materiali

ComponenteQuantitàNota
Kit telaio in acrilico 2WD per macchinina robot1Di solito include 2 motori TT, 2 ruote, ruota pivottante, interruttore, supporti motore e viti
Arduino Uno R3 (va bene un clone) + cavo USB1Va bene anche un Nano; i numeri dei pin sono gli stessi
Modulo driver per motori L298N12 A per canale; comanda due motori in modo indipendente
Modulo Bluetooth HC-05 o HC-061Per comunicare con uno smartphone Android
Batteria al litio 186502Celle di marca in grado di erogare almeno 5 A
Portabatterie per 2 celle 18650 (in serie)1Collega le due celle in serie e fornisce 7,4 V
Caricabatterie per 186501Un caricatore che carichi ogni cella separatamente
Cavetti jumper (maschio-femmina e femmina-femmina)20+Tra Arduino, L298N e HC-05
Resistenze da 1 kΩ e 2 kΩ1 + 1Partitore di tensione per l'ingresso RXD dell'HC-05
Condensatore ceramico da 100 nF2–4Sui terminali dei motori; attenua i disturbi
Condensatore elettrolitico da 470–1000 µF (16 V o più)1Consigliato; sull'ingresso di alimentazione dell'L298N
Fascette, biadesivo, distanziali M3Qualche pezzoPer fissare schede e cavi

La maggior parte dei kit telaio include anche un portabatterie per 4 stilo AA; come vedrai fra poco, insieme all'L298N risulta troppo debole, ed è per questo che abbiamo aggiunto le 18650 all'elenco. L'HC-06 è il fratello più semplice dell'HC-05, funziona solo come slave ed è più che sufficiente per guidare una macchinina dallo smartphone. I dischi di plastica forati del kit sono dischi encoder per un sensore di velocità che più avanti ti permetterà di andare perfettamente dritto; non buttarli, mettili da parte per ora.

Costi: dove va il budget?

I prezzi cambiano di continuo a seconda del venditore e del cambio, quindi non diamo cifre; ti mostriamo invece quali voci pesano sul budget e dove puoi risparmiare. La regola generale è: i moduli elettronici (L298N, HC-05, resistenze) costano poco, mentre la maggior parte del budget va nella scheda, nel kit telaio e soprattutto nelle batterie e nel caricatore. La batteria è l'ultima cosa su cui risparmiare: buone celle 18650 si ricaricano centinaia di volte e si riutilizzano in tutti i tuoi prossimi progetti di robot.

VoceLivello di prezzoConsiglio per risparmiare
Kit telaio (motori e ruote inclusi)MedioUn kit costa di solito meno che comprare motori, ruote e ruota pivottante separatamente
Arduino UnoMedio (clone) – alto (originale)Per imparare basta un clone; puoi anche riutilizzare l'Uno o il Nano che hai già
Driver L298NBassoUn modulo comanda due motori; ne basta uno anche per il 4WD
HC-05 / HC-06Basso – medioSe guidi solo dallo smartphone, un HC-06 è sufficiente
2 batterie 18650 + caricatoreLa voce più caraLe celle molto economiche con scritto "9900 mAh" sono di solito false; non risparmiare qui
Cavi, resistenze, condensatori, vitiBassoQuasi tutto si trova già negli starter kit
Se hai già uno starter kit Arduino, scheda, cavetti e resistenze ci sono già; ti servono solo il kit telaio, un L298N, un HC-05 e le batterie. I "kit smart car" con tutto in un'unica scatola sono comodi perché portano con sé la propria scheda motori e il codice pronto, ma costano di più e ti tolgono l'occasione di imparare i collegamenti.

2WD o 4WD?

Caratteristica2WD (2 motori + ruota pivottante)4WD (4 motori)
SterzataRuota su se stessa, stretta e senza faticaSterza facendo slittare le ruote di lato (skid steer); fatica sul tappeto
AssorbimentoCirca 0,3–0,6 A in marciaCirca il doppio
AutonomiaMaggioreMinore
Terreno irregolareLa ruota pivottante può incastrarsi sui bordiAderenza migliore
Andare drittoLa ruota pivottante può deviare la macchinina quando si riorientaPiù stabile
Collegamento all'L298NOgni motore sul proprio canaleI due motori di ogni lato in parallelo su un canale
Ideale perPrima macchinina, robot seguilineaEsterni, carichi più pesanti

Per la tua prima macchinina consigliamo il 2WD: costa meno, assorbe meno corrente, ruota facilmente su se stessa ed è più adatto a progetti successivi come un robot seguilinea. Se costruisci un 4WD, collega in parallelo i due motori di ogni lato agli stessi morsetti OUT e controlla che girino nello stesso verso. Un canale dell'L298N porta allora la corrente di due motori; nella guida normale non è un problema, ma se le ruote si bloccano si può superare il limite di 2 A per canale e la protezione termica del driver spegne i motori.

Alimentazione: perché due batterie 18650?

La maggior parte dei problemi delle macchinine robot nasce da una batteria sbagliata. La fonte giusta deve soddisfare due condizioni insieme: lasciare ai motori tensione sufficiente dopo la perdita dell'L298N e non crollare quando i motori chiedono diversi ampere in partenza. Due celle al litio 18650 in serie (2S) danno 8,4 V a piena carica e 7,4 V in media, ed erogano senza fatica diversi ampere. Arduino Uno consiglia 7–12 V sull'ingresso VIN, quindi lo stesso pacco può alimentare sia i motori sia Arduino. Con celle da 2500 mAh, una 2WD che assorbe in media 0,8 A in marcia (motori e schede compresi) funziona in teoria circa 3 ore; dato che non scarichi mai del tutto la batteria, 2–2,5 ore è una stima più realistica. Per fare il calcolo con i tuoi valori usa lo strumento Durata della batteria.

Batteria ricaricabile al litio 18650
Batteria al litio 18650: 18 mm di diametro e 65 mm di lunghezza; 4,2 V a piena carica, 3,6–3,7 V in media. Due in serie formano il pacco da 7,4 V ideale per una macchinina robot.
AlimentazioneTensioneCorrente erogabilePer una macchinina robot
Batteria da 9 V9 VMolto bassaNon adatta; la causa più comune dei reset
4 stilo AA alcaline6 V (cala in fretta sotto carico)MediaDebole; dopo l'L298N ai motori arrivano circa 4 V
4 stilo AA NiMH (ricaricabili)4,8 VBuonaTensione insufficiente con l'L298N
2 batterie 18650 al litio (2S)7,4 V (8,4 V cariche)Alta (diversi ampere)La scelta migliore
3 batterie 18650 al litio (3S)11,1 V (12,6 V cariche)AltaTroppo per i motori TT; supera il limite di 12 V del jumper 5V
Power bank USB5 VBuonaSolo per alimentare Arduino separatamente
Le batterie al litio sono potenti ma richiedono attenzione. Quando le inserisci nel portabatterie controlla due volte la polarità; una 18650 inserita al contrario o in cortocircuito si scalda moltissimo e può provocare un incendio. La tensione per cella non deve mai scendere sotto 3,0 V; ricarica quando la macchinina comincia a rallentare (circa 6,6 V per il pacco). I moduli TP4056 caricano solo una singola cella e non possono caricare direttamente un pacco in serie; togli le celle dal portabatterie, caricale in un caricatore per 18650 e non lasciarle mai incustodite durante la carica.

Invece di indovinare quanta carica resta, puoi misurarla. Collega il positivo della batteria (dopo l'interruttore) ad A0 tramite un partitore di tensione fatto con due resistenze da 10 kΩ: un pacco da 8,4 V appare su A0 come 4,2 V, sotto il limite di lettura di 5 V di Arduino. Il partitore assorbe solo circa 0,4 mA e non incide sull'autonomia.

Arduino (C++)
1// Pil + (anahtardan sonra) → 10 kΩ → A0 → 10 kΩ → GND / battery + (after the switch) → 10 kΩ → A0 → 10 kΩ → GND
2const float DIVIDER = 2.0;   // iki eşit direnç gerilimi yarıya böler / two equal resistors halve the voltage
3
4void setup() {
5  Serial.begin(9600);
6}
7
8void loop() {
9  float v = analogRead(A0) * 5.0 / 1023.0 * DIVIDER;
10  Serial.print(F("Pil / Battery: "));
11  Serial.print(v, 2);
12  Serial.println(F(" V"));
13  if (v < 6.6) Serial.println(F("Sarj et / Charge now"));   // hücre başına 3,3 V / 3.3 V per cell
14  delay(1000);
15}

Montaggio passo passo

  1. Togli la pellicola protettiva dai pezzi in acrilico. Se i motori arrivano senza fili, salda due fili su ogni motore e rinforza le saldature con colla a caldo; un filo del motore che si stacca per le vibrazioni è il guasto più frequente.
  2. Fissa i motori sotto il telaio con i supporti in acrilico a T e le viti M3 lunghe del kit. I due alberi devono essere allineati e i terminali dei motori rivolti verso l'interno.
  3. Se vuoi usare i dischi encoder, montali ora sul lato interno dell'albero del motore; con le ruote già montate è difficile.
  4. Monta la ruota pivottante al centro dell'altra estremità del telaio con dei distanziali. Scegli un'altezza che tenga il telaio parallelo al pavimento.
  5. Infila le ruote fino in fondo allineandole all'albero a forma di D; una ruota lenta fa deviare la macchinina di continuo.
  6. Fissa il portabatterie con biadesivo o velcro in modo che il suo peso sia vicino all'asse delle ruote. Se la maggior parte del peso grava sulla ruota pivottante, le ruote motrici slittano.
  7. Monta Arduino e l'L298N sul ripiano superiore con distanziali in plastica. Devi poter raggiungere facilmente la porta USB di Arduino e il dissipatore dell'L298N deve restare all'aria; attento che le viti metalliche non tocchino le saldature sotto le schede.
  8. Collega l'interruttore in serie al filo positivo della batteria; così potrai accendere e spegnere la macchinina senza togliere le celle.
  9. Attorciglia i due fili di ogni motore fino all'L298N, tieni corti tutti i cavi e raccoglili con le fascette. Prima di inserire le celle, verifica con un multimetro che non ci sia un cortocircuito tra i terminali della batteria.
Prima di fissare i motori al telaio, tocca per un attimo i terminali di ciascuno con 2 stilo AA per controllare il verso di rotazione e segna i fili. Se segni entrambi i motori in modo che "filo rosso al positivo significa avanti", non sbaglierai il verso durante i collegamenti.

Schema dei collegamenti

Pensa ai collegamenti in due parti: la parte di potenza (batteria, interruttore, L298N, motori) e la parte di segnale (i fili sottili che vanno da Arduino all'L298N e all'HC-05). Togli i piccoli jumper dai pin ENA ed ENB dell'L298N; collegheremo questi pin alle uscite PWM di Arduino per regolare la velocità da codice. Il jumper 5V dell'L298N invece resta al suo posto: poiché il pacco è sotto i 12 V, il regolatore della scheda alimenta la logica del driver.

Modulo driver per motori L298N a doppio canale
Driver L298N: i motori vanno ai morsetti blu laterali e la batteria al morsetto triplo davanti; i pin ENA, IN1–IN4 ed ENB vanno ad Arduino.
Morsetto dell'L298NCollegamento
OUT1, OUT2Motore sinistro (nel 4WD i due motori di sinistra in parallelo)
OUT3, OUT4Motore destro (nel 4WD i due motori di destra in parallelo)
12VPositivo della batteria tramite l'interruttore
GNDNegativo della batteria e pin GND di Arduino (massa comune)
5VLibero con Arduino Uno; alimenta la scheda con ESP32 e Pico
Jumper 5VResta inserito (batteria sotto i 12 V)
Jumper di ENA ed ENBSi tolgono; i pin vanno alle uscite PWM di Arduino
CollegamentoArduino UnoESP32Raspberry Pi Pico
L298N ENA (velocità motore sinistro)D5 (PWM)GPIO 25GP15
L298N IN1D7GPIO 27GP14
L298N IN2D8GPIO 33GP13
L298N ENB (velocità motore destro)D6 (PWM)GPIO 26GP10
L298N IN3D9GPIO 32GP12
L298N IN4D4GPIO 4GP11
HC-05 TXDD10 (RX di SoftwareSerial)Non serve (Bluetooth integrato)GP1 (RX di UART0)
HC-05 RXDD11, tramite partitore 1 kΩ / 2 kΩNon serveGP0 (TX di UART0), diretto
HC-05 VCC5VNon serveUscita 5V dell'L298N
Alimentazione della schedaVIN ← positivo della batteria dopo l'interruttore5V (VIN) ← uscita 5V dell'L298NVSYS ← uscita 5V dell'L298N
GNDIn comune con GND dell'L298N e negativo della batteriaIn comuneIn comune
Non infrangere mai queste tre regole: tutti i GND (negativo della batteria, L298N, Arduino, HC-05) devono essere collegati tra loro; i motori non vanno mai alimentati dal pin 5V di Arduino; e l'uscita 5V dell'L298N non va collegata al pin VIN di Arduino. VIN richiede almeno 7 V; con 5 V il regolatore di Arduino non lavora bene e la scheda diventa instabile. Il pin RXD dell'HC-05 è un ingresso a 3,3 V; abbassa il segnale TX a 5 V dell'Uno con un partitore da 1 kΩ e 2 kΩ: D11 → 1 kΩ → RXD, RXD → 2 kΩ → GND (5 V × 2/3 ≈ 3,3 V).

Abbiamo scelto D5 e D6 come pin di velocità di proposito. Sull'Uno la libreria Servo disattiva il PWM sui pin 9 e 10 e la funzione tone() quello sui pin 3 e 11. Con ENA ed ENB su 5 e 6, il controllo di velocità continua a funzionare anche quando più avanti aggiungi un servo o un buzzer. D2 e D3 restano riservati agli encoder perché supportano gli interrupt. Puoi vedere la piedinatura della tua scheda nello strumento Pinout.

Primo sketch: avanti, indietro, sinistra e destra

Prima di passare al Bluetooth, proviamo motori e collegamenti da soli. Il cuore del codice è la funzione drive(sinistra, destra): riceve la velocità di ciascun motore separatamente da -255 a 255; un valore positivo significa avanti, uno negativo indietro e zero stop. Come il valore di velocità diventa tensione lo spieghiamo in Che cos'è il PWM?. Prima di caricare lo sketch, appoggia la macchinina su una scatola in modo che le ruote girino a vuoto; l'attesa di 3 secondi in setup() ti dà il tempo per farlo.

Arduino (C++)
1// Sol motor / left motor: ENA=5, IN1=7, IN2=8 — Sağ motor / right motor: ENB=6, IN3=9, IN4=4
2const int ENA = 5, IN1 = 7, IN2 = 8;
3const int ENB = 6, IN3 = 9, IN4 = 4;
4
5const int SPEED = 180;   // temel hız 0-255 / base speed 0-255
6const int TRIM = 0;      // % düzeltme: + sol, - sağ motoru yavaşlatır / % trim: + slows left, - slows right
7
8void drive(int left, int right) {               // her biri -255 … 255 / each -255 … 255
9  if (TRIM > 0) left = left * (100 - TRIM) / 100;
10  if (TRIM < 0) right = right * (100 + TRIM) / 100;
11  digitalWrite(IN1, left > 0);  digitalWrite(IN2, left < 0);
12  digitalWrite(IN3, right > 0); digitalWrite(IN4, right < 0);
13  analogWrite(ENA, abs(left));
14  analogWrite(ENB, abs(right));
15}
16
17void forward()   { drive(SPEED, SPEED); }
18void backward()  { drive(-SPEED, -SPEED); }
19void turnLeft()  { drive(-SPEED, SPEED); }     // yerinde sola / spin left in place
20void turnRight() { drive(SPEED, -SPEED); }     // yerinde sağa / spin right in place
21void stopCar()   { drive(0, 0); }
22
23void setup() {
24  int pins[] = {ENA, IN1, IN2, ENB, IN3, IN4};
25  for (int p : pins) pinMode(p, OUTPUT);
26  stopCar();
27  delay(3000);             // tekerlekleri kaldırmak için zaman / time to lift the wheels
28}
29
30void loop() {
31  forward();   delay(1500);
32  stopCar();   delay(500);
33  backward();  delay(1500);
34  stopCar();   delay(500);
35  turnLeft();  delay(600);
36  stopCar();   delay(500);
37  turnRight(); delay(600);
38  stopCar();   delay(2000);
39}
MovimentoMotore sinistroMotore destroCodice
AvantiAvantiAvantidrive(180, 180)
IndietroIndietroIndietrodrive(-180, -180)
Rotazione a sinistra sul postoIndietroAvantidrive(-180, 180)
Rotazione a destra sul postoAvantiIndietrodrive(180, -180)
Curva larga a sinistraAvanti pianoAvantidrive(90, 180)
StopFermoFermodrive(0, 0)

Con le ruote sollevate, la macchinina deve andare a turno avanti, indietro, a sinistra e a destra. Se una ruota gira al contrario non toccare il codice: scambia i due fili di quel motore sul morsetto OUT dell'L298N. Se girano al contrario entrambe le ruote, scambia i fili di tutti e due i motori. Se i motori ronzano ma non girano, il valore SPEED è troppo basso: la maggior parte dei motori TT ha bisogno di un valore PWM di almeno 80–120 circa per partire, e questa soglia sale man mano che la batteria si scarica.

Controllo Bluetooth dallo smartphone (HC-05)

L'HC-05 funziona come un cavo seriale senza fili tra lo smartphone e Arduino: l'app sul telefono invia una lettera, Arduino la legge ed esegue il movimento corrispondente. La maggior parte delle app di comando che trovi sul Play Store cercando "Bluetooth RC Car" o "Bluetooth RC Controller" invia F per avanti, B per indietro, L per sinistra, R per destra e S per stop quando rilasci il tasto; alcune usano anche G, I, H e J per le diagonali e 0–9 più q per la velocità. Pin, lampeggi del LED e comandi AT del modulo sono spiegati in Modulo Bluetooth HC-05.

Modulo Bluetooth HC-05
HC-05: si collega allo smartphone tramite Bluetooth classico (SPP); velocità predefinita 9600 baud, PIN di associazione 1234 o 0000.
  1. Mentre carichi lo sketch qui sotto, l'interruttore della macchinina può restare spento; Arduino e HC-05 sono alimentati via USB. Se il LED dell'HC-05 lampeggia velocemente, il modulo è in attesa di connessione.
  2. Cerca l'HC-05 nelle impostazioni Bluetooth del tuo smartphone Android e associalo con il PIN 1234 (o 0000 se non funziona).
  3. Apri l'app di comando, concedi i permessi Bluetooth e dispositivi nelle vicinanze e scegli l'HC-05 dall'elenco. A connessione avvenuta, il LED del modulo fa due brevi lampeggi ogni due secondi.
  4. Tieni Arduino collegato via USB, apri il Monitor seriale a 9600 baud e premi i tasti nell'app. Sullo schermo compare la lettera inviata da ogni tasto; se la tua app invia lettere diverse, modifica di conseguenza le righe case del codice.
  5. Scollega il cavo USB, accendi l'interruttore, appoggia la macchinina a terra e guida.
Arduino (C++)
1#include <SoftwareSerial.h>
2
3SoftwareSerial bt(10, 11);               // RX, TX → HC-05 TXD, RXD (RXD bölücüyle / RXD via divider)
4
5const int ENA = 5, IN1 = 7, IN2 = 8;     // sol motor / left motor
6const int ENB = 6, IN3 = 9, IN4 = 4;     // sağ motor / right motor
7const int TRIM = 0;                      // % düzeltme / % trim
8const unsigned long TIMEOUT = 600;       // ms; 0 = kapalı / 0 = disabled
9
10int speed = 200;                         // 0-255
11unsigned long lastCmd = 0;
12
13void drive(int left, int right) {
14  if (TRIM > 0) left = left * (100 - TRIM) / 100;
15  if (TRIM < 0) right = right * (100 + TRIM) / 100;
16  digitalWrite(IN1, left > 0);  digitalWrite(IN2, left < 0);
17  digitalWrite(IN3, right > 0); digitalWrite(IN4, right < 0);
18  analogWrite(ENA, abs(left));
19  analogWrite(ENB, abs(right));
20}
21
22void setup() {
23  int pins[] = {ENA, IN1, IN2, ENB, IN3, IN4};
24  for (int p : pins) pinMode(p, OUTPUT);
25  drive(0, 0);
26  Serial.begin(9600);                    // gelen harfleri görmek için / to see incoming letters
27  bt.begin(9600);                        // HC-05 veri modu hızı / HC-05 data mode baud rate
28}
29
30void loop() {
31  if (bt.available()) {
32    char c = bt.read();
33    Serial.println(c);
34    lastCmd = millis();
35    int half = speed / 2;
36    switch (c) {
37      case 'F': drive(speed, speed);   break;   // ileri / forward
38      case 'B': drive(-speed, -speed); break;   // geri / backward
39      case 'L': drive(-speed, speed);  break;   // yerinde sola / spin left
40      case 'R': drive(speed, -speed);  break;   // yerinde sağa / spin right
41      case 'G': drive(half, speed);    break;   // ileri-sol / forward-left
42      case 'I': drive(speed, half);    break;   // ileri-sağ / forward-right
43      case 'H': drive(-half, -speed);  break;   // geri-sol / back-left
44      case 'J': drive(-speed, -half);  break;   // geri-sağ / back-right
45      case 'S': drive(0, 0);           break;   // dur / stop
46      case 'q': speed = 255;           break;   // tam hız / full speed
47      default:
48        if (c >= '0' && c <= '9') speed = map(c - '0', 0, 9, 100, 240);   // hız kademesi / speed level
49    }
50  }
51  if (TIMEOUT > 0 && millis() - lastCmd > TIMEOUT) drive(0, 0);   // komut yoksa dur / no command: stop
52}
LetteraMovimentoMotore sinistro / destro
FAvanti+velocità / +velocità
BIndietro−velocità / −velocità
LRotazione a sinistra−velocità / +velocità
RRotazione a destra+velocità / −velocità
G, IAvanti-sinistra, avanti-destraUn lato a metà velocità
H, JIndietro-sinistra, indietro-destraUn lato a metà velocità
SStop0 / 0
0–9, qLivello di velocità0 → 100, 9 → 240, q → 255

Il TIMEOUT nel codice è una misura di sicurezza: queste app inviano la stessa lettera in continuazione finché tieni premuto il tasto, quindi se per 600 ms non arriva nessuna lettera il codice presume che la connessione sia caduta e ferma la macchinina. Così la macchinina non continua verso il muro se lo smartphone esce dalla portata o l'app si chiude. Se la tua app invia la lettera una sola volta per ogni pressione, la macchinina si fermerà dopo 600 ms; in quel caso imposta TIMEOUT a 0 per disattivare la funzione. Inoltre non abbiamo usato delay() da nessuna parte in loop(); le attese lunghe ritardano i comandi, e il perché lo trovi in millis() o delay().

HC-05 e HC-06 usano il Bluetooth classico, quindi non funzionano con l'iPhone; iOS non permette questo tipo di connessione seriale. Se vuoi guidare con un iPhone, usa un modulo BLE come l'HM-10 o un ESP32 con BLE. Se vuoi creare la tua app di comando, dai un'occhiata alla guida Arduino e Bluetooth con App Inventor.

La macchinina non va dritta: cause e soluzione

Se la macchinina devia lentamente da un lato anche se dai a entrambi i motori lo stesso valore PWM per "avanti", niente paura: è il problema più comune delle macchinine robot. I motoriduttori economici girano a velocità diverse anche alla stessa tensione; differenze di attrito negli ingranaggi, nelle spazzole e nei magneti rendono ogni motore un po' diverso. Aggiungi una ruota lenta, una ruota pivottante che cambia orientamento o il peso concentrato su un lato, e una deviazione di 20–30 cm su 2 metri è del tutto normale. Elimina prima le cause meccaniche, poi correggi la differenza rimasta via software.

SintomoCausa probabileSoluzione
Devia sempre dallo stesso latoI motori girano a velocità diverseCorrezione software con TRIM, oppure encoder
Sbanda in partenza e poi si raddrizzaUn motore parte in ritardo o la ruota pivottante si riorientaPartenza graduale; ruota a sfera (ball caster) al posto della pivottante
La deviazione cambia ogni voltaRuota lenta, pneumatico che slitta o supporto motore stortoInfila bene la ruota sull'albero, stringi le viti
Gira su se stessa invece di andare avantiI fili di un motore sono invertitiScambia i fili di quel motore sul morsetto OUT
La deviazione aumenta con la batteria scaricaA bassa tensione la differenza tra i motori cresceRicarica la batteria; regola TRIM a batteria carica
Tira da un lato quando acceleraIl peso è da un latoSposta batteria e schede al centro, vicino all'asse delle ruote

Risolti i problemi meccanici, fai la regolazione fine via software. La costante TRIM nel codice rallenta in percentuale il motore più veloce: un valore positivo rallenta il motore sinistro, uno negativo il destro. Procedi così:

  1. Carica completamente le celle; tarare a batteria carica dà risultati coerenti.
  2. Attacca sul pavimento una striscia di nastro dritta lunga 2 metri e metti la macchinina all'inizio, allineata al nastro.
  3. Nel loop() del primo sketch lascia solo forward() e un'attesa di 3 secondi, poi lascia andare la macchinina.
  4. Se la macchinina devia a destra, il motore sinistro è più veloce: aumenta TRIM di 3; se devia a sinistra, diminuisci TRIM di 3.
  5. Ripeti finché la deviazione su 2 metri scende a pochi centimetri, poi copia lo stesso valore di TRIM nello sketch Bluetooth.
  6. Tara alla velocità che usi di più; la differenza tra i motori cambia leggermente con la velocità.

Il livello successivo per andare perfettamente dritto e misurare le distanze è l'encoder. Monti sugli alberi dei motori i dischi a 20 fessure del kit e conti ogni fessura con un sensore di velocità a forcella basato sull'LM393. Collega le uscite dei sensori ai pin D2 e D3, che supportano gli interrupt, e confronta il numero di impulsi delle due ruote: se il lato sinistro va più avanti, rallenti un po' il motore sinistro. Questo semplice controllo proporzionale (P) mantiene la macchinina dritta indipendentemente dalla carica della batteria e dal pavimento. Una ruota da 65 mm percorre circa 20,4 cm per giro, quindi ogni impulso corrisponde a circa 1 cm. Spieghiamo come funzionano gli interrupt in Interrupt su Arduino.

Arduino si resetta quando partono i motori

Se Arduino si riavvia o l'HC-05 perde la connessione (il LED torna a lampeggiare velocemente) quando la macchinina parte, cambia direzione o urta un ostacolo, il problema è quasi sempre nell'alimentazione. In partenza due motori insieme possono assorbire 2–3 A; una batteria debole non ce la fa e la sua tensione crolla per un istante. Il processore dell'Uno si resetta per sicurezza quando l'alimentazione scende sotto 2,7 V (brown-out). A questo si aggiungono i disturbi elettrici delle spazzole dei motori e la caduta di tensione nei cavi sottili. Ecco le soluzioni, partendo dalla più efficace:

  • Cambia batteria: usa due 18650 cariche al posto di una batteria da 9 V o di stilo AA esauste; qui finisce la maggior parte dei problemi.
  • Il percorso di alimentazione giusto: alimenta Arduino dalla batteria tramite VIN; non collegare l'uscita 5V dell'L298N a VIN.
  • Condensatori sui motori: salda un condensatore ceramico da 100 nF tra i due terminali di ogni motore; elimina alla fonte i disturbi delle spazzole.
  • Condensatore di riserva: collega un elettrolitico da 470–1000 µF ai morsetti 12V e GND dell'L298N (positivo sul 12V). Copre il breve picco di corrente della partenza.
  • Partenza graduale: invece di passare subito a 255, aumenta la velocità a gradini come qui sotto; il picco di corrente si riduce.
  • Fermati prima di invertire: passare direttamente da avanti a indietro porta la corrente del motore al massimo; fermati per 100–200 ms prima di cambiare verso.
  • Cavi di potenza spessi e corti: non usare cavetti jumper né breadboard tra batteria e L298N; usa cavo da almeno 0,5 mm² e morsettiere.
  • Alimentazioni separate: se il problema persiste, alimenta Arduino con un power bank e i motori con la batteria, e collega insieme i due GND.
Arduino (C++)
1// Yumuşak kalkış: ilk koddaki drive() ile kullan / soft start: use with drive() from the first sketch
2void rampTo(int target) {
3  for (int s = 60; s < target; s += 20) {
4    drive(s, s);
5    delay(15);              // yaklaşık 10 adımda tam hız / full speed in about 10 steps
6  }
7  drive(target, target);
8}
9
10// Kullanım: forward() yerine rampTo(SPEED) / usage: rampTo(SPEED) instead of forward()
Un modo semplice per capire se il problema è l'alimentazione o il codice: scollega il filo di VIN, alimenta Arduino via USB dal computer (lascia il collegamento GND) e fai girare i motori con la batteria. Se i reset spariscono, il problema è sicuramente nell'alimentazione. Anche un multimetro collegato tra VIN e GND, guardando la tensione mentre la macchinina parte, mostra direttamente il calo. Per le altre cause consulta Arduino si resetta da solo.

Macchinina robot con ESP32 e Raspberry Pi Pico

L'ESP32 ha il Bluetooth classico integrato, quindi l'HC-05 non serve: la libreria BluetoothSerial crea la stessa connessione seriale con lo smartphone e le app di comando viste sopra funzionano senza modifiche. Gli ingressi dell'L298N considerano HIGH tutto ciò che supera circa 2,3 V, quindi i segnali a 3,3 V dell'ESP32 bastano. Alimenta la scheda ESP32 dall'uscita 5V dell'L298N sul suo pin 5V (VIN); non collegare la batteria direttamente a quel pin. Questo codice non si compila per ESP32-S3 ed ESP32-C3, perché hanno solo il BLE.

Arduino (C++)
1#include "BluetoothSerial.h"
2
3BluetoothSerial bt;
4
5const int ENA = 25, IN1 = 27, IN2 = 33;   // sol motor / left motor
6const int ENB = 26, IN3 = 32, IN4 = 4;    // sağ motor / right motor
7
8int speed = 200;                          // 0-255
9unsigned long lastCmd = 0;
10
11void drive(int left, int right) {
12  digitalWrite(IN1, left > 0);  digitalWrite(IN2, left < 0);
13  digitalWrite(IN3, right > 0); digitalWrite(IN4, right < 0);
14  analogWrite(ENA, abs(left));
15  analogWrite(ENB, abs(right));
16}
17
18void setup() {
19  int pins[] = {ENA, IN1, IN2, ENB, IN3, IN4};
20  for (int p : pins) pinMode(p, OUTPUT);
21  drive(0, 0);
22  bt.begin("BlueGrays-Car");              // telefonda görünecek ad / name shown on the phone
23}
24
25void loop() {
26  if (bt.available()) {
27    char c = bt.read();
28    lastCmd = millis();
29    switch (c) {
30      case 'F': drive(speed, speed);   break;   // ileri / forward
31      case 'B': drive(-speed, -speed); break;   // geri / backward
32      case 'L': drive(-speed, speed);  break;   // yerinde sola / spin left
33      case 'R': drive(speed, -speed);  break;   // yerinde sağa / spin right
34      case 'S': drive(0, 0);           break;   // dur / stop
35      case 'q': speed = 255;           break;   // tam hız / full speed
36      default:
37        if (c >= '0' && c <= '9') speed = map(c - '0', 0, 9, 100, 240);
38    }
39  }
40  if (millis() - lastCmd > 600) drive(0, 0);    // komut yoksa dur / no command: stop
41}

Il Raspberry Pi Pico standard non ha il Bluetooth, quindi colleghi l'HC-05 ai pin della UART0. Dato che il Pico lavora a 3,3 V, questa volta il partitore di tensione non serve. Alimenta il Pico dal pin VSYS e l'HC-05 direttamente dall'uscita 5V dell'L298N; funzionando a batteria senza USB, sul pin VBUS non c'è tensione. Nel codice del Pico la velocità si indica in percentuale da -100 a 100:

MicroPython
1from machine import Pin, PWM, UART
2import time
3
4bt = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1))   # GP0 → HC-05 RXD, GP1 ← HC-05 TXD
5
6ena = PWM(Pin(15)); ena.freq(1000)                  # sol motor hızı / left motor speed
7enb = PWM(Pin(10)); enb.freq(1000)                  # sağ motor hızı / right motor speed
8in1, in2 = Pin(14, Pin.OUT), Pin(13, Pin.OUT)
9in3, in4 = Pin(12, Pin.OUT), Pin(11, Pin.OUT)
10
11def drive(left, right):                             # -100 … 100 (%)
12    in1.value(left > 0); in2.value(left < 0)
13    in3.value(right > 0); in4.value(right < 0)
14    ena.duty_u16(int(abs(left) * 655))
15    enb.duty_u16(int(abs(right) * 655))
16
17speed = 80
18last = time.ticks_ms()
19drive(0, 0)
20
21while True:
22    if bt.any():
23        c = bt.read(1)
24        last = time.ticks_ms()
25        if c == b'F':   drive(speed, speed)          # ileri / forward
26        elif c == b'B': drive(-speed, -speed)        # geri / backward
27        elif c == b'L': drive(-speed, speed)         # yerinde sola / spin left
28        elif c == b'R': drive(speed, -speed)         # yerinde sağa / spin right
29        elif c == b'S': drive(0, 0)                  # dur / stop
30        elif c == b'q': speed = 100                  # tam hız / full speed
31        elif c and 48 <= c[0] <= 57:                 # '0'…'9' hız kademesi / speed level
32            speed = 40 + (c[0] - 48) * 6
33    if time.ticks_diff(time.ticks_ms(), last) > 600:
34        drive(0, 0)                                  # komut yoksa dur / no command: stop

Prossimi passi: potenzia la tua macchinina

  • Robot che evita gli ostacoli: aggiungi davanti un sensore di distanza HC-SR04 e un servomotore che lo ruoti a destra e a sinistra; i dettagli nella guida Robot che evita gli ostacoli.
  • Robot seguilinea: monta 2–3 sensori a infrarossi TCRT5000 sotto la parte anteriore e segui una linea nera sul pavimento; vedi Robot seguilinea.
  • Telecomando con joystick: costruisci un vero telecomando, senza smartphone, con un secondo Arduino, un modulo joystick e un nRF24L01.
  • Telecomando a infrarossi: guida con i tasti del telecomando della TV; associa i codici di Ricevitore IR e telecomando ai comandi di guida.
  • Guida via Wi-Fi: fai servire da un ESP32 una pagina di comando che si apre nel browser dello smartphone; la guida Web server ESP32 e WebSocket spiega le basi.
  • Encoder e distanza: con i sensori di velocità fai avanzare la macchinina esattamente di 1 metro e girarla di 90 gradi precisi; è la base dei robot che risolvono labirinti.
  • Braccio robotico: monta sulla macchinina un piccolo braccio robotico con servo per trasportare oggetti.
HC-SR04
HC-SR04
TCRT5000
TCRT5000
SG90 servo
SG90 servo

Errori comuni e soluzioni

  • Nessun motore gira: i GND non sono in comune, l'interruttore è spento, i jumper di ENA ed ENB sono stati tolti ma i pin non sono collegati, oppure la batteria è scarica.
  • Il LED dell'L298N è acceso ma i motori ronzano soltanto: il valore PWM è sotto la soglia di partenza o la tensione della batteria è bassa; aumenta la velocità e ricarica la batteria.
  • Lo sketch non si carica: forse hai scelto la porta o la scheda sbagliata; se hai collegato l'HC-05 ai pin 0 e 1, scollegalo durante il caricamento. Altre cause in Lo sketch Arduino non si carica.
  • Lo smartphone vede l'HC-05 ma non si connette: il modulo è collegato a un altro telefono, l'app non ha il permesso "dispositivi nelle vicinanze" o il PIN di associazione è sbagliato.
  • La macchinina risponde in ritardo: c'è un delay() nel loop() o si stampa troppo sul Monitor seriale; gestisci le attese con millis().
  • Il dissipatore dell'L298N scalda molto: le ruote fanno attrito o, nel 4WD, la corrente per canale è eccessiva; controlla l'attrito meccanico.
  • La macchinina dà uno scatto all'accensione: all'avvio i pin sono indefiniti per un istante; impostali come uscite e chiama drive(0, 0) nelle primissime righe di setup().

Una macchinina robot con Arduino è un ottimo punto di partenza che insegna controllo dei motori, gestione dell'alimentazione, comunicazione wireless e debug in un solo progetto. Alla fine avrai una base che diventa un po' più intelligente con ogni nuovo sensore. Nell'app BlueGrays trovi passo passo, con schemi e codice, i progetti macchinina controllata via Bluetooth con L298N, robot che evita gli ostacoli e rilevamento del fondo bianco e nero con TCRT5000.

Domande frequenti

Cosa serve per costruire una macchinina con Arduino e quanto costa?

Per una macchinina Bluetooth di base bastano un kit telaio 2WD (2 motori TT, ruote, ruota pivottante), un Arduino Uno, un driver L298N, un modulo Bluetooth HC-05, due batterie 18650 con portabatterie e qualche cavetto jumper. I prezzi dipendono dal venditore; i moduli costano poco e la maggior parte del budget va nella scheda, nel kit telaio e nelle batterie con il caricatore. Se hai già uno starter kit, il costo scende parecchio.

Che batteria usare per una macchinina robot Arduino?

La scelta migliore sono due celle al litio 18650 in serie: forniscono 7,4 V, lasciano 5–6 V ai motori dopo la perdita di circa 2 V dell'L298N ed erogano la corrente elevata necessaria alla partenza. Una batteria da 9 V non fornisce abbastanza corrente e provoca reset, mentre con 4 stilo AA i motori girano lenti dietro un L298N.

Perché la mia macchinina Arduino non va dritta?

I motoriduttori economici girano a velocità diverse anche con lo stesso valore PWM, e ruote lente, ruota pivottante e peso mal distribuito aumentano la deviazione. Sistema prima la meccanica, poi rallenta un po' il motore più veloce con un valore di correzione (trim) nel codice. Per andare perfettamente dritto servono encoder che misurino e uguaglino la velocità delle due ruote.

Perché Arduino si resetta quando partono i motori?

In partenza i motori assorbono diversi ampere e la tensione di una batteria debole crolla per un istante; il processore dell'Uno si resetta quando l'alimentazione scende. Usa 18650 cariche, aggiungi condensatori da 100 nF sui terminali dei motori e uno da 470–1000 µF sull'ingresso dell'L298N, e aumenta la velocità gradualmente. Se il problema resta, alimenta Arduino con una fonte separata e collega insieme i GND.

Una macchinina Bluetooth con HC-05 funziona con l'iPhone?

No. HC-05 e HC-06 usano il profilo porta seriale del Bluetooth classico, e iOS non permette alle normali app di aprire questo tipo di connessione. Per comandarla da iPhone ti serve un modulo BLE come l'HM-10 o un ESP32 con BLE; gli smartphone Android si collegano all'HC-05 senza problemi.

Posso usare uno shield motori L293D al posto dell'L298N?

Sì. Lo shield motori L293D si innesta sopra Arduino Uno e può comandare quattro motori DC, semplificando i collegamenti nelle macchinine 4WD. La sua corrente continua però è di circa 0,6 A per canale, quindi va in difficoltà prima dell'L298N quando i motori si bloccano, e lo shield occupa molti pin. Se cerchi qualcosa di più efficiente, i driver a MOSFET come il TB6612FNG perdono molta meno tensione.

Vedi tutti i progetti
Auto controllata via Bluetooth con L298N
#80Avanzato
Premium

Auto controllata via Bluetooth con L298N

Progetto di auto robot 4WD (quattro motori, quattro ruote motrici) che può essere controllata dal telefono con Arduino e il modulo HC-05 Bluetooth. Un totale di quattro ruote sono azionate simultaneam

5.0(38)
64
Robot che evita gli ostacoli
#81Avanzato
Premium

Robot che evita gli ostacoli

Che ne dite di costruire un veicolo intelligente che trova la propria strada? L'Obstacle Avoiding Robot scruta costantemente l'ambiente circostante grazie al sensore a ultrasuoni posto davanti a lui.

5.0(38)
49
Controllare un LED dal telefono tramite Bluetooth
#34Principiante
Premium

Controllare un LED dal telefono tramite Bluetooth

Progetto di controllo wireless che accende e spegne i LED con comandi inviati dal telefono con il modulo Bluetooth HC-06. Insegna lo scambio di dati Bluetooth sulla comunicazione seriale.

4.8(68)
88
TCRT5000 Rilevamento di superfici bianche e nere
#78Intermedio
Premium

TCRT5000 Rilevamento di superfici bianche e nere

Progetto che rileva il colore del terreno con il sensore TCRT5000 e accende il LED rosso sul terreno nero e il LED verde sul terreno bianco. Insegna la logica di rilevamento della soglia di colore che

4.7(40)
49
Misurazione della distanza con TCRT5000
#77Intermedio
Premium

Misurazione della distanza con TCRT5000

Progetto che misura la quantità di luce riflessa dalla superficie con il sensore a infrarossi TCRT5000 e la visualizza come valore analogico sullo schermo LCD I2C. Insegna le basi del rilevamento otti

4.6(33)
43
HC-SR04 Misura della distanza (display seriale)
#27Principiante

HC-SR04 Misura della distanza (display seriale)

Il sensore a ultrasuoni HC-SR04 misura la distanza e visualizza il risultato in cm sul monitor seriale. Insegna il principio del calcolo della distanza con l'onda sonora.

4.6(44)
66
Sensore di parcheggio con HC-SR04
#28Intermedio
Premium

Sensore di parcheggio con HC-SR04

Progetto di sensore di parcheggio con sensore HC-SR04 che aumenta la frequenza del segnale acustico all'avvicinarsi dell'oggetto e lo segnala con un LED. Insegna una logica di feedback proporzionale a

4.8(64)
83
Utilizzo del servomotore
#35Principiante
Premium

Utilizzo del servomotore

Progetto di base che posiziona il servomotore su angoli di 0°, 90° e 180° in sequenza. Insegna la libreria dei servo e la logica di controllo degli angoli.

4.7(48)
66