
Passo 1 de 8
O caminho da comunicação e as conexões seguras
Reconheça como a comunicação do monitor serial chega ao Uno R3 e quais conexões UART são eletricamente seguras.
Trilha de aprendizado · Nível 11 · Tutorial 2
Ao concluir, o aluno será capaz de trocar valores e comandos de um caractere entre seu Uno R3 e o monitor serial local, reconhecendo o enquadramento UART e os cuidados elétricos da conexão.
O caminho da comunicação e as conexões seguras
Reconheça como a comunicação do monitor serial chega ao Uno R3 e quais conexões UART são eletricamente seguras. 2 min
Quadros 8N1 e tempo de transmissão
Entenda o enquadramento 8N1 e estime o tempo nominal de transmissão de bytes em uma UART. 3 min
Preparação do monitor serial local
2 min
Envio de valores como texto
Exiba valores do programa no monitor serial usando linhas textuais legíveis. 3 min
Caracteres e comandos de um byte
Use `char` e literais de caractere para definir comandos de um byte, distinguindo `'1'` do valor numérico `1`. 2 min
Recepção sem esperar por dados
Receba comandos de um caractere do monitor serial sem interromper o contador periódico. 3 min
Buffers finitos e ritmo de comunicação
Entenda os limites das filas de transmissão e recepção para manter o monitor serial útil sem comprometer o loop. 2 min
Aplicação final: valores e comandos no Uno
Integre contador periódico e comandos de um caractere no monitor serial do Uno R3, verificando configuração, tempo 8N1 e cuidados de conexão. 4 min

Passo 1 de 8
Reconheça como a comunicação do monitor serial chega ao Uno R3 e quais conexões UART são eletricamente seguras.
UART é uma comunicação serial assíncrona: os dispositivos trocam bits sem uma linha de clock compartilhada. Cada lado tem uma linha para transmitir (TX) e outra para receber (RX). Para que a conversa funcione, transmissor e receptor precisam estar configurados de modo compatível — esse formato será detalhado no próximo passo.

Em uma ligação UART entre dispositivos compatíveis, TX vai ao RX do outro lado, RX vai ao TX e os dois compartilham GND.
Os sinais UART do Uno R3 usam níveis lógicos de 5 V. Antes de ligar outro dispositivo aos pinos seriais, confirme que ele aceita esses níveis e que haverá uma referência de terra comum.
Não basta o conector “parecer compatível”: tensão, função de cada pino e referência elétrica precisam ser compatíveis.
Atenção
Não conecte uma porta RS-232 diretamente aos GPIOs do Uno.
Embora RS-232 também transmita dados em série, sua interface elétrica usa tensões e polaridades diferentes da UART lógica de 5 V. Ela exige um circuito transceptor apropriado, que não será montado nesta prática.

UART descreve a troca serial; a compatibilidade elétrica da interface ainda precisa ser verificada.
Nesta prática, o computador conversa com o ATmega328P por este caminho:
Monitor serial local → USB → ponte USB-UART da placa → UART do ATmega328P
O cabo USB não é ligado diretamente aos sinais TX e RX do microcontrolador. A ponte presente no Uno converte a comunicação USB do computador para a UART lógica usada pelo ATmega328P.

A ponte USB-UART da própria placa permite usar o monitor serial sem uma ligação externa nos pinos seriais.
Atenção
No Uno R3, essa UART também está ligada aos pinos D0/RX e D1/TX. Durante todo este tutorial, use somente o cabo USB e deixe D0 e D1 sem dispositivos externos.
Se precisar alterar conexões nesses pinos em outra prática, desligue a placa antes. Assim, você evita conflitos com a ponte USB-UART e reduz o risco de conexões inadequadas.
Associe cada elemento à sua função ou conexão correta.
Faça as associações corretas.
Toque em um item e depois no par correspondente.

Passo 2 de 8
Entenda o enquadramento 8N1 e estime o tempo nominal de transmissão de bytes em uma UART.
Cada byte na UART é enviado dentro de um quadro. Como não há clock compartilhado, a linha fica em repouso no nível alto e o receptor usa a transição para baixo do início para se sincronizar.
Um quadro pode ter: bit de início, bits de dados, paridade opcional e um ou mais bits de parada. As duas pontas precisam usar a mesma configuração para interpretar corretamente os mesmos instantes e bits.
Observe a sequência temporal: repouso alto, início baixo, oito intervalos de dados e parada alta.

O início baixo marca o começo do quadro; a parada alta encerra a transmissão.
A notação 8N1 resume a configuração mais comum:
Há ainda 1 bit de início. Portanto, um byte em 8N1 ocupa 10 bits na linha: 1 + 8 + 1. A paridade é um campo possível em outras configurações, mas não existe em 8N1.
Exemplo
Se uma ponta usar 8N1 e a outra esperar, por exemplo, outro número de bits de parada, a interpretação pode falhar. Para esta UART binária, a taxa indicada em baud é igual à taxa de bits por segundo.
Se a taxa for R bit/s:
Esses valores descrevem os bits efetivamente transmitidos; não incluem pausas causadas pelo programa, USB ou monitor serial.
Exemplo
Exemplo: em 9600 bit/s, cada bit dura aproximadamente:
1 / 9600 s = 0,0001042 s = 104,2 µs
Um quadro 8N1 dura dez vezes isso:
10 / 9600 s ≈ 1,04 ms por byte
Para N bytes consecutivos, estime:
T = 10 × N / R
Se forem 12 bytes a 9600 bit/s: T = 10 × 12 / 9600 s = 0,0125 s, ou 12,5 ms.
Complete a expressão para o tempo nominal de transmissão de N bytes consecutivos em UART 8N1, à taxa de R bit/s:
T = {{lacuna}}
T =
Coloque os campos de um quadro 8N1 na ordem em que atravessam a linha. Considere o byte já pronto para ser transmitido.
Ordene os campos do quadro 8N1.

Passo 3 de 8
Para esta prática, use apenas seu Uno R3, um cabo USB de dados, um computador e a IDE Arduino já preparada. Não conecte sensores, adaptadores nem outros dispositivos aos pinos D0/RX e D1/TX.
O cabo USB já estabelece o caminho entre o computador e a UART do microcontrolador por meio da ponte USB-UART da placa. Portanto, não é preciso montar fios de UART externos.

Nesta prática, o cabo USB já cria o caminho entre o monitor serial e a UART do Uno.
Dica
Mantenha D0/RX e D1/TX livres durante esta prática. Caso precise alterar uma conexão externa nesses pinos em outra atividade, desligue a placa antes de conectar ou remover fios.
No setup(), inicialize a comunicação com Serial.begin(9600);. O valor 9600 é a taxa de 9600 bit/s escolhida para esta prática.
No Uno R3, Serial.begin(9600) usa a configuração padrão 8N1: 8 bits de dados, nenhuma paridade e 1 bit de parada. O monitor serial precisa usar uma taxa correspondente para interpretar a comunicação corretamente.
Grave este sketch mínimo no Uno R3. Em seguida, abra o monitor serial configurado em 9600 baud: a área de saída permanecerá vazia.
void setup() {
Serial.begin(9600);
}
void loop() {
}
(nenhuma saída no monitor serial)
O monitor vazio é o resultado esperado: `Serial.begin()` configura a UART, mas não transmite bytes. A transmissão de texto será apresentada no próximo step.
Dica
A inicialização não escreve uma mensagem automática. Portanto, um monitor vazio com esse sketch não demonstra, por si só, um erro de configuração.
Depois de gravar o sketch, abra o Monitor Serial na IDE. Selecione a porta que corresponde ao Uno R3 e ajuste a taxa para 9600 baud, igual ao valor usado em Serial.begin(9600).
No seletor de término de linha, escolha Sem final de linha. Mais adiante, você enviará comandos de um caractere; essa opção evita que o monitor acrescente bytes extras a cada envio.

A taxa do monitor deve coincidir com a taxa definida no sketch; use Sem final de linha para os futuros comandos de um caractere.
Preencha a chamada que inicializa a UART na taxa usada nesta prática.
void setup() {
(9600);
}
void loop() {
}
O sketch contém apenas Serial.begin(9600);, foi gravado com sucesso e o monitor está em 9600 baud, mas permanece vazio. Qual interpretação é correta?

Passo 4 de 8
Exiba valores do programa no monitor serial usando linhas textuais legíveis.
Depois de inicializar a comunicação com Serial.begin(9600), use Serial.print() para enviar partes que devem continuar na mesma linha. Use Serial.println() na última parte para encerrar a linha e posicionar o cursor na próxima.
Exemplo de intenção: enviar o rótulo contador=, depois o valor atual e, por fim, iniciar uma nova linha para a próxima leitura.

print mantém a linha aberta; println envia o final de linha após seu conteúdo.
Dica
Serial.println() acrescenta dois caracteres de controle ao fim: retorno de carro (\r) e nova linha (\n). Portanto, mesmo Serial.println(); sem argumento transmite 2 bytes.
Para manter a contagem simples nesta prática, os rótulos do código não terão acentos.
Quando você passa um número a Serial.print, ele é convertido para sua representação decimal em texto. Assim, o valor 7 envia o caractere 7; o valor 125 envia três caracteres: 1, 2 e 5.
Isso não é o envio do valor binário bruto. Aqui, o objetivo é uma saída humana e legível no monitor.
Exemplo
Considere a linha exibida abaixo, produzida por print e println:
contador=12
A contagem enviada é:
contador=: 9 bytes12: 2 bytes\r\n de println: 2 bytesTotal: 13 bytes. Se o contador virar 100, a mesma linha passará a ter 14 bytes: o número tem mais um dígito.
Dica
A taxa de 9600 bit/s e o quadro 8N1 vistos antes permitem estimar o tempo de transmissão. Porém, antes de calcular, conte os caracteres do texto e inclua os dois bytes finais de println.
Copie este sketch para a IDE Arduino, envie ao Uno R3 e abra o monitor serial local em 9600 baud. O programa reutiliza a temporização não bloqueante com millis() para transmitir um contador a cada segundo.
unsigned long anterior = 0;
unsigned long contador = 0;
const unsigned long intervalo = 1000;
void setup() {
Serial.begin(9600);
}
void loop() {
unsigned long agora = millis();
if (agora - anterior >= intervalo) {
anterior = agora;
Serial.print("contador=");
Serial.println(contador);
contador++;
}
}contador=0 contador=1 contador=2 contador=3 contador=4
A contagem começa em 0 após a placa reiniciar. Os instantes exatos podem variar levemente, mas uma nova linha deve aparecer aproximadamente a cada segundo.
Dica
Confira dois pontos no monitor:
contador=.Se nada aparecer, confirme primeiro se a porta selecionada é a do Uno e se o monitor está em 9600 baud. A inicialização sozinha não exibe texto: é preciso executar um print ou println.
Complete as chamadas para produzir uma linha como contador=8 e depois iniciar a próxima linha. A primeira lacuna deve manter o rótulo e o valor na mesma linha; a segunda deve encerrar essa linha.
Preencha os nomes das duas funções Serial.
unsigned long contador = 8;
Serial.("contador=");
Serial.(contador);Com Serial.println(contador), quantos bytes são enviados para exibir exatamente contador=7 em uma linha, incluindo o final de linha?

Passo 5 de 8
Use char e literais de caractere para definir comandos de um byte, distinguindo '1' do valor numérico 1.
Um comando de um caractere cabe em um char. Em C/C++, escreva um caractere literal entre aspas simples:
'1' representa o caractere 1;'0' representa o caractere 0.Na prática, cada envio no monitor será um comando independente: '1' pedirá para ligar o LED integrado; '0', para desligá-lo. Isso não é ainda o código de recepção: aqui vamos definir corretamente o que cada byte significa.
Declarações de caracteres usadas para representar comandos.
char ligar = '1';
char desligar = '0';
O caractere enviado é um byte cujo significado é definido pelo programa.
O computador codifica caracteres em bytes. Para os dois comandos desta prática, a correspondência ASCII é suficiente:
Compare o valor que parece igual, mas tem outro significado.
| Escrita no código | Significado | Valor do byte |
|---|---|---|
| '0' | caractere zero | 48 |
| '1' | caractere um | 49 |
| 0 ou 1 | valor numérico | 0 ou 1 |
| "1" | texto contendo um caractere | 49 como conteúdo |
Dica
'1' e 1 não são equivalentes. O primeiro é o caractere cujo byte ASCII é 49; o segundo é o valor numérico um. Para comparar um comando recebido que representa a tecla 1, a comparação deve usar '1'.
Aspas duplas, como em "1", formam um texto. Nesta prática, os comandos têm exatamente um caractere, portanto use char e aspas simples.
Complete a condição que identifica o comando para ligar o LED integrado.
Preencha os dois comandos: '0' desliga e '1' liga o LED integrado.
if (comando == ) {
digitalWrite(LED_BUILTIN, LOW);
} else if (comando == ) {
digitalWrite(LED_BUILTIN, HIGH);
}
Passo 6 de 8
Receba comandos de um caractere do monitor serial sem interromper o contador periódico.
O programa não precisa parar até chegar um comando. A UART guarda temporariamente os bytes que já chegaram em um buffer de recepção. Em cada passagem por loop(), consulte esse buffer e só trate uma entrada quando houver algo disponível.
Serial.available() informa quantos bytes aguardam leitura. Se retornar 0, nenhum byte está pronto agora: o loop() segue para as outras tarefas, como atualizar o contador periódico.

