Início
/
Software
/
Dicas de Software
/
Onze maneiras diferentes de ligar e desligar um led com push button e Arduino
Onze maneiras diferentes de ligar e desligar um led com push button e Arduino
Angelo Luis Ferreira | 11/11/2021
Acessos: 13.794
Formas para ligar e desligar um led (programação Arduino)
Objetivo
O objetivo deste tutorial é mostrar formas diferentes de programação para ligar e desligar um led usando um único botão (push button) e o Arduino. Os formatos apresentados no tutorial poderão ser escolhidos para serem utilizados em aplicações nos seus projetos para ligar e desligar um led ou qualquer outro componente eletrônico.
Obs.: Os botões de pressão (push button) apenas mudam seu estado enquanto o botão está sendo pressionado, voltando ao seu estado original quando o botão é liberado. Neste projeto, vamos criar várias rotinas diferentes de programação para atribuir a um só botão duas funções de ligar e desligar um led ou um componente eletrônico qualquer.
Critérios utilizados
1. Circuito eletrônico
1.1. Para a montagem do push button no circuito, utilizaremos o sistema de resistor pull-up interno do Arduino.
1.1.1. Circuito Pull-up interno do Arduíno: Nível lógico (HIGH ou 1) no estado normal e Nível lógico (LOW ou 0) quando pressionado. Neste caso não precisaremos utilizar um resistor para garantir um nível estável, pois utilizaremos um resistor interno do Arduino. Para isto, basta habilitar o resitor pull-up interno do Arduino através da programação, utilizando pinMode(). Leia: Como usar o push button com Arduino (programação)
1.2. A montagem do circuito deverá ser constituída de um botão (push button) conectado na entrada do Arduino, porta digital 2, e o led conectado na saída do Arduino, porta digital 8. Utilize um resistor de 150Ω ou superior para a montagem do led. Leia: Projeto 02b - Led apaga com push button pressionado (pull-up interno do Arduino) Veja o desenho da montagem abaixo:
2. Tipo de ação do botão (push button)
2.1. Como critério adotaremos o padrão para que o a carga (led) seja acionada (liga ou desliga) ao pressionarmos o botão. Desta forma, quando pressionarmos o botão, nível lógico LOW, o led será ativado ou desativado, e ao soltarmos o botão será iniciado um novo ciclo.
2.2. Ao manter o botão pressionado a ação não será repetida, ou seja, o programa irá esperar que o botão seja liberado para iniciar um novo ciclo. Para isso podemos utilizar a linha de comando: while (!digitalRead(buttonPin)) {}
Forma nº 1 - Com state dentro do loop
3. Esta é a forma mais clássica e muito utilizada pelos programadores. Começamos com a variável "state = 0" e vamos alternando entre 0 (false) e 1 (true) a cada vez que pressionamos o botão. Teste o código abaixo:
3.1. Leia o Projeto 04a - Push Button como interruptor - liga e desliga (padrão para pull-down ou pull-up) que explica os detalhes do projeto.
/*******************************************************************************
*
* Programação 1 – Push button com funão liga / desliga
* http://squids.com.br/arduino
*
*******************************************************************************/
// set pinos Arduino
const int buttonPin = 2; // entrada digital - pushbutton
const int ledPin = 8; // saída digital - LED
// set variáveis
boolean state = 0; // variável para armazenar valores do pushbutton
void setup() {
// define pinos de saída e entrada
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP); // pullup interno do Arduino
}
void loop(){
if (!digitalRead(buttonPin)) { // botão pressionado - LOW (true)
state = !state; // inverte valor da variável state
if (state) {
// liga o led
digitalWrite(ledPin, HIGH); // liga se state for 1
} else {
// desliga o led
digitalWrite(ledPin, LOW); // desliga se state for 0
}
while (!digitalRead(buttonPin)) {} // aguarda soltar o botão
delay(150); // delay para reduzir o efeito bouncing
}
}
3.1. Abaixo segue dados da memória utilizada pelo Arduino com este programa:
Forma nº 2 - Com state e função fora do loop
4. Esta é a mesma forma clássica do código anterior, mas com uma vantagem: o controle do botão fica fora do loop. Isto deixa o código mais organizado. Teste o código abaixo:
/*******************************************************************************
*
* Programação 2 – Push button com funão liga / desliga
* http://squids.com.br/arduino
*
*******************************************************************************/
// set pinos Arduino
const int buttonPin = 2; // entrada digital - pushbutton
const int ledPin = 8; // saída digital - LED
// set variáveis
boolean state = 0; // variável para armazenar valores do pushbutton
void setup() {
// define pinos de saída e entrada
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP); // pullup interno do Arduino
}
void loop(){
readPushButton();
}
void readPushButton() {
if (!digitalRead(buttonPin)) { // botão pressionado - LOW (true)
state = !state; // inverte valor da variável state
if (state) {
// liga o led
digitalWrite(ledPin, HIGH); // liga se state for 1
} else {
// desliga o led
digitalWrite(ledPin, LOW); // desliga se state for 0
}
while (!digitalRead(buttonPin)) {} // aguarda soltar o botão
delay(150); // delay para reduzir o efeito bouncing
}
}
4.1. Abaixo segue dados da memória utilizada pelo Arduino com este programa:
Forma nº 3 - Usando o switch para controle
5. Nesta forma usamos o switch...case para o controle do botão. O switch...case substitui o comando if e é muito utilizado para a criação de menus. Teste o código abaixo:
/*******************************************************************************
*
* Programação 3 – Push button com funão liga / desliga
* http://squids.com.br/arduino
*
*******************************************************************************/
// set pinos Arduino
const int buttonPin = 2; // entrada digital - pushbutton
const int ledPin = 8; // saída digital - LED
// set variáveis
boolean state = 1; // variável para armazenar valores do pushbutton
void setup() {
// define pinos de saída e entrada
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP); // pullup interno do Arduino
}
void loop(){
readPushButton();
}
void readPushButton() {
if (!digitalRead(buttonPin)) { // botão pressionado - LOW (true)
state = !state; // inverte valor da variável state
switch(state) {
case 0: // caso esteja apagado
digitalWrite(ledPin, HIGH); // liga led
break;
case 1: // caso esteja aceso
digitalWrite(ledPin, LOW); // desliga led
break;
}
while (!digitalRead(buttonPin)) {} // aguarda soltar o botão
delay(150); // delay para reduzir o efeito bouncing
}
}
5.1. Abaixo segue dados da memória utilizada pelo Arduino com este programa. Observe que o valor da memória utilizada foi ligeiramente maior que nos exemplos anteriores.
Forma nº 4 - Usando o operador ternário
6. Nesta forma usamos o operador ternário, deixando o código muito mais elegante. Leia Como utilizar o operador ternário na programação com Arduino. Teste o código abaixo:
/*******************************************************************************
*
* Programação 4 – Push button com funão liga / desliga
* http://squids.com.br/arduino
*
*******************************************************************************/
// set pinos Arduino
const int buttonPin = 2; // entrada digital - pushbutton
const int ledPin = 8; // saída digital - LED
// set variáveis
boolean state = 0; // variável para armazenar valores do pushbutton
void setup() {
// define pinos de saída e entrada
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP); // pullup interno do Arduino
}
void loop(){
readPushButton();
}
void readPushButton() {
if (!digitalRead(buttonPin)) { // verifica se o botão foi acionado
state = !state; // inverte valor da variável variable_buttonEstado
state ? digitalWrite(ledPin, HIGH) : digitalWrite(ledPin, LOW);
while (!digitalRead(buttonPin)) {} // aguarda soltar o botão
delay(150); // delay para reduzir o efeito bouncing
}
}
6.1. Abaixo segue dados da memória utilizada pelo Arduino com este programa:
Forma nº 5 - Sem a variável state
7. Nesta forma eliminamos a variável "state" dando lugar ao comando digitalRead(), que vai ler se o led está ligado ou desligado, alternando o seu estado. Teste o código abaixo:
/*******************************************************************************
*
* Programação 5 – Push button com funão liga / desliga
* http://squids.com.br/arduino
*
*******************************************************************************/
// set pinos Arduino
const int buttonPin = 2; // entrada digital - pushbutton
const int ledPin = 8; // saída digital - LED
void setup() {
// define pinos de saída e entrada
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP); // pullup interno do Arduino
}
void loop(){
readPushButton();
}
void readPushButton() {
if (!digitalRead(buttonPin)) { // verifica se o botão foi acionado
if (!digitalRead(ledPin)) { // se tiver apagado
digitalWrite(ledPin, HIGH);
} else digitalWrite(ledPin, LOW);
while (!digitalRead(buttonPin)) {} // aguarda soltar o botão
delay(150); // delay para reduzir o efeito bouncing
}
}
7.1. Abaixo segue dados da memória utilizada pelo Arduino com este programa:
Forma nº 6 - Sem a variável state e o uso do operador ternário
8. Nesta forma usamos o comando digitalRead() junto com o operador ternário, deixando o código mais enxuto. Teste o código abaixo:
/*******************************************************************************
*
* Programação 6 – Push button com funão liga / desliga
* http://squids.com.br/arduino
*
*******************************************************************************/
// set pinos Arduino
const int buttonPin = 2; // entrada digital - pushbutton
const int ledPin = 8; // saída digital - LED
void setup() {
// define pinos de saída e entrada
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP); // pullup interno do Arduino
}
void loop(){
readPushButton();
}
void readPushButton() {
if (!digitalRead(buttonPin)) { // verifica se o botão foi acionado
!digitalRead(ledPin) ? digitalWrite(ledPin, HIGH) : digitalWrite(ledPin, LOW);
while (!digitalRead(buttonPin)) {} // aguarda soltar o botão
delay(150); // delay para reduzir o efeito bouncing
}
}
8.1. Abaixo segue dados da memória utilizada pelo Arduino com este programa:
Forma nº 7 - Invertendo o valor do estado do botão no próprio comando
9. Nesta forma mais concisa ainda e mais elegante, vamos inverter o valor do sinal do usamos o comando digitalRead() junto com o operador ternário, deixando o código mais enxuto. Teste o código abaixo:
/*******************************************************************************
*
* Programação 7 – Push button com funão liga / desliga
* http://squids.com.br/arduino
*
*******************************************************************************/
// set pinos Arduino
const int buttonPin = 2; // entrada digital - pushbutton
const int ledPin = 8; // saída digital - LED
void setup() {
// define pinos de saída e entrada
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP); // pullup interno do Arduino
}
void loop(){
readPushButton();
}
void readPushButton() {
if (!digitalRead(buttonPin)) { // verifica se o botão foi acionado
digitalWrite(ledPin,!digitalRead(ledPin)); // lê o sinal do botão e inverte
while (!digitalRead(buttonPin)) {} // aguarda soltar o botão
delay(150); // delay para reduzir o efeito bouncing
}
}
9.1. Abaixo segue dados da memória utilizada pelo Arduino com este programa:
Forma nº 8 - Substituindo o if por while e Invertendo o valor do estado do botão no próprio comando
10. Nesta forma substituímos o if por while na leitura do botão e fazemos com que o programa fique parado até que se pressione o botão, acendendo ou apagando o led em seguida. É muito útil em aplicações específicas. Teste o código abaixo:
10.1. Atenção: Esta forma interrompe o programa e aguarda o botão ser pressionado para continuar. Use somente em casos específicos.
/*******************************************************************************
*
* Programação 8 – Push button com funão liga / desliga
* http://squids.com.br/arduino
*
*******************************************************************************/
// set pinos Arduino
const int buttonPin = 2; // entrada digital - pushbutton
const int ledPin = 8; // saída digital - LED
void setup() {
Serial.begin(9600);
// define pinos de saída e entrada
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP); // pullup interno do Arduino
}
void loop(){
readPushButton();
Serial.println(digitalRead(ledPin));
}
void readPushButton() {
// Aguarda pressionar o botão
while(digitalRead(buttonPin)) { } // espera apertar o botão para iniciar
digitalWrite(ledPin,!digitalRead(ledPin)); // lê o sinal do botão e inverte
while (!digitalRead(buttonPin)) { } //esperera soltar o botão
delay(150); // delay para reduzir o efeito bouncing
}
10.2. Abra o Monitor Serial e observe que o valor lido pelo comando digitalRead() só será exibido ao pressionar o botão. Caso contrário, o programa ficará parado aguardando o botão ser pressionado novamente.
10.3. Nesta forma obtemos uma redução no número de linhas e na memória utilizada. Abaixo segue dados da memória utilizada pelo Arduino com este programa:
Forma nº 9 - Utilizando registradores (manipulação direta de portas do Arduino)
11. Esta é a forma mais profissional, onde acessamos diretamente às portas do Arduino sem a necessidade de compilação. Isto torna tudo mais rápido com uso bem menor de memória utilizada.
11. Atenção: O código abaixo foi desenvolvido para Arduino com microcontrolador ATmega328. Outros microcontroladores podem ter configurações diferentes. Leia Projeto 81 - Ligar e desligar um led por manipulação direta de portas do Arduino
/*******************************************************************************
*
* Programação 9 – Push button com funão liga / desliga
* http://squids.com.br/arduino
*
*******************************************************************************/
const byte BOT = (1<<2); // pino digital 2 (bit 2 da Porta D)
const byte LED = (1<<0); // pino digital 8 (bit 0 da Porta B)
void setup() {
DDRB |= LED; // Configura o pino 3 como OUTPUT (1) na porta B
DDRD &= ~BOT; // Configura o pino 2 como INPUT (0) na porta D
PORTD |= BOT; // Habilita o pullup interno (1) (INPUT_PULLUP)
readPushButton(); // lê o botão e realiza a ação
}
void readPushButton() {
while (1) {
if (!(PIND &BOT)) {
PORTB ^= LED;
while (!(PIND &BOT)) { }
delay(150); // debouncing
}
}
}
11.1. Nesta forma obtemos uma redução considerável da memória utilizada. Abaixo segue dados da memória utilizada pelo Arduino com este programa:
Forma nº 10 - Utilizando interrupção externa
12. Esta é a forma deve ser utilizada apenas nos casos em que há a necessidade de manter 2 ou mais atividades simultâneas. Assim, quando você aciona o botão, é executada a ação sem interromper as demais atividades do circuito. Leia: Projeto 78 - Como realizar interrupção externa no Arduino usando sensor de toque.
12.1. Como a interrupção externa gera uma ação muito rápida, somente o delay utilizado no software não será suficiente para evitar as oscilações geradas pelo efeito "bouncing". É recomendável utilizar um capacitor cerâmico de 2,0nF a 10nF na montagem do botão. Veja abaixo como conectar o capacitor cerâmico. Leia: Projeto 82 - Como realizar interrupção externa utilizando registradores do Arduino
12.2. Teste o código abaixo:
/*******************************************************************************
*
* Programação 10 – Push button com funão liga / desliga
* http://squids.com.br/arduino
*
*******************************************************************************/
// set pinos Arduino
const int buttonPin = 2; // entrada digital - pushbutton
const int ledPin = 8; // saída digital - LED
// set variables
boolean state = 0;
void setup() {
// define pinos de saída e entrada
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP); // pullup interno do Arduino
// -- Configura Interrupção Externa int 0 -- pino 2 Arduino
// Chama função "extInt", quando houver o toque no botão
attachInterrupt(0, extInt, FALLING);
}
void loop(){
readPushButton();
}
void readPushButton() {
// liga ou desliga o led
if(state){
digitalWrite(ledPin,HIGH); //inverte o estado do Led
} else digitalWrite(ledPin, LOW);
delayMicroseconds(50000); // debouncing
}
// --- função a ser executada quando houver interrupção ---
void extInt() {
state = !state;
}
12.3. Nesta forma obtemos uma pequena redução da memória utilizada no Arduino em relação ao primeiro skecthc. Abaixo segue dados da memória utilizada pelo Arduino com este programa:
Forma nº 11 - Utilizando interrupção externa com manipulação direta
13. Esta é a forma mais econômica possível, pois executamos todos os comandos com acesso direto às portas do Arduino sem a necessidade de compilação. Isto torna tudo muito mais rápido com uso bem menor da memória utilizada. Este formato também pode ser utilizado quando há a necessidade de manter 2 ou mais atividades simultâneas, ou seja, a interrupção do botão não afeta as demais atividades do circuito. Leia: Projeto 78 - Como realizar interrupção externa no Arduino usando sensor de toque.
13.1. Atenção: O código a seguir foi desenvolvido para Arduino com microcontrolador ATmega328. Outros microcontroladores podem ter configurações diferentes. Leia Projeto 81 - Ligar e desligar um led por manipulação direta de portas do Arduino
13.2. Como a interrupção externa gera uma ação muito rápida e não foi utilizado nenhum delay no software para evitar as oscilações geradas pelo efeito "bouncing", é necessário utilizar um capacitor cerâmico de no mínimo 10nF na montagem do botão. Veja abaixo como conectar o capacitor cerâmico. Leia: Projeto 82 - Como realizar interrupção externa utilizando registradores do Arduino
13.2.1. Caso precise melhorar ainda mais o efeito "bouncing" do botão, considere aumentar o capacitor cerâmico utilizado.
13.3. Teste o código abaixo:
/*******************************************************************************
*
* Programação 11 – Push button com funão liga / desliga
* http://squids.com.br/arduino
*
*******************************************************************************/
const byte BOT = (1<<2); // pino digital 2 (bit 2 da Porta D)
const byte LED = (1<<0); // pino digital 8 (bit 0 da Porta B)
void setup() {
DDRB |= LED; // Configura o pino 8 como OUTPUT (1) na porta B
DDRD &= ~BOT; // Configura o pino 2 como INPUT (0) na porta D
PORTD |= BOT; // Habilita o pullup interno (1) (INPUT_PULLUP)
EIMSK |= (1<
13.4. Nesta forma obtemos a melhor condição de uso de memória, pois quase tudo é processado diretamente nas portas do Arduino, sem a necessidade de compilação. Abaixo segue dados da memória utilizada pelo Arduino com este programa:
O anúncio abaixo ajuda a manter o Squids Arduino funcionando
Comentários