Módulo laser KY-008 com Arduino: alarme de barreira laser e cronômetro
Módulo laser KY-008 e Arduino: ligação, segurança ocular com 5 mW e 650 nm, barreira laser com LDR, calibração automática do limite, espelhos, cronômetro de corrida e alertas com ESP32.
O módulo laser é um dos componentes mais chamativos que você pode usar com um Arduino: ele produz um feixe vermelho fino que percorre metros sem se espalhar. O módulo laser KY-008, presente nos kits para hobbistas, reúne em uma pequena placa um diodo laser de 650 nm e cerca de 5 mW; ele é ligado a um único pino digital do Arduino e é ligado e desligado com digitalWrite(). Sozinho, ele é só um apontador, mas coloque um sensor de luz na frente dele e ele vira um alarme de barreira laser como nos filmes, um contador de pessoas que passam por uma porta ou um cronômetro de corrida com precisão de milissegundos.
Neste guia você vai conhecer as especificações do KY-008, entender o quanto um laser de 5 mW é realmente perigoso para os olhos e quais regras seguir, e aprender a ligar o módulo corretamente a um Arduino Uno, a um ESP32 e a um Raspberry Pi Pico. Depois, vai montar uma barreira laser com um LDR, deixar o Arduino medir o limite automaticamente em vez de chutá-lo, transformar um laser em vários feixes com espelhos, contar passagens e medir velocidade, e usar um ESP32 para enviar uma notificação ao seu celular quando o feixe for interrompido.

O que é o módulo laser KY-008 e como ele funciona?
O coração do módulo é um pequeno diodo laser montado dentro de um tubo de latão. Diferente de um LED comum, o diodo laser emite luz em um único comprimento de onda e de forma ordenada (coerente) quando a corrente passa de um certo limite; uma lente minúscula na ponta do tubo transforma essa luz em um feixe quase paralelo. Por isso a luz de um LED se espalha em poucos centímetros, enquanto o ponto do laser continua com poucos milímetros mesmo a vários metros de distância. 650 nm corresponde a um vermelho intenso que o olho enxerga facilmente. O resistor na pequena placa atrás da cabeça laser limita a corrente que passa pelo diodo. Diodos laser são muito mais sensíveis a sobrecorrente do que LEDs; ignorar esse resistor e alimentar o diodo diretamente pode destruí-lo em segundos.
| Característica | Valor |
|---|---|
| Modelo | KY-008 (vendido como HW-493 por alguns vendedores) |
| Comprimento de onda | 650 nm (vermelho visível) |
| Potência de saída | Cerca de 5 mW |
| Classe do laser | 3R (IEC 60825-1), IIIa nos EUA |
| Tensão de operação | 5 V (mais fraco em 3,3 V) |
| Corrente | Abaixo de 40 mA; varia de placa para placa |
| Cabeça laser | Tubo de latão de 6 mm |
| Pinos | S (sinal), pino do meio (+5V ou desconectado na maioria das placas), − (GND) |
| Temperatura de operação | −10 a 40 °C |
Segurança ocular: o quanto um laser de 5 mW é perigoso?
O perigo de um laser não vem da potência total, mas do fato de essa potência estar concentrada em um ponto minúsculo. A lente do seu olho foca um feixe paralelo em um ponto de tamanho de mícrons na retina; por isso, 5 mW que parecem inofensivos em uma parede podem virar, na retina, um ponto mais intenso do que olhar diretamente para o sol. Os lasers são divididos em classes de acordo com esse risco. Nos lasers Classe 2, abaixo de 1 mW, o reflexo de piscar (cerca de 0,25 segundo) geralmente protege o suficiente. A Classe 3R, à qual o KY-008 pertence, vai até cinco vezes esse limite: uma olhada rápida e acidental tem risco baixo, mas olhar para o feixe diretamente ou por um espelho pode danificar o olho.
| Classe | Potência (luz visível) | Risco |
|---|---|---|
| 1 | Muito baixa, ou o feixe fica fechado dentro do aparelho | Seguro no uso normal |
| 2 | Até 1 mW | O reflexo de piscar protege; não olhe de propósito |
| 3R | 1–5 mW (KY-008) | Olhar diretamente pode danificar o olho |
| 3B | 5–500 mW | Feixes diretos e refletidos por espelho são perigosos |
| 4 | Acima de 500 mW | Risco para olhos, pele e de incêndio |
- Nunca olhe para o feixe: não aproxime a saída do laser do olho e não fique balançando o módulo na mão enquanto ele estiver ligado.
- Mantenha o feixe abaixo da altura dos olhos: monte os feixes de alarme e de contador a 20–50 cm do chão. Essa altura coincide com a altura dos olhos de um bebê engatinhando, de uma criança pequena ou de um gato ou cachorro; então não deixe o laser ligado quando eles estiverem por perto.
- Cuidado com reflexos: espelhos, vidro, mostradores de relógio e metais brilhantes mandam o feixe para direções inesperadas. Confira o caminho do feixe do início ao fim e termine-o em uma superfície fosca e escura.
- Crianças não devem usar sozinhas: laser não é brinquedo; em projetos escolares e de feira de ciências, trabalhe sob a supervisão de um adulto.
- Não confie cegamente na etiqueta: a potência real de módulos baratos pode ser diferente da indicada; trate todo módulo como, no mínimo, Classe 3R.
- Alinhe com uma folha de papel: segure um papel branco na frente do feixe e acompanhe o ponto no papel; nunca olhe para dentro do feixe para ver para onde ele vai.
Ligação do KY-008: Arduino Uno, ESP32 e Raspberry Pi Pico
O KY-008 tem três pinos: S é o pino de sinal e liga o laser quando está em HIGH, − é o GND, e o pino do meio, sem marcação, vai ao +5V na maioria das placas ou nem está conectado. O laser fica entre S e −, então o pino do Arduino ligado ao S fornece diretamente a corrente do laser. No Arduino Uno isso serve para testes rápidos, mas a corrente do módulo varia de placa para placa e pode chegar perto de 40 mA. Esse é o máximo absoluto por pino do ATmega328P; o valor recomendado é 20 mA. Se você vai deixar o laser ligado por horas, usar mais de um laser ou trabalhar com ESP32 ou Pico, alimente o laser pelo 5V e chaveie-o com um transistor NPN (BC547, S8050 ou 2N2222). Você pode conferir a pinagem do transistor no guia de transistores.
| Conexão | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| KY-008 S | D7 | 5V (VIN) | VBUS (pino 40) |
| Pino do meio do KY-008 | Desconectado (5V se o laser não acender) | 5V (VIN) | VBUS (pino 40) |
| KY-008 − | GND | Coletor do NPN | Coletor do NPN |
| Emissor do NPN | – | GND | GND (pino 38) |
| Base do NPN (via 1 kΩ) | – | GPIO 26 | GP15 (pino 20) |
| Terminal 1 do LDR | 5V | 3V3 | 3V3(OUT) (pino 36) |
| Terminal 2 do LDR + ponta superior do resistor | A0 | GPIO 34 | GP26 (pino 31) |
| Ponta inferior do resistor (3,3–10 kΩ) | GND | GND | GND |
| Buzzer ativo + | D8 | GPIO 25 | GP14 (pino 19) |
Antes de passar aos sketches, teste o laser e o LDR juntos com o pequeno programa de teste abaixo. Ele liga e desliga o laser a cada meio segundo e mostra no Monitor Serial a leitura nos dois estados. Quanto maior a diferença entre os dois valores, mais confiável é a sua barreira: no Uno, uma diferença acima de 300 é muito boa; abaixo de 100 significa que o feixe não está acertando o LDR em cheio ou que a luz ambiente está forte demais.
1// KY-008 + LDR ilk test: lazer açıkken ve kapalıyken değerleri gör / First test: see readings with the laser on and off
2const int LASER_PIN = 7; // KY-008 S pini / KY-008 S pin
3const int LDR_PIN = A0; // LDR bölücü çıkışı / LDR divider output
4
5void setup() {
6 Serial.begin(9600);
7 pinMode(LASER_PIN, OUTPUT);
8}
9
10void loop() {
11 digitalWrite(LASER_PIN, HIGH); // lazer açık / laser on
12 delay(500); // LDR'nin oturmasını bekle / let the LDR settle
13 int onValue = analogRead(LDR_PIN);
14
15 digitalWrite(LASER_PIN, LOW); // lazer kapalı / laser off
16 delay(500);
17 int offValue = analogRead(LDR_PIN);
18
19 Serial.print(F("Isin var / beam: "));
20 Serial.print(onValue);
21 Serial.print(F(" Isin yok / no beam: "));
22 Serial.print(offValue);
23 Serial.print(F(" Fark / gap: "));
24 Serial.println(onValue - offValue);
25}Como funciona uma barreira laser com LDR?
A ideia de uma barreira laser é simples: o feixe do laser incide o tempo todo sobre um LDR (resistor dependente de luz) do outro lado. Com o ponto do laser sobre ele, a resistência do LDR cai para algumas centenas de ohms; quando o feixe é interrompido, ela sobe para dezenas de quilo-ohms. Ligue o LDR com um resistor fixo como um divisor de tensão e essa variação de resistência vira uma variação de tensão no pino analógico: com 5V → LDR → A0 → resistor → GND, A0 lê um valor alto enquanto o feixe está lá e baixo quando ele é interrompido. No instante em que alguém passa pelo feixe, o valor cai e o Arduino dispara o alarme.



Uma conta rápida mostra por que o laser tem um efeito tão forte sobre o LDR: quando o feixe de 5 mW se concentra em um ponto de cerca de 3 mm de diâmetro, ele gera uma intensidade de aproximadamente 700 W por metro quadrado. Isso está na mesma faixa da luz do sol ao meio-dia e é centenas de vezes mais forte que a luz de um cômodo bem iluminado. Mesmo assim, o maior inimigo da barreira é a luz ambiente: na frente de uma janela ensolarada, o LDR continua iluminado mesmo com o feixe interrompido, e o alarme não percebe nada. A solução é muito barata: coloque o LDR no fundo de um tubo preto de 3–5 cm de comprimento (o corpo vazio de uma caneta esferográfica, um canudo preto ou um espaguete termorretrátil). O tubo só deixa entrar o laser que vem de frente e bloqueia a luz ambiente que vem dos lados.
| Situação | Resistência do LDR (exemplo) | analogRead com 10 kΩ | analogRead com 3,3 kΩ |
|---|---|---|---|
| Laser sobre o LDR (dentro de um tubo) | 300 Ω | 993 | 938 |
| Feixe interrompido (dentro de um tubo) | 30 kΩ | 256 | 101 |
| Feixe interrompido (sem tubo, cômodo iluminado) | 3 kΩ | 787 | 536 |
| Diferença entre com e sem feixe (dentro de um tubo) | – | 737 | 837 |
Passo a passo: alarme de barreira laser com Arduino
- Ligue o pino S do KY-008 ao D7 e o pino − ao GND; deixe o pino do meio desconectado (ligue-o ao 5V se o laser não acender).
- Ligue um terminal do LDR ao 5V e o outro ao A0; coloque um resistor de 3,3 kΩ ou 10 kΩ entre A0 e GND.
- Coloque o LDR no fundo de um tubo preto e aponte a abertura do tubo para o laser.
- Ligue o terminal + do buzzer ativo ao D8 e o terminal − ao GND. Coloque o botão de silenciar entre D4 e GND; não é preciso resistor extra, porque o pull-up interno é usado.
- Fixe o laser e o LDR em uma base firme; primeiro encontre o ponto do laser com uma folha de papel branco e depois guie-o para dentro do tubo.
- Carregue o sketch e abra o Monitor Serial em 9600 baud. Ninguém deve estar na frente do feixe na inicialização; o Arduino se calibra desligando e ligando o laser uma vez.
1// KY-008 lazer + LDR ile lazerli alarm / Laser tripwire alarm with KY-008 + LDR
2const int LASER_PIN = 7; // KY-008 S pini ya da transistör bazı / KY-008 S pin or transistor base
3const int LDR_PIN = A0; // LDR bölücü çıkışı / LDR divider output
4const int BUZZER_PIN = 8; // aktif buzzer / active buzzer
5const int LED_PIN = 13; // kart üzerindeki LED / on-board LED
6const int RESET_PIN = 4; // susturma butonu, diğer ucu GND / silence button, other leg to GND
7
8const int BREAK_PCT = 40; // %40'ın altı = ışın kesik / below 40% = beam broken
9const int RESTORE_PCT = 60; // %60'ın üstü = ışın sağlam / above 60% = beam intact
10const unsigned long CONFIRM_MS = 30; // en az bu kadar kesik kalmalı / must stay broken this long
11const unsigned long ALARM_MS = 10000; // alarm süresi / alarm duration
12
13int onLevel = 0, offLevel = 0; // ışınlı ve ışınsız ölçüm / reading with and without the beam
14bool beamOk = true;
15bool alarmOn = false;
16unsigned long brokenSince = 0;
17unsigned long alarmStart = 0;
18
19int readAvg() {
20 long sum = 0;
21 for (int i = 0; i < 8; i++) sum += analogRead(LDR_PIN); // 8 ölçüm ortalaması / average of 8 readings
22 return sum / 8;
23}
24
25void calibrate() {
26 while (true) {
27 digitalWrite(LASER_PIN, LOW); // lazer kapalı = kesik ışın / laser off = broken beam
28 delay(300); // LDR yavaştır, bekle / the LDR is slow, wait
29 offLevel = readAvg();
30 digitalWrite(LASER_PIN, HIGH); // lazer açık = sağlam ışın / laser on = intact beam
31 delay(300);
32 onLevel = readAvg();
33 Serial.print(F("Isinli / beam: "));
34 Serial.print(onLevel);
35 Serial.print(F(" Isinsiz / no beam: "));
36 Serial.println(offLevel);
37 if (abs(onLevel - offLevel) >= 100) return; // yeterli fark var / enough difference
38 Serial.println(F("Isin LDR'ye ulasmiyor, hizala! / Beam misses the LDR, align it!"));
39 delay(2000);
40 }
41}
42
43// 100 = ışın tam, 0 = ışın yok; LDR'nin yönü fark etmez / 100 = full beam, 0 = no beam; LDR polarity doesn't matter
44int beamPercent() {
45 return (long)(readAvg() - offLevel) * 100 / (onLevel - offLevel);
46}
47
48void setup() {
49 Serial.begin(9600);
50 pinMode(LASER_PIN, OUTPUT);
51 pinMode(BUZZER_PIN, OUTPUT);
52 pinMode(LED_PIN, OUTPUT);
53 pinMode(RESET_PIN, INPUT_PULLUP);
54 calibrate();
55 Serial.println(F("Alarm hazir / Alarm armed"));
56}
57
58void loop() {
59 unsigned long now = millis();
60 int pct = beamPercent();
61
62 if (beamOk && pct < BREAK_PCT) { // ışın yeni kesildi / beam just broke
63 beamOk = false;
64 brokenSince = now;
65 } else if (!beamOk && pct > RESTORE_PCT) {
66 beamOk = true; // ışın geri geldi / beam restored
67 }
68
69 if (!beamOk && !alarmOn && now - brokenSince >= CONFIRM_MS) {
70 alarmOn = true;
71 alarmStart = now;
72 Serial.println(F("ALARM: isin kesildi! / beam broken!"));
73 }
74
75 if (alarmOn && (now - alarmStart >= ALARM_MS || digitalRead(RESET_PIN) == LOW)) {
76 alarmOn = false; // süre doldu ya da butona basıldı / timeout or button pressed
77 }
78
79 digitalWrite(LED_PIN, beamOk ? LOW : HIGH);
80 digitalWrite(BUZZER_PIN, (alarmOn && (now / 200) % 2) ? HIGH : LOW); // kesik siren / beeping siren
81}O sketch não usa um limite fixo. Na inicialização, calibrate() desliga o laser e mede o valor do LDR sem o feixe, depois liga o laser e mede o valor com o feixe. beamPercent() converte cada leitura em uma porcentagem entre 0 e 100 com base nesses dois valores: 100 significa que o feixe está chegando inteiro, 0 que está totalmente bloqueado. Esse cálculo não depende de o LDR estar em cima ou embaixo no divisor; o resultado é o mesmo, quer a leitura suba ou desça com a luz. Se o feixe cair abaixo de 40% e ficar assim por pelo menos 30 ms, o alarme apita de forma intermitente por 10 segundos, e o botão no D4 o silencia antes. Se o feixe continuar interrompido, o alarme recomeça; ou seja, o sistema não fica quieto enquanto alguém estiver parado no feixe.
Calibração do limite: por que não fixar um número no código
Muitos exemplos de alarme laser na internet usam um limite fixo como “analogRead(A0) < 500”. Isso funciona na noite em que você testa na mesa, mas falha na manhã seguinte, quando o sol entra no cômodo, quando você mexe o laser alguns milímetros ou quando troca o LDR. O limite certo fica exatamente no meio entre as leituras com e sem feixe. A calibração automática, que mede os dois valores de novo a cada inicialização, adapta o sistema ao ambiente. No sketch acima o limite não é um número, mas dois: o feixe é considerado interrompido quando cai abaixo de 40% e intacto quando sobe acima de 60%. Essa folga se chama histerese; ela impede que o alarme ligue e desligue dezenas de vezes por segundo quando a leitura fica oscilando bem em cima do limite.
| Ajuste | Valor no código | Para que serve? | Quando mudar? |
|---|---|---|---|
| BREAK_PCT | 40 | Nível em que o feixe é considerado interrompido | Suba para 60–70 para detectar também objetos semitransparentes (vidro, tecido fino) |
| RESTORE_PCT | 60 | Nível em que o feixe volta a ser considerado intacto | Mantenha sempre 15–20 pontos acima de BREAK_PCT |
| CONFIRM_MS | 30 | Ignora interferências curtas (insetos, poeira, vibração) | Suba para 100–200 ms se houver alarmes falsos; diminua se passagens rápidas estiverem escapando |
| Número de leituras na média | 8 | Suaviza o ruído elétrico e a cintilação das lâmpadas | Cada leitura leva cerca de 0,1 ms no Uno; 8 leituras ficam abaixo de 1 ms |
| Diferença de calibração | 100 | Interrompe a configuração se o feixe não chegar ao LDR | Você pode baixar para 50 em distâncias muito longas ou em cômodos muito iluminados |
Em um sistema que fica ligado por muito tempo, a luz ambiente muda aos poucos ao longo do dia. Um jeito fácil de compensar é chamar calibrate() de novo enquanto o feixe está intacto e o alarme não está tocando (a cada hora, por exemplo). Como é o próprio Arduino que desliga o laser, ele não confunde esse breve escuro com um intruso. O Plotter Serial do Arduino IDE é muito útil para acompanhar as leituras: passe a mão pelo feixe e você verá o quanto o gráfico cai e quanto tempo leva para se recuperar.
Vários feixes com espelhos: uma rede com um só laser
Um único feixe é fácil de driblar, abaixando-se sob ele ou passando por cima. Para montar as redes de laser que você vê nos filmes, em vez de dar a cada feixe seu próprio laser e LDR, você pode fazer um só laser ricochetear em zigue-zague com espelhos. Você coloca espelhos frente a frente dos dois lados de uma porta ou corredor; o feixe vai quicando de um lado para o outro e finalmente chega ao LDR. Se qualquer trecho for interrompido, o LDR fica no escuro; assim, um único LDR e o mesmo sketch protegem a rede inteira. Como o ângulo de reflexão é igual ao ângulo de incidência, basta inclinar cada espelho muito levemente para que ele mande o feixe ao centro do próximo.
Cada espelho perde um pouco da luz. Um espelho de banheiro comum reflete cerca de 90% e produz um segundo ponto fraco (um reflexo fantasma) causado pelo vidro da frente. Os espelhos de primeira superfície, cuja camada refletora fica por cima do vidro, refletem 95% ou mais e dão um único ponto limpo. As perdas se multiplicam, então a luz que chega ao LDR cai rapidamente à medida que você acrescenta espelhos:
| Número de espelhos | Espelho comum (90%) | Espelho de primeira superfície (95%) |
|---|---|---|
| 1 | 90% | 95% |
| 2 | 81% | 90% |
| 4 | 66% | 81% |
| 6 | 53% | 74% |
| 8 | 43% | 66% |
Essa tabela mostra algo importante: mesmo 43% é mais do que suficiente para o sketch calibrado, porque o ponto do laser é centenas de vezes mais brilhante que a luz ambiente. O verdadeiro desafio não é a perda de potência, e sim o alinhamento. Quanto mais longo o caminho do feixe, mais um pequeno erro de ângulo cresce: um erro de 1 grau desloca o ponto em cerca de 9 cm a 5 m. O feixe de um laser barato também se alarga um pouco pelo caminho; depois de alguns metros, o ponto pode ficar maior que a superfície de 5 mm do LDR.
- Monte o laser, os espelhos e o tubo do LDR em suportes firmes (cantoneiras em L parafusadas, suportes impressos em 3D ou blocos de madeira fixados com cola quente); um espelho segurado na mão nunca fica alinhado.
- Diminua a luz do cômodo e encontre o ponto do laser segurando um papel branco na frente do primeiro espelho.
- Alinhe os espelhos em ordem, do início ao fim: incline cada um muito levemente até o ponto cair no centro do próximo espelho.
- Direcione o último feixe para a abertura do tubo do LDR e rode o sketch de teste para achar a posição em que a diferença no Monitor Serial é maior.
- Quando tudo estiver alinhado, trave o ângulo dos espelhos com cola quente ou um parafuso de trava; até uma pequena batida na mesa pode estragar o alinhamento.
- Teste cada trecho da rede interrompendo-o com a mão, um por um, e confirme que o alarme toca todas as vezes.
Contador de passagens: quantos passaram e por quanto tempo?
A mesma barreira pode contar pessoas passando por uma porta, caixas andando em uma esteira ou bolas caindo em um cesto. O segredo é contar cada passagem uma vez só. O sketch abaixo registra o instante em que o feixe é interrompido e conta a passagem quando o feixe volta; assim, alguém que fica parado no feixe por um tempo ainda conta como uma única passagem. Interrupções menores que 15 ms são tratadas como poeira ou ruído elétrico e ignoradas. O sketch também mostra por quanto tempo o feixe ficou bloqueado: se você sabe o comprimento do objeto, esse tempo dá diretamente a velocidade (v = L / t). Por exemplo, se um carrinho de brinquedo de 25 cm bloqueia o feixe por 50 ms, a velocidade dele é 0,25 / 0,05 = 5 m/s.
1// Lazer bariyeriyle geçiş sayacı ve kesilme süresi / Laser barrier pass counter and block time
2const int LASER_PIN = 7; // KY-008 S pini / KY-008 S pin
3const int LDR_PIN = A0; // LDR bölücü çıkışı / LDR divider output
4const unsigned long MIN_BREAK_MS = 15; // daha kısa kesintiler parazittir / shorter breaks are noise
5const float OBJECT_LENGTH_M = 0.0; // cismin boyu biliniyorsa yaz (ör. 0.25) / object length if known (e.g. 0.25)
6
7int onLevel = 0, offLevel = 0;
8bool beamOk = true;
9unsigned long brokenSince = 0;
10unsigned long passCount = 0;
11
12int readAvg() {
13 long sum = 0;
14 for (int i = 0; i < 4; i++) sum += analogRead(LDR_PIN); // 4 ölçüm yeterli ve hızlı / 4 readings: enough and fast
15 return sum / 4;
16}
17
18void calibrate() {
19 while (true) {
20 digitalWrite(LASER_PIN, LOW);
21 delay(300);
22 offLevel = readAvg();
23 digitalWrite(LASER_PIN, HIGH);
24 delay(300);
25 onLevel = readAvg();
26 if (abs(onLevel - offLevel) >= 100) return;
27 Serial.println(F("Isin LDR'ye ulasmiyor / Beam misses the LDR"));
28 delay(2000);
29 }
30}
31
32int beamPercent() {
33 return (long)(readAvg() - offLevel) * 100 / (onLevel - offLevel);
34}
35
36void setup() {
37 Serial.begin(9600);
38 pinMode(LASER_PIN, OUTPUT);
39 calibrate();
40 Serial.println(F("Sayac hazir / Counter ready"));
41}
42
43void loop() {
44 unsigned long now = millis();
45 int pct = beamPercent();
46
47 if (beamOk && pct < 40) {
48 beamOk = false;
49 brokenSince = now; // kesilme anı / moment of the break
50 } else if (!beamOk && pct > 60) {
51 beamOk = true;
52 unsigned long blocked = now - brokenSince; // ışın ne kadar kesik kaldı / how long the beam was blocked
53 if (blocked >= MIN_BREAK_MS) {
54 passCount++;
55 Serial.print(F("Gecis / Pass #"));
56 Serial.print(passCount);
57 Serial.print(F(" Sure / Time: "));
58 Serial.print(blocked);
59 Serial.print(F(" ms"));
60 if (OBJECT_LENGTH_M > 0) {
61 float speed = OBJECT_LENGTH_M / (blocked / 1000.0); // v = L / t
62 Serial.print(F(" Hiz / Speed: "));
63 Serial.print(speed, 2);
64 Serial.print(F(" m/s"));
65 }
66 Serial.println();
67 }
68 }
69}Se quiser saber em que sentido a pessoa passa, use dois feixes paralelos separados por 10–15 cm. Se o feixe externo A for interrompido primeiro e depois o interno B, a pessoa está entrando; se B for interrompido primeiro e depois A, ela está saindo. Se só A for interrompido e o feixe voltar sem B ser interrompido, a pessoa se aproximou da porta e desistiu, então não conta. O número de pessoas dentro é obtido subtraindo as saídas das entradas, e você pode mostrá-lo em um display de 7 segmentos ou em um display LCD I2C. A distância entre os dois feixes deve ser pequena o bastante para que o corpo de uma pessoa bloqueie os dois ao mesmo tempo por um instante.
Cronômetro de corrida e medição de velocidade
Medir o tempo entre duas portas laser dá um cronômetro preciso para corrida, ciclismo, carrinhos de brinquedo ou experimentos de física. Você monta as portas de largada e de chegada a uma distância conhecida (d) uma da outra, e a velocidade é v = d / t. Quem corre uma pista de 10 m em 2,5 segundos está correndo a 4 m por segundo, ou 14,4 km/h. Para ligar e desligar os dois lasers juntos, ligue o pino − de cada um ao coletor de um único transistor 2N2222 ou S8050; ligue os pinos S e do meio ao 5V, o emissor do transistor ao GND e a base ao D7 através de 1 kΩ. O LDR da porta de largada vai ao A0 e o da porta de chegada ao A1.
1// İki lazer kapılı yarış zamanlayıcı ve hız ölçer / Two-gate laser race timer and speed meter
2const int LASER_PIN = 7; // iki lazer tek transistörle / both lasers through one transistor
3const int START_LDR = A0; // başlangıç kapısı / start gate
4const int FINISH_LDR = A1; // bitiş kapısı / finish gate
5const int BUZZER_PIN = 8; // aktif buzzer / active buzzer
6const float DISTANCE_M = 10.0; // kapılar arası mesafe (metre) / distance between the gates (m)
7const unsigned long TIMEOUT_MS = 60000; // 60 sn'de bitmezse iptal / cancel after 60 s
8
9int onA, offA, onB, offB;
10enum State { READY, RUNNING, DONE };
11State state = READY;
12unsigned long startUs = 0;
13unsigned long startMs = 0;
14unsigned long doneMs = 0;
15
16int readAvg(int pin) {
17 long sum = 0;
18 for (int i = 0; i < 4; i++) sum += analogRead(pin);
19 return sum / 4;
20}
21
22bool isBroken(int pin, int on, int off) {
23 long pct = (long)(readAvg(pin) - off) * 100 / (on - off);
24 return pct < 40; // %40'ın altı = kesik / below 40% = broken
25}
26
27void calibrate() {
28 while (true) {
29 digitalWrite(LASER_PIN, LOW); // iki lazer de kapalı / both lasers off
30 delay(300);
31 offA = readAvg(START_LDR);
32 offB = readAvg(FINISH_LDR);
33 digitalWrite(LASER_PIN, HIGH); // iki lazer de açık / both lasers on
34 delay(300);
35 onA = readAvg(START_LDR);
36 onB = readAvg(FINISH_LDR);
37 if (abs(onA - offA) >= 100 && abs(onB - offB) >= 100) return;
38 Serial.println(F("Kapilardan biri hizali degil / One gate is misaligned"));
39 delay(2000);
40 }
41}
42
43void beep(int ms) {
44 digitalWrite(BUZZER_PIN, HIGH);
45 delay(ms);
46 digitalWrite(BUZZER_PIN, LOW);
47}
48
49void setup() {
50 Serial.begin(9600);
51 pinMode(LASER_PIN, OUTPUT);
52 pinMode(BUZZER_PIN, OUTPUT);
53 calibrate();
54 Serial.println(F("Hazir: baslangic kapisini gec / Ready: cross the start gate"));
55}
56
57void loop() {
58 if (state == READY && isBroken(START_LDR, onA, offA)) {
59 startUs = micros(); // zamanı hemen al / grab the time immediately
60 startMs = millis();
61 state = RUNNING;
62 beep(30);
63 } else if (state == RUNNING) {
64 if (isBroken(FINISH_LDR, onB, offB)) {
65 unsigned long elapsedUs = micros() - startUs;
66 float seconds = elapsedUs / 1000000.0;
67 float speed = DISTANCE_M / seconds; // v = d / t
68 Serial.print(F("Sure / Time: "));
69 Serial.print(seconds, 3);
70 Serial.print(F(" s Hiz / Speed: "));
71 Serial.print(speed, 2);
72 Serial.print(F(" m/s = "));
73 Serial.print(speed * 3.6, 1);
74 Serial.println(F(" km/h"));
75 beep(300);
76 state = DONE;
77 doneMs = millis();
78 } else if (millis() - startMs > TIMEOUT_MS) {
79 Serial.println(F("Zaman asimi / Timeout"));
80 state = READY;
81 }
82 } else if (state == DONE && millis() - doneMs > 3000 &&
83 !isBroken(START_LDR, onA, offA) && !isBroken(FINISH_LDR, onB, offB)) {
84 state = READY; // 3 sn sonra yeni tur / new run after 3 s
85 Serial.println(F("Hazir / Ready"));
86 }
87}O sketch funciona como uma máquina de estados: no estado READY (pronto), ele registra o tempo com micros() quando o feixe de largada é interrompido e passa para RUNNING (correndo); quando o feixe de chegada é interrompido, mostra o tempo decorrido e a velocidade e, depois de 3 segundos, fica pronto para a próxima volta. Se a porta de chegada não for cruzada em 60 segundos, a volta é cancelada. Sendo honesto sobre a precisão: o código em si mede com resolução melhor que 1 ms, mas o LDR leva 10–30 ms para reagir ao escuro. Felizmente, como você usa o mesmo tipo de LDR nas duas portas, esse atraso acontece nas duas pontas e se cancela em grande parte; para corrida e ciclismo, o resultado é mais do que bom.
Notificações no celular com ESP32 (Telegram)
Para que o alarme seja útil quando você não está em casa, você pode usar um ESP32: no instante em que o feixe é interrompido, ele envia uma mensagem para o seu celular pelo Telegram. A ligação é como na tabela acima: o laser é alimentado pelo 5V e chaveado por um transistor NPN ligado ao GPIO 26, e o divisor do LDR é alimentado pelo 3V3 e ligado ao GPIO 34. Essa escolha não é aleatória: os pinos ADC2 do ESP32 não funcionam com o Wi-Fi ligado, então ligue sempre sensores analógicos em pinos ADC1 (GPIO 32–39). O ADC do ESP32 é de 12 bits e retorna valores de 0 a 4095; por isso a diferença mínima de calibração no código é 400. Mostramos em detalhes como criar o bot e obter o token e o chat ID no guia bot do Telegram com ESP32; para o sketch, instale as bibliotecas UniversalTelegramBot e ArduinoJson pelo Gerenciador de Bibliotecas.
1// ESP32 lazer bariyeri + Telegram bildirimi / ESP32 laser tripwire + Telegram notification
2#include <WiFi.h>
3#include <WiFiClientSecure.h>
4#include <UniversalTelegramBot.h> // ArduinoJson kütüphanesi de gerekir / also needs the ArduinoJson library
5
6const char* WIFI_SSID = "WIFI_ADI"; // Wi-Fi ağının adı / your Wi-Fi name
7const char* WIFI_PASS = "WIFI_SIFRESI"; // Wi-Fi şifren / your Wi-Fi password
8#define BOT_TOKEN "1234567890:ABCdefGhIJKlmNoPQRstuVWXyz" // BotFather'dan / from BotFather
9#define CHAT_ID "123456789" // senin chat ID'n / your chat ID
10
11const int LASER_PIN = 26; // NPN transistör bazına 1 kΩ ile / to the NPN base via 1 kΩ
12const int LDR_PIN = 34; // ADC1 pini, Wi-Fi ile çalışır / ADC1 pin, works with Wi-Fi
13const int BUZZER_PIN = 25; // aktif buzzer / active buzzer
14const unsigned long CONFIRM_MS = 30; // en az bu kadar kesik kalmalı / must stay broken this long
15const unsigned long SIREN_MS = 5000; // siren süresi / siren duration
16const unsigned long COOLDOWN_MS = 30000; // iki deneme arası en az 30 sn / at least 30 s between attempts
17
18WiFiClientSecure client;
19UniversalTelegramBot bot(BOT_TOKEN, client);
20
21int onLevel = 0, offLevel = 0;
22bool beamOk = true;
23bool counted = false; // bu kesinti sayıldı mı / has this break been counted
24unsigned long brokenSince = 0;
25bool sirenOn = false;
26unsigned long sirenStart = 0;
27unsigned long breakCount = 0;
28bool pending = false; // gönderilecek bildirim var / a notification is waiting
29bool triedOnce = false;
30unsigned long lastTry = 0;
31
32int readAvg() {
33 long sum = 0;
34 for (int i = 0; i < 16; i++) sum += analogRead(LDR_PIN); // 16 ölçüm ortalaması / average of 16 readings
35 return sum / 16;
36}
37
38void calibrate() {
39 while (true) {
40 digitalWrite(LASER_PIN, LOW); // lazer kapalı = kesik ışın / laser off = broken beam
41 delay(300);
42 offLevel = readAvg();
43 digitalWrite(LASER_PIN, HIGH); // lazer açık = sağlam ışın / laser on = intact beam
44 delay(300);
45 onLevel = readAvg();
46 Serial.printf("Isinli / beam: %d Isinsiz / no beam: %d\n", onLevel, offLevel);
47 if (abs(onLevel - offLevel) >= 400) return; // 12 bit ölçekte yeterli fark / enough gap on the 12-bit scale
48 Serial.println("Isin LDR'ye ulasmiyor / Beam misses the LDR");
49 delay(2000);
50 }
51}
52
53int beamPercent() {
54 return (long)(readAvg() - offLevel) * 100 / (onLevel - offLevel);
55}
56
57void setup() {
58 Serial.begin(115200);
59 pinMode(LASER_PIN, OUTPUT);
60 pinMode(BUZZER_PIN, OUTPUT);
61 calibrate();
62
63 WiFi.mode(WIFI_STA);
64 WiFi.begin(WIFI_SSID, WIFI_PASS);
65 client.setCACert(TELEGRAM_CERTIFICATE_ROOT); // api.telegram.org kök sertifikası / root certificate
66 unsigned long start = millis();
67 while (WiFi.status() != WL_CONNECTED && millis() - start < 15000) { // en fazla 15 sn bekle / wait up to 15 s
68 delay(500);
69 Serial.print(".");
70 }
71 if (WiFi.status() == WL_CONNECTED) {
72 Serial.println(WiFi.localIP());
73 bot.sendMessage(CHAT_ID, "Lazer alarmi devrede / Laser alarm armed", "");
74 }
75}
76
77void loop() {
78 unsigned long now = millis();
79 int pct = beamPercent();
80
81 if (beamOk && pct < 40) { // ışın yeni kesildi / beam just broke
82 beamOk = false;
83 counted = false;
84 brokenSince = now;
85 } else if (!beamOk && pct > 60) {
86 beamOk = true; // ışın geri geldi / beam restored
87 }
88
89 if (!beamOk && !counted && now - brokenSince >= CONFIRM_MS) {
90 counted = true; // her kesinti bir kez sayılır / each break counts once
91 breakCount++;
92 pending = true;
93 sirenOn = true;
94 sirenStart = now;
95 Serial.printf("Kesinti / Break #%lu\n", breakCount);
96 }
97
98 if (sirenOn && now - sirenStart >= SIREN_MS) sirenOn = false;
99 digitalWrite(BUZZER_PIN, (sirenOn && (now / 200) % 2) ? HIGH : LOW); // kesik siren / beeping siren
100
101 if (pending && (!triedOnce || now - lastTry >= COOLDOWN_MS)) {
102 triedOnce = true;
103 lastTry = now;
104 if (WiFi.status() == WL_CONNECTED) {
105 String text = "Lazer bariyeri kesildi! / Laser beam broken! Toplam / Total: " + String(breakCount);
106 if (bot.sendMessage(CHAT_ID, text, "")) pending = false; // gitmezse 30 sn sonra yeniden / retry in 30 s if it fails
107 } else {
108 WiFi.reconnect(); // bağlantı koptuysa yeniden dene / reconnect if the link dropped
109 }
110 }
111}Cada interrupção é contada uma vez, a sirene toca por 5 segundos e uma notificação entra na fila. As notificações são tentadas no máximo uma vez a cada 30 segundos; novas interrupções que acontecem nesse meio-tempo são somadas ao total e aparecem na próxima mensagem. Assim, seu celular não é inundado de mensagens enquanto alguém vai e volta pelo feixe. Se uma mensagem não puder ser enviada, o código tenta de novo 30 segundos depois e, se o Wi-Fi tiver caído, começa a reconectar. sendMessage() leva um ou dois segundos, porque abre uma conexão HTTPS segura; durante esse tempo o padrão da sirene congela e o feixe não é monitorado, o que é normal.
Barreira laser com Raspberry Pi Pico e MicroPython
No Raspberry Pi Pico, você monta a mesma lógica em poucas linhas de MicroPython. O laser é alimentado pelo VBUS (5 V do USB, pino 40) e chaveado por um transistor NPN ligado ao GP15; o divisor do LDR é alimentado pelo pino 3V3(OUT) e ligado ao GP26 (ADC0), e o buzzer ativo vai ao GP14. Como o ADC do Pico retorna valores de 0 a 65535 com read_u16(), a diferença mínima de calibração é 6000. O código usa o mesmo cálculo de porcentagem, a mesma histerese e o mesmo tempo de confirmação; ele conta cada interrupção, toca a sirene por 5 segundos e mostra por quanto tempo o feixe ficou bloqueado. Para o Pico funcionar sem computador, salve o arquivo na placa como main.py usando o Thonny.
1# Raspberry Pi Pico lazer bariyeri: alarm + geçiş sayacı / Laser barrier: alarm + pass counter
2from machine import Pin, ADC
3import time
4
5laser = Pin(15, Pin.OUT) # NPN transistör bazına 1 kΩ ile / to the NPN base via 1 kΩ
6ldr = ADC(26) # GP26 = ADC0, bölücü 3V3'ten / divider fed from 3V3
7buzzer = Pin(14, Pin.OUT) # aktif buzzer / active buzzer
8
9CONFIRM_MS = 30 # en az bu kadar kesik kalmalı / must stay broken this long
10SIREN_MS = 5000 # siren süresi / siren duration
11
12
13def read_avg(n=8):
14 total = 0
15 for _ in range(n):
16 total += ldr.read_u16()
17 return total // n
18
19
20def calibrate():
21 while True:
22 laser.value(0) # lazer kapalı = kesik ışın / laser off = broken beam
23 time.sleep_ms(300)
24 off = read_avg(32)
25 laser.value(1) # lazer açık = sağlam ışın / laser on = intact beam
26 time.sleep_ms(300)
27 on = read_avg(32)
28 print("Isinli / beam:", on, " Isinsiz / no beam:", off)
29 if abs(on - off) > 6000: # 16 bit ölçekte yeterli fark / enough gap on the 16-bit scale
30 return on, off
31 print("Isin LDR'ye ulasmiyor / Beam misses the LDR")
32 time.sleep(2)
33
34
35on_level, off_level = calibrate()
36beam_ok = True
37counted = False
38broken_at = time.ticks_ms()
39siren_until = time.ticks_ms()
40count = 0
41
42while True:
43 now = time.ticks_ms()
44 pct = (read_avg() - off_level) * 100 // (on_level - off_level) # 100 = ışın tam / full beam
45
46 if beam_ok and pct < 40: # ışın yeni kesildi / beam just broke
47 beam_ok = False
48 counted = False
49 broken_at = now
50 elif not beam_ok and pct > 60: # ışın geri geldi / beam restored
51 beam_ok = True
52 print("Kesik kaldigi sure / blocked for", time.ticks_diff(now, broken_at), "ms")
53
54 if not beam_ok and not counted and time.ticks_diff(now, broken_at) >= CONFIRM_MS:
55 counted = True # her kesinti bir kez sayılır / each break counts once
56 count += 1
57 siren_until = time.ticks_add(now, SIREN_MS)
58 print("Gecis / Pass:", count)
59
60 siren = time.ticks_diff(siren_until, now) > 0
61 buzzer.value(1 if siren and (now // 200) % 2 else 0) # kesik siren / beeping sirenIdeias de projetos com módulo laser
- Alarme residencial a laser: combine feixes na porta e no corredor com um sensor de movimento PIR e reúna todas as entradas em uma única central; detalhes no guia sistema de alarme com Arduino.
- Harpa laser: monte 5–7 feixes lado a lado e toque uma nota diferente em um buzzer passivo sempre que um feixe for interrompido.
- Contador de visitantes: separe entradas e saídas com dois feixes e mostre em um display o número de pessoas dentro.
- Medidor de velocidade para feira de ciências: use duas portas para medir a velocidade de objetos descendo um plano inclinado e compare o atrito; para mais ideias, veja o guia ideias de projetos para feira de ciências.
- Jogo de labirinto laser: monte com espelhos uma rede de feixes abaixo da altura dos joelhos; cronometre quem tenta atravessar sem encostar e acrescente uma penalidade a cada toque.
- Proteção de gaveta e cofre: detecte a interrupção do feixe quando a tampa abrir e envie uma notificação ao seu celular com um ESP32.
Erros comuns e como resolvê-los
| Sintoma | Causa provável | Solução |
|---|---|---|
| O laser não acende de jeito nenhum | S e − invertidos, ou uma placa cujo pino do meio precisa de alimentação | Confira as marcações dos pinos, ligue o pino do meio ao 5V e tente de novo |
| O laser está muito fraco | O módulo está alimentado com 3,3 V ou o pino não fornece corrente suficiente | Alimente o laser pelo 5V e chaveie-o com um transistor |
| Mensagem “Isin LDR'ye ulasmiyor” (o feixe não chega ao LDR) | O ponto não está sobre o LDR ou a luz ambiente está forte demais | Encontre o ponto com papel e coloque o LDR em um tubo preto |
| O alarme não para de tocar | O alinhamento saiu do lugar, o laser ou um espelho está balançando | Fixe bem os suportes e acompanhe a leitura no Plotter Serial |
| O alarme nunca toca | Mesmo com o feixe interrompido, a luz do sol ou de uma lâmpada mantém o LDR iluminado | Acrescente um tubo e vire o sensor para longe da janela |
| Passagens rápidas não são contadas | O tempo de resposta do LDR (10–30 ms) é lento demais | Diminua CONFIRM_MS e MIN_BREAK_MS ou use um fototransistor |
| O Arduino reinicia ou um pino esquenta | Vários lasers estão sendo acionados por um só pino | Alimente os lasers pelo 5V e chaveie-os com um transistor |
| No ESP32, a leitura fica errada quando o Wi-Fi liga | O LDR está em um pino ADC2 | Mude o LDR para um pino ADC1 entre GPIO 32 e 39 |
| Nenhuma mensagem do Telegram chega | Token ou chat ID errado, ou você nunca mandou mensagem para o bot | Envie /start para o bot e confira de novo o token e o chat ID |
O módulo laser KY-008 torna possível um dos raros projetos que ensinam óptica, divisor de tensão, calibração e medição de tempo ao mesmo tempo, com um único componente barato. Comece vendo a diferença com o sketch de teste, depois monte o alarme e faça seu projeto crescer com espelhos, um contador e um cronômetro. No app BlueGrays você encontra, passo a passo e com esquema do circuito e código, os projetos de sistema de aviso e segurança a laser, medição de luz e luz noturna com LDR, alarme de movimento com ESP32 e notificação pelo Telegram.
Perguntas frequentes
Com que tensão o módulo laser KY-008 funciona?
O KY-008 foi projetado para 5 V e, graças ao resistor limitador de corrente do módulo, pode ser ligado diretamente a um pino digital do Arduino Uno. Ele também acende em 3,3 V, mas mais fraco. Nunca alimente o módulo com mais de 5 V e nunca alimente o diodo laser sem o resistor.
Um laser de 5 mW pode danificar os olhos?
Um laser vermelho de 5 mW é Classe 3R: uma exposição breve e acidental geralmente não causa dano permanente, mas olhar fixamente para o feixe ou receber nos olhos o reflexo de um espelho pode lesionar a retina. Mantenha o feixe abaixo da altura dos olhos, nunca aponte para pessoas ou animais e, em montagens com espelhos, confira todo o caminho do feixe.
Até que distância funciona uma barreira laser?
O alinhamento e a luz ambiente limitam a distância mais do que a potência do laser. Com suportes firmes e um LDR dentro de um tubo preto, funciona bem por 10–20 m em ambientes internos; em distâncias maiores o ponto cresce e menos luz cai sobre o LDR. Ao ar livre, a luz do sol, a neblina e a trepidação causada pelo vento reduzem bastante o alcance.
O que posso usar no lugar do LDR em uma barreira laser?
O LDR é barato e fácil, mas o tempo de resposta dele é de 10–30 ms. Para cronômetros e contadores que precisam de medições mais rápidas, usa-se um fototransistor ou fotodiodo, que reage em microssegundos. Também existem módulos receptores de laser prontos; eles dão uma saída digital quando recebem luz e são ligados diretamente a um pino digital.
O módulo laser funciona com ESP32 e Raspberry Pi Pico?
Sim, mas em vez de alimentar o laser direto de um pino, é melhor alimentá-lo pelo 5V e chaveá-lo com um transistor NPN; os pinos do Pico fornecem só 4 mA por padrão. Nessas placas, alimente o divisor do LDR pelo 3V3 e, no ESP32, use um pino ADC1 (GPIO 32–39), que funciona junto com o Wi-Fi.
Uma barreira de feixe infravermelho é melhor que um alarme laser?
Sistemas de segurança profissionais usam feixes infravermelhos invisíveis e receptores modulados; o feixe não pode ser visto e, graças à modulação, quase não é afetado pela luz do sol. Já o laser vermelho é visível e, por isso, muito fácil de alinhar, o que o torna ideal para projetos de aprendizado, contadores e cronômetros.
Projetos para montar depois desta leitura
Ver todos os projetos
Medição da intensidade da luz com LDR
Quer ver a luminosidade do seu quarto em números? O LDR, um pequeno componente sensível à luz, mede a luz ambiente, e o Arduino exibe o valor na tela do computador a cada meio segundo. Cubra o sensor

Luz noturna com LDR
Uma pequena luz noturna que acende sozinha quando escurece e apaga ao amanhecer. Um sensor de luz mede a luminosidade do quarto, e o Arduino acende o LED quando está escuro o suficiente e apaga quando

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.

Sistema de alerta com laser
Você monta uma barreira de luz invisível, como nos filmes. Um laser ilumina um sensor de luz do outro lado; assim que alguém passa e interrompe o feixe, o LED acende e o buzzer soa. Quando o feixe vol

Sistema de segurança com laser
Como nas cenas de roubo com lasers dos filmes: um feixe de laser atinge um sensor de luz e, assim que alguém passa e interrompe o feixe, o LED vermelho acende e o buzzer começa a soar. O alarme não pa

Luz noturna com LDR e ESP32
Uma luz noturna em que o LED acende automaticamente no escuro e apaga na claridade. Usamos o pino D0 (saída digital) do módulo sensor LDR. O pequeno potenciômetro no módulo ajusta o limiar de escuridão, e o próprio módulo gera a saída HIGH/LOW. O ESP32 apenas lê esse sinal com digitalRead(), deixando o código bem simples.

Alarme de movimento com ESP32 (PIR + buzzer + LED + Telegram)
Um sistema de alarme de segurança inteligente que aciona o buzzer e o LED quando o sensor PIR detecta movimento e, ao mesmo tempo, envia uma notificação instantânea ao proprietário pelo Telegram. Inclui um intervalo de espera de 30 segundos para limitar a frequência dos alarmes repetidos; esse mecanismo não valida as detecções do PIR nem elimina disparos falsos. Pode ser usado na segurança de casas, no monitoramento de garagens, depósitos ou salas de trabalho.
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

