Boa noite.

Estou tentando, sem sucesso, uma forma de adicionar um delay (ou millis) dentro de um script para "push on / push off". Alguém poderia dar uma ajuda?

O script (sem o delay) é o seguinte:

int buttonPin = 2;

int ledPin = 3;

boolean lastButtonState = LOW;

boolean buttonState = LOW;

boolean on = false;


void setup() { 

  pinMode(buttonPin, INPUT); 

  pinMode(ledPin, OUTPUT);

}


void loop() {

  pushOnPushOff_theShortWay();

  setLed();

}

void pushOnPushOff_theLongWay() {

  lastButtonState = buttonState;    

  buttonState = digitalRead(buttonPin);


if(buttonState == HIGH && lastButtonState == LOW) {     

  delay(5); //to prevent noise     

    if(on == false) {       

      on = true;       

      on = false;     

      } else if(on == true) {       

      on = false;     

      }   

      } else if(buttonState == LOW && lastButtonState == HIGH) {     

        delay(5); //to prevent noise   

      }

}


void pushOnPushOff_theShortWay() {

  lastButtonState = buttonState;    

  buttonState = digitalRead(buttonPin);   

if(buttonState == HIGH && lastButtonState == LOW) {     

  delay(5); //to prevent noise     

  on = !on;

} else if(buttonState == LOW && lastButtonState == HIGH) {     

  delay(5); //to prevent noise   

}

}


void setLed() {

if(on == true) {   

  digitalWrite(ledPin, HIGH);   

} else if(on == false) {     

  digitalWrite(ledPin, LOW);   

}  

}

Nele é possível acender e apagar o led através do botão no pino 2, com o funcionamento de push on / push off.

Gostaria que, ao apertar o botão uma vez, ao invés de o led ficar aceso direto, tivesse um delay para apaga-lo, E se caso o botão fosse apertado mais uma vez antes do termino do delay, apagasse o led.

Ex: 

Led apagado; Apertou botão, acende led por x tempo, mas enquanto está aceso, se apertar botão novamente, apaga o led.

Alguém poderia dar uma luz?

Obrigado.

Exibições: 385

Responder esta

Respostas a este tópico

Boa noite Sr. ESG, (se não gosta que te chame pelas iniciais, avise),

   gostaria muito de te ajudar, mas para isto recomendo as seguintes ações:


1. Remova seu sketch da área de texto do seu tópico;

    Remova todos!!!!!!

2Clique em : " Arquivos "  e depois anexe o arquivo  com o seu sketch completo;


3. Leia http://labdegaragem.com/forum/topics/sugest-o-de-como-postar


4. Comente as linhas do seu sketch. Fica mais fácil entender o que vc quer fazer

     com cada linha e facilita a ajuda.

Mas fique 'a vontade caso não queira seguir minhas recomendações.

RV

Fala mineirin RV.

Obrigado pelas dicas!

Pode deixar que na próxima postagem vou seguir suas orientações.

Abs,

Creio que este código resolva a questão.... não testei!

teste_de_LED_com_Botao.ino

depois conta se funcionou...

Opa, tudo bem Rodrigo Corbera?

Primeiro obrigado pelo seu código.

Testei o código, mas quando aciono o botão, ele leva o mesmo tempo do "LED_ON_TIME" para acender o led.

Ou seja, ao acionar, ele espera o tempo definido no "LED_ON_TIME" para acender, depois espera mais o mesmo tempo com o led acesso para apaga-lo.

Outro problema é que ao acender o led, enquanto o led está aceso, se apertar o botão novamente, deveria apaga-lo imediatamente, mas o led continua aceso pelo tempo definido no "LED_ON_TIME"

Abs,

Opa, verdade, eu coloquei o tempo de debouncing do botão como sendo o tempo do led aceso no código de teste do botão.... segue a versão corrigida. Novamente não restei.

teste_de_LED_com_Botao_V2.ino

Rapaz, cê é rápido!!! hehehe

Agora fooooii!!!

Só tem uma coisa, às vezes eu aperto o botão e ele só pisca o led antes de acender, e o contrário também. Pisca o led mas não apaga.

Cara, ajustei o DEBOUNCING_TIME para 200, e parece que foi!!!

Deixa eu dificultar um pouco.

Dá pra adicionar mais 2 leds e 2 botões nesta mesma condição?

Push1 acionando Led1

Push2 acionando Led2

Push3 acionando Led3

Cada Led com seu tempo distinto

Cada um acendendo e apagando nestas mesmas condições, mas...

Todos os botões podendo desligar o ciclo dos outros?

rs

kkkkk

Em software tudo é possível.

Mas nesse caso vou deixar como exercício para você mesmo.

Em linhas gerais, bastaria criar 3 tempos de temporização, repetir o mesmo teste da temporização 3 vezes - uma para cada botão e seu respectivo LED + tempo de temporização.

Apenas que quando identificar que qualquer um dos 3 botões for apertado, tem que anular o tempo de temporização dos 3 LEDs juntos, simultaneamente.

Simples assim.  :-)

Boa Sorte!

Ahaha

Muito justo isso!!

Cara, eu consegui fazer quase tudo o que preciso, mas empaquei só em 1 detalhe:

No código que enviei aí, quando eu acendo um dos leds, se eu pressionar o botão do outro led, ao invés de apagar todos, ele:

- Apaga todos os outros, que estiverem acesos

- Mas acende o led correspondente.

Cara, já tentei algumas soluções, mas não tive sucesso.

Pode me dar uma ajuda?

Anexos

Sim, há alguns problemas estruturais no código:

1- note que a função testButton_X() gera um efeito colateral de bloquear a execução por algum tempo (delay de DEBOUNCING_TIME_X). Essa função é executada várias vezes no loop em sequencia para cada LED/BOTÃO, portanto o teste de um LED vai influenciar em cadeia o tempo do teste seguinte e, no fim do loop, a temporização geral não vai funcionar corretamente.

2- Cada bloco de código de LED/BOTÃO somente está tratando o caso de desligar o seu próprio LED, portando ao apertar um botão somente desliga seu próprio LED e não todos, como desejado. Além de desligar tem que zerar a temporização de todos os LEDs também.

Para resolver isso há que mudar a estrutura do algoritmo.

É algo mais complexo que exige pensar na sequência dos eventos e testes.

Nesse caso há algumas estruturas de solução do tipo:

a) Testar todos os botões juntos de uma vez em uma única função que devolve um array com os estados de todos os botões e em seguida faz um único delay de debouncing.

b) Uma técnica mais avançada é mudar ao invés de testar o botão via digitalRead(), gerar uma interrupção na subida do sinal do pino. Assim é possível anular o efeito de flutuação elétrica gerada no movimento mecânico do botão, que é de fato o problema do debouncing. Para isso usamos o attachInterrupt(pin) do Arduino. O problema é que somente 2 pinos (2 e 3) do UNO (328p) geram interrupção na subida ou descida do sinal de entrada.

https://www.arduino.cc/reference/en/language/functions/external-int...

3) Outra estrutura é fazer a leitura diretamente do registrador do microcontrolador para ler a porta digital sem usar do digitalRead(). Isso é mais rápido em ciclos de CPU que usar digitalRead(). Mas exige um conhecimento mais profundo do 328p. Há exemplos na Internet. Segue um link que fala sobre o tema:

https://cadernodelaboratorio.com.br/en/digital-input-and-output-on-...

É isso. Boa sorte!

Na minha opinião caminho é mudar o código para criar uma Máquina de Estados que guardam o estado de cada LED, o tempo decorrido de cada LED e lê o estado de cada botão, somente permitindo que o estado do botão mude após 250 ms, medido via diferença de tempo calculada por millis().

Tudo isso deve ser feito guardando millis() de cada evento e calculando diferenças de tempo a cada iteração de loop().

É bem diferente do que apresentei inicialmente, mas é uma estrutura que vai resolver todos os problemas e poderá ser expandida para qualquer número de botões e leds.

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço