Bloco se na programação em blocos: botão e LED no Arduino com if/else
Bloco se na programação em blocos com botão e LED no Arduino: leitura de pinos, if/else, =, ≠, <, >, ifs aninhados, liga/desliga, debounce e luz noturna com LDR.
O bloco se da programação em blocos permite que o programa escolha um de dois caminhos com base em uma pergunta: “O botão está pressionado? Se sim, acenda o LED; se não, apague.” No C++ do Arduino essa estrutura se chama if/else, e o bloco “se … fazer … senão” do BlueGrays é o equivalente exato dela. Neste post você vai usar um projeto de botão e LED no Arduino para aprender a configurar um pino como entrada e a lê-lo e, depois, o bloco se, os operadores de comparação, as condições aninhadas e como combinar duas condições com “e”, bloco a bloco e linha a linha.
Até agora nossos programas sempre faziam a mesma coisa: o LED acendia, esperava, apagava e esperava de novo. Eles nunca prestavam atenção no mundo lá fora. Com as condições, a placa passa a tomar decisões olhando para um botão, um sensor de luz ou uma distância que ela mede, e é aí que começa a verdadeira diversão da programação de robótica. Todos os exemplos daqui vêm de projetos em blocos grátis, então você pode abrir os blocos e o código deles na página de programação em blocos ou no app e acompanhar o texto lado a lado.
Entrada e saída: em que sentido o pino trabalha?
Os pinos digitais do Arduino fazem um de dois trabalhos. Um pino configurado como saída fornece 5 V (HIGH) ou 0 V (LOW); é assim que você aciona um LED, um buzzer ou um relé. Um pino configurado como entrada não fornece nada e só “escuta” a tensão que chega nele: no Arduino Uno, ele lê qualquer coisa acima de cerca de 3 V como HIGH e qualquer coisa abaixo de 1,5 V como LOW. Nos blocos, você faz essa escolha na seção de configuração: o bloco “configurar pino 13 como ENTRADA” vira pinMode(13, INPUT); em C++, e “configurar pino 7 como SAÍDA” vira pinMode(7, OUTPUT);. Para ler o pino, você usa o bloco “ler pino 13”. Ele tem uma aparência diferente dos outros: não é um comando que você empilha, e sim um bloco de valor de cantos arredondados que se encaixa em um espaço dentro de outro bloco. O equivalente dele em C++ é digitalRead(13), que retorna HIGH ou LOW (nos blocos, ALTO ou BAIXO). Como no Arduino HIGH vale 1 e LOW vale 0, você também pode guardar o resultado em uma variável, como se fosse um número. Resumindo: blocos de comando fazem algo, blocos de valor dão um resultado, e o encaixe de condição do bloco se só pode ser preenchido com um resultado desse tipo.
| Bloco | Equivalente em C++ | O que faz |
|---|---|---|
| configurar pino 13 como ENTRADA | pinMode(13, INPUT); | Coloca o pino em modo de escuta (uma vez, no setup) |
| configurar pino 7 como SAÍDA | pinMode(7, OUTPUT); | Permite que o pino forneça tensão |
| ler pino 13 | digitalRead(13) | Retorna HIGH (1) ou LOW (0) |
| escrever ALTO no pino 7 | digitalWrite(7, HIGH); | Coloca 5 V no pino e o LED acende |
| ler analógico A0 | analogRead(A0) | Retorna um número de 0 a 1023 |
| se … fazer … senão | if (…) { … } else { … } | Executa um de dois caminhos conforme a condição |
Circuito: botão no 13, LED no 7, resistor de pull-down obrigatório
No projeto Controle de LED com botão (momentâneo), o botão fica no D13 e o LED no D7. Uma perna do botão vai ao 5V e a outra ao D13, e um resistor de pull-down de 10 kΩ fica entre o D13 e o GND. Com o botão solto, o resistor puxa o pino para o GND e ele lê LOW. Quando você pressiona, o 5V chega direto ao pino e ele lê HIGH. Como o resistor é grande, só cerca de meio miliampère passa do 5V para o GND enquanto o botão está pressionado. A perna longa do LED se liga ao D7 por um resistor de 220 Ω e a perna curta vai ao GND.
| Peça | Liga-se a | Pino do Arduino Uno |
|---|---|---|
| Botão, perna 1 | Direto | 5V |
| Botão, perna 2 (diagonal) | Direto | D13 |
| Resistor de 10 kΩ (pull-down) | Entre D13 e GND | D13 – GND |
| Perna longa do LED (ânodo) | Por um resistor de 220 Ω | D7 |
| Perna curta do LED (cátodo) | Direto | GND |
O bloco se e o if/else: acender o LED enquanto o botão está pressionado
A versão em blocos do projeto tem duas seções. Em “configuração (uma vez)”, o pino 13 é configurado como ENTRADA e o pino 7 como SAÍDA. Em “repetir para sempre”, há um único bloco grande: se … fazer … senão. O encaixe hexagonal de condição dele guarda a comparação “ler pino 13 = ALTO”. Se a condição for verdadeira, roda o bloco “escrever ALTO no pino 7” do ramo “fazer”; se for falsa, roda o bloco “escrever BAIXO no pino 7” do ramo “senão”.

1void setup() {
2 pinMode(13, INPUT); // Buton girişi (harici pull-down) / Button input (external pull-down)
3 pinMode(7, OUTPUT); // LED çıkışı / LED output
4}
5
6void loop() {
7 if (digitalRead(13) == HIGH) { // Buton basılı mı? / Is the button pressed?
8 digitalWrite(7, HIGH); // Basılı: LED yanar / Pressed: LED on
9 } else {
10 digitalWrite(7, LOW); // Bırakıldı: LED söner / Released: LED off
11 }
12}
13Coloque o código ao lado dos blocos e a correspondência fica evidente. A palavra if corresponde ao “se” do bloco, a condição digitalRead(13) == HIGH entre parênteses corresponde ao encaixe de condição, o primeiro par de chaves corresponde ao ramo “fazer”, e o else com suas chaves corresponde ao ramo “senão”. Cada bloco que você coloca em um ramo vira uma linha dentro das chaves correspondentes no código. Como o loop() roda dezenas de milhares de vezes por segundo, a placa lê o botão sem parar; no instante em que você tira o dedo, a condição fica falsa no ciclo seguinte e o LED apaga. É por isso que o projeto é “momentâneo” (Push, no nome em inglês): o LED só fica aceso enquanto você segura o botão. O ramo “senão” é opcional; um bloco se só com o ramo “fazer” vira um if sem else. Mas, se você remover o ramo “senão” aqui, o LED nunca mais apaga depois de aceso, porque não sobra nenhuma linha para desligá-lo. Pensar nos dois ramos em toda condição é um bom hábito.
Blocos de comparação: =, ≠, < e >
| Símbolo no bloco | C++ | Significado | Exemplo dos projetos |
|---|---|---|---|
| = | == | igual a | digitalRead(13) == HIGH (LED com botão momentâneo) |
| ≠ | != | diferente de | button != lastButton (LED liga/desliga com botão) |
| < | < | menor que | value < 50 (luz noturna com LDR) |
| > | > | maior que | distance > minDistance (distância com HC-SR04) |
Liga/desliga com um botão: ifs aninhados e uma variável de estado
No projeto momentâneo, o LED só ficava aceso enquanto você segurava o botão. Se você quer que ele se comporte como um interruptor de luz de verdade, “aperte uma vez para ligar, aperte de novo para desligar”, o programa precisa lembrar duas coisas: se o LED está aceso agora e o que o botão leu no ciclo anterior. O projeto Ligar e desligar um LED com botão declara dois inteiros para isso na seção “variáveis globais (no topo)”: ledState (0 = apagado, 1 = aceso) e lastButton (a leitura anterior). O circuito é o mesmo de antes: botão no D13 com pull-down externo e LED no D7.

1int ledState = 0; // LED durumu: 0 = sönük, 1 = yanık / LED state: 0 = off, 1 = on
2int lastButton = 0; // Butonun önceki okuması / Previous button reading
3
4void setup() {
5 pinMode(13, INPUT); // Buton girişi (harici pull-down) / Button input (external pull-down)
6 pinMode(7, OUTPUT); // LED çıkışı / LED output
7}
8
9void loop() {
10 int button = digitalRead(13); // Butonu oku / Read the button
11 if (button != lastButton) { // Buton durumu değişti / Button state changed
12 if (button == 1) { // Yalnız basış anında (LOW -> HIGH) / Only at the press (LOW -> HIGH)
13 ledState = !ledState; // Durumu ters çevir / Flip the state
14 digitalWrite(7, ledState);
15 }
16 delay(50); // Sıçramayı atlamak için kısa bekleme / Short wait to skip the bounce
17 lastButton = button; // Bu okumayı sakla / Store this reading
18 }
19}
20| Bloco | Linha em C++ | Função |
|---|---|---|
| declarar inteiro (int) ledState = 0 | int ledState = 0; | Guarda o estado do LED |
| declarar inteiro (int) lastButton = 0 | int lastButton = 0; | Guarda a leitura anterior do botão |
| definir button como ler pino 13 | int button = digitalRead(13); | Lê o estado atual do botão |
| se button ≠ lastButton | if (button != lastButton) { | Entra se o estado do botão mudou |
| se button = 1 | if (button == 1) { | Entra se a mudança for um aperto (de 0 para 1) |
| definir ledState como não ledState | ledState = !ledState; | Transforma 0 em 1 e 1 em 0 |
| escrever ledState no pino 7 | digitalWrite(7, ledState); | Coloca o LED no novo estado |
| aguardar 50 ms | delay(50); | Ignora o repique dos contatos |
| definir lastButton como button | lastButton = button; | Guarda esta leitura para o próximo ciclo |
O coração do programa é o par de blocos se aninhados. A condição de fora, button ≠ lastButton, só é verdadeira no ciclo em que o estado do botão muda; nos milhares de ciclos em que você segura o botão ou nem encosta nele, nada acontece. Uma mudança pode ir em dois sentidos: um aperto (de 0 para 1) ou uma soltura (de 1 para 0). A condição de dentro, button = 1, escolhe só o aperto. Assim, o LED muda uma vez a cada aperto e não muda nada ao soltar. No código, ifs aninhados aparecem como chaves dentro de chaves. Nos blocos, o se de dentro fica no ramo “fazer” do de fora, então você vê de relance qual linha depende de qual condição.
O bloco não ledState é escrito !ledState em C++. O ponto de exclamação dá o oposto lógico: o oposto de 0 é 1, e o oposto de qualquer número diferente de zero é 0. Atribuir a ledState o seu próprio oposto inverte o estado a cada aperto. O bloco seguinte, “escrever ledState no pino 7”, é a linha digitalWrite(7, ledState); como HIGH vale 1 e LOW vale 0, o valor da variável pode ser escrito direto no pino. Por fim, lastButton recebe a leitura deste ciclo para que a comparação do próximo ciclo saia correta. Se você esquecer essa atribuição, lastButton fica em 0; enquanto você segura o botão, a condição de fora é verdadeira em todo ciclo e o LED pisca rapidamente.
Condição analógica: luz noturna com LDR
As condições não servem só para HIGH e LOW. No projeto Luz noturna com LDR, o bloco “definir value como ler analógico A0” transforma a tensão no A0, onde o LDR está ligado, em um número entre 0 e 1023; em C++, essa é a linha value = analogRead(A0);. Em seguida, o bloco se verifica value < 50. Se o valor estiver abaixo de 50, o ambiente conta como escuro e o LED no D13 acende; caso contrário, apaga. A estrutura é a mesma do projeto momentâneo; só muda a comparação no encaixe de condição.

1int value; // Işık okuması (0-1023) / Light reading (0-1023)
2
3void setup() {
4 pinMode(13, OUTPUT); // LED çıkışı / LED output
5}
6
7void loop() {
8 value = analogRead(A0); // Işık seviyesini oku / Read the light level
9
10 // Eşik 50: altı karanlık sayılır, hassasiyeti bu sayıyla ayarla
11 // Threshold 50: anything below counts as dark. Tune the sensitivity with this number
12 if (value < 50) {
13 digitalWrite(13, HIGH); // Karanlık: LED yanar / Dark: LED on
14 } else {
15 digitalWrite(13, LOW); // Aydınlık: LED söner / Bright: LED off
16 }
17}
18Dependendo do seu LDR e do resistor do circuito, um limite de 50 pode ser baixo ou alto demais para o seu cômodo. Para achar o número certo, use primeiro o projeto Medição da intensidade da luz com LDR para ver os valores de claro e escuro no Monitor Serial e depois coloque o limite entre eles. Se o valor ficar oscilando bem em volta do limite, o LED pode tremular; usar dois limites separados, um para ligar e outro para desligar, resolve isso de um jeito elegante. Você encontra como um LDR funciona no post sensor de luz LDR.
Combinando condições: o bloco “e” e o &&
Às vezes uma condição só não basta. No projeto Medição de distância com HC-SR04 (Monitor Serial), a distância medida só é exibida no Monitor Serial se estiver entre 3 cm e 100 cm. Nos blocos, duas comparações são unidas lado a lado com um bloco e: “distance > minDistance e distance < maxDistance”. Em C++, essa linha vira if (distance > minDistance && distance < maxDistance). O operador && torna o resultado verdadeiro só se os dois lados forem verdadeiros; se pelo menos um for falso, a condição é falsa. Assim, valores sem sentido fora do alcance do sensor nunca chegam à tela. Em C++, “ou” se escreve || e basta uma condição verdadeira. Você pode testar as tabelas-verdade de AND, OR e NOT na ferramenta Portas lógicas.
As mesmas condições no ESP32: pull-up interno e lógica invertida
O projeto Controle de LED com botão no ESP32 (momentâneo) usa o mesmo bloco se em um ESP32, com duas diferenças. O LED fica no GPIO 5, o botão no GPIO 4, e o pino do botão recebe a opção “ENTRADA (PULLUP)” no bloco “configurar pino … como …”. Em C++, isso é pinMode(BUTTON_PIN, INPUT_PULLUP);: um resistor dentro do chip puxa o pino para HIGH, então nenhum resistor externo é necessário. Desta vez o botão vai ao GND, por isso o pino lê LOW quando pressionado, e a condição vira “ler pino BUTTON_PIN = BAIXO”. O projeto Controle de LED com botão no ESP32 (alternância) faz o liga/desliga com o bloco “milissegundos desde o início”, ou seja, millis(), em vez de uma espera de 50 ms, e de novo une duas condições com um bloco “e”. Os pinos do ESP32 trabalham com 3,3 V; não ligue o botão ao 5 V.
Erros comuns e soluções
| Erro | Sintoma | Solução |
|---|---|---|
| Sem resistor de pull-down | O LED tremula sozinho e acende quando a mão chega perto | Coloque 10 kΩ entre D13 e GND, ou use INPUT_PULLUP e inverta a lógica |
| Igual simples na condição: if (button = 1) | O LED fica sempre aceso e ignora o botão | Use == para comparações |
| Ponto e vírgula no fim da linha do if | O código entre chaves roda em todo ciclo, independentemente da condição | Apague o ; depois de if (…) |
| Usar pernas do botão do mesmo lado | O pino lê sempre HIGH ou sempre LOW | Use pernas na diagonal |
| lastButton não atualizado ou falta de espera no liga/desliga | O LED pisca enquanto o botão está pressionado ou fica num estado aleatório | Adicione lastButton = button e a espera de 50 ms |
| Tratar HIGH como pressionado com INPUT_PULLUP | O LED funciona ao contrário e acende ao soltar | Com o pull-up interno, LOW significa pressionado |
| Limite do LDR inadequado para o cômodo | O LED nunca acende ou fica sempre aceso | Observe o valor no Monitor Serial e escolha um novo limite |
Abrindo blocos e código lado a lado no app
Todos os projetos deste post estão entre os projetos em blocos grátis do app BlueGrays. Ative a chave Ver em blocos na seção de código de um projeto e o código é substituído pelo mesmo programa em blocos; toque na imagem para abri-la em tela cheia. A aba Entenda os blocos explica o programa passo a passo: cada passo mostra só os blocos daquele passo e o que eles fazem, para que você acompanhe os blocos se aninhados um de cada vez. Os exemplos de if/else e digitalRead do Guia de código também aparecem em blocos. Os blocos não são carregados diretamente na placa e, por enquanto, você não pode montar seus próprios programas arrumando blocos; você sempre copia o código C++ real do projeto para o Arduino IDE e o carrega. Se quiser revisar o que aprendeu, as Perguntas do dia trazem 5 perguntas por dia, em níveis de A1 a C2.
Agora que você conhece as condições, o próximo passo é lidar com repetições e contadores: na parte de laços e variáveis, você vai ver como “repetir para sempre” se relaciona com o loop() e como o bloco de contagem se relaciona com um laço for. Até lá, você pode ver o esquema do circuito e o código dos projetos de LED com botão momentâneo, luz noturna com LDR e botão no ESP32 no app BlueGrays, passar para a visualização em blocos com Ver em blocos e para a explicação passo a passo com Entenda os blocos.
Perguntas frequentes
Para que serve o bloco se na programação em blocos?
O bloco se permite que o programa tome uma decisão: se a condição for verdadeira, rodam os blocos do ramo “fazer”; se for falsa, rodam os do ramo “senão”. Nos projetos com Arduino, ele costuma ser usado para verificar se um botão está pressionado ou se o valor de um sensor passou de um limite. O equivalente em C++ é a estrutura if/else.
Qual é a diferença entre if e else no Arduino?
O if executa o código entre as chaves dele quando a condição entre parênteses é verdadeira. O else é opcional e guarda o código que roda só quando a condição é falsa. Sem else, nada acontece quando a condição é falsa e o programa segue para a próxima linha.
Qual é a diferença entre = e == no Arduino?
Um sinal de igual simples (=) atribui um valor a uma variável, enquanto o sinal de igual duplo (==) compara dois valores. Escrever if (x = 1) atribui 1 a x e deixa a condição sempre verdadeira; a forma correta é if (x == 1). Nos blocos, o sinal “=” de um bloco de comparação vira == no código.
Por que o LED do meu Arduino acende sem eu apertar o botão?
O mais provável é que o pino do botão esteja flutuando, ou seja, sem resistor de pull-down ou pull-up. Aí o pino lê o ruído em volta e parece HIGH ou LOW ao acaso. Coloque um resistor de 10 kΩ entre o pino e o GND, ou use pinMode(pin, INPUT_PULLUP) e ligue o botão ao GND.
Como ligar e desligar um LED com um botão no Arduino?
Guarde o estado do LED em uma variável (ledState) e a leitura anterior do botão em outra (lastButton). Quando o estado do botão mudar e o novo estado for pressionado, inverta o estado com ledState = !ledState e escreva-o no LED com digitalWrite. Acrescente uma espera curta, como 50 ms, para ignorar o repique dos contatos; o projeto Ligar e desligar um LED com botão faz exatamente isso.
Posso carregar os blocos do BlueGrays no meu Arduino?
Não, os blocos não são carregados diretamente na placa. Eles correspondem um a um ao código real do projeto e servem para ajudar você a entender o programa. Você sempre copia o código C++ do projeto para o Arduino IDE e o carrega na placa.
Projetos para montar depois desta leitura
Ver todos os projetos
Controle de LED com botão (momentâneo)
É como uma campainha: a luz fica acesa enquanto você pressiona o botão e apaga quando você solta. O Arduino monitora o botão continuamente; enquanto ele está pressionado, o LED fica aceso e apaga assi

Ligar e desligar um LED com botão
Pressione o botão uma vez para acender a luz e outra vez para apagar, como o interruptor do seu quarto. O Arduino detecta cada toque e inverte o estado do LED, aguardando um breve instante para que as

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

Medição de distância com HC-SR04 (Monitor Serial)
O sensor HC-SR04 funciona como um morcego que se orienta no escuro: emite um som que você não consegue ouvir, escuta o eco e mede a distância até o objeto à sua frente. O Arduino escreve essa distânci

Controle de LED com botão no ESP32 (momentâneo)
O LED acende enquanto o botão está pressionado e apaga ao soltá-lo. Mostra como usar o pino de entrada digital e o resistor pull-up interno do ESP32. O modo INPUT_PULLUP dispensa um resistor externo.

Controle de LED com botão no ESP32 (alternância)
Cada vez que o botão é pressionado, o estado do LED muda: se estiver aceso, apaga; se estiver apagado, acende. É o padrão clássico de alternância. Com debounce, eliminamos o ruído mecânico dos contatos do botão para garantir uma única mudança a cada pressionamento.

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

LED piscante
O primeiro contato com a eletrônica: acender e apagar um único LED. O Arduino acende e apaga o LED em intervalos curtos, fazendo a luz piscar rapidamente. Você vê da forma mais simples como a placa co
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