A consulta é rápida: sem byte disponível, o programa continua executando as demais atividades.
Depois de confirmar que há dado, use Serial.read(). Essa função lê e remove um byte do buffer.
Embora um byte tenha valores de 0 a 255, Serial.read() retorna um int. Assim, ela também pode sinalizar -1 quando não há byte para ler. Preserve o retorno em int até confirmar que ele é válido; só então ele pode ser tratado como um caractere.
Nesta prática, a condição com available() faz a leitura somente quando existe ao menos um byte. A verificação de -1 ainda deixa o trecho seguro caso a leitura não produza um byte válido.
Leia no máximo um byte quando ele já estiver disponível.
if (Serial.available() > 0) {
int recebido = Serial.read();
if (recebido != -1) {
char comando = (char)recebido;
// Trate comando aqui.
}
}Atenção
Evite chamar Serial.read() repetidamente à espera de uma entrada. Uma repetição bloqueante impede que o restante do loop() execute enquanto nenhum caractere chega. Consultar a disponibilidade e retornar ao fluxo normal é o que mantém o programa responsivo.
Use este sketch completo no seu Uno R3. Ele mantém o contador enviado a cada segundo e aceita um comando por passagem do loop():
1 para ligar o LED integrado;0 para desligá-lo;Abra o monitor serial na porta do Uno, selecione 9600 baud e Sem final de linha. Durante esta prática, não conecte dispositivos externos aos pinos D0/RX e D1/TX.
Grave o sketch. Sem enviar nada, o contador continua. Depois, envie 1 e 0, um caractere por vez.
const byte LED = LED_BUILTIN;
unsigned long anterior = 0;
unsigned long contador = 0;
void setup() {
pinMode(LED, OUTPUT);
Serial.begin(9600);
}
void loop() {
unsigned long agora = millis();
if (agora - anterior >= 1000) {
anterior = agora;
Serial.print("contador=");
Serial.println(contador);
contador++;
}
if (Serial.available() > 0) {
int recebido = Serial.read();
if (recebido == '1') {
digitalWrite(LED, HIGH);
} else if (recebido == '0') {
digitalWrite(LED, LOW);
}
}
}contador=0 contador=1 contador=2 contador=3 contador=4
Os números aumentam aproximadamente uma vez por segundo. O instante em que a primeira linha aparece depende da abertura do monitor e da reinicialização da placa.
Complete o padrão de consulta, leitura e validação de um byte recebido.
if (() > 0) {
int recebido = ();
if () {
char comando = (char)recebido;
}
}O que significa o retorno -1 de Serial.read()?
Verdadeiro ou falso: testar Serial.available() > 0 com if permite que o contador periódico continue sendo atendido quando nenhum comando chega; uma repetição que espera pela entrada não tem esse comportamento.

Passo 7 de 8
Entenda os limites das filas de transmissão e recepção para manter o monitor serial útil sem comprometer o loop.
Entre o seu sketch e a UART há filas temporárias, chamadas buffers. Elas ajudam o programa e a transmissão física a trabalharem em ritmos diferentes, mas têm capacidade limitada.
Serial.print() e Serial.println() querem enviar; a UART os transmite depois.Serial.read().Pense em cada buffer como uma fila: bytes entram por uma ponta e saem pela outra. Se a fila encher, há consequências diferentes na saída e na entrada.

A transmissão e a recepção usam filas separadas; ambas são finitas.
Atenção
Quando chegam caracteres mais rápido do que o loop() os lê, o buffer de recepção pode ficar cheio. Bytes que chegarem depois podem se perder.
Consultar Serial.available() com frequência e ler os bytes disponíveis reduz esse risco. Na prática anterior, a leitura condicional de no máximo um byte por passagem evita esperar por entrada, mas um loop que passa muito tempo em outra tarefa ainda pode demorar demais para esvaziar a fila.
Portanto, “não bloquear esperando um comando” não significa que toda a comunicação esteja automaticamente livre de esperas ou perdas.
Atenção
Se o programa gera saída mais rápido do que a UART consegue transmiti-la, o buffer de transmissão também enche. Nessa situação, Serial.print() ou Serial.println() pode precisar esperar por espaço na fila antes de retornar.
Isso pode atrasar o restante do loop(). Assim, o sketch pode não ficar parado esperando por um caractere recebido, mas ainda sofrer espera ao tentar escrever texto demais.
Compare os dois riscos
| Situação | Consequência possível | Cuidado básico |
|---|---|---|
| RX recebe mais do que o loop lê | Bytes de entrada podem se perder | Consultar e ler a recepção com frequência |
| TX recebe mais do que a UART transmite | print/println podem esperar | Reduzir tamanho ou frequência das mensagens |
| Loop sem dados de entrada | Nenhuma espera pela chegada de caractere | Usar available antes de read |
Em 8N1, a capacidade nominal é aproximadamente R/10 bytes por segundo, pois cada byte ocupa 10 bits no quadro. A 9600 bit/s, isso dá cerca de 960 bytes/s em condições ideais.
Esse valor não é uma meta de uso: deixe folga. O monitor, a USB e o próprio programa têm variações e pausas. Para esta prática, uma linha curta a cada segundo e consultas frequentes à recepção são um ritmo moderado.
Evite transformar o loop() em uma fonte contínua de mensagens. Antes de adicionar uma impressão, pergunte: ela é necessária para observar o comportamento?
Considere um sketch que envia uma linha curta uma vez por segundo e, em todas as passagens pelo loop(), testa se há um comando disponível.
Qual alteração aumenta diretamente o risco de Serial.print() atrasar o restante do loop por falta de espaço no buffer de transmissão?
| Alteração | Efeito esperado |
|---|---|
| Enviar dezenas de linhas em toda passagem do loop | Aumenta muito a produção de bytes |
| Manter uma linha curta a cada segundo | Mantém saída moderada |
| Testar available frequentemente | Atende a fila de recepção |
Qual associação está correta?

Passo 8 de 8
Integre contador periódico e comandos de um caractere no monitor serial do Uno R3, verificando configuração, tempo 8N1 e cuidados de conexão.
Você vai reunir a transmissão periódica e a recepção de comandos em um único sketch. O contador deve continuar aparecendo mesmo quando nenhum caractere chega ao Uno: a leitura serial só ocorre quando há byte disponível.

Use somente o cabo USB nesta prática; não conecte dispositivos externos a D0/RX e D1/TX.
Grave este sketch no Uno R3. Ele envia um contador a cada segundo e atende, quando disponíveis, os comandos 1 e 0.
const byte LED = LED_BUILTIN;
unsigned long anterior = 0;
unsigned long contador = 0;
void setup() {
pinMode(LED, OUTPUT);
Serial.begin(9600);
}
void loop() {
unsigned long agora = millis();
if (agora - anterior >= 1000) {
anterior = agora;
Serial.print("contador=");
Serial.println(contador);
contador++;
}
if (Serial.available() > 0) {
int recebido = Serial.read();
if (recebido == '1') {
digitalWrite(LED, HIGH);
} else if (recebido == '0') {
digitalWrite(LED, LOW);
}
}
}contador=0 contador=1 contador=2 contador=3
A numeração cresce continuamente. A aparência do LED é física: o LED integrado acende com `1` e apaga com `0`.
Abra o monitor serial da porta do Uno e selecione 9600 baud e Sem final de linha. Envie um único caractere por vez:
1: o LED integrado deve acender.0: o LED integrado deve apagar.contador=... devem continuar crescendo.Se enviar retorno de carro ou nova linha junto ao comando, eles serão bytes extras. Por isso, mantenha Sem final de linha nesta prática.
Depois do teste, descreva o que ocorreu ao enviar 1, ao enviar 0 e durante alguns segundos sem enviar nada. Inclua uma linha do contador que você observou.
Escreva pelo menos 80 caracteres (0/80).
Considere a linha transmitida contador=12 pelo println a 9600 bit/s em 8N1. Ela contém 8 letras, o sinal =, 2 dígitos e os 2 bytes finais de println: 13 bytes ao todo. Cada byte ocupa 10 bits no enquadramento 8N1.
Complete: o tempo nominal para transmitir contador=12 é aproximadamente ____ a 9600 bit/s.
Qual configuração mantém a prática compatível e evita interferência na UART compartilhada?
Resumo
Serial.begin(9600) e monitor em 9600, o sketch envia linhas textuais legíveis e recebe 1 ou 0 como caracteres.Serial.available() evita esperar por entrada: sem comando, o loop continua atendendo o contador periódico.Parabéns! Você concluiu: Comunicação UART pelo monitor serial
Milhares de cursos online em vídeo, ebooks e áudiobooks.
Para testar seus conhecimentos no decorrer dos cursos online
Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail
Baixe nosso aplicativo pelo QR Code ou pelos links abaixo:.
+ de 10 milhões
de alunos
Certificado grátis e
válido em todo o Brasil
60 mil exercícios
gratuitos
4,8/5 classificação
nas lojas de apps
Cursos gratuitos em
vídeo, ebooks e audiobooks