[DESAFIO 2] Dá pra piscar o led sem delay com um Codigo Menor ???

Olá Galera,

    Abri um tópico anterior com o desafio BLINK MINIMO, e realmente ao meu ver foi um sucesso ( veja AQUI ) !  ele foi vencido pelo grande Eduardo Silva.

    Agora o desafio é um pouco mais difícil,  o desafio é:

    É possível diminuir o blink sem o uso de delay abaixo :

unsigned long conter=0;      // declara variavel

void setup() {
pinMode(13,OUTPUT);    // indica pino do led 13 como saida
}

void loop() {
if(millis() > conter+1000){      // se o millis for maior que a variavel mais mil entra no condicional
conter=millis();    //  atribui o ultimo millis a variavel
digitalWrite(13, !digitalRead(13));     // inverte a situacao do led
}
}

E ai quem diminui o codigo ?

Exibições: 2696

Responder esta

Respostas a este tópico

Olá Welder!

Fiquei quebrando a cabeça para reduzir esse código e cheguei em uma solução que não usa variáveis nem IFs:

void setup() {
pinMode(13,OUTPUT);    // indica pino do led 13 como saida
}

void loop() {
digitalWrite(13, (((int)(millis() / 1000)) % 2) == 0);   
}

Testei e funcionou. O problema dessa solução é que, como ela não usa IFs, ela vai setar o pino 13 a cada milissegundo, o que não é muito inteligente.

Mas como você queria o menor código possível. Isso foi o máximo que consegui. O certo seria colocar uma decisão para otimizar o código.

Observação: O seu código original está muito bom, mas acho que ele tem um problema. Me corrijam se eu estiver errado:

O millis() vai zerar depois de aproximadamente 50 dias. Dessa forma, o led ficaria sem piscar depois desse tempo. Correto?

José Augusto,

Ótima solução!

millis zera +- em 50 dias mas continua contando só perdemos a referencia de quanto tempo a placa esta ligada.

Abs

Mauricio Ortega

Mauricio, bom dia!

Sim, o millis() zera e continua contando.

Mas aí vai falhar o IF abaixo:

if(millis() > conter+1000)

pois, depois que ele zerar, será sempre menor que conter + 1000.

Ele nunca mais vai entrar no IF e a variável conter vai  ficar sempre com o mesmo valor. O led não piscará mais

Concordam?

Tem razão, erro meu.

if ( conter < (millis() -1000) || conter > (millis() +1000) )



Ha ha ha,  o millis()  não zera,  ele reinicia  kkk

Não lembro bem se ele reinicia contando negativo ou reinicia positivo novamente,  mas com certeza ele não zera no sentido de parar de funcionar.

Eu fiz um testezinho vem simples,  atribui o millis() a uma variavel int,  e mande multiplicar essa variavel,  dai como o int aceita valores até 32.XXX ai ele inverte,  mas basta usar o unsigned antes que ai vai até 64.XXX e sempre fica no positivo.

   Mas gostei do raciocinio utilizando lógica matematica no setador de estado do digitalWrite()  bem legal o raciocinio.

    Direi até qual vai ser o raciocinio que irei buscar, será assim:

  a cada vez que o millis() atingir uma variante de 1000,  de alguma forma o estado booleano de 0 ou 1 deverá ser mudado,  se conseguirmos fazer isso, ele piscará certinho.

Foi isso que nosso colega José Augusto fez

Caro Weider.

Zerar é modo de falar. Ele reinicia do zero, ou seja começa a contagem novamente.

O Millis() nunca fica negativo. Ele é controlado por uma variável unsigned long.O "unsigned" significa sem sinal --> Só aceita valores positivos.

Por isso que ele demora cerca de 50 dias para "zerar" novamente e causar um erro no IF do programa apresentado. O amigo Odilon Passou a correção que deve ser feita.

Na verdade pode ser apenas:

if ( conter < (millis() -1000) || conter > millis() )

Eu tenho preferido utilizar contadores de tempo baseado em interrupções.

Foi mais complicado a principio, mas aos poucos comecei a entender e fica mais fácil colocar tarefas temporizadas.

Odilon,

   Please,  coloca o codigo completo,  a ideia aqui é contarmos o numero de linhas pra fazermos um codigo menor, mas tão produtivo quanto o citado.

   O codigo base, que coloquei,  tem 7 linhas( colocando os colchetes finais nas suas respectivas linhas)

   a ideia é diminuir

Não dá para diminuir mais Weider, seu código tá enxuto. Só dá para deixar ele rodando mesmo quando millis() estourar:

unsigned long conter=0;      // declara variavel

void setup() {
    pinMode(13,OUTPUT);    // indica pino do led 13 como saida
}

void loop() {

   // se o millis for maior que a variavel mais mil entra no condicional

   // ou quando millis() estourar...
    if ( conter < (millis() -1000) || conter > millis() ){
       conter=millis();    //  atribui o ultimo millis a variavel
       digitalWrite(13, !digitalRead(13));     // inverte a situacao do led
    }
}

Você pode usar registrador, para diminuir o código compilado, mas pouca coisa. O fonte vai ficar maior, tá bacana desse jeito que vc fez.

Weider, boa noite!

Não sei se você leu todas as postagens, mas eu já mandei o código reduzido completo que você solicitou. O programa abaixo faz tudo em apenas uma linha na função loop.

Não era essa a proposta? Reduzir o seu código? A confusão aconteceu porque eu apontei um erro no seu código referente ao millis. Segue o programa:

void setup() {
pinMode(13,OUTPUT);    // indica pino do led 13 como saida
}

void loop() {
digitalWrite(13, (((int)(millis() / 1000)) % 2) == 0);   
}

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço