Pressionar o botão e executar o código uma vez

Pessoal, estou tentando montar um botão, e o botão mostra no LCD a quantidade de vezes que foi pressionado. Um contador!

O problema é que o botão nao conta por cada pressionada, mas sim por tempo que ele ta pressionado. Se eu fico segurando o botão, ele fica subindo o valor. Tem alguma forma mais facil de fazer isso sem ser com o código abaixo?

Outra coisa, quando solto o botão, ele nao da low, por isso coloquei ele como low la em cima, isso é normal?

#include <LiquidCrystal.h>

// Inicializa o LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// Configura o ATMEGA
void setup()
{
// Configura a porta
pinMode(8, INPUT);
pinMode(9, INPUT);
pinMode(10, INPUT);

// Configura o LCD
lcd.begin(16, 2);

// Mostra um OK
lcd.print(“Inicializacao ok”);
}

// Looping principal
void loop()
{
// Declaracoes
int botao01;
int displayes = 0;
bool pressioned = false;
char buffer[33];

// Verifica o botão 1
botao01 = LOW;
botao01 = digitalRead(8);

// Para o looping principal enquanto o botão está pressionado (aparentemente nao da LOW quando largo o botão)
while(botao01 == HIGH)
{
// Verifica se ja executou o código uma vez (aqui sem o IF fica subindo o valor)
if(pressioned == false)
{
// Mostra a quantidade de vezes que ja foi pressionado
displayes++;
sprintf(buffer,“Botao 1: %d”, displayes);

lcd.setCursor(0, 1);
lcd.print(buffer);

// Marca como executado
pressioned = true;
}
}

// Marca com esperando botão
pressioned = false;

delay(500);
}

Valeu =)

Vc "aterrou" o botão?

Pra contar só uma pressionada, vc pode fazer desse jeito que vc fez, ou contar a mudança do botão, ou seja, contar qtas vezes ele vai de LOW pra HIGH, por exemplo. Se vc fizer isso usando interrupções, já tem uma variável que automatiza o processo.

Um problema que vc vai encontrar usando botões pra esse tipo de aplicação é o "bounce" do botão. Isso acontece quando ocorrem várias apertadas não intencionais, devido à parte mecânica do botão mesmo. Dá uma procurada aqui no fórum por "debounce".

Cara, o negócio é tenso hem, é meio diferente a forma de programação, então to meio perdido ainda, me acostumando.

Engraçado você ter dito isso, veio na hora certa, por que eu consegui um código (com certeza não é o melhor, mas não to pensando em otimização ainda), e como consegui, percebi esse problema do “bounce”. Vou procurar sobre isso, agora já sei o nome haehae, se você não falasse ia ficar assim mesmo =/

Muito legal isso tudo :wink:

Posso aproveitar o tópico para outro assunto? acho que sera breve.

Quero fazer um relogio, o botão 1 e 2 vai subir e descer o valor, o botão 3 vai mudar entre hora e minuto, para ajustar a hora correta. Não sei como fazer ele esperar 1 segundo para incrementar o segundo, e ao mesmo tempo nao fazer os botões esperarem esse 1 segundo, sacou? seria show se houvesse thread, assim conseguiria fazer uma thread para incrementar o segundo e o main ficaria esperando os botões.

Enfim, tenho muito o que brincar ainda =D

ps: segue o código como ficou

#include <LiquidCrystal.h>

// Inicializa o LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// Declaracoes
int botao08, botao09, botao10;
bool pressioned = false;
char buffer[33];
int displayes = 0;

// Configura o ATMEGA
void setup()
{
// Configura a porta
pinMode(8, INPUT);
pinMode(9, INPUT);
pinMode(10, INPUT);

// Configura o LCD
lcd.begin(16, 2);

// Mostra um OK
lcd.print(“Inicializacao ok”);
}

// Looping principal
void loop()
{
// Verifica os botões
botao08 = digitalRead(8);
botao09 = digitalRead(9);
botao10 = digitalRead(10);

// Verifica se os botões não estão pressionados
if((botao08 == LOW) && (botao09 == LOW) && (botao10 == LOW))
{
// Marca com esperando botão
pressioned = false;
}

// Verifica se não tem botões presionados
if(!pressioned)
{
if(botao08 == HIGH)
{
// Mostra a quantidade de vezes que ja foi pressionado
sprintf(buffer,“Botao 1: %d”, displayes);

// Marca como executado
pressioned = true;
}

if(botao09 == HIGH)
{
// Mostra a quantidade de vezes que ja foi pressionado
sprintf(buffer,“Botao 2: %d”, displayes);

// Marca como executado
pressioned = true;
}

if(botao10 == HIGH)
{
// Mostra a quantidade de vezes que ja foi pressionado
sprintf(buffer,“Botao 3: %d”, displayes);

// Marca como executado
pressioned = true;
}

if(pressioned)
{
// Soma mais um
displayes++;

// Mostra o buffer
lcd.setCursor(0, 1);
lcd.print(buffer);
}
}
}

Rapaz, o negocio é doido hem. Consegui prevenir o tal “bounce”, e o bom é que não preciso mais daquelas verificações doidas que eu tinha feito.

Valeu mesmo Italo :wink:

#include <LiquidCrystal.h>

// Inicializa o LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// Declaracoes
int botao08, botao09, botao10;
char buffer[33];
int displayes = 0;

// Configura o ATMEGA
void setup()
{
// Configura a porta
pinMode(8, INPUT);
pinMode(9, INPUT);
pinMode(10, INPUT);

// Configura o LCD
lcd.begin(16, 2);

// Mostra um OK
lcd.print(“Inicializacao ok”);
}

// Looping principal
void loop()
{
// Verifica os botões
botao08 = digitalRead(8);
botao09 = digitalRead(9);
botao10 = digitalRead(10);

if(canInterrupt())
{
if(botao08 == HIGH)
{
refrashLCD(“1”);
}

if(botao09 == HIGH)
{
refrashLCD(“2”);
}

if(botao10 == HIGH)
{
refrashLCD(“3”);
}
}
}

void refrashLCD(char *botao)
{
// Soma mais um
displayes++;

// Monta a string
sprintf(buffer,“Botao %s: %d”, botao, displayes);

// Mostra o buffer
lcd.setCursor(0, 1);
lcd.print(buffer);
}

bool canInterrupt()
{
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();

// Verifica se a ultima interrupção foi à 200 ms
if(interrupt_time - last_interrupt_time > 400)
{
last_interrupt_time = interrupt_time;
return true;
}
return false;
}