Projeto de radar com Arduino: guia com HC-SR04, servo SG90 e Processing
Projeto de radar com Arduino passo a passo: ligação do HC-SR04 e do servo SG90, código de ângulo e distância, tela de radar verde no Processing, minirradar em OLED e soluções comuns.
Um radar com Arduino é um projeto que monta um sensor de distância ultrassônico HC-SR04 sobre um servo motor SG90, faz o sensor varrer entre 0 e 180 graus para medir a direção e a distância dos objetos próximos e mostra o resultado no computador em uma tela de radar verde, de filme. A cada ângulo, o Arduino faz uma leitura e envia uma linha “ângulo,distância” pela porta serial; um pequeno programa em Processing rodando no computador lê esses números e desenha a linha de varredura girando e os objetos detectados como linhas vermelhas.
Neste guia você encontra cada passo explicado, da lista de peças e do esquema de ligação ao código do Arduino e à tela de radar no Processing. Também mostramos um minirradar em display OLED que não precisa de computador, versões para ESP32 e Raspberry Pi Pico, como ajustar a velocidade da varredura e a precisão das medições e como resolver os erros de porta serial mais comuns. Ele é barato, dá para terminar em uma tarde e é um dos projetos com Arduino que mais chamam a atenção nas apresentações escolares.




Como funciona um radar com Arduino?
O coração do sistema é o HC-SR04. Um dos dois cilindros do sensor (T) emite uma rajada curta de som de 40 kHz que os humanos não ouvem; quando o som bate em um objeto e volta, o outro (R) capta o eco. O Arduino mede esse tempo de ida e volta em microssegundos. O som viaja no ar a cerca de 343 m/s, então precisa de uns 29 microssegundos para percorrer um centímetro; como o caminho é feito duas vezes, ida e volta, a fórmula fica distância (cm) = tempo (µs) / 58. O servo gira o sensor passo a passo e a medição se repete a cada passo. O resultado é “algo neste ângulo, a tantos centímetros”, ou seja, uma coordenada polar. Para desenhar na tela, ângulo e distância são convertidos em uma posição de pixel com x = distância × cos(ângulo) e y = distância × sen(ângulo).
| Peça | Função | Valores principais |
|---|---|---|
| HC-SR04 | Medição de distância por ultrassom | 40 kHz, 2–400 cm, ângulo de medição de cerca de 15°, 5 V, 15 mA |
| Servo SG90 | Gira o sensor de 0–180° | 0,1 s/60° (4,8 V), torque de 1,8 kg·cm, 4,8–6 V, 9 g |
| Arduino Uno | Mede, aciona o servo, envia os dados | 16 MHz, nível lógico de 5 V, porta serial USB |
| Processing | Desenha a tela de radar no computador | Grátis, baseado em Java, biblioteca Serial incluída |
| OLED SSD1306 (opcional) | Minitela de radar sem computador | 128×64 pixels, I2C, endereço 0x3C |
Lista de peças do radar com Arduino
- Arduino Uno ou Nano e um cabo USB que transmita dados (cabos só de carga não aparecem como porta no computador).
- Sensor de distância ultrassônico HC-SR04.
- Microsservo SG90 e os braços plásticos que vêm no saquinho dele.
- Uma protoboard e 8–10 jumpers macho-macho e macho-fêmea.
- Um capacitor eletrolítico de 470 µF (de pelo menos 10 V): ele impede que a tensão de alimentação caia quando o servo se move.
- Fita dupla face, cola quente ou um pequeno suporte impresso em 3D para prender o sensor no servo.
- Opcional: um display OLED I2C de 0,96 polegada (para a versão sem computador) e uma fonte externa de 5 V 2 A.
Esquema de ligação do radar com Arduino
| Ligação | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| VCC do HC-SR04 | 5V | VIN (5 V) | VBUS (pino 40) |
| GND do HC-SR04 | GND | GND | GND |
| Trig do HC-SR04 | D10 | GPIO 26 | GP14 |
| Echo do HC-SR04 | D11 | GPIO 27 (por divisor) | GP13 (por divisor) |
| SG90 marrom (GND) | GND | GND | GND |
| SG90 vermelho (+5 V) | 5V | VIN (5 V) | VBUS (pino 40) |
| SG90 laranja (sinal) | D9 | GPIO 13 | GP15 |
No Uno, a ligação fica mais organizada se você ligar os fios de 5 V e GND do sensor e do servo nos barramentos positivo e negativo da protoboard, e esses barramentos nos pinos 5V e GND do Arduino. Encaixe o capacitor de 470 µF nos mesmos barramentos, com a perna longa (+) no 5 V e a perna curta, marcada pela faixa no corpo, no GND. Em alguns servos os fios são preto, vermelho e branco; nesse caso, o preto é o GND e o branco é o sinal. Para conferir onde ficam os pinos da sua placa, use a ferramenta de pinagem.
Montando o sensor no servo

Antes de encaixar o braço, coloque o servo em 90 graus: basta carregar um sketch de teste curto com radarServo.write(90) e deixar o servo nessa posição. Depois encaixe o braço de modo que o sensor aponte bem para a frente. Assim, 0° aponta para a direita, 90° para a frente e 180° para a esquerda, e as direções na tela do Processing batem exatamente com o mundo real. Ao colar o HC-SR04 no braço com fita dupla face ou cola quente, garanta que os dois cilindros fiquem paralelos ao chão; se o sensor ficar inclinado para baixo, ele vai confundir a superfície da mesa com um objeto. Deixe folga nos fios para que não fiquem esticados durante o giro de 180 graus e prenda o servo a uma base pesada ou a uma caixa; um corpo que balança a cada passo estraga as leituras.
Montando o radar com Arduino passo a passo
- Ligue as peças conforme a tabela acima, não esqueça o capacitor e monte o sensor no servo.
- Abra o Arduino IDE; a biblioteca Servo vem com o IDE, então não há nada extra para instalar.
- Carregue o código do radar abaixo. Se tiver problemas para escolher a placa ou a porta, veja Arduino não carrega o código.
- Abra o Monitor Serial em 9600 baud; se linhas de ângulo e distância como “30,45” estiverem passando, o lado do Arduino está pronto. Depois, não deixe de fechar o Monitor Serial.
- Instale o Processing 4 no computador, abra um sketch novo e cole o código da tela de radar.
- Aperte Run (executar); a lista de portas aparece no console embaixo e a janela do radar se abre. Quando você mover a mão na frente do sensor, devem aparecer linhas vermelhas.
Código do radar com Arduino
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}Como o código funciona
| Parte do código | O que faz |
|---|---|
| STEP e STEP_DELAY | Definem quantos graus o servo gira por passo e quanto tempo esperar antes de medir; você ajusta a velocidade da varredura com essas duas constantes. |
| measureCm() | Envia um pulso de 10 µs ao pino Trig, usa o pulseIn para medir quanto tempo o pino Echo fica em HIGH e divide por 58 para obter centímetros. |
| pulseIn(..., 30000UL) | Espera no máximo 30 ms e retorna 0 se nenhum eco chegar. Sem esse timeout, a função poderia travar por até 1 segundo apontando para o vazio. |
| radarServo.write(angle) | Leva o servo ao ângulo pedido; a biblioteca transforma o valor de 0–180 em um pulso de 544–2400 µs. |
| Serial.print ... println | Envia cada leitura como uma única linha “ângulo,distância”; o fim de linha diz ao Processing “dado completo”. |
| dir = -dir | Inverte o sentido quando o ângulo chega a 180 ou 0, para o servo varrer para lá e para cá sem parar. |
Há um motivo para os dados serem tão simples: uma única linha separada por vírgula é fácil de ler no Monitor Serial e pode ser interpretada com uma linha de código no Processing, no Python ou no Excel. Uma distância 0 significa “nada no alcance neste ângulo”, e o Processing não desenha esses valores. Se você abrir os mesmos dados no Plotter Serial do Arduino IDE, verá o ângulo subir e descer como dente de serra e a distância saltar sempre que o sensor passa por um objeto. Usar delay não tem problema neste projeto; se quiser ler um botão ou acender um LED enquanto o radar funciona, reescreva o loop com millis().
A tela de radar verde no Processing
O Processing é um programa gratuito, baseado em Java, feito para programação visual, e a interface dele é muito parecida com a do Arduino IDE: você escreve o código e aperta Run. A biblioteca Serial, necessária para a comunicação serial, vem com o Processing; você pode adicioná-la pelo menu Sketch > Import Library ou simplesmente contar com a linha import no topo do código. O código abaixo vai no Processing, não no Arduino IDE.
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}A parte mais importante do código é a função serialEvent(). Graças ao bufferUntil('\n'), o Processing junta os dados que chegam até vir um fim de linha e então chama essa função automaticamente com uma linha completa. A linha é limpa de espaços e do caractere \r com trim(), dividida em duas na vírgula com split() e convertida em números com int(). Já o draw() roda cerca de 60 vezes por segundo: primeiro ele pinta um retângulo preto translúcido sobre a tela (fill(0, 12)), depois redesenha a grade, a linha de varredura e o objeto. Como as linhas antigas ficam um pouco mais escuras a cada quadro, o rastro que se apaga, visto nas telas de radar de verdade, aparece sozinho.
| Configuração | Onde? | O que faz |
|---|---|---|
| MAX_CM = 100 | Processing | A maior distância que a tela cobre; o arco externo é de 100 cm e os arcos internos mostram 25, 50 e 75 cm. |
| Serial.list()[0] | Processing | Escolhe a primeira porta serial do computador; se o seu Arduino estiver mais abaixo na lista, mude o índice ou digite o nome direto, como “COM4”. |
| 9600 | Nos dois | Baud rate; o valor do Serial.begin do Arduino e o do Processing precisam ser iguais. |
| fill(0, 12) | Processing | Velocidade do apagamento; 5 dá um rastro longo, 30 uma imagem quase sem rastro. |
| size(1200, 700) | Processing | Tamanho da janela; diminua se não couber na sua tela. O raio acompanha a largura, então mantenha a altura acima da metade da largura. |
Ajustando a velocidade do servo e o tempo de varredura
Segundo o datasheet, o SG90 gira 60 graus em 0,1 segundo a 4,8 V, então termina um passo de 2 graus em poucos milissegundos. O que define de fato o tempo de varredura não é o servo, mas o tempo de espera e de medição em cada passo. Depois que o servo para, o braço e o sensor balançam por um instante; medir nesse momento faz as distâncias pularem. O fabricante do HC-SR04 também recomenda deixar cerca de 60 ms entre duas medições, porque ecos do pulso anterior rebatendo pela sala podem vazar para a próxima leitura. Na prática, um total de 50–60 ms por passo (espera + medição) é um bom equilíbrio. Uma varredura completa leva mais ou menos (180 / passo + 1) × tempo do passo.
| Passo | STEP_DELAY | Uma varredura (0→180°) | Resultado |
|---|---|---|---|
| 1° | 20 ms | cerca de 7 s | Imagem mais suave, mas lenta; o mesmo objeto é medido muitas vezes. |
| 2° | 40 ms | cerca de 5 s | Configuração recomendada: suave e estável. |
| 3° | 50 ms | cerca de 4 s | Mais rápida; graças ao feixe de 15° do sensor, nenhum objeto escapa. |
| 5° | 70 ms | cerca de 3,5 s | A tela parece aos trancos; passos maiores causam mais balanço, então a espera precisa ser maior. |
Para suavizar o movimento, mantenha o passo pequeno e a espera curta; se quiser velocidade, aumente o passo e alongue um pouco a espera. Limitar a varredura à área que interessa (por exemplo, 45–135°) também corta o tempo pela metade. Se o servo der trancos sozinho, o Arduino reiniciar de vez em quando e o Processing perder a conexão, o problema não é a velocidade, e sim a alimentação: o SG90 pode puxar cerca de 100–250 mA em movimento e até 600 mA com carga. Acrescente o capacitor e, se precisar, alimente o servo com uma fonte externa de 5 V que divida o GND com o Arduino.
Melhorando a precisão das medições
Embora o HC-SR04 prometa no papel uma resolução de 3 mm, três coisas decidem a precisão de um radar: a largura do feixe, a velocidade do som e o tipo de superfície. O feixe sonoro do sensor se abre como um cone de cerca de 15 graus. Por isso, uma caneta fina a 50 cm aparece na tela não como um ponto, mas como um arco de 15–20 graus de largura; a resolução angular do radar é definida por esse feixe, não pelo passo do servo, e a direção real do objeto é o meio do arco. A velocidade do som muda com a temperatura e é calculada com v = 331,3 + 0,606 × T (m/s, T em °C). O número 58 do código corresponde a cerca de 22 °C; em uma garagem fria, as leituras saem alguns por cento longas demais.
| Temperatura | Velocidade do som | Ida e volta por 1 cm | Objeto a 100 cm (com /58) |
|---|---|---|---|
| 0 °C | 331,3 m/s | 60,4 µs | cerca de 104 cm |
| 10 °C | 337,4 m/s | 59,3 µs | cerca de 102 cm |
| 20 °C | 343,4 m/s | 58,2 µs | cerca de 100 cm |
| 30 °C | 349,5 m/s | 57,2 µs | cerca de 99 cm |
| 40 °C | 355,5 m/s | 56,3 µs | cerca de 97 cm |
Você pode medir a temperatura do ambiente com um DHT11 ou um DS18B20 e levar a velocidade do som em conta, e pode descartar leituras ruins isoladas tirando a mediana de três. Basta acrescentar as duas funções abaixo ao código principal e trocar a chamada measureCm() no loop() por uma delas. Como o filtro de mediana faz três leituras por passo, ele deixa a varredura um pouco mais lenta.
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- Superfícies macias (cortinas, tecido, espuma) absorvem o som; um objeto pode não aparecer onde está.
- Superfícies inclinadas refletem o som para outro lado; uma caixa plana virada mais de 45° em relação ao sensor pode ser lida como espaço vazio.
- Objetos a menos de 2 cm não podem ser medidos; na prática, considere pouco confiável qualquer coisa abaixo de 3–4 cm.
- Cantos da sala causam reflexões múltiplas e podem criar “fantasmas” distantes que não existem; teste em uma área vazia e aberta.
- Alcance: o datasheet diz 400 cm, mas as leituras estáveis de objetos pequenos normalmente chegam a cerca de 2 metros; escolha o MAX_CM de acordo.
Minirradar em display OLED (sem computador)
Se você quer que o radar seja um aparelho portátil, alimentado por bateria e que não precise de computador, pode usar um display OLED de 0,96 polegada no lugar do Processing. O centro da parte de baixo da tela SSD1306 de 128×64 vira o centro do radar; sobre ela são desenhados um semicírculo com raio de 60 pixels, a linha de varredura e pontos mostrando o último objeto medido em cada ângulo. Para a ligação do display (SDA → A4, SCL → A5) e a instalação da biblioteca, veja o guia display OLED de 0,96 polegada (SSD1306); o HC-SR04 e o servo são ligados igual ao que está acima.

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}Nesta versão, as distâncias são guardadas por ângulo no array dist, então os pontos continuam na tela depois que a linha de varredura passa e são atualizados na próxima passagem. O centro do círculo fica na borda de baixo da tela, então a metade de baixo dele cai fora do display e a biblioteca não a desenha, deixando um semicírculo certinho. Enviar um quadro para a tela leva cerca de 25 ms com I2C a 400 kHz, então a espera foi reduzida para 20 ms e o passo aumentado para 3 graus; uma varredura leva cerca de 4–5 segundos. Uma escala de 50 cm é mais fácil de ler em uma tela pequena, então o MAX_CM foi definido como 50. Metade dos 2 KB de memória do Uno vai para o buffer do display, e é por isso que importa manter o array em bytes (uint8_t).
Radar com ESP32
A biblioteca Servo do Arduino não funciona no ESP32; instale no lugar dela a biblioteca ESP32Servo pelo Gerenciador de Bibliotecas. O resto do código é quase igual. Como o ESP32 trabalha em 3,3 V, não esqueça o divisor de tensão na linha Echo do HC-SR04; já o pulso de 3,3 V na linha Trig basta para disparar a maioria dos sensores. Este código usa 115200 baud, então mude também o 9600 do código do Processing para 115200. Graças ao Wi-Fi do ESP32, mais tarde você poderia enviar os dados do radar para uma página web no celular em vez de um computador; se está começando com o ESP32, comece por O que é o ESP32.
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 com Raspberry Pi Pico e MicroPython
No Pico você não precisa de uma biblioteca de servo separada: ajustar a largura do pulso de um sinal PWM de 50 Hz com duty_ns() basta. O tempo do eco é medido com machine.time_pulse_us(), que retorna um número negativo no timeout. Os pinos do Pico também são de 3,3 V, então o divisor na linha Echo é obrigatório. Salve o código no Pico como main.py com o Thonny e depois feche o Thonny; senão a porta continua ocupada e o Processing não consegue se conectar. Como o Pico abre uma porta serial virtual pela USB, o valor de baud no Processing não importa; a mesma tela de radar funciona sem nenhuma mudança.
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 += stepErros comuns e soluções
| Sintoma ou mensagem de erro | Causa | Solução |
|---|---|---|
| Error opening serial port COM3: Port busy (porta ocupada) | O Monitor Serial ou o Plotter Serial do Arduino IDE, o Thonny ou uma segunda janela do Processing está segurando a porta. | Feche o Monitor Serial e os outros programas e rode o sketch do Processing de novo; se precisar, desconecte e reconecte o cabo USB. |
| ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0 (lista de portas vazia) | O Serial.list() está vazio: a placa não está conectada, o cabo é só de carga ou o driver do CH340 não está instalado. | Use um cabo de dados e instale o driver; se o Arduino IDE enxerga a porta, o Processing também vai enxergar. |
| A janela abre, mas a linha de varredura não se move | A porta errada está selecionada (no Windows, a COM1 muitas vezes é a primeira da lista) ou os baud rates são diferentes. | Encontre a posição do Arduino na lista do console, mude para Serial.list()[1] ou algo parecido e use o mesmo baud rate dos dois lados. |
| The package “processing.serial” does not exist. You might be missing a library. (biblioteca Serial ausente) | A biblioteca Serial não é encontrada; o instalador do Processing 4.4.8 veio sem ela. | Atualize o Processing para uma versão mais nova ou use a 4.4.7, e confira se a linha import está digitada corretamente. |
| Error opening serial port /dev/ttyACM0: Permission denied (permissão negada) | No Linux, o seu usuário não tem permissão para acessar a porta serial. | Adicione o seu usuário ao grupo dialout (sudo usermod -a -G dialout $USER) e depois saia e entre de novo na sessão. |
| O código não carrega no Arduino com o Processing aberto | A porta está sendo usada pelo Processing. | Pare o sketch do Processing com o botão Stop antes de carregar. |
| A distância é sempre 0 ou sem sentido | Trig e Echo estão trocados, o sensor está sem alimentação ou o objeto está fora do alcance. | Confira a ligação com a tabela e teste primeiro com um sketch simples que só mede a distância. |
| O servo treme e o Arduino reinicia sozinho | A porta USB não fornece a corrente do servo e a tensão cai. | Acrescente um capacitor de 470 µF ou alimente o servo com uma fonte externa de 5 V com GND compartilhado. |
| Esquerda e direita estão trocadas na tela do radar | O servo ou o sensor está montado ao contrário. | No Processing, escreva angle = 180 - int(parts[0]); ou tire o braço e encaixe-o virado ao contrário. |
Ideias para levar o projeto de radar adiante
- Radar de segurança com alarme: quando um objeto chegar a menos de 30 cm, toque um buzzer e acenda um LED vermelho; combine com as ideias de sistema de alarme com Arduino.
- Robô que desvia de obstáculos: coloque o radar na frente de um robô; quando o robô para, ele varre para a esquerda e para a direita e vira para a direção mais livre. Detalhes em robô que desvia de obstáculos.
- Mapa do cômodo: grave os dados da varredura em um módulo de cartão SD e desenhe-os como uma nuvem de pontos no computador.
- Radar sem fio: envie as leituras de um ESP32 por Wi-Fi para uma página web no celular; com um servidor web no ESP32, dá para desenhar em tempo real.
- Mapa mais nítido: use um sensor a laser (ToF) de feixe estreito no lugar do HC-SR04; você encontra as opções na comparação de sensores de distância.
- Bengala inteligente: monte uma bengala que avisa pessoas com deficiência visual sobre obstáculos usando um sensor de distância e um motor de vibração: projeto de bengala inteligente.
Por reunir sensor de distância, controle de servo, comunicação serial e desenho de gráficos no computador em uma só montagem, o projeto de radar com Arduino é um ótimo próximo passo para iniciantes. Para reforçar o básico, dê uma olhada também nos guias sensor de distância HC-SR04 e servo motor. No app BlueGrays você encontra projetos passo a passo de medição de distância com HC-SR04, sensor de estacionamento, uso de servo motor e robô que desvia de obstáculos, cada um com esquemas do circuito e código comentado.
Perguntas frequentes
Um radar com Arduino é um radar de verdade?
Tecnicamente não, é um sonar. Radares de verdade emitem ondas de rádio, enquanto este projeto usa ondas sonoras de 40 kHz do HC-SR04. Ele é conhecido como “radar com Arduino” porque o princípio de funcionamento é o mesmo (emitir uma onda, medir o tempo do eco, desenhar com a direção) e a tela parece a de um radar.
A que distância um radar com Arduino consegue detectar?
O alcance do HC-SR04 segundo o datasheet é de 2–400 cm. Superfícies grandes e planas, como paredes, podem ser medidas até 3–4 metros, mas, para objetos como pés de cadeira ou pessoas, o alcance confiável costuma ser de 1,5–2 metros. Ajustar o MAX_CM do código do Processing para essa faixa dá a imagem mais clara.
Do que preciso para montar um radar com Arduino?
Bastam um Arduino Uno ou Nano, um sensor ultrassônico HC-SR04, um servo SG90, uma protoboard, alguns jumpers e um capacitor de 470 µF para o servo. O programa gratuito Processing desenha a tela do radar no computador; para uma versão sem computador, você acrescenta um display OLED de 0,96 polegada.
Dá para fazer um radar com Arduino sem o Processing?
Sim. Com um display OLED SSD1306, você pode desenhar o radar direto no Arduino e transformá-lo em um aparelho portátil alimentado por bateria. Mesmo sem display, dá para acompanhar os valores de ângulo e distância em gráfico no Plotter Serial do Arduino IDE.
Como resolvo o erro “Port busy” no Processing?
Esse erro significa que outro programa está usando a porta serial. Feche o Monitor Serial e o Plotter Serial do Arduino IDE, o Thonny ou qualquer outro sketch do Processing que tenha ficado aberto e tente de novo. Se continuar, desconecte o cabo USB e conecte de novo.
Por que o servo treme e o Arduino reinicia?
O SG90 puxa picos curtos de corrente alta quando se move, e a linha de 5 V de um Arduino alimentado pela USB cai por um instante. Um capacitor de 470 µF na alimentação do servo costuma resolver; se não resolver, alimente o servo com uma fonte externa de 5 V que divida o GND com o Arduino.
Projetos para montar depois desta leitura
Ver todos os projetos
Medição de distância com HC-SR04 (Monitor Serial)
O sensor HC-SR04 funciona como um morcego que se orienta no escuro: emite um som que você não consegue ouvir, escuta o eco e mede a distância até o objeto à sua frente. O Arduino escreve essa distânci

Uso de servo motor
O braço de um pequeno servo motor gira para três posições em sequência: o início, o meio e o fim do percurso, esperando dois segundos em cada parada. O Arduino informa ao motor em qual ângulo ficar, e

Sensor de estacionamento com HC-SR04
Uma versão em miniatura do sensor de estacionamento de um carro: quanto mais perto um objeto chega, mais rápidos ficam os bipes. O sensor de distância mede a distância até o objeto à sua frente; se el

Robô que desvia de obstáculos
Que tal construir um veículo inteligente que encontra seu próprio caminho? O robô que desvia de obstáculos monitora o ambiente constantemente com o sensor ultrassônico na parte da frente. Ao encontrar

Medidor ultrassônico de distância HC-SR04 com ESP32
O sensor ultrassônico HC-SR04 calcula a distância medindo o tempo que a onda sonora emitida leva para atingir um objeto e retornar (tempo de voo). Neste projeto, enviaremos um pulso de 10 microssegundos do ESP32 ao pino TRIG do sensor e leremos a duração do eco no pino ECHO com pulseIn(). Exibiremos a distância calculada em centímetros em um LCD I2C 16x2. Como o HC-SR04 opera a 5V, é preciso usar um divisor de tensão no pino ECHO; caso contrário, o GPIO de 3,3V do ESP32 será danificado.

Sensor de estacionamento com ESP32 (HC-SR04 + barra de 5 LEDs + buzzer + OLED)
A versão com ESP32 do sensor de estacionamento de carro! Usamos o sensor ultrassônico HC-SR04 para medir a distância até o objeto à sua frente. Conforme a distância diminui, a barra de 5 LEDs vai se preenchendo (verde → amarelo → vermelho) e o intervalo entre os bipes do buzzer diminui. Quando o objeto chega muito perto (menos de 10 cm), o alarme soa continuamente e todos os LEDs acendem.

Medição de distância com display LCD
Uma ferramenta que mede distâncias sem régua: aproxime e afaste a mão na frente do sensor e veja o número mudar. O HC-SR04 emite uma onda sonora e escuta seu eco, e o Arduino calcula a distância em ce
Mais artigos
App BlueGrays
Monte este circuito passo a passo pelo celular
Esquema do circuito, código e lista de componentes em uma só tela. Mais de 200 projetos com Arduino, ESP32 e Pico prontos para montar.
Escaneie com seu celular
Aponte a câmera para o código para abrir a loja de aplicativos do seu celular.
ou abrir a loja

