Boa noite a todos, me chamo André e estou iniciando no mundo de arduíno e estou fazendo alguns experimentos pra aprender mais sobre isso. 

O experimento que estou tentando fazer é o seguinte: fazer o monitotamentou contato que acende um led, e se esse contato for acionado mais de 1 vez no intervalo de 3 segundo ele manda sinal para um buzzer.

Se alguém puder me ajudar ficaria muito grato.

Exibições: 429

Responder esta

Respostas a este tópico

Boa noite Tiago !

Acabei de dar uma organizada no sketch acho que já podemos prosseguir com a explicação. Estou deixando ele em anexo.

Obrigado.

TESTE2.ino

Muito legal! Parabéns pelas mudanças.

Adicionei um ino com alguns pequenos ajustes estéticos, que são 100% dispensáveis durante a escrita, mas que fica mais arrumado APÓS a conclusão do código.

TESTE2.ino

Então vamos aos próximos passos. 

Agora que está tudo separado, devemos analisar algumas questões em cada uma das funções.

1º) void Ohmimetro(); {

Obs- Pessoalmente, não entendi o ";" ali (assim como em outras funções), mas tudo bem.

A ideia aqui é obter o valor da diferença entre duas tensões para saber qual resistor foi utilizado. como você já tinha citado que o calculo funcionava, então não analisei ele, entretanto uma coisa deve ser observada.

Veja que nesta rotina existe um delay(1000). Tomando como base as outras funções, acredito que TALVEZ fosse o caso de substituí-lo por um millis, assim, seu código não ficará travado pela maior parte do tempo.

2º) void Print_LCD()

Esta era uma separação que eu realmente achei importante para facilitar a visualização. Veja... anteriormente você tinha comentado que não queria que fosse impresso os valores no lcd, caso uma condição não fosse obedecida. Correto?

Já que ela está isolada, percebe que isso abre espaço para aplicarmos essa condição em alguns locais?

Podemos criar uma condição direto no loop, SOMENTE para esta função, ou podemos criar uma condição em uma outra função existente.

Mas vamos dar continuidade e voltaremos com ela logo depois.

3º) Contador()

Este servirá para tomarmos referência de ordem de chamada baseando-nos nas condições anteriores.

Se nosso objetivo, nesta função, é saber ser o R2 será menor que 60, então, OBRIGATORIAMENTE, deveremos saber o valor de R2 primeiro. Concorda comigo? 

Então, a condição para esta função ser chamada, seria no exato instante em que o calculo de R2 foi realizado e, após, ele interrompe até o novo calculo. Caso contrário, ele ficaria incrementando o valor de forma infinita. E acho que este não seria o objetivo (acho que por isso você colocou o delay(1000) no Ohmimetro() ).

4º) Resultado_Cont()

O que temos nesta função, é um "reset" constante, para um "delay" com millis, que será utilizado na função Zerar_Tempo().

Aqui não tem mistério, então vamos dar continuidade.

5º) Exibicao_Led()

Aqui temos alguns problemas baseado nas descrições.

if (contador > 3 ) {
digitalWrite(led1, HIGH); // Se a contagem chegar a 3 acende o led1.
}

Neste caso, sua descrição não bate com sua formula, pois a formula diz que:

"Quando o número foi MAIOR que 3, o led acende". 

Ou seja, quando ela for IGUAL a 3, ela não irá acender.

Solução A: se contador for IGUAL a 3: if(contador == 3){

Solução B: Se contador for MAIOR ou IGUAL a 3: if(contador >= 3){

Pessoalmente, quando um determinado número é o teto, eu costumo colocar um "maior ou igual" ou "menor ou igual", para me prevenir de erros que, eventualmente, eu possa não ter percebido por falta de atenção. Ai fica a seu critério, pois qualquer um dos dois resolverá.

6º) Zerar_Tempo()

Aqui temos a função com millis, para zerar o tempo. Simples e direta. Mas vamos as observações:

void Zerar_Tempo(); {
if (millis() - inicioTimer > tempoTimer) { 
inicioTimer = 0; // Zera a váriavel inicioTimer.
contador = 0; // Zera o contador.
}

A linha "inicioTimer = 0", é meio morta, afinal, quando você coloca o "contador = 0", na próxima rotina do "Resultado_Cont()" ele fará essa alteração. Então perceba que se você colocar a chamada citada, após o "zerar_tempo()", então esta linha não terá nenhuma importância prática, só irá ocupar mais espaço.

Exemplo:

void loop(){

// Ohmimetro() e todas as outras chamadas......

// depois...

Zerar_Tempo();

Resultado_Cont();

}

Então, acredito que o código deveria ter uma rotina semelhante a esta:

1º) A cada 1 segundo, seria calculado o valor de R2.

2º) SOMENTE APÓS obter o valor de R2, iremos saber se ele É ou não, maior que 60.

3º) SEEEE ele for menor que 60, então iriamos imprimir o valor no LCD (correto?)

4º) SEEEE ele for menor que 60, iriamos adicionar +1 ao contador.

5º) SEEEE o contador for igual a 3 (ou maior), então ligaríamos o led, caso contrário, off.

6º) SEEEE R2 for MAIOR (ou igual?) a 68, então o led2 será acionado, caso contrário, off.

PAUSA ---- Observou que se o valor de R2 estiver entre 61 e 68, nada acontece? É intencional? 

7º) Se, após contador >= 1, o tempo for maior que 3s, o tempo reinicia.

8º) Se o contador ficar em 0, o tempo reinicia sempre (é possível otimizar isso ainda)

Então, esta parte é apenas para compreendermos melhor a linha de pensamento do código.

Antes de darmos continuidade para sugestões de melhorias (com exemplos), gostaria de saber:

- Você conseguiu compreender o que apresentei?

- Chegou a fazer alguma modificação no seu código, baseado no citado?

- Quando possui apenas 1 resistor, qual valor é exibido?

- Faltou analisar algo? Me equivoquei em algo? Se sim, por favor, informe.

Aguardo seu retorno.

Vamos lá !!

O ";" foi apenas um erro de digitação eu atualizei o sketch e já o removi.

Também fiz a alteração sugerida por você para trocar o delay pelo millis.

Fiz a alteração de ">=" que você falou, realmente foi algo que não percebi na hora que estava escrevendo.

Respondendo suas perguntas

Sim entendi tudo que vc falou e tentei alterar o que consegui.

Como falei quando não tem nem um resistor o Display fica meio bugado piscando.

Sim eu fiz algumas alterações, separei a função dos leds em duas, uma delas vai mostrar o estado do resistor e a outra vai ser para acender o led de quando o contador for igual ou maior a 3.

E agora quando o valor de R2 esta dentro dos parâmetros ele acende um terceiro led.

vou deixar o arquivo e anexo abaixo

TEST2.ino

Olá André Alves.

Olhei seu código. Então vamos olhar rapidamente suas alterações antes de dar continuidade.

 

Primeira: leds (cima, dentro, baixo + contador).

Segunda: divisão da função “Exibicao_LedCont()” para “Exibicao_LedCont()” e “Exibicao_LedSin()”

 

Agora vamos as correções das suas mudanças.

1º) Linha 108 (em “Exibicao_LedCont()”).

Você diz no comentário: “Se a contagem chegar a 3 acende o led1.”, entretanto a formula que você escreve (if (contador > 3 )) não diz isso. A sua formula diz: “Se a contagem for SUPERIOR a 3, isto é, se for igual ou superior a 4).

Exemplo: if(contador >3) é o mesmo que if(contador >=4)

Correção: if(contador ==3) ou if(contador>=3)

 

2º) Linha 131 (Em “Exibicao_LedSin())

Aqui existem 2 problemas, o primeiro é de lógica de programação, e o segundo é de lógica matemática.

“if ( 60 >= R2 <=68)”, na matemática isso diria: 60 é MAIOR ou igual a R2, e R2 é MENOR ou igual a 68., ou seja, NESTA LÓGICA, para isso ser verdadeiro, obrigatoriamente R2 deverá ser IGUAL ou INFERIOR a 60. Qualquer outra situação, será falso. Então não faz sentido o R2<=68.

Penso que, como você quer um valor entre estes dois números, o correto seria: 60 <= R2 <= 68.

Entretanto, até onde tenho conhecimento, a formula não pode ser escrita desta forma. Veja o exemplo que postei abaixo. 

rascunho.ino

Ao utilizar sua formula, em TODAS as condições ele irá retornar verdadeiro, e tenho certeza que este não é seu objetivo. (obs- existem algumas instruções no código).

A forma correta de se escrever, é utilizando o "e" (&&), seria: if( R2 >= 60 && R2 <= 68). Para facilitar a leitura, no primeiro momento, eu costumo colocar assim: if(  ( R2 >= 60)  &&  (R2 <=68) )

Sugestão de leitura: https://www.arduino.cc/reference/pt/language/structure/boolean-oper...

Isso encerra as correções de suas ultimas mudanças. Agora vamos para o próximo passo.

 

Vamos seguindo o cronograma citado anteriormente.

1º) "A cada 1 segundo, seria calculado o valor de R2."

Tudo o que precisamos aqui, é remover aquele delay(1000) e adicionar um “delay” baseado no cálculo com millis. Para isso, primeiro declaramos a variável (chamei de OhmTimer, para ficar parecido com o nome da função, mas pode renomear ao seu gosto e colocar até “cachorro5000”, não fará diferença).

unsigned long OhmTimer;

 

depois, no setup, atribuímos o valor de millis() a esta variável

OhmTimer = millis();

Por fim, colocamos a condição no próprio loop, fazendo com que este se mantenha constante.

if (millis() - OhmTimer >= 1000) { Ohmimetro();  OhmTimer = millis();}

 

 

2º) SOMENTE APÓS obter o valor de R2, iremos saber se ele É ou não, maior que 60.

Como é necessário que seja aguardado o valor de R2, consequentemente teremos que aguardar 1 segundo também, então tudo que precisamos fazer é realizar a chamada desta função logo após a conclusão de Ohmimetro()! Então para deixar o processo BEM simples, apenas iremos jogar a função “Contador()” para dentro da condição responsável pelo delay com millis de Ohmimetro(), mas somente após este.

if (millis() - OhmTimer >= 1000) {

Ohmimetro(); 

Contador();

OhmTimer = millis();

}

 

3º) SEEEE ele for menor que 60, então iriamos imprimir o valor no LCD

Exatamente a mesma coisa que o item 2. Ohmimetro é requisito de contador. Contador é requisito de Print_LCD(). Então também iremos adicionar esta função dentro da condição responsável pelo delay(com millis) de ohmímetro, mas após o contador() e antes do OhmTimer.

 

4º) SEEEE ele for menor que 60, iriamos adicionar +1 ao contador.

Já resolvido no item 2.

 

5º, 6º, 7º e 8º) Não é necessário correção

 

/// ============= ///

Então, observe que fazendo desta forma, faremos a leitura do ohmímetro() a cada 1 segundo, e colocando na sequencia as funções que utilizam-na como requesito.

//===============//

 

E depois disso, ta pronto? Não, principalmente por essa questão: “Como falei quando não tem nem um resistor o Display fica meio bugado piscando.”

Isso pode acontecer por vários motivos, mas não tenho como saber sem conhecer seu circuito, em todo caso, podemos fazer um teste, certo? E, depois de resolvermos a questão do pisca-pisca do lcd, podemos otimizar esse código.

1º passo) Leia o valor de R2, no monitor serial, quando você remove o resistor. Para isso, adicione no Print_LCD():

Serial.print("R2: ");

Serial.println(R2);

2º passo) se der um numero muuuuuuuuuito grande, você pode limitar o valor

Exemplo: if (R2 > 9999) {R2 = 9999;)

3º) Se não funcionar, mantenha essas alterações e altere R2 de float para long, e veja o que acontece.

obs- passo 2 e 3 é apenas um chute, pois não sei o que é exibido.

Olá Tiago Merces,

Então li sua postagem e entendi todas as correções que voce sugeriu.

O problema que estava tendo com o LCD foi resolvido. Para fazer o teste eu estava removendo o cabo que ligava o pino de leitura ao circuito ao em vez de tirar o resistor por isso ele ficava dando um valor errado.

So tenho mais uma questão. Quando R2 é menor que 60 ele incrementa a contagem certo? so que enquanto essa informação é verdadeira ele fica incrementando sem parar e eu queria que isso acontece-se apenas uma vez a cada transição. Como poderia fazer isso ? Tentei fazer alguns teste baseado em alguns videos que vi mas não tive sucesso.

Assim que terminarmos o código e estiver funcionando conforme planejo eu tento montar um simulação no proteus pra mostrar como tudo esta funcionando o circuito, ou gravo um vídeo e posto aqui.

Como disse antes o intuito do código é apenas para aprender o funcionamento de algumas coisas que ainda não conheço, e acredito que essas informações serão bastante uteis em diversas aplicações, podendo substituir o Ohmímetro por um sensor e em vez de leds atribuir funções e etc.

Planejo depois que conseguir compreender tudo elaborar algum projetinho e mostrar as coisas aprendidas em aplicação.

 

Andre Alves, depois teste isso e me diz o que exibe para você.

TEST2.ino

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço