Trilha de aprendizado · Nível 11 · Tutorial 2

Comunicação UART pelo monitor serial

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.

  • Nível: Intermediário
  • Duração: 20 min
  • 8 passos
Comunicação UART pelo monitor serial

O que você vai percorrer

  1. 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
  2. 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
  3. Preparação do monitor serial local 2 min
  4. Envio de valores como texto Exiba valores do programa no monitor serial usando linhas textuais legíveis. 3 min
  5. 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
  6. Recepção sem esperar por dados Receba comandos de um caractere do monitor serial sem interromper o contador periódico. 3 min
  7. 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
  8. 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

O que você vai aprender

  • Identificar as conexões e configurações necessárias para uma ligação UART compatível.
  • Calcular o tempo aproximado de transmissão de uma mensagem em 8N1.
  • Exibir valores produzidos pelo programa no monitor serial.
  • Receber um comando de um caractere sem esperar em uma repetição bloqueante.

Antes de começar

  • Preparação da placa e do ambiente de programação
  • Variáveis, tipos e cálculos em C/C++
  • Leitura de botões com if e else
  • Compatibilidade elétrica entre circuitos digitais

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.

O enlace UART básico

UART: duas direções, sem clock

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.

Conexão UART entre dois dispositivos

Diagrama com duas placas: as linhas de transmissão e recepção se cruzam, e os terras são unidos; não há linha de clock.

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.

Sinais compatíveis e conexão segura

Compatibilidade vem antes da conexão

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

UART lógica não é RS-232

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.

Interfaces parecidas, eletricamente diferentes

Comparação entre UART lógica de baixa tensão ligada a um módulo compatível e uma porta RS-232 separada dos GPIOs por um conversor.

UART descreve a troca serial; a compatibilidade elétrica da interface ainda precisa ser verificada.

A prática usa a UART já presente na placa

O caminho dentro do Uno R3

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.

Do monitor até o microcontrolador

Diagrama do computador ligado por USB à ponte USB-UART do Uno, que se conecta à UART do ATmega328P.

A ponte USB-UART da própria placa permite usar o monitor serial sem uma ligação externa nos pinos seriais.

Atenção

Regra da prática

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.

Verificação rápida

Confira o percurso e as conexões

Associe cada elemento à sua função ou conexão correta.

Conexões e percurso UART

Faça as associações corretas.

Toque em um item e depois no par correspondente.

Passo 2 de 8

Quadros 8N1 e tempo de transmissão

Entenda o enquadramento 8N1 e estime o tempo nominal de transmissão de bytes em uma UART.

O formato de um quadro UART

Um byte precisa de enquadramento

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.

Diagrama de sinal UART: linha alta em repouso, um intervalo baixo de início, oito intervalos de dados e um intervalo alto de parada.

O início baixo marca o começo do quadro; a parada alta encerra a transmissão.

De bits para tempo

Lendo 8N1

A notação 8N1 resume a configuração mais comum:

  • 8: oito bits de dados;
  • N: nenhuma paridade (None);
  • 1: um bit de parada.

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

Taxa e duração nominal

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:

  • duração nominal de 1 bit: t_bit = 1/R
  • duração nominal de 1 quadro 8N1: t_quadro = 10/R

Esses valores descrevem os bits efetivamente transmitidos; não incluem pausas causadas pelo programa, USB ou monitor serial.

Estimando uma sequência de bytes

Exemplo

Exemplo de cálculo

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.

Fórmula de transmissão

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 =

Verifique sua leitura do quadro

Pratique a ordem do quadro

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.

  1. 8 bits de dados
  2. Bit de parada
  3. Bit de início

Passo 3 de 8

Preparação do monitor serial local

Recursos e conexão USB

O que você precisa

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.

Conexão usada na prática

Diagrama de um computador ligado por cabo USB ao Uno R3, com o caminho até a UART interna e os pinos D0 e D1 sem conexões externas.

Nesta prática, o cabo USB já cria o caminho entre o monitor serial e a UART do Uno.

Dica

Cuidado com os pinos seriais

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.

Configuração no sketch

Inicialize a UART

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.

Sketch de inicialização

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.

cpp
void setup() {
  Serial.begin(9600);
}

void loop() {
}
Saída esperada
(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

Monitor vazio não é erro

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.

Configuração correspondente no monitor

Ajuste o monitor serial

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.

Configurações correspondentes

Painel ilustrado de monitor serial com seleção de porta da placa, taxa 9600 e opção sem final de linha destacadas.

A taxa do monitor deve coincidir com a taxa definida no sketch; use Sem final de linha para os futuros comandos de um caractere.

Cheque rápido

Complete a inicialização

Preencha a chamada que inicializa a UART na taxa usada nesta prática.

cpp
void setup() {
  (9600);
}

void loop() {
}

Interprete o resultado

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

Envio de valores como texto

Exiba valores do programa no monitor serial usando linhas textuais legíveis.

Construindo uma saída legível

Print e quebra de linha

Uma linha é formada em partes

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.

Diagrama mostrando duas chamadas print formando contador=12 e println encerrando a linha.

print mantém a linha aberta; println envia o final de linha após seu conteúdo.

Dica

O que println acrescenta

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.

Texto decimal ocupa um byte por caractere

Números viram texto

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

Contagem de bytes na linha

Considere a linha exibida abaixo, produzida por print e println:

contador=12

A contagem enviada é:

  • contador=: 9 bytes
  • 12: 2 bytes
  • \r\n de println: 2 bytes

Total: 13 bytes. Se o contador virar 100, a mesma linha passará a ter 14 bytes: o número tem mais um dígito.

Dica

Atenção à contagem

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.

Pratique no seu Uno R3

Prática local: contador periódico

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.

Sketch completo

cpp
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++;
  }
}
Saída esperada
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

Resultado esperado

Confira dois pontos no monitor:

  1. Cada valor aparece na mesma linha de contador=.
  2. Cada nova leitura começa na linha seguinte.

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.

Verifique sua compreensão

Complete a saída

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.

cpp
unsigned long contador = 8;

Serial.("contador=");
Serial.(contador);

Conte os bytes

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

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.

Comandos de um caractere

Um byte com significado de comando

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.

Literais de caractere

Declarações de caracteres usadas para representar comandos.

cpp
char ligar = '1';
char desligar = '0';

Do caractere ao comando

Diagrama relacionando o caractere 1 ao byte 49 e ao LED ligado, e o caractere 0 ao byte 48 e ao LED desligado.

O caractere enviado é um byte cujo significado é definido pelo programa.

Byte, número e texto

Caractere não é número

O computador codifica caracteres em bytes. Para os dois comandos desta prática, a correspondência ASCII é suficiente:

ASCII dos comandos

Compare o valor que parece igual, mas tem outro significado.

Os bytes são apresentados em decimal.
Escrita no códigoSignificadoValor do byte
'0'caractere zero48
'1'caractere um49
0 ou 1valor numérico0 ou 1
"1"texto contendo um caractere49 como conteúdo

Dica

Aspas simples fazem diferença

'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.

Pratique a comparação

Complete a comparação

Complete a condição que identifica o comando para ligar o LED integrado.

Defina os dois comandos

Preencha os dois comandos: '0' desliga e '1' liga o LED integrado.

cpp
if (comando == ) {
  digitalWrite(LED_BUILTIN, LOW);
} else if (comando == ) {
  digitalWrite(LED_BUILTIN, HIGH);
}

Passo 6 de 8

Recepção sem esperar por dados

Receba comandos de um caractere do monitor serial sem interromper o contador periódico.

Consulta condicional ao buffer

Consultar sem esperar

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.

O byte espera no buffer; o loop não espera pelo byte

Diagrama mostrando um caractere chegando a uma fila de recepção; o loop consulta a fila, lê um byte quando ela não está vazia e continua o contador periódico.

A consulta é rápida: sem byte disponível, o programa continua executando as demais atividades.

Leitura segura de um byte

Ler mantendo a validação

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.

Padrão de recepção de um byte

Leia no máximo um byte quando ele já estiver disponível.

cpp
if (Serial.available() > 0) {
  int recebido = Serial.read();

  if (recebido != -1) {
    char comando = (char)recebido;
    // Trate comando aqui.
  }
}

Atenção

Não transforme a leitura em espera

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.

Aplicar sem bloquear o loop

Prática local: contador e comandos

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():

  • envie 1 para ligar o LED integrado;
  • envie 0 para desligá-lo;
  • outros caracteres são ignorados.

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.

Sketch completo

Grave o sketch. Sem enviar nada, o contador continua. Depois, envie 1 e 0, um caractere por vez.

cpp
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);
    }
  }
}
Saída esperada
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.

Verificar o raciocínio

Complete a recepção condicional

Complete o padrão de consulta, leitura e validação de um byte recebido.

cpp
if (() > 0) {
  int recebido = ();

  if () {
    char comando = (char)recebido;
  }
}

Interprete o retorno

O que significa o retorno -1 de Serial.read()?

Compare os dois comportamentos

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

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.

Buffers: espaço limitado para bytes

Duas filas, dois sentidos

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.

  • Buffer de transmissão (TX): recebe os bytes que Serial.print() e Serial.println() querem enviar; a UART os transmite depois.
  • Buffer de recepção (RX): guarda os bytes que chegaram até o sketch fazer 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.

Buffers entre o sketch e a UART

Diagrama com duas filas de bytes: uma sai do sketch para a UART e outra chega da UART ao sketch.

A transmissão e a recepção usam filas separadas; ambas são finitas.

Quando uma fila não acompanha o ritmo

Atenção

Recepção atrasada pode perder comandos

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

Saída em excesso também atrasa o loop

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.

Recepção e transmissão não falham do mesmo modo

Compare os dois riscos

A ação prudente depende de qual fila está sob pressão.
SituaçãoConsequência possívelCuidado básico
RX recebe mais do que o loop lêBytes de entrada podem se perderConsultar e ler a recepção com frequência
TX recebe mais do que a UART transmiteprint/println podem esperarReduzir tamanho ou frequência das mensagens
Loop sem dados de entradaNenhuma espera pela chegada de caractereUsar available antes de read

Ritmo prudente para a prática

Capacidade nominal não é orçamento completo

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?

Escolha a causa

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?

Use o sentido do fluxo para decidir.
AlteraçãoEfeito esperado
Enviar dezenas de linhas em toda passagem do loopAumenta muito a produção de bytes
Manter uma linha curta a cada segundoMantém saída moderada
Testar available frequentementeAtende a fila de recepção

Verifique seu entendimento

Diagnóstico das filas

Qual associação está correta?

Passo 8 de 8

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.

Monte a aplicação integrada

Meta da aplicaçã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.

Fluxo da prática

Diagrama do Uno conectado por USB ao computador: o contador sai para o monitor serial, os comandos voltam para o LED integrado e D0/D1 permanecem sem conexões externas.

Use somente o cabo USB nesta prática; não conecte dispositivos externos a D0/RX e D1/TX.

Sketch integrado

Grave este sketch no Uno R3. Ele envia um contador a cada segundo e atende, quando disponíveis, os comandos 1 e 0.

cpp
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);
    }
  }
}
Saída esperada
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`.

Valide comandos e continuidade

Teste no seu computador

Abra o monitor serial da porta do Uno e selecione 9600 baud e Sem final de linha. Envie um único caractere por vez:

  1. Envie 1: o LED integrado deve acender.
  2. Envie 0: o LED integrado deve apagar.
  3. Não envie nada por alguns segundos: as linhas 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.

Registre sua observação

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).

Confira taxa, quadro e conexão

Tempo nominal de uma linha

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.

Calcule o tempo 8N1

Complete: o tempo nominal para transmitir contador=12 é aproximadamente ____ a 9600 bit/s.

Confira a conexão

Qual configuração mantém a prática compatível e evita interferência na UART compartilhada?

Fechamento

Resumo

Síntese final

  • O cabo USB leva a comunicação entre o monitor local e a ponte USB-UART do Uno; durante a prática, D0/RX e D1/TX ficam sem dispositivos externos.
  • Com 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.
  • Em 8N1, cada byte ocupa 10 bits. Rótulos, dígitos e o final de linha entram na contagem do tempo de transmissão.
  • Esta solução é deliberadamente simples: usa comandos de um caractere, tráfego moderado e não garante entrega nem trata mensagens completas.

Baixe o Aplicativo agora para ter acesso a + de 5000 cursos gratuitos, exercícios, certificado e muito conteúdo sem pagar nada!

  • Cursos online 100% gratuitos do início ao fim

    Milhares de cursos online em vídeo, ebooks e áudiobooks.

  • Mais de 60 mil exercícios gratuitos

    Para testar seus conhecimentos no decorrer dos cursos online

  • Certificado Digital gratuito válido em todo o Brasil

    Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail

Aplicativo Cursa na tela de ebook, na tela de curso em vídeo e na tela de exercícios do curso, mais o certificado de conclusão de curso