O que é UART? Guia de ligação TX/RX, baud rate e comunicação serial com Arduino
O que é UART e como funciona? Ligação cruzada TX/RX, baud rate, bits de início/parada, conexão entre dois Arduinos, SoftwareSerial, níveis de 5V/3,3V, Serial2 do ESP32 e UART do Pico.
A resposta curta para o que é UART: UART (Universal Asynchronous Receiver-Transmitter) é o hardware de comunicação serial que permite a dois dispositivos trocar dados byte a byte por apenas dois fios de dados (TX e RX) e um GND comum. Cada linha que você vê no Monitor Serial quando seu Arduino está conectado ao computador chega por UART. Dezenas de módulos, como receptores GPS, o módulo Bluetooth HC-05, o módulo Wi-Fi ESP-01, o módulo GSM SIM800L, leitores de impressão digital e tocadores de MP3, também se comunicam com o Arduino por UART.
Neste artigo, explicamos passo a passo por que UART não precisa de uma linha de clock, o que é baud rate, como um byte é enquadrado com bits de início, dados e parada, por que TX e RX se cruzam, como fazer dois Arduinos se comunicarem primeiro em uma direção e depois nas duas, os limites de SoftwareSerial, como conectar placas de 5 V e 3,3 V com segurança, as três UARTs do ESP32 e os pinos UART do Raspberry Pi Pico. Na última seção, você verá como montar pacotes com caracteres de início e fim para evitar que os dados se misturem, além dos erros mais comuns.

O que é UART e como funciona?
A palavra “assíncrono” no nome UART é a chave: em I2C e SPI, um sinal de clock é enviado junto com os dados, enquanto UART não tem linha de clock. Em vez disso, os dois lados combinam previamente uma velocidade, chamada baud rate. Em repouso, a linha fica em HIGH (1). Para enviar um byte, o transmissor leva a linha a LOW pelo tempo de um bit; esse é o bit de início, que diz ao receptor “comece a contar agora”. Em seguida vêm os 8 bits de dados, começando pelo bit menos significativo (LSB), podendo haver depois um bit de paridade opcional; por fim, a linha fica em HIGH por pelo menos o tempo de um bit; esse é o bit de parada. A configuração padrão do Arduino é 8N1: 8 bits de dados, sem paridade, 1 bit de parada.
| Bit | Início | D0 | D1 | D2 | D3 | D4 | D5 | D6 | D7 | Parada |
|---|---|---|---|---|---|---|---|---|---|---|
| Letra 'A' (0x41 = 0100 0001) | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
| Nível da linha | LOW | HIGH | LOW | LOW | LOW | LOW | LOW | HIGH | LOW | HIGH |
Cada bit dura 1 / baud segundo. Em 9600 baud, um bit leva 104,2 microssegundos; como um quadro 8N1 tem 10 bits por byte (início + 8 dados + parada), é possível enviar no máximo 960 bytes por segundo. Depois de detectar a borda de descida do bit de início, o receptor amostra a linha no meio de cada bit. Mesmo que os dois clocks sejam um pouco diferentes, os dados são lidos corretamente desde que o erro acumulado em 10 bits fique abaixo de meio bit; por isso, o erro total de baud deve ficar abaixo de aproximadamente 2–3%. Com seu cristal de 16 MHz, o Arduino Uno não consegue produzir exatamente 115200 baud, e a taxa real tem um desvio de cerca de 2,1%; ainda assim funciona porque está dentro do limite.
| Baud | Tempo de um bit | Máximo de bytes por segundo (8N1) | Onde é usado |
|---|---|---|---|
| 9600 | 104,2 µs | 960 | GPS NEO-6M, modo de dados do HC-05, DFPlayer Mini, configuração clássica do Monitor Serial |
| 19200 | 52,1 µs | 1920 | Alguns sensores e modems antigos |
| 38400 | 26,0 µs | 3840 | Modo de comandos AT do HC-05 |
| 57600 | 17,4 µs | 5760 | Bootloaders antigos do Arduino, limite superior de SoftwareSerial |
| 115200 | 8,68 µs | 11520 | ESP32 e ESP-01, saída rápida de depuração |
| 1.000.000 ou mais | 1 µs ou menos | 100.000+ | Conexões curtas entre placas, registro rápido de dados |
UART vs I2C vs SPI
Os três métodos de comunicação serial mais comuns no Arduino são UART, I2C e SPI. UART funciona apenas ponto a ponto entre dois dispositivos, e os dois lados podem falar quando quiserem (full duplex). I2C reúne dezenas de dispositivos nos mesmos dois fios usando endereços; SPI é muito mais rápido com quatro fios, mas precisa de um pino de seleção separado para cada dispositivo. Para mais detalhes, veja os artigos O que é I2C e O que é SPI.
| Característica | UART | I2C | SPI |
|---|---|---|---|
| Fios | 2 (TX, RX) + GND | 2 (SDA, SCL) + GND | 4 (SCK, MOSI, MISO, CS) + GND |
| Linha de clock | Nenhuma (assíncrona) | Sim | Sim |
| Número de dispositivos | 2 (ponto a ponto) | Até 127, por endereço | Tantos quanto os pinos CS |
| Velocidade típica | 9600–115200 baud | 100–400 kHz | 1–80 MHz |
| Nas duas direções ao mesmo tempo | Sim (full duplex) | Não | Sim |
| Módulos típicos | GPS, Bluetooth, GSM, ESP-01, impressão digital | OLED, LCD, RTC, BME280 | Cartão SD, RFID, TFT, LoRa |
Ligação cruzada de TX e RX e GND comum
A regra de ouro da ligação UART: o pino TX (transmissão) de um dispositivo se conecta ao pino RX (recepção) do outro, ou seja, os fios se cruzam. Pense em boca e ouvido: onde um fala, o outro deve escutar. Se você conectar TX a TX, duas saídas ficam ligadas entre si e nenhum dado passa. O terceiro fio, GND, dá às duas placas a mesma referência de tensão; sem ele, “HIGH” e “LOW” perdem o significado e os dados recebidos viram caracteres estranhos. Mesmo que as placas sejam alimentadas por fontes separadas, seus terras devem estar conectados.
| Arduino A | Fio | Arduino B | Observação |
|---|---|---|---|
| TX (D11, SoftwareSerial) | → | RX (D10, SoftwareSerial) | O que A envia vai para B |
| RX (D10, SoftwareSerial) | ← | TX (D11, SoftwareSerial) | A resposta de B chega a A |
| GND | — | GND | GND comum, obrigatório |
| 5V | opcional | 5V | Apenas se só uma placa estiver alimentada por USB |
Comunicação entre dois Arduinos: uma direção

No primeiro exemplo, a placa A envia o valor de um potenciômetro em A0 para a placa B dez vezes por segundo, e a placa B ajusta o brilho do LED em D9 de acordo com esse valor. As duas placas usam SoftwareSerial em D10 (RX) e D11 (TX), mantendo livres a conexão USB e o Monitor Serial. Como os valores são enviados com println(), cada número termina com os caracteres “\r\n” (final de linha); o receptor sabe que o número está completo quando os vê. Ligação: D11 de A ao D10 de B, D10 de A ao D11 de B e os terras unidos.
1#include <SoftwareSerial.h>
2
3SoftwareSerial link(10, 11); // RX = 10, TX = 11 (diğer karta / to the other board)
4
5void setup() {
6 Serial.begin(9600); // USB: bilgisayar / computer
7 link.begin(9600); // iki tarafta aynı baud / same baud on both sides
8}
9
10void loop() {
11 int deger = analogRead(A0); // potansiyometre 0-1023 / potentiometer 0-1023
12 link.println(deger); // ör. "512\r\n" / e.g. "512\r\n"
13 Serial.println(deger);
14 delay(100); // saniyede 10 ölçüm / 10 readings per second
15}
161#include <SoftwareSerial.h>
2
3SoftwareSerial link(10, 11); // RX = 10, TX = 11
4const int LED_PIN = 9; // PWM pini / PWM pin
5
6char tampon[8]; // en fazla 7 karakter + '\0' / up to 7 chars + '\0'
7byte konum = 0;
8
9void setup() {
10 Serial.begin(9600);
11 link.begin(9600);
12 pinMode(LED_PIN, OUTPUT);
13}
14
15void loop() {
16 while (link.available()) { // gelen her baytı oku / read every incoming byte
17 char c = link.read();
18 if (c == '\n') { // satır bitti / line complete
19 tampon[konum] = '\0';
20 int deger = atoi(tampon);
21 analogWrite(LED_PIN, map(deger, 0, 1023, 0, 255));
22 Serial.println(deger);
23 konum = 0;
24 } else if (c != '\r' && konum < sizeof(tampon) - 1) {
25 tampon[konum++] = c; // satıra ekle / append to the line
26 }
27 }
28}
29Há duas coisas a observar no código do receptor. Primeiro, os dados nunca chegam “de uma vez”: “512” chega como três bytes separados, com cerca de 1 milissegundo entre eles. Por isso, acumulamos os bytes em um buffer e os convertemos em número quando chega o final de linha. Segundo, o código nunca fica esperando: funções como readString() ou parseInt() esperam 1 segundo por padrão quando nenhum dado chega e deixam o programa lento. Ler os bytes conforme chegam é a abordagem mais confiável e rápida. Também limitamos o tamanho do buffer para que dados corrompidos não sejam escritos além do fim do array.
Comunicação bidirecional: comando e resposta
Projetos reais geralmente precisam de uma conversa nas duas direções: uma placa envia um comando, a outra o executa e responde. No exemplo abaixo, a placa A funciona como uma ponte: encaminha para B cada caractere que você digita no Monitor Serial e imprime cada caractere recebido de B. A placa B entende os comandos “LED ON”, “LED OFF” e “DURUM?” (estado), responde a cada um e também informa por conta própria quando o botão em D2 é pressionado. Não se esqueça de definir o final de linha do Monitor Serial como Nova linha; B usa esse caractere para saber que o comando terminou.
1#include <SoftwareSerial.h>
2
3SoftwareSerial link(10, 11); // RX = 10, TX = 11
4
5void setup() {
6 Serial.begin(9600);
7 link.begin(9600);
8 Serial.println("Komut yaz / type a command: LED ON, LED OFF, DURUM?");
9}
10
11void loop() {
12 if (Serial.available()) link.write(Serial.read()); // bilgisayar -> B kartı / computer -> board B
13 if (link.available()) Serial.write(link.read()); // B kartı -> bilgisayar / board B -> computer
14}
151#include <SoftwareSerial.h>
2
3SoftwareSerial link(10, 11); // RX = 10, TX = 11
4const int LED_PIN = 13; // kart üstündeki LED / on-board LED
5const int BUTON_PIN = 2; // buton GND'ye / button to GND
6
7String satir = "";
8int oncekiButon = HIGH;
9
10void komutCalistir(String k) {
11 k.trim(); // \r ve boşlukları at / strip \r and spaces
12 if (k == "LED ON") {
13 digitalWrite(LED_PIN, HIGH);
14 link.println("OK LED=1");
15 } else if (k == "LED OFF") {
16 digitalWrite(LED_PIN, LOW);
17 link.println("OK LED=0");
18 } else if (k == "DURUM?") { // durum sorgusu / status query
19 link.print("LED=");
20 link.print(digitalRead(LED_PIN));
21 link.print(" BUTON=");
22 link.println(digitalRead(BUTON_PIN) == LOW ? 1 : 0);
23 } else {
24 link.print("HATA / unknown: ");
25 link.println(k);
26 }
27}
28
29void setup() {
30 link.begin(9600);
31 pinMode(LED_PIN, OUTPUT);
32 pinMode(BUTON_PIN, INPUT_PULLUP);
33 satir.reserve(32);
34}
35
36void loop() {
37 while (link.available()) {
38 char c = link.read();
39 if (c == '\n') {
40 komutCalistir(satir);
41 satir = "";
42 } else if (satir.length() < 31) {
43 satir += c;
44 }
45 }
46
47 int buton = digitalRead(BUTON_PIN); // değişince kendiliğinden bildir / report changes unprompted
48 if (buton != oncekiButon) {
49 oncekiButon = buton;
50 link.println(buton == LOW ? "BUTON BASILDI / pressed" : "BUTON BIRAKILDI / released");
51 delay(20); // basit debounce / simple debounce
52 }
53}
54A chamada trim() na placa B remove o caractere \r que chega quando o Monitor Serial está configurado como “Ambos, NL e CR”, além dos espaços extras, para que os comandos sejam reconhecidos com qualquer uma das configurações. Usar reserve(32) no objeto String evita que a memória seja realocada toda vez que um caractere é acrescentado e reduz a fragmentação dos 2 KB de RAM do Uno. Essa estrutura também é a base para conversar com o Arduino a partir de um programa Python no computador; veja os detalhes no artigo Comunicação serial entre Arduino e Python.
Os limites de SoftwareSerial
SoftwareSerial imita uma UART por software em vez de hardware: o próprio processador controla o tempo de cada bit. Isso é muito útil, mas tem um custo. Durante a transmissão, as interrupções ficam desativadas por todo o tempo de cada byte; em 9600 baud, isso dá cerca de 1 milissegundo por byte, período em que millis() pode acumular desvio, os pulsos do servo podem variar e dados que chegam por outra porta serial podem ser perdidos. Apenas uma porta SoftwareSerial pode escutar por vez; se abrir uma segunda, você precisa escolher qual escuta com listen(). Em placas como Mega e Leonardo, só determinados pinos com suporte a interrupções podem ser usados como RX.
| Característica | UART de hardware (Serial) | SoftwareSerial | AltSoftSerial |
|---|---|---|---|
| Pinos no Uno | D0 (RX), D1 (TX), compartilhados com USB | Quase qualquer pino (PCINT para RX) | Fixos: D8 (RX), D9 (TX) |
| Maior velocidade confiável | 1–2 Mbaud | 57600 baud (115200 fica no limite) | Estável em velocidades moderadas (9600–38400) |
| Carga da CPU | Muito baixa (buffer de hardware) | Alta, interrupções desativadas ao enviar | Média, usa Timer1 |
| Enviar e receber ao mesmo tempo | Sim | Não | Sim |
| Mais de uma porta | 4 no Mega | Só uma escuta por vez | Porta única |
| Conflitos | Carregamento e Monitor Serial | Bibliotecas sensíveis à temporização, como Servo e NeoPixel | PWM em D10 e Servo (Timer1) |
Adequação dos níveis de 5V e 3,3V
Em UART, o nível “HIGH” é a tensão de operação da placa: 5 V no Arduino Uno, 3,3 V no ESP32, Raspberry Pi Pico, ESP-01 e na maioria dos módulos mais novos. Conectar uma saída TX de 5 V diretamente a uma entrada RX de 3,3 V expõe a entrada a uma sobretensão e danifica o pino com o tempo ou imediatamente; o ESP32 e o Pico baseado no RP2040 não toleram 5 V. Na outra direção, geralmente não há problema: o Uno considera 3,0 V ou mais como HIGH, então pode ler um TX de 3,3 V, mas, como isso fica perto do limite, um conversor de nível lógico é mais robusto com fios longos.
| Conexão | O que você precisa | Exemplo |
|---|---|---|
| Uno TX (5 V) → ESP32 / Pico RX (3,3 V) | Divisor de tensão ou conversor de nível lógico | 1 kΩ em série + 2 kΩ para GND: 5 × 2/3 ≈ 3,3 V |
| ESP32 / Pico TX (3,3 V) → Uno RX (5 V) | Geralmente direta | O Uno considera acima de 3,0 V como HIGH |
| Uno TX → HC-05 RX | Divisor de tensão recomendado | O RX do HC-05 é uma entrada com nível de 3,3 V |
| Uno TX → SIM800L RX | Divisor de tensão | O nível do sinal do SIM800L é de cerca de 2,8 V |
| Ambas as placas de 5 V ou ambas de 3,3 V | Direta | Uno ↔ Nano, ESP32 ↔ Pico |
UART do ESP32: Serial, Serial1 e Serial2
O ESP32 tem três UARTs de hardware, e a melhor parte é que, graças à sua matriz de GPIO, os pinos UART podem ser movidos para quase qualquer pino que você quiser. UART0 (Serial) está conectada ao chip USB-serial e é usada para o Monitor Serial. UART2 (Serial2) fica por padrão nos GPIO 16 (RX) e 17 (TX). Os antigos pinos padrão de UART1 (GPIO 9 e 10) estão conectados à memória flash da placa e não podem ser usados diretamente, então sempre inicialize Serial1 informando os pinos: begin(baud, SERIAL_8N1, RX, TX). O código abaixo monta uma ponte bidirecional entre o Monitor Serial e um dispositivo na UART2 (um GPS, outro Arduino, um sensor); é ideal para acompanhar as sentenças NMEA de um módulo GPS.
| UART | Nome no Arduino | RX / TX padrão | Observação |
|---|---|---|---|
| UART0 | Serial | GPIO 3 / GPIO 1 | Conectada ao chip USB-serial, carregamento e Monitor Serial |
| UART1 | Serial1 | GPIO 9 / GPIO 10 (flash, não use) | Informe outros pinos em begin(), por exemplo, 25 / 26 |
| UART2 | Serial2 | GPIO 16 / GPIO 17 | Nas placas WROVER, 16/17 são usados pela PSRAM; escolha outros pinos |
1// ESP32: UART0 = Serial (USB), UART2 = Serial2 (GPIO 16/17)
2const int RXD2 = 16; // karşı cihazın TX'i buraya / the other device's TX goes here
3const int TXD2 = 17; // karşı cihazın RX'ine / to the other device's RX
4
5void setup() {
6 Serial.begin(115200); // USB Seri Monitör / USB Serial Monitor
7 Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2); // baud, çerçeve, RX, TX / baud, frame, RX, TX
8 // UART1'i de istediğin pinlere taşıyabilirsin / UART1 can be moved to any free pins:
9 // Serial1.begin(115200, SERIAL_8N1, 25, 26);
10 Serial.println("UART2 hazir / ready");
11}
12
13void loop() {
14 while (Serial2.available()) Serial.write(Serial2.read()); // UART2 -> USB
15 while (Serial.available()) Serial2.write(Serial.read()); // USB -> UART2
16}
17As UARTs do ESP32 podem chegar a 5 Mbaud e cada uma tem um buffer de hardware; o buffer de recepção padrão tem 256 bytes e pode ser ampliado antes de begin() com uma chamada como Serial2.setRxBufferSize(1024). Isso importa para módulos GPS que enviam dezenas de sentenças por segundo ou módulos GSM com respostas longas. Como os pinos do ESP32 são de 3,3 V, não se esqueça do divisor da seção anterior ao conectar um Arduino de 5 V. Você pode ver a pinagem do ESP32 na ferramenta Pinagem.
Pinos UART do Raspberry Pi Pico e MicroPython
O Raspberry Pi Pico tem duas UARTs de hardware (uart0 e uart1), e cada uma pode ser direcionada a vários pares de pinos diferentes. No MicroPython, o REPL e a saída de print() chegam por uma porta serial virtual separada no USB, então UART0 fica completamente livre; não é preciso desconectar fios ao carregar o código, como no Arduino. Os pinos do Pico são de 3,3 V e, no Pico baseado no RP2040, não toleram 5 V. O código abaixo faz no Pico o que a placa B fazia no Arduino: lê linhas de UART0, liga ou desliga o LED integrado com os comandos “LED ON” e “LED OFF” e responde. Se quiser que ele converse com o sketch de ponte do Uno, não se esqueça de um divisor de tensão na linha TX do Uno.
| UART | Pinos TX | Pinos RX | Exemplo em MicroPython |
|---|---|---|---|
| uart0 | GP0, GP12, GP16 | GP1, GP13, GP17 | UART(0, 9600, tx=Pin(0), rx=Pin(1)) |
| uart1 | GP4, GP8 | GP5, GP9 | UART(1, 9600, tx=Pin(4), rx=Pin(5)) |
1from machine import UART, Pin
2import time
3
4uart = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1)) # UART0: GP0 = TX, GP1 = RX
5led = Pin("LED", Pin.OUT) # Pico ve Pico W dahili LED / on-board LED
6
7tampon = b""
8while True:
9 if uart.any():
10 tampon += uart.read() # gelen baytlar / incoming bytes
11 while b"\n" in tampon: # her tam satırı işle / handle each full line
12 satir, tampon = tampon.split(b"\n", 1)
13 try:
14 komut = satir.decode().strip()
15 except UnicodeError:
16 continue # bozuk bayt: atla / corrupt byte: skip
17 if komut == "LED ON":
18 led.on()
19 uart.write("OK LED=1\n")
20 elif komut == "LED OFF":
21 led.off()
22 uart.write("OK LED=0\n")
23 else:
24 uart.write("HATA / unknown: " + komut + "\n")
25 if len(tampon) > 64: # satır sonu hiç gelmezse taşmayı önle / avoid overflow
26 tampon = b""
27 time.sleep_ms(5)
28Enquadramento de pacotes: caracteres de início e fim
UART é um fluxo de bytes; não sabe onde algo começa ou termina. Quando o transmissor escreve “23.5,48,812”, o receptor pode ter começado a escutar no meio, um byte pode ter se perdido por ruído ou duas leituras podem se juntar. A solução é transformar os dados em um pacote: se cada pacote começa com “<” e termina com “>”, o receptor ignora tudo até o primeiro “<”, processa o pacote quando chega “>” e descarta os pacotes incompletos que aparecem no meio. O transmissor só precisa imprimir os valores entre Serial.print('<'), vírgulas e Serial.print('>'). Você pode testar imediatamente o código do receptor abaixo digitando <23.5,48,812> no Monitor Serial.
1// Paket biçimi / packet format: <sicaklik,nem,isik> ör. / e.g. <23.5,48,812>
2const byte MAKS = 32;
3char tampon[MAKS];
4byte konum = 0;
5bool paketIcinde = false; // '<' görüldü mü? / have we seen '<'?
6
7void paketiIsle(char* p) {
8 char* parca = strtok(p, ","); // ilk alan / first field
9 if (!parca) return;
10 float sicaklik = atof(parca);
11 parca = strtok(NULL, ",");
12 if (!parca) return; // eksik alan: paketi at / missing field: drop
13 int nem = atoi(parca);
14 parca = strtok(NULL, ",");
15 if (!parca) return;
16 int isik = atoi(parca);
17
18 Serial.print("Sicaklik / temp: ");
19 Serial.print(sicaklik, 1);
20 Serial.print(" Nem / humidity: ");
21 Serial.print(nem);
22 Serial.print(" Isik / light: ");
23 Serial.println(isik);
24}
25
26void setup() {
27 Serial.begin(9600); // Seri Monitör'den <23.5,48,812> yazarak dene / test from the Serial Monitor
28}
29
30void loop() {
31 while (Serial.available()) {
32 char c = Serial.read();
33 if (c == '<') { // yeni paket başladı / a new packet starts
34 paketIcinde = true;
35 konum = 0;
36 } else if (c == '>' && paketIcinde) { // paket bitti / packet complete
37 tampon[konum] = '\0';
38 paketIcinde = false;
39 paketiIsle(tampon);
40 } else if (paketIcinde) {
41 if (konum < MAKS - 1) tampon[konum++] = c;
42 else paketIcinde = false; // çok uzun, bozuk: at / too long, corrupt: drop
43 } // paket dışındaki baytlar yok sayılır / bytes outside packets are ignored
44 }
45}
46| Método | Exemplo | Vantagens | Desvantagens |
|---|---|---|---|
| Texto com final de linha | 512\n | Mais simples, legível no Monitor Serial | No meio de uma linha, não dá para saber onde ela começa |
| Caracteres de início e fim | <23.5,48,812> | Recupera-se sozinho após perder a sincronização | Não permite usar < e > nos dados |
| Texto com soma de verificação (como NMEA) | $GPGGA,...*47 | Pacotes corrompidos são detectados | Um pouco mais de cálculo e código |
| Pacote binário | 0xAA, comprimento, dados, CRC | Mais curto e rápido | Difícil de ler e depurar |
Em ambientes com ruído ou com fios longos, você pode ir além e acrescentar uma soma de verificação ao pacote. O formato NMEA usado pelos módulos GPS é um bom exemplo: todos os caracteres entre “$” e “*” passam por uma operação XOR entre si, e o resultado é escrito no final como um número hexadecimal de dois dígitos. O receptor faz o mesmo cálculo e descarta o pacote se o resultado não coincidir. Isso protege contra erros discretos, como um “812” corrompido ser processado como “872”.
Ideias de projetos com UART
- Controle pelo celular: o módulo Bluetooth HC-05 é, na verdade, uma UART sem fio; controle um LED, um relé ou um carrinho robô pelo celular com o HC-05.
- Registro de posição GPS: analise as sentenças NMEA que um módulo GPS NEO-6M envia por UART e grave a posição em um cartão SD.
- Sistema com duas placas: conecte por UART um Uno que lê os sensores a um ESP32 que envia os dados para a internet por Wi-Fi.
- Alarme por SMS: envie comandos AT a um módulo SIM800L por UART e mande um SMS para você quando uma porta abrir.
- Painel de controle no computador: envie comandos para o Arduino a partir de um app para computador escrito em Python e exiba os dados dos sensores em gráficos.
- Tocador de MP3: escolha faixas, ajuste o volume e reproduza alertas de voz por UART com um DFPlayer Mini.
Erros comuns e soluções
| Sintoma | Causa provável | Solução |
|---|---|---|
| Caracteres estranhos no Monitor Serial | Os baud rates não coincidem | Use o mesmo baud rate no código e no Monitor Serial |
| Nenhum dado recebido | TX ligado a TX, RX a RX | Cruze os fios: TX → RX, RX → TX |
| Caracteres corrompidos aleatórios | GND não conectado | Conecte os terras das duas placas |
| Falha no carregamento (not in sync) | Há um módulo conectado a D0/D1 | Desconecte os fios durante o carregamento ou use SoftwareSerial |
| Os comandos não são reconhecidos | O final de linha é \r\n ou está ausente | Configure o Monitor Serial como Nova linha e limpe o texto com trim() |
| O final de mensagens longas desaparece | O buffer de 64 bytes transbordou | Evite delay(), leia os dados conforme chegam e reduza a velocidade |
| O pino RX do ESP32 não funciona ou está danificado | TX de 5 V conectado diretamente | Acrescente um divisor de tensão ou conversor de nível lógico |
| SoftwareSerial falha em 115200 | A temporização por software não consegue acompanhar | Use 57600 ou menos ou mude para uma UART de hardware |
UART é o primeiro método de comunicação a aprender em eletrônica: bastam dois fios, um GND comum e o mesmo baud rate, e, quando configurado corretamente, funciona por anos sem problemas. Depois de dominar a ligação cruzada, a adequação de níveis e o enquadramento de pacotes, você poderá usar com facilidade dezenas de módulos, de GPS a GSM. No app BlueGrays, você encontra projetos passo a passo com esquemas do circuito e código para comunicação unidirecional e bidirecional entre dois Arduinos, acendimento de um LED pelo celular via Bluetooth e um carrinho controlado por Bluetooth.
Perguntas frequentes
O que significa UART e para que serve?
UART significa Universal Asynchronous Receiver-Transmitter, ou receptor-transmissor assíncrono universal. Permite que dois dispositivos troquem dados byte a byte sem uma linha de clock, usando apenas os fios TX e RX e um baud rate combinado previamente. O Monitor Serial do Arduino e os módulos GPS, Bluetooth e GSM usam UART.
Como conectar TX e RX?
O pino TX de um dispositivo vai para o RX do outro, e seu RX vai para o TX do outro, formando uma ligação cruzada. Os pinos GND dos dois dispositivos também devem estar conectados. Ligar TX a TX bloqueia completamente os dados.
O que é baud rate e qual devo escolher?
Baud rate é o número de bits enviados por segundo e deve ser igual nos dois lados. Os valores mais comuns nos módulos usados com Arduino são 9600 e 115200; 9600 é o padrão na maioria dos módulos GPS e Bluetooth, enquanto 115200 é preferido para ESP32 e saídas rápidas. Comece com a velocidade padrão indicada na documentação do módulo.
UART é a mesma coisa que porta serial?
No uso cotidiano, os termos costumam ter o mesmo sentido. UART é a unidade de hardware que serializa os dados; porta serial é a conexão COM ou /dev/tty de um computador. RS-232 e RS-485 são padrões que usam níveis de tensão diferentes para transportar sinais UART por distâncias maiores.
Como usar mais de uma UART em um Arduino?
O Uno tem uma única UART de hardware compartilhada com USB; para portas extras, você usa SoftwareSerial, mas apenas uma pode escutar por vez. O Arduino Mega tem três UARTs de hardware extras (Serial1, Serial2 e Serial3), o ESP32 tem três no total e o Raspberry Pi Pico tem duas.
Qual pode ser o comprimento de um cabo UART?
UART em nível TTL de 3,3 V ou 5 V funciona de forma confiável por até alguns metros em baud rates baixos, e a distância diminui conforme a velocidade aumenta. Para distâncias maiores, transceptores RS-485 (como o MAX485) alcançam centenas de metros, e RS-232, cerca de 15 metros.
Projetos para montar depois desta leitura
Ver todos os projetos
Comunicação unidirecional entre 2 Arduinos
Faça dois Arduinos conversarem por um único fio: ao pressionar o botão de um, o LED do outro acende; ao pressionar de novo, ele apaga. A placa transmissora informa que o botão foi pressionado com uma

Comunicação bidirecional entre 2 Arduinos
Dois Arduinos se conectam por fios e conversam entre si: ao pressionar o botão de um, a luz do outro acende; ao pressionar novamente, ela apaga. As duas placas executam o mesmo programa, então ambas e

Controle de LED pelo celular via Bluetooth
Um pequeno ensaio para acender e apagar as luzes do seu quarto pelo celular. O módulo Bluetooth repassa ao Arduino as letras enviadas pelo celular; uma letra acende o LED vermelho, outra acende o verd

Carrinho controlado por Bluetooth com L298N
Transforme seu celular em um controle remoto e dirija seu próprio carrinho robô. O Arduino recebe os comandos de um aplicativo de controle remoto no celular por meio de um módulo Bluetooth e aciona as

Teclado para programar em Python
Se você se cansou de digitar os mesmos padrões várias vezes ao programar, este pequeno teclado é para você. O Arduino Leonardo se conecta ao computador como um teclado, e cada tecla do teclado matrici

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

Temperatura e umidade com DHT11
Qual é a temperatura do seu quarto? O ar está úmido ou seco? O sensor DHT11 mede a temperatura e a umidade, e o Arduino mostra os valores em um display LCD de duas linhas, atualizando a cada poucos se

Leitura da intensidade da luz com módulo LDR e ESP32
Acompanhe em tempo real no Monitor Serial o valor bruto do ADC do módulo LDR e a porcentagem relativa de luz calculada a partir de referências de escuridão e claridade. Essa porcentagem não é uma medida em lux. O projeto ensina a lógica de calibração do módulo. É ideal fazê-lo antes do projeto 10, pois ajuda a determinar o valor do limiar.
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

