Guide · 13 min di lettura

Radar con Arduino: HC-SR04, servo SG90 e schermo in Processing

Radar con Arduino passo passo: collegamento di HC-SR04 e servo SG90, codice per angolo e distanza, schermo radar verde in Processing, mini radar OLED ed errori.

Un radar con Arduino è un progetto che monta un sensore a ultrasuoni HC-SR04 su un servomotore SG90 e lo fa ruotare tra 0 e 180 gradi per misurare sia la direzione sia la distanza degli oggetti vicini, mostrando il risultato sul computer come uno schermo radar verde, proprio come nei film. A ogni angolo Arduino esegue una misura e invia sulla porta seriale una riga nel formato "angolo,distanza"; un piccolo programma Processing in esecuzione sul computer legge questi numeri e disegna la linea di scansione che ruota e gli oggetti rilevati come linee rosse.

In questa guida trovi ogni passaggio spiegato, dall'elenco dei componenti e dallo schema di collegamento fino al codice Arduino e allo schermo radar in Processing. Vediamo anche un mini radar su display OLED che non ha bisogno del computer, le versioni per ESP32 e Raspberry Pi Pico, come regolare la velocità di scansione e la precisione delle misure e come risolvere gli errori più comuni della porta seriale. È economico, si finisce in un pomeriggio ed è uno dei progetti Arduino che attirano più attenzione nelle presentazioni a scuola.

Arduino Uno
Arduino Uno
HC-SR04
HC-SR04
SG90 servo
SG90 servo
Breadboard
Breadboard

Come funziona un radar con Arduino?

Il cuore del sistema è l'HC-SR04. Uno dei due cilindri del sensore (T) emette un breve impulso sonoro a 40 kHz che l'orecchio umano non sente; quando il suono colpisce un oggetto e torna indietro, l'altro (R) capta l'eco. Arduino misura questo tempo di andata e ritorno in microsecondi. Il suono viaggia nell'aria a circa 343 m/s, quindi impiega circa 29 microsecondi per percorrere un centimetro; dato che il percorso viene fatto due volte, andata e ritorno, la formula diventa distanza (cm) = tempo (µs) / 58. Il servo ruota il sensore passo dopo passo e a ogni passo la misura viene ripetuta. Alla fine sai "a quale angolo e a quanti centimetri c'è qualcosa", cioè una coordinata polare. Per disegnarla sullo schermo, angolo e distanza vengono convertiti in una posizione in pixel con x = distanza × cos(angolo) e y = distanza × sin(angolo).

ComponenteFunzioneValori chiave
HC-SR04Misura della distanza a ultrasuoni40 kHz, 2–400 cm, angolo di misura di circa 15°, 5 V, 15 mA
Servo SG90Ruota il sensore da 0 a 180°0,1 s/60° (4,8 V), coppia 1,8 kg·cm, 4,8–6 V, 9 g
Arduino UnoMisura, muove il servo e invia i dati16 MHz, livello logico 5 V, porta seriale USB
ProcessingDisegna lo schermo radar sul computerGratuito, basato su Java, libreria Serial inclusa
OLED SSD1306 (opzionale)Mini schermo radar senza computer128×64 pixel, I2C, indirizzo 0x3C

Componenti per il radar con Arduino

  • Arduino Uno o Nano e un cavo USB che trasmetta dati (i cavi di sola ricarica non compaiono come porta sul computer).
  • Sensore di distanza a ultrasuoni HC-SR04.
  • Micro servo SG90 e le squadrette di plastica incluse nella confezione.
  • Una breadboard e 8–10 cavetti jumper maschio-maschio e maschio-femmina.
  • Un condensatore elettrolitico da 470 µF (almeno 10 V): evita che la tensione crolli quando il servo si muove.
  • Nastro biadesivo, colla a caldo o un piccolo supporto stampato in 3D per fissare il sensore al servo.
  • Opzionale: un display OLED I2C da 0,96 pollici (per la versione senza computer) e un alimentatore esterno da 5 V 2 A.

Schema di collegamento del radar con Arduino

CollegamentoArduino UnoESP32Raspberry Pi Pico
HC-SR04 VCC5VVIN (5 V)VBUS (pin 40)
HC-SR04 GNDGNDGNDGND
HC-SR04 TrigD10GPIO 26GP14
HC-SR04 EchoD11GPIO 27 (con partitore)GP13 (con partitore)
SG90 marrone (GND)GNDGNDGND
SG90 rosso (+5 V)5VVIN (5 V)VBUS (pin 40)
SG90 arancione (segnale)D9GPIO 13GP15

Sull'Uno il cablaggio è più ordinato se colleghi i fili 5 V e GND del sensore e del servo alle linee positiva e negativa della breadboard, e queste linee ai pin 5V e GND di Arduino. Inserisci il condensatore da 470 µF sulle stesse linee, con la gamba lunga (+) sui 5 V e la gamba corta, indicata dalla striscia sul corpo, su GND. Su alcuni servo i fili sono nero, rosso e bianco: in questo caso il nero è GND e il bianco il segnale. Per verificare dove si trovano i pin sulla tua scheda, usa lo strumento pinout.

Quando l'HC-SR04 è alimentato a 5 V, anche il suo pin Echo fornisce 5 V. Per Arduino Uno non è un problema, ma i pin di ESP32 e Raspberry Pi Pico non tollerano i 5 V. Metti un partitore di tensione da 1 kΩ e 2 kΩ sulla linea Echo (Echo → 1 kΩ → GPIO, GPIO → 2 kΩ → GND); la tensione sul pin scende a circa 3,3 V. Puoi controllare i valori con il calcolatore del partitore di tensione.

Montare il sensore sul servo

Micro servo SG90
Servo SG90: marrone è GND, rosso +5 V, arancione il segnale. L'HC-SR04 si incolla sulla squadretta di plastica del servo.

Prima di montare la squadretta, porta il servo a 90 gradi: basta caricare un breve sketch di prova con radarServo.write(90) e lasciare il servo in quella posizione. Poi monta la squadretta in modo che il sensore guardi dritto davanti a sé. Così 0° punta a destra, 90° in avanti e 180° a sinistra, e le direzioni sullo schermo di Processing corrispondono esattamente al mondo reale. Quando incolli l'HC-SR04 alla squadretta con biadesivo o colla a caldo, assicurati che i due cilindri restino paralleli al pavimento; se il sensore è inclinato verso il basso, scambierà il piano del tavolo per un oggetto. Lascia ai cavi abbastanza gioco perché non si tendano durante la rotazione di 180 gradi e fissa il servo a una base pesante o a una scatola; una struttura che traballa a ogni passo rovina le misure.

Costruire il radar con Arduino passo passo

  1. Collega i componenti secondo la tabella qui sopra, non dimenticare il condensatore e monta il sensore sul servo.
  2. Apri l'IDE di Arduino; la libreria Servo è già inclusa, non devi installare altro.
  3. Carica il codice del radar qui sotto. Se hai problemi con la scelta della scheda o della porta, leggi Arduino non carica lo sketch.
  4. Apri il Monitor seriale a 9600 baud; se scorrono righe di angolo e distanza come "30,45", la parte Arduino è pronta. Poi chiudi assolutamente il Monitor seriale.
  5. Installa Processing 4 sul computer, apri un nuovo sketch e incolla il codice dello schermo radar.
  6. Premi Run; nella console in basso compare l'elenco delle porte e si apre la finestra del radar. Muovendo la mano davanti al sensore dovrebbero comparire delle linee rosse.

Codice del radar con Arduino

Arduino (C++)
1#include <Servo.h>
2
3const byte SERVO_PIN  = 9;     // SG90 turuncu kablo / SG90 orange wire
4const byte TRIG_PIN   = 10;    // HC-SR04 Trig
5const byte ECHO_PIN   = 11;    // HC-SR04 Echo
6const int  MIN_ANGLE  = 0;     // tarama başlangıcı / sweep start
7const int  MAX_ANGLE  = 180;   // tarama sonu / sweep end
8const int  STEP       = 2;     // adım başına derece / degrees per step
9const int  STEP_DELAY = 40;    // ölçümden önce bekleme (ms) / wait before measuring (ms)
10
11Servo radarServo;
12int angle = MIN_ANGLE;
13int dir = STEP;
14
15int measureCm() {
16  digitalWrite(TRIG_PIN, LOW);
17  delayMicroseconds(2);
18  digitalWrite(TRIG_PIN, HIGH);                         // 10 µs tetik darbesi / 10 µs trigger pulse
19  delayMicroseconds(10);
20  digitalWrite(TRIG_PIN, LOW);
21  unsigned long us = pulseIn(ECHO_PIN, HIGH, 30000UL);  // en çok 30 ms bekle / wait at most 30 ms
22  if (us == 0) return 0;                                // yankı yok = menzil dışı / no echo = out of range
23  return us / 58;                                       // gidiş-dönüş süresi → cm / round-trip time → cm
24}
25
26void setup() {
27  Serial.begin(9600);
28  pinMode(TRIG_PIN, OUTPUT);
29  pinMode(ECHO_PIN, INPUT);
30  radarServo.attach(SERVO_PIN);
31  radarServo.write(angle);
32  delay(500);                                           // başlangıç konumuna gitsin / reach the start position
33}
34
35void loop() {
36  radarServo.write(angle);                              // servoyu yeni açıya döndür / move the servo to the new angle
37  delay(STEP_DELAY);                                    // titreşim geçsin / let the vibration settle
38  int distance = measureCm();
39
40  Serial.print(angle);                                  // biçim: açı,mesafe / format: angle,distance
41  Serial.print(',');
42  Serial.println(distance);
43
44  if (angle + dir > MAX_ANGLE || angle + dir < MIN_ANGLE) dir = -dir;  // uçta yön değiştir / reverse at the ends
45  angle += dir;
46}

Spiegazione del codice

Parte del codiceCosa fa?
STEP e STEP_DELAYStabiliscono di quanti gradi ruota il servo a ogni passo e quanto si aspetta prima di misurare; con queste due costanti regoli la velocità di scansione.
measureCm()Invia un impulso di 10 µs al pin Trig, misura con pulseIn per quanto tempo il pin Echo resta HIGH e divide per 58 per ottenere i centimetri.
pulseIn(..., 30000UL)Aspetta al massimo 30 ms e restituisce 0 se non arriva nessuna eco. Senza questo timeout, puntando nel vuoto la funzione potrebbe bloccarsi fino a 1 secondo.
radarServo.write(angle)Porta il servo all'angolo richiesto; la libreria converte il valore 0–180 in un impulso di 544–2400 µs.
Serial.print ... printlnInvia ogni misura come un'unica riga "angolo,distanza"; il fine riga segnala a Processing che il dato è completo.
dir = -dirInverte la direzione quando l'angolo arriva a 180 o a 0, così il servo scansiona avanti e indietro senza sosta.

C'è un motivo se i dati sono così semplici: una sola riga separata da una virgola si legge comodamente nel Monitor seriale e si divide con una riga di codice in Processing, Python o Excel. Una distanza pari a 0 significa "nulla entro la portata a questo angolo" e Processing non disegna questi valori. Se apri gli stessi dati nel Plotter seriale dell'IDE di Arduino, vedrai l'angolo salire e scendere a dente di sega e la distanza fare un salto ogni volta che il sensore passa davanti a un oggetto. Per questo progetto delay va benissimo; se vuoi leggere un pulsante o accendere un LED mentre il radar lavora, riscrivi il ciclo con millis().

Se il servo ronza e vibra proprio a 0° o a 180°, sta arrivando al suo fine corsa meccanico. Riduci la scansione a 10–170° oppure avvia il servo con radarServo.attach(SERVO_PIN, 500, 2400) e adatta l'intervallo degli impulsi al tuo servo.

Lo schermo radar verde con Processing

Processing è un software gratuito basato su Java pensato per la programmazione visuale, e la sua interfaccia somiglia molto all'IDE di Arduino: scrivi il codice e premi Run. La libreria Serial, necessaria per la comunicazione seriale, è inclusa in Processing; puoi aggiungerla dal menu Sketch > Import Library o affidarti semplicemente alla riga import all'inizio del codice. Il codice seguente va incollato in Processing, non nell'IDE di Arduino.

Arduino (C++)
1// Processing 4 çizimi: Arduino IDE'ye değil, Processing'e yapıştır / Processing 4 sketch: paste into Processing, not the Arduino IDE
2import processing.serial.*;                       // Serial kütüphanesi / Serial library
3
4Serial port;
5int angle = 0;                                    // son açı / last angle
6int distance = 0;                                 // son mesafe (cm) / last distance (cm)
7final int MAX_CM = 100;                           // ekrandaki en uzak mesafe / farthest distance on screen
8float R;                                          // radar yarıçapı (piksel) / radar radius (pixels)
9
10void setup() {
11  size(1200, 700);
12  R = width * 0.45;
13  printArray(Serial.list());                      // portları konsola yaz / print the ports to the console
14  String portName = Serial.list()[0];             // gerekirse [1] ya da "COM4" yaz / use [1] or "COM4" if needed
15  port = new Serial(this, portName, 9600);        // Arduino ile aynı baud / same baud as the Arduino
16  port.bufferUntil('\n');                         // satır sonunu bekle / wait for the end of a line
17  background(0);
18}
19
20void draw() {
21  noStroke();
22  fill(0, 12);                                    // yarı saydam siyah: solan iz / translucent black: fading trail
23  rect(0, 0, width, height);
24  translate(width / 2, height - 60);              // radar merkezi alt ortada / radar centre at the bottom middle
25  drawGrid();
26  drawSweep();
27  drawObject();
28  drawLabels();
29}
30
31void drawGrid() {
32  noFill();
33  strokeWeight(2);
34  stroke(98, 245, 31);
35  for (int i = 1; i <= 4; i++) {
36    float d = 2 * R * i / 4;
37    arc(0, 0, d, d, PI, TWO_PI);                  // 25-50-75-100 cm yayları / 25-50-75-100 cm arcs
38  }
39  for (int a = 0; a <= 180; a += 30) {
40    line(0, 0, R * cos(radians(a)), -R * sin(radians(a)));   // 30 derecelik çizgiler / 30-degree lines
41  }
42}
43
44void drawSweep() {
45  strokeWeight(5);
46  stroke(30, 250, 60);
47  line(0, 0, R * cos(radians(angle)), -R * sin(radians(angle)));   // tarama çizgisi / sweep line
48}
49
50void drawObject() {
51  if (distance <= 0 || distance > MAX_CM) return;  // menzil dışı / out of range
52  float p = R * distance / MAX_CM;                 // cm → piksel / cm → pixels
53  float c = cos(radians(angle));
54  float s = sin(radians(angle));
55  strokeWeight(7);
56  stroke(255, 10, 10);
57  line(p * c, -p * s, R * c, -R * s);              // nesneden dışa kırmızı çizgi / red line from the object outwards
58}
59
60void drawLabels() {
61  resetMatrix();
62  noStroke();
63  fill(0);
64  rect(0, height - 40, width, 40);                 // yazı şeridi / text strip
65  fill(98, 245, 31);
66  textSize(20);
67  for (int i = 1; i <= 4; i++) {
68    text(MAX_CM * i / 4 + " cm", width / 2 + R * i / 4 + 4, height - 66);   // yay etiketleri / arc labels
69  }
70  String d = (distance > 0 && distance <= MAX_CM) ? distance + " cm" : "-";
71  text("Açı / Angle: " + angle + "°", 40, height - 12);
72  text("Mesafe / Distance: " + d, width / 2, height - 12);
73}
74
75void serialEvent(Serial p) {
76  String msg = p.readStringUntil('\n');            // "açı,mesafe" satırı / "angle,distance" line
77  if (msg == null) return;
78  String[] parts = split(trim(msg), ',');
79  if (parts.length == 2) {
80    angle = int(parts[0]);
81    distance = int(parts[1]);
82  }
83}

La parte più importante del codice è la funzione serialEvent(). Grazie a bufferUntil('\n'), Processing accumula i dati in arrivo finché non arriva un fine riga e poi chiama automaticamente questa funzione con una riga completa. La riga viene ripulita dagli spazi e dal carattere \r con trim(), divisa in due alla virgola con split() e convertita in numeri con int(). draw(), invece, viene eseguita circa 60 volte al secondo: prima dipinge sullo schermo un rettangolo nero semitrasparente (fill(0, 12)), poi ridisegna la griglia, la linea di scansione e l'oggetto. Dato che le linee vecchie si scuriscono un po' a ogni fotogramma, l'effetto scia che svanisce, tipico dei radar veri, nasce da solo.

ImpostazioneDove?A cosa serve?
MAX_CM = 100ProcessingLa distanza massima coperta dallo schermo; l'arco esterno vale 100 cm, quelli interni indicano 25, 50 e 75 cm.
Serial.list()[0]ProcessingSceglie la prima porta seriale del computer; se il tuo Arduino è più in basso nell'elenco, cambia l'indice o scrivi direttamente il nome, per esempio "COM4".
9600EntrambiVelocità in baud; il valore di Serial.begin su Arduino e quello in Processing devono coincidere.
fill(0, 12)ProcessingVelocità di dissolvenza; 5 dà una scia lunga, 30 un'immagine quasi senza scia.
size(1200, 700)ProcessingDimensione della finestra; riducila se non entra nel tuo schermo. Il raggio dipende dalla larghezza, quindi tieni l'altezza superiore a metà della larghezza.

Regolare la velocità del servo e la durata della scansione

Secondo il datasheet, l'SG90 ruota di 60 gradi in 0,1 secondi a 4,8 V, quindi completa un passo di 2 gradi in pochi millisecondi. A determinare davvero la durata della scansione non è il servo, ma l'attesa e la misura a ogni passo. Quando il servo si ferma, squadretta e sensore oscillano per un attimo; se misuri in quel momento, le distanze saltano. Inoltre il produttore dell'HC-SR04 consiglia di lasciare circa 60 ms tra due misure, perché gli echi dell'impulso precedente che rimbalzano nella stanza possono finire nella misura successiva. In pratica, un totale di 50–60 ms per passo (attesa + misura) è un buon compromesso. Una scansione completa dura circa (180 / passo + 1) × durata di un passo.

PassoSTEP_DELAYUna scansione (0→180°)Risultato
1°20 mscirca 7 sImmagine più fluida ma lenta; lo stesso oggetto viene misurato molte volte.
2°40 mscirca 5 sImpostazione consigliata: fluida e stabile.
3°50 mscirca 4 sPiù veloce; grazie al fascio di 15° del sensore nessun oggetto sfugge.
5°70 mscirca 3,5 sLo schermo appare a scatti; con passi grandi le oscillazioni aumentano e l'attesa deve essere più lunga.

Per un movimento più morbido, tieni il passo piccolo e l'attesa breve; se vuoi velocità, aumenta il passo e allunga un po' l'attesa. Limitare la scansione alla zona che ti interessa (per esempio 45–135°) dimezza anche il tempo. Se il servo dà strattoni da solo, Arduino ogni tanto si riavvia e Processing perde la connessione, il problema non è la velocità ma l'alimentazione: l'SG90 può assorbire circa 100–250 mA in movimento e fino a 600 mA sotto sforzo. Aggiungi il condensatore e, se serve, alimenta il servo con un alimentatore esterno da 5 V con GND in comune con Arduino.

Migliorare la precisione delle misure

Anche se sulla carta l'HC-SR04 promette una risoluzione di 3 mm, in un radar la precisione dipende da tre fattori: larghezza del fascio, velocità del suono e tipo di superficie. Il fascio sonoro del sensore si allarga come un cono di circa 15 gradi. Per questo una penna sottile a 50 cm non appare sullo schermo come un punto, ma come un arco di 15–20 gradi; la risoluzione angolare del radar la decide questo fascio, non il passo del servo, e la direzione reale dell'oggetto è al centro dell'arco. La velocità del suono cambia con la temperatura e si calcola con v = 331,3 + 0,606 × T (m/s, T in °C). Il numero 58 nel codice corrisponde a circa 22 °C; in un garage freddo le misure risultano più lunghe di qualche punto percentuale.

TemperaturaVelocità del suonoAndata e ritorno per 1 cmOggetto a 100 cm (con /58)
0 °C331,3 m/s60,4 µscirca 104 cm
10 °C337,4 m/s59,3 µscirca 102 cm
20 °C343,4 m/s58,2 µscirca 100 cm
30 °C349,5 m/s57,2 µscirca 99 cm
40 °C355,5 m/s56,3 µscirca 97 cm

Puoi misurare la temperatura ambiente con un DHT11 o un DS18B20 e tenere conto della velocità del suono, e scartare le letture sbagliate isolate prendendo la mediana di tre misure. Ti basta aggiungere le due funzioni qui sotto al codice principale e sostituire la chiamata a measureCm() dentro loop() con una delle due. Dato che il filtro a mediana fa tre misure a ogni passo, rallenta un po' la scansione.

Arduino (C++)
1// Ana radar koduna eklenecek fonksiyonlar / functions to add to the main radar sketch
2
3// Sıcaklığa göre düzeltilmiş ölçüm / temperature-compensated reading
4int measureCmTemp(float tempC) {
5  digitalWrite(TRIG_PIN, LOW);
6  delayMicroseconds(2);
7  digitalWrite(TRIG_PIN, HIGH);
8  delayMicroseconds(10);
9  digitalWrite(TRIG_PIN, LOW);
10  unsigned long us = pulseIn(ECHO_PIN, HIGH, 30000UL);
11  if (us == 0) return 0;                                // yankı yok / no echo
12  float v = 331.3 + 0.606 * tempC;                      // ses hızı (m/s) / speed of sound (m/s)
13  return (int)(us * v / 20000.0 + 0.5);                 // µs × (m/s) / 20000 = cm
14}
15
16// Üç ölçümün ortancası: tek seferlik sıçramaları atar / median of three: drops one-off spikes
17int medianCm() {
18  int a = measureCm(); delay(20);
19  int b = measureCm(); delay(20);
20  int c = measureCm();
21  return max(min(a, b), min(max(a, b), c));
22}
23
24// loop() içinde kullanım / use inside loop():
25// int distance = medianCm();
26// int distance = measureCmTemp(18.5);                  // sıcaklık DHT11'den gelebilir / temperature can come from a DHT11
  • Le superfici morbide (tende, tessuti, spugna) assorbono il suono; un oggetto potrebbe non comparire dove si trova.
  • Le superfici inclinate deviano il suono; una scatola piatta ruotata di oltre 45° rispetto al sensore può essere letta come spazio vuoto.
  • Gli oggetti a meno di 2 cm non si possono misurare; in pratica considera poco affidabile ogni valore sotto i 3–4 cm.
  • Gli angoli della stanza creano riflessioni multiple e possono generare "fantasmi" lontani che non esistono; fai le prove in uno spazio libero e ampio.
  • Portata: il datasheet indica 400 cm, ma con oggetti piccoli le misure stabili arrivano di solito a circa 2 metri; scegli MAX_CM di conseguenza.

Mini radar su display OLED (senza computer)

Se vuoi che il radar diventi un dispositivo portatile a batteria che non dipende dal computer, puoi usare un display OLED da 0,96 pollici al posto di Processing. Il punto centrale del bordo inferiore dello schermo 128×64 con driver SSD1306 diventa il centro del radar; ci vengono disegnati un semicerchio con raggio di 60 pixel, la linea di scansione e dei punti che mostrano l'ultimo oggetto misurato a ogni angolo. Per il collegamento del display (SDA → A4, SCL → A5) e l'installazione delle librerie, consulta la guida display OLED SSD1306; HC-SR04 e servo si collegano come sopra.

Display OLED I2C da 0,96 pollici SSD1306
Display OLED da 0,96 pollici: nel mini radar senza computer diventa uno schermo di scansione semicircolare da 128×64 pixel.
Arduino (C++)
1#include <Wire.h>
2#include <Adafruit_GFX.h>
3#include <Adafruit_SSD1306.h>
4#include <Servo.h>
5
6const byte SERVO_PIN = 9;                 // SG90 sinyal / SG90 signal
7const byte TRIG_PIN  = 10;                // HC-SR04 Trig
8const byte ECHO_PIN  = 11;                // HC-SR04 Echo
9const int  MAX_CM    = 50;                // ekrandaki en uzak mesafe / farthest distance on screen
10const int  STEP      = 3;                 // adım başına derece / degrees per step
11const int  CX = 64, CY = 63, R = 60;      // radar merkezi ve yarıçapı (piksel) / radar centre and radius (px)
12
13Adafruit_SSD1306 display(128, 64, &Wire, -1);
14Servo radarServo;
15uint8_t dist[180 / STEP + 1];             // her açının son ölçümü (cm) / last reading per angle (cm)
16int angle = 0;
17int dir = STEP;
18
19int measureCm() {
20  digitalWrite(TRIG_PIN, LOW);
21  delayMicroseconds(2);
22  digitalWrite(TRIG_PIN, HIGH);
23  delayMicroseconds(10);
24  digitalWrite(TRIG_PIN, LOW);
25  unsigned long us = pulseIn(ECHO_PIN, HIGH, 30000UL);
26  if (us == 0) return 0;                  // yankı yok / no echo
27  return us / 58;
28}
29
30void setup() {
31  pinMode(TRIG_PIN, OUTPUT);
32  pinMode(ECHO_PIN, INPUT);
33  radarServo.attach(SERVO_PIN);
34  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
35    for (;;);                             // ekran bulunamadı / display not found
36  }
37  display.setTextColor(SSD1306_WHITE);
38}
39
40void loop() {
41  radarServo.write(angle);
42  delay(20);                              // çizim de zaman aldığı için kısa / short, drawing takes time too
43  int d = measureCm();
44  dist[angle / STEP] = (d > 255) ? 255 : d;   // byte'a sığdır / fit into a byte
45
46  display.clearDisplay();
47  display.drawCircle(CX, CY, R, SSD1306_WHITE);       // dış yay, alt yarısı ekran dışında / outer arc, lower half off-screen
48  display.drawCircle(CX, CY, R / 2, SSD1306_WHITE);   // orta yay = MAX_CM / 2 / middle arc = MAX_CM / 2
49  for (int i = 0; i <= 180 / STEP; i++) {
50    if (dist[i] > 0 && dist[i] <= MAX_CM) {
51      float rad = radians(i * STEP);
52      int r = map(dist[i], 0, MAX_CM, 0, R);          // cm → piksel / cm → pixels
53      display.fillCircle(CX + r * cos(rad), CY - r * sin(rad), 1, SSD1306_WHITE);
54    }
55  }
56  float rad = radians(angle);
57  display.drawLine(CX, CY, CX + R * cos(rad), CY - R * sin(rad), SSD1306_WHITE);  // tarama çizgisi / sweep line
58  display.setCursor(0, 0);
59  display.print(angle);                   // açı / angle
60  display.setCursor(98, 0);
61  display.print(d);                       // mesafe / distance
62  display.print(F("cm"));
63  display.display();
64
65  if (angle + dir > 180 || angle + dir < 0) dir = -dir;   // uçta yön değiştir / reverse at the ends
66  angle += dir;
67}

In questa versione le distanze vengono salvate per angolo nell'array dist, così i punti restano sullo schermo anche dopo il passaggio della linea di scansione e vengono aggiornati al giro successivo. Il centro del cerchio si trova sul bordo inferiore del display, quindi la sua metà inferiore esce dallo schermo e la libreria non la disegna: resta un semicerchio pulito. Inviare un fotogramma al display richiede circa 25 ms con I2C a 400 kHz, perciò l'attesa è stata ridotta a 20 ms e il passo portato a 3 gradi; una scansione dura circa 4–5 secondi. Su uno schermo piccolo una scala di 50 cm è più leggibile, quindi MAX_CM vale 50. Metà dei 2 KB di memoria dell'Uno va al buffer del display, per questo è importante tenere l'array in byte (uint8_t).

Radar con ESP32

Sull'ESP32 la libreria Servo di Arduino non funziona; devi installare la libreria ESP32Servo dal Gestore librerie. Il resto del codice è quasi identico. Dato che l'ESP32 lavora a 3,3 V, non dimenticare il partitore di tensione sulla linea Echo dell'HC-SR04; l'impulso a 3,3 V sulla linea Trig, invece, basta a far scattare la maggior parte dei sensori. Questo codice usa 115200 baud, quindi cambia anche il 9600 nel codice Processing in 115200. Grazie al Wi-Fi dell'ESP32, in seguito potrai inviare i dati del radar a una pagina web sul telefono invece che al computer; se l'ESP32 è una novità per te, parti da Cos'è l'ESP32.

Arduino (C++)
1#include <ESP32Servo.h>                // Kütüphane Yöneticisi: ESP32Servo / Library Manager: ESP32Servo
2
3const int SERVO_PIN  = 13;             // SG90 sinyal / SG90 signal
4const int TRIG_PIN   = 26;             // HC-SR04 Trig
5const int ECHO_PIN   = 27;             // 1k/2k bölücüden / through the 1k/2k divider
6const int STEP       = 2;              // adım başına derece / degrees per step
7const int STEP_DELAY = 40;             // ölçümden önce bekleme (ms) / wait before measuring (ms)
8
9Servo radarServo;
10int angle = 0;
11int dir = STEP;
12
13int measureCm() {
14  digitalWrite(TRIG_PIN, LOW);
15  delayMicroseconds(2);
16  digitalWrite(TRIG_PIN, HIGH);
17  delayMicroseconds(10);
18  digitalWrite(TRIG_PIN, LOW);
19  unsigned long us = pulseIn(ECHO_PIN, HIGH, 30000UL);
20  if (us == 0) return 0;               // yankı yok / no echo
21  return us / 58;
22}
23
24void setup() {
25  Serial.begin(115200);                       // Processing'de de 115200 / 115200 in Processing too
26  pinMode(TRIG_PIN, OUTPUT);
27  pinMode(ECHO_PIN, INPUT);
28  radarServo.setPeriodHertz(50);              // standart servo 50 Hz / standard servo 50 Hz
29  radarServo.attach(SERVO_PIN, 500, 2400);    // SG90 darbe aralığı (µs) / SG90 pulse range (µs)
30  radarServo.write(angle);
31  delay(500);
32}
33
34void loop() {
35  radarServo.write(angle);
36  delay(STEP_DELAY);
37  int distance = measureCm();
38  Serial.printf("%d,%d\n", angle, distance);  // açı,mesafe / angle,distance
39  if (angle + dir > 180 || angle + dir < 0) dir = -dir;   // uçta yön değiştir / reverse at the ends
40  angle += dir;
41}

Radar con Raspberry Pi Pico e MicroPython

Sul Pico non serve una libreria apposita per il servo: basta impostare la larghezza dell'impulso di un segnale PWM a 50 Hz con duty_ns(). Il tempo dell'eco si misura con machine.time_pulse_us(), che in caso di timeout restituisce un numero negativo. Anche i pin del Pico lavorano a 3,3 V, quindi il partitore sulla linea Echo è obbligatorio. Salva il codice sul Pico come main.py con Thonny e poi chiudi Thonny; altrimenti la porta resta occupata e Processing non riesce a collegarsi. Poiché il Pico apre una porta seriale virtuale via USB, il valore dei baud in Processing non conta: lo stesso schermo radar funziona senza modifiche.

MicroPython
1from machine import Pin, PWM, time_pulse_us
2import time
3
4servo = PWM(Pin(15))                     # SG90 sinyal / SG90 signal
5servo.freq(50)                           # standart servo 50 Hz / standard servo 50 Hz
6trig = Pin(14, Pin.OUT)
7echo = Pin(13, Pin.IN)                   # bölücüden gelir / comes through the divider
8
9def set_angle(a):
10    # 0° = 500 µs, 180° = 2400 µs darbe / pulse
11    servo.duty_ns(500000 + a * 1900000 // 180)
12
13def measure_cm():
14    trig.value(0)
15    time.sleep_us(2)
16    trig.value(1)                        # 10 µs tetik / 10 µs trigger
17    time.sleep_us(10)
18    trig.value(0)
19    t = time_pulse_us(echo, 1, 30000)    # en çok 30 ms bekle / wait at most 30 ms
20    if t < 0:
21        return 0                         # yankı yok / no echo
22    return t // 58
23
24angle, step = 0, 2
25set_angle(angle)
26time.sleep_ms(500)
27
28while True:
29    set_angle(angle)
30    time.sleep_ms(40)                    # servo otursun / let the servo settle
31    print("{},{}".format(angle, measure_cm()))   # açı,mesafe / angle,distance
32    if angle + step > 180 or angle + step < 0:
33        step = -step                     # uçta yön değiştir / reverse at the ends
34    angle += step

Errori comuni e soluzioni

Sintomo o messaggio di erroreCausaSoluzione
Error opening serial port COM3: Port busyIl Monitor seriale o il Plotter seriale dell'IDE di Arduino, Thonny o una seconda finestra di Processing stanno occupando la porta.Chiudi il Monitor seriale e gli altri programmi e riavvia lo sketch di Processing; se serve, scollega e ricollega il cavo USB.
ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0Serial.list() è vuoto: la scheda non è collegata, il cavo è di sola ricarica o manca il driver CH340.Usa un cavo dati e installa il driver; se l'IDE di Arduino vede la porta, la vedrà anche Processing.
La finestra si apre ma la linea di scansione non si muoveÈ stata scelta la porta sbagliata (su Windows COM1 è spesso la prima dell'elenco) oppure i baud non coincidono.Trova la posizione di Arduino nell'elenco della console, cambia in Serial.list()[1] o simile e imposta gli stessi baud da entrambe le parti.
The package “processing.serial” does not exist. You might be missing a library.La libreria Serial non viene trovata; il pacchetto di installazione di Processing 4.4.8 ne era privo.Aggiorna Processing a una versione più recente oppure usa la 4.4.7, e controlla che la riga import sia scritta correttamente.
Error opening serial port /dev/ttyACM0: Permission deniedSu Linux il tuo utente non ha il permesso di accedere alla porta seriale.Aggiungi il tuo utente al gruppo dialout (sudo usermod -a -G dialout $USER), poi esci e rientra nella sessione.
Con Processing aperto lo sketch non si carica su ArduinoLa porta è occupata da Processing.Prima di caricare, ferma lo sketch di Processing con il pulsante Stop.
La distanza è sempre 0 o dà valori assurdiTrig ed Echo sono invertiti, il sensore non è alimentato o l'oggetto è fuori portata.Controlla i collegamenti con la tabella e prova prima con uno sketch semplice che misura solo la distanza.
Il servo vibra e Arduino si riavvia da soloLa porta USB non fornisce la corrente richiesta dal servo e la tensione cala.Aggiungi un condensatore da 470 µF o alimenta il servo con un alimentatore esterno da 5 V con GND in comune.
Destra e sinistra invertite sullo schermo radarIl servo o il sensore sono montati al contrario.In Processing scrivi angle = 180 - int(parts[0]); oppure togli la squadretta e rimontala girata.
Durante il debug rispetta quest'ordine: prima controlla le righe "angolo,distanza" nel Monitor seriale, poi chiudi il Monitor seriale e avvia Processing. Se i dati arrivano correttamente da Arduino, il problema è quasi sempre la scelta della porta o la velocità in baud.

Idee per sviluppare il progetto radar

  • Radar di sicurezza con allarme: quando un oggetto si avvicina a meno di 30 cm, fai suonare un buzzer e accendi un LED rosso; abbinalo alle idee di sistema di allarme con Arduino.
  • Robot che evita gli ostacoli: metti il radar sulla parte anteriore di un robot; quando si ferma, scansiona a destra e a sinistra e gira verso la direzione più libera. Dettagli in robot evita ostacoli.
  • Mappa della stanza: salva i dati della scansione su un modulo scheda SD e disegnali sul computer come nuvola di punti.
  • Radar wireless: invia le misure da un ESP32 via Wi-Fi a una pagina web sul telefono; con un web server ESP32 puoi disegnare in tempo reale.
  • Mappa più nitida: usa un sensore laser (ToF) a fascio stretto al posto dell'HC-SR04; trovi le alternative nel confronto tra sensori di distanza.
  • Bastone intelligente: costruisci un bastone che avvisa le persone non vedenti della presenza di ostacoli con un sensore di distanza e un motorino a vibrazione: progetto bastone intelligente.

Poiché unisce sensore di distanza, controllo del servo, comunicazione seriale e grafica sul computer in un unico progetto, il radar con Arduino è un ottimo passo successivo per chi inizia. Per consolidare le basi, dai un'occhiata anche alle guide sul sensore di distanza HC-SR04 e sul servomotore. Nell'app BlueGrays trovi, passo passo e con schemi elettrici e codice commentato, i progetti di misura della distanza con l'HC-SR04, sensore di parcheggio, uso del servomotore e robot che evita gli ostacoli.

Domande frequenti

Il radar con Arduino è un vero radar?

Tecnicamente no, è un sonar. I radar veri emettono onde radio, mentre questo progetto usa le onde sonore a 40 kHz dell'HC-SR04. Si chiama "radar con Arduino" perché il principio è lo stesso (emettere un'onda, misurare il tempo dell'eco e disegnarla con la sua direzione) e la schermata somiglia a quella di un radar.

Fino a che distanza rileva un radar con Arduino?

Secondo il datasheet l'HC-SR04 misura da 2 a 400 cm. Superfici grandi e piatte come una parete vengono rilevate fino a 3–4 metri, ma con oggetti come la gamba di una sedia o una persona la portata affidabile è in genere di 1,5–2 metri. Impostare MAX_CM nel codice Processing su questa portata dà l'immagine più chiara.

Quali componenti servono per un radar con Arduino?

Bastano un Arduino Uno o Nano, un sensore a ultrasuoni HC-SR04, un servo SG90, una breadboard, qualche cavetto jumper e un condensatore da 470 µF per il servo. Lo schermo radar lo disegna sul computer il programma gratuito Processing; per la versione senza computer si aggiunge un display OLED da 0,96 pollici.

Si può fare un radar con Arduino senza Processing?

Sì. Con un display OLED SSD1306 puoi disegnare il radar direttamente su Arduino e trasformarlo in un dispositivo portatile a batteria. Anche senza display puoi seguire angolo e distanza come grafico nel Plotter seriale dell'IDE di Arduino.

Come si risolve l'errore "Port busy" in Processing?

Questo errore indica che un altro programma sta usando la porta seriale. Chiudi il Monitor seriale e il Plotter seriale dell'IDE di Arduino, Thonny o qualsiasi altro sketch di Processing rimasto aperto e riprova. Se il problema persiste, scollega il cavo USB e ricollegalo.

Perché il servo vibra e Arduino si riavvia?

L'SG90 assorbe picchi di corrente quando si muove e la linea a 5 V di un Arduino alimentato via USB cala per un istante. Un condensatore da 470 µF sull'alimentazione del servo di solito risolve; altrimenti alimenta il servo con un alimentatore esterno da 5 V con GND in comune con Arduino.

Vedi tutti i progetti
HC-SR04 Misura della distanza (display seriale)
#27Principiante

HC-SR04 Misura della distanza (display seriale)

Il sensore HC-SR04 funziona come un pipistrello che trova la strada al buio: manda un suono che non puoi sentire, ne ascolta l'eco e misura quanto è lontano l'oggetto davanti a sé. L'Arduino scrive qu

4.6(45)
68
Utilizzo del servomotore
#35Principiante
Premium

Utilizzo del servomotore

Il braccio di un piccolo servomotore ruota a turno in tre posizioni: tutto all'inizio, esattamente a metà e tutto alla fine, aspettando due secondi a ogni fermata. L'Arduino dice al motore a quale ang

4.7(48)
67
SG90 Servocomando angolare con potenziometro
#99Principiante
Premium

SG90 Servocomando angolare con potenziometro

Controllo del servomotore (SG90) con il potenziometro L'obiettivo principale di questo progetto è controllare con precisione la posizione angolare di un servomotore in tempo reale utilizzando un'unità di ingresso analogica, il potenziometro. Il progetto è un esempio di ingegneria di base per comprendere la logica della conversione analogico-digitale (ADC) e la mappatura dei segnali. Logica di funzionamento: Lettura dei dati analogici: Quando l'utente ruota il potenziometro, un segnale di tensio

4.5(24)
38
Sensore di parcheggio con HC-SR04
#28Intermedio
Premium

Sensore di parcheggio con HC-SR04

Una versione in miniatura del sensore di parcheggio delle auto: più qualcosa si avvicina, più i bip accelerano. Il sensore di distanza misura l'oggetto davanti a sé; se è a più di 20 centimetri resta

4.8(64)
84
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
ESP32 HC-SR04 Misuratore di distanza a ultrasuoni
#116Intermedio

ESP32 HC-SR04 Misuratore di distanza a ultrasuoni

Il sensore a ultrasuoni HC-SR04 calcola la distanza misurando il tempo di volo (Time of Flight) dell'onda sonora che emette dopo aver colpito un oggetto e essere rimbalzata indietro. In questo progetto invieremo un impulso di 10 microsecondi dall'ESP32 al pin TRIG del sensore e leggeremo il tempo di eco proveniente dal pin ECHO con `pulseIn()`. Visualizziamo la distanza calcolata in cm su un display LCD I2C 16x2. Poiché l'HC-SR04 funziona a 5V, è necessario un **divisore di tensione** sul pin EC

4.9(28)
44
Sensore di parcheggio ESP32 (HC-SR04 + barra a 5 LED + cicalino + OLED)
#142Avanzato
Premium

Sensore di parcheggio ESP32 (HC-SR04 + barra a 5 LED + cicalino + OLED)

La versione ESP32 del sensore di parcheggio per auto! Grazie al sensore a ultrasuoni HC-SR04 misuriamo la distanza dall'oggetto davanti al veicolo. Man mano che la distanza diminuisce, la barra composta da 5 LED si riempie (da verde → giallo → rosso) e l'intervallo tra i bip del cicalino si accorcia. Quando ci si avvicina troppo (meno di 10 cm), l'allarme suona ininterrottamente e tutti i LED si accendono. Sul display OLED SSD1306 vengono visualizzati in caratteri grandi il valore istantaneo in

0.0(0)
14
Misurazione della distanza tramite display LCD
#31Avanzato
Premium

Misurazione della distanza tramite display LCD

Uno strumento che misura le distanze senza righello: muovi la mano avanti e indietro davanti al sensore e guarda il numero cambiare. L'HC-SR04 manda un'onda sonora e ascolta l'eco, e l'Arduino calcola

4.6(45)
59