Skip to content

O LED que Pisca SOS

ATENÇÃO Não considerar este tutorial ainda

  • Ainda está a ser revisto
  • carece de imagens
  • código tem que ser verificado e adaptado
  • BOM em construção
  • author André Rocha (ESELx / IPL)

  • licence CC-BY 4.0

  • tags children, electronics, code, communication

  • type Activity Guide


Como transformar luz em linguagem? Nesta atividade, vamos explorar o Código Morse — um sistema de comunicação inventado no século XIX que ainda hoje pulsa em submarinos, satélites e sinais de emergência. Com um Arduino, um LED e um sensor de luz (LDR), vamos construir um emissor e um recetor de mensagens luminosas. Depois, saltamos para o navegador web com p5.js, onde o ecrã se transforma em lanterna e a câmara do computador em olho que decifra. Será que consegues enviar uma mensagem secreta ao teu colega do lado? Só os pontos e os traços o dirão.

Montagem do circuito emissor Morse com Arduino e LED

Atividade 1: Emissor Morse com Arduino — O LED que Fala

Como podemos usar um microcontrolador para transformar texto em pulsos de luz?

Lista de Materiais (BOM)

Quantidade Componente Valor/Tipo Especificações Link (sugestão PT)
1 Arduino Uno (ou Nano) - Qualquer placa compatível com Arduino IDE Mauser PT
1 Cabo USB Tipo A-B (Uno) ou Mini-USB (Nano) Para programação e alimentação -
1 LED - Padrão 5mm, qualquer cor (preferencialmente branco ou vermelho) Mauser PT
1 Resistência 220Ω 1/4W, tolerância de ±5% Mauser PT
1 Mini Breadboard - ~170 pontos de ligação Mauser PT
1 Conjunto de Jumper Wires - Vários comprimentos, núcleo sólido Mauser PT

Ferramentas Necessárias:

  • Computador com Arduino IDE instalado

  • Cabo USB adequado à placa Arduino

Contexto: O que é o Código Morse?

O Código Morse é um sistema de comunicação que representa letras e números através de combinações de sinais curtos (pontos ·) e sinais longos (traços ). Foi inventado por Samuel Morse e Alfred Vail na década de 1830 e utilizado extensivamente no telégrafo elétrico. O famoso sinal de socorro SOS (··· −−− ···) é talvez a sequência Morse mais conhecida do mundo.

Temporização do Código Morse

Elemento Duração Descrição
Ponto (·) 200ms Sinal curto
Traço (−) 800ms Sinal longo (4× a duração do ponto)
Espaço entre símbolos 200ms Pausa entre pontos/traços da mesma letra
Espaço entre letras 400ms Pausa entre letras diferentes
Espaço entre palavras 1000ms Pausa entre palavras

Passos:

  1. Montar o circuito do LED:

    1. Insira o LED na breadboard. Identifique a perna mais longa (ânodo, +) e a perna mais curta (cátodo, −);

    2. Ligue a resistência de 220Ω entre o pino digital 13 do Arduino e a perna positiva do LED;

    3. Ligue a perna negativa do LED ao GND do Arduino com um jumper wire.

Arduino Pin 13 ----[220Ω]---- LED (+) ---- LED (-) ---- GND

💡 Nota: O pino 13 do Arduino tem um LED integrado na placa. Mesmo sem montar o circuito externo, é possível observar o LED da placa a piscar — útil para testar o código antes de montar o hardware.

  1. Instalar o Arduino IDE e carregar o código do Emissor:

    1. Descarregue e instale o Arduino IDE caso ainda não esteja instalado;

    2. Ligue o Arduino ao computador com o cabo USB;

    3. No Arduino IDE, selecione a placa correta em Tools > Board e a porta em Tools > Port;

    4. Crie um novo sketch e cole o código do ficheiro encoder.ino (disponível na pasta arduino/);

    5. Carregue o código para a placa com o botão Upload (seta para a direita).

  2. Testar o Emissor:

    1. Abra o Monitor Série (ícone de lupa no canto superior direito do Arduino IDE) e configure o baud rate para 9600;

    2. Escreva uma mensagem em letras maiúsculas (ex: SOS ou HELLO) e pressione Enter;

    3. Observe o LED a piscar a mensagem em Código Morse;

    4. O Monitor Série mostrará a correspondência entre cada letra e a sua representação Morse.

  3. Explorar e modificar:

    1. Experimente enviar diferentes mensagens — o seu nome, uma palavra secreta, uma saudação;

    2. Discuta: Porque é que utilizamos letras maiúsculas? (O código suporta A-Z e 0-9);

    3. Desafio: Conseguem decifrar a mensagem Morse de um colega apenas observando o LED?

Código do Emissor (encoder.ino) — Excerto Principal:

void sendMorse(char character)

{

String morse = charToMorse(character);

Serial.print(character);

Serial.print(": ");

Serial.println(morse);



for (int i = 0; i < morse.length(); i++)

{

if (morse[i] == '.')

blinkLED(DOT_DURATION); // 200ms

else if (morse[i] == '-')

blinkLED(DASH_DURATION); // 800ms

delay(SYMBOL_GAP); // 200ms entre símbolos

}

}



void blinkLED(int duration)

{

digitalWrite(led, HIGH);

delay(duration);

digitalWrite(led, LOW);

}

Atividade 2: Recetor Morse com Arduino — O Olho que Lê a Luz

Como podemos usar um sensor de luz para descodificar mensagens Morse transmitidas por um LED?

Lista de Materiais Adicionais (BOM)

Quantidade Componente Valor/Tipo Especificações Link (sugestão PT)
1 LDR (Fotorresistência) - Sensor de luz dependente de resistência Mauser PT
1 Resistência 10kΩ 1/4W, tolerância de ±5% (para divisor de tensão) Mauser PT

ℹ️ Nota: Os restantes componentes (Arduino, breadboard, jumper wires) são os mesmos da Atividade 1. É necessário um segundo Arduino para construir o recetor, ou pode-se alternar entre os sketches no mesmo Arduino.

Passos:

Diagrama de montagem do circuito recetor com LDR

  1. Montar o circuito do recetor (LDR):

    1. Insira o LDR na breadboard;

    2. Ligue um terminal do LDR ao pino 5V do Arduino;

    3. Ligue o outro terminal do LDR à entrada analógica A0 do Arduino;

    4. Coloque a resistência de 10kΩ entre o pino A0 e o GND (divisor de tensão pull-down).

Arduino 5V ----[LDR]---- Ponto de junção (A0) ----[10kΩ]---- GND

💡 Explicação: O LDR e a resistência de 10kΩ formam um divisor de tensão. Quando há muita luz sobre o LDR, a sua resistência diminui e a tensão em A0 sobe. Quando está escuro, a resistência do LDR aumenta e a tensão desce. É assim que o Arduino "vê" a diferença entre luz ligada e desligada.

  1. Carregar o código do Descodificador:

    1. Crie um novo sketch no Arduino IDE;

    2. Cole o código do ficheiro decoder.ino (disponível na pasta arduino/);

    3. Carregue o código para a placa do recetor.

  2. Calibrar o sensor:

    1. Abra o Monitor Série (9600 baud);

    2. Observe os valores do LDR com o LED desligado (valores típicos: 100–300);

    3. Observe os valores do LDR com o LED ligado e apontado para o sensor (valores típicos: 500–800);

    4. Ajuste o valor de THRESHOLD_DARK no código para ficar aproximadamente a meio entre os dois valores;

    5. Recarregue o código após o ajuste.

  3. Testar a comunicação entre emissor e recetor:

    1. Posicione o LED do emissor a 5–10 cm do LDR do recetor;

    2. No Arduino emissor, envie uma mensagem (ex: SOS);

    3. No Monitor Série do Arduino recetor, observe os pontos e traços a serem descodificados em tempo real;

    4. Quando deteta um espaço entre letras, o recetor converte o padrão Morse na letra correspondente;

    5. Discuta os resultados: A mensagem foi descodificada corretamente? O que pode causar erros?

  4. Experimentar e desafiar:

    1. Afaste progressivamente o LED do LDR — a que distância máxima consegue descodificar?

    2. Experimente em diferentes condições de iluminação — luz natural vs. sala escura;

    3. Desafio em grupo: cada par de participantes troca mensagens secretas usando os seus circuitos!

Código do Descodificador (decoder.ino) — Excerto Principal:

void processSignal(unsigned long duration)

{

unsigned int midpoint = (DOT_DURATION + DASH_DURATION) / 2;

if (duration < midpoint)

currentMorse += "."; // Ponto (sinal curto)

else

currentMorse += "-"; // Traço (sinal longo)

}



void checkForGap(unsigned long duration)

{

if (duration < 350) return; // Espaço entre símbolos — ignorar



// Espaço entre letras (~400ms)

if (duration >= 350 && duration < 550 && currentMorse.length() > 0)

{

char letter = morseToChar(currentMorse);

if (letter != '?') decodedText += letter;

currentMorse = "";

}



// Espaço entre palavras (>550ms)

if (duration >= 550)

{

if (currentMorse.length() > 0)

{

char letter = morseToChar(currentMorse);

if (letter != '?') decodedText += letter;

currentMorse = "";

}

decodedText += " ";

}

}

Atividade 3: Do Arduino ao Navegador — Morse com p5.js

Como podemos usar programação criativa no navegador para codificar e descodificar Morse, sem qualquer hardware?

Nesta atividade, transitamos do mundo físico (Arduino, LED, LDR) para o mundo digital (navegador web, ecrã, câmara). Utilizamos a biblioteca p5.js — uma ferramenta de programação criativa baseada em JavaScript — para recriar todo o sistema de comunicação Morse.

O que é o p5.js?

O p5.js é uma biblioteca JavaScript de código aberto para programação criativa. Permite criar gráficos interativos, animações, som e muito mais, diretamente no navegador web — sem necessidade de instalar software. É amplamente utilizada em educação e arte digital.

Lista de Materiais (BOM)

Quantidade Componente Especificações
1 Computador Com navegador web moderno (Chrome, Firefox, Edge)
1 Webcam Integrada ou externa (para o descodificador)
- Ligação à Internet Para carregar a biblioteca p5.js do CDN (ou descarregar previamente)

Ferramentas Necessárias:

  • Editor de texto (ex: Visual Studio Code, Notepad++, ou o editor online do p5.js)

  • Navegador web com suporte a WebRTC (para acesso à câmara)


Atividade 3a: Codificador p5.js — O Ecrã que Pisca

Passos:

  1. Abrir o codificador no navegador:

  2. Abra o ficheiro p5js/encoder/index.html no navegador (duplo clique ou arrastar para a janela do navegador);

  3. Alternativamente, utilize o editor online do p5.js e cole o código de sketch.js.

  4. Utilizar o codificador:

  5. Escreva uma mensagem no campo de texto (ex: HELLO WORLD);

  6. Clique em Start Flashing (ou pressione a barra de espaços);

  7. Observe o ecrã a alternar entre branco (sinal) e preto (pausa);

  8. A secção Output mostra a representação Morse da mensagem;

  9. O Status indica o progresso da transmissão.

  10. Compreender o código — passo a passo:

a) A tabela de conversão — de letras a pontos e traços:

const textToMorse = {

A: ".-", B: "-...", C: "-.-.", D: "-..",

E: ".", F: "..-.", G: "--.", H: "....",

I: "..", J: ".---", K: "-.-", L: ".-..",

M: "--", N: "-.", O: "---", P: ".--.",

// ... e assim por diante

};

Este objeto funciona como um dicionário: dada uma letra, devolve a sequência Morse correspondente. É o equivalente digital da tabela de Código Morse que Samuel Morse criou.

b) Transformar texto numa sequência de ações:

function textToMorseSequence(text) {

let sequence = [];

for (let i = 0; i < text.length; i++) {

let char = text[i];

if (char === " ") {

sequence.push({ type: "word_gap", durationMs: WORD_GAP });

continue;

}

let morse = textToMorse[char];

for (let j = 0; j < morse.length; j++) {

let symbol = morse[j];

let signalDuration = symbol === "." ? DOT_DURATION : DASH_DURATION;

sequence.push({ type: "signal", symbol: symbol, durationMs: signalDuration });

if (j < morse.length - 1) {

sequence.push({ type: "symbol_gap", durationMs: SYMBOL_GAP_DOT });

}

}

if (i < text.length - 1 && text[i + 1] !== " ") {

sequence.push({ type: "letter_gap", durationMs: LETTER_GAP });

}

}

return sequence;

}

Esta função percorre cada letra da mensagem e cria uma lista ordenada de ações: piscar (branco) para pontos e traços, e pausar (preto) para os espaços. É como criar uma partitura musical onde cada nota tem uma duração definida.

c) Reproduzir a sequência — o ecrã como lanterna:

function playMorseSequence() {

let currentItem = morseSequence[currentIndex];

let elapsed = millis() - stateStartTime;



if (currentItem.type === "signal") {

background(255); // Ecrã branco = sinal

if (elapsed >= currentItem.durationMs) {

stateStartTime = millis();

currentIndex++;

}

} else {

background(18); // Ecrã escuro = pausa

if (elapsed >= currentItem.durationMs) {

stateStartTime = millis();

currentIndex++;

}

}

}

A função draw() do p5.js executa continuamente (~60 vezes por segundo). Verificamos quanto tempo passou desde o início do elemento atual. Se já decorreu o tempo definido, avançamos para o próximo. Assim, o ecrã transforma-se numa lanterna digital que pisca Código Morse.

  1. Atalhos de teclado:

  2. Espaço — Iniciar/Parar a transmissão

  3. Esc — Parar a transmissão


Atividade 3b: Descodificador p5.js — A Câmara que Lê

Passos:

  1. Abrir o descodificador no navegador:

  2. Abra o ficheiro p5js/decoder/index.html no navegador;

  3. Autorize o acesso à câmara (webcam) quando solicitado pelo navegador.

  4. Preparar a descodificação:

  5. A câmara do computador será mostrada no ecrã;

  6. Clique sobre o LED emissor (ou sobre o ecrã do codificador p5.js) para posicionar o círculo de rastreamento;

  7. O sistema de auto-calibragem ajustará automaticamente o limiar de deteção;

  8. Opcionalmente, desative a auto-calibragem e ajuste o Threshold manualmente com o slider.

  9. Descodificar mensagens:

  10. No computador emissor (ou no Arduino), inicie a transmissão de uma mensagem;

  11. Aponte a câmara do descodificador para a fonte de luz (LED ou ecrã);

  12. Observe no painel Output o código Morse a ser recebido e o texto descodificado a aparecer;

  13. Experimente com diferentes distâncias e ângulos.

  14. Compreender o código — passo a passo:

a) Captura de vídeo e amostragem de brilho:

function setup() {

capture = createCapture(VIDEO); // Acede à webcam

capture.hide(); // Esconde o elemento HTML nativo

trackX = width / 2; // Posição inicial do rastreador

trackY = height / 2;

}

O p5.js fornece uma forma simples de aceder à webcam com createCapture(VIDEO). Escondemos o elemento de vídeo original e desenhamos a imagem nós mesmos para ter controlo total sobre a apresentação.

b) Medir o brilho na zona de rastreamento:

// Dentro de draw():

capture.loadPixels();

let totalBrightness = 0;

let pixelCount = 0;



for (let y = captureY - captureRadius; y < captureY + captureRadius; y++) {

for (let x = captureX - captureRadius; x < captureX + captureRadius; x++) {

let index = (floor(y) * capture.width + floor(x)) * 4;

let r = capture.pixels[index];

let g = capture.pixels[index + 1];

let b = capture.pixels[index + 2];

let brightness = (r + g + b) / 3;

totalBrightness += brightness;

pixelCount++;

}

}

avgBrightness = totalBrightness / pixelCount;

Percorremos todos os píxeis dentro do círculo de rastreamento e calculamos o brilho médio (média de RGB). Este valor é comparado com o limiar (threshold) para determinar se a luz está "ligada" ou "desligada" — exatamente como o LDR do Arduino, mas usando software!

c) Detetar transições e classificar sinais:

let currentlyOn = avgBrightness > threshold;



if (currentlyOn !== isLightOn) {

let signalLength = millis() - lastStateChange;

if (isLightOn) {

processSignal(signalLength); // Classificar como ponto ou traço

} else {

checkForLetterOrWordGap(signalLength); // Verificar espaços

}

isLightOn = currentlyOn;

lastStateChange = millis();

}

A lógica é idêntica ao Arduino: quando detetamos uma transição de estado (luz ligou ou desligou), medimos a duração e classificamos o sinal. A diferença é que aqui usamos píxeis em vez de um sensor analógico.

d) Converter Morse em texto:

const morseCode = {

".-": "A", "-...": "B", "-.-.": "C", "-..": "D",

".": "E", "..-.": "F", "--.": "G", "....": "H",

// ... dicionário inverso: de Morse para letra

};

Note-se que o dicionário do descodificador é o inverso do codificador: as chaves são padrões Morse e os valores são letras. Quando acumulamos pontos e traços suficientes e detetamos um espaço entre letras, procuramos o padrão no dicionário.

  1. Atalhos de teclado:

  2. R — Reiniciar tudo (limpar texto e Morse)

  3. E — Limpar apenas o texto descodificado

  4. C — Recalibrar o sensor


Atividade 3c: Comunicação entre Pares — Ecrã a Ecrã

Dinâmica de Grupo:

  1. Divida os participantes em pares;

  2. Cada par utiliza dois computadores:

  3. Computador A — abre o Codificador (p5js/encoder/index.html)

  4. Computador B — abre o Descodificador (p5js/decoder/index.html)

  5. O participante A escreve uma mensagem secreta e inicia a transmissão;

  6. O participante B aponta a câmara do seu computador para o ecrã do computador A;

  7. O descodificador lê os flashes do ecrã e reconstrói a mensagem;

  8. Depois trocam papéis!

⚡ Dica: Para melhores resultados, reduza o brilho da sala e aumente o brilho do ecrã emissor. Posicione a câmara a 20–40cm do ecrã.


Tabela de Referência do Código Morse

Letra Morse Letra Morse
A ·− N −·
B −··· O −−−
C −·−· P ·−−·
D −·· Q −−·−
E · R ·−·
F ··−· S ···
G −−· T
H ···· U ··−
I ·· V ···−
J ·−−− W ·−−
K −·− X −··−
L ·−·· Y −·−−
M −− Z −−··
Número Morse
--- ---
0 −−−−−
1 ·−−−−
2 ··−−−
3 ···−−
4 ····−
5 ·····
6 −····
7 −−···
8 −−−··
9 −−−−·

Resolução de Problemas

O LED não pisca (Arduino)

  • Verifique a polaridade do LED (perna mais longa = positivo)

  • Confirme a ligação ao pino 13

  • Teste com a alimentação USB diretamente

O LDR não deteta alterações (Arduino)

  • Certifique-se de que o LED está brilhante e próximo do LDR (5–10 cm)

  • Verifique as ligações ao pino A0

  • Confirme o valor da resistência (10kΩ pull-down)

  • Consulte o Monitor Série para ver as leituras do LDR

O limiar está demasiado alto ou baixo

  • Leia os valores do Monitor Série com LED ligado/desligado

  • Ajuste THRESHOLD_DARK para o ponto médio entre as duas leituras

  • Intervalo típico: 300–500 (depende da iluminação ambiente)

A câmara não deteta os flashes (p5.js)

  • Autorize o acesso à câmara no navegador

  • Clique sobre a fonte de luz para reposicionar o círculo de rastreamento

  • Aumente o brilho do ecrã emissor e reduza a luz ambiente

  • Experimente ajustar o slider de Threshold manualmente

  • Recalibre com a tecla C

Caracteres descodificados incorretamente

  • Verifique que a temporização do emissor e do recetor são coincidentes

  • Assegure uma alimentação estável (no caso do Arduino)

  • Reduza a distância entre emissor e recetor


Notas Finais

  • Segurança: Não há tensões perigosas neste projeto (alimentação USB a 5V). Contudo, supervisione sempre os mais jovens quando manuseiam componentes eletrónicos pequenos.

  • Do físico ao digital: Discuta com os participantes as semelhanças e diferenças entre usar um LED+LDR (mundo físico) e um ecrã+câmara (mundo digital). Ambos partilham a mesma lógica: emitir luz → detetar luz → medir duração → classificar → descodificar.

  • Contextualização histórica: Explore a história do telégrafo, do Código Morse e da comunicação à distância. Discuta como o mesmo princípio é usado hoje em fibras óticas e comunicações por infravermelhos.

  • Extensões artísticas: Incentive os participantes a pensar em como este sistema poderia ser usado numa instalação artística — mensagens secretas projetadas numa parede, comunicação entre salas, ou performances de luz e som.

  • Extensões técnicas: Participantes mais avançados podem modificar os tempos de duração, adicionar suporte para caracteres especiais, ou criar uma interface sonora (bip para ponto, biiiip para traço) adicionando um buzzer ao circuito Arduino ou usando a API Web Audio no p5.js.

  • Comparação de abordagens: Compare a abordagem Arduino (hardware dedicado, baixo consumo, sempre ligado) com a abordagem p5.js (flexível, visual, sem hardware extra). Cada uma tem as suas vantagens — quando usaríamos uma ou outra?