Olá, boa tarde.

Estou fazendo uma máquina de estados com um temporizador que irá acionar/desarmar o relé.

Porém, o que estou percebendo é que ele começa a contagem do tempo antes de entrar no case selecionado.

Por exemplo, abaixo do void setup já tem as linhas da livraria TimerOne, provavelmente iniciando a contagem já, então ele ja começa a contagem do tempo antes mesmo de entrar nos cases seguintes e eu não estou conseguindo arrumar, passei meu horário de almoço inteiro mexendo, se puderem me dar uma luz.

https://pastebin.com/gs27GpWq

Timer1.initialize(100000); // Inicializa o Timer1 e configura para um período de 0,01 segundos
Timer1.attachInterrupt(callback); // Configura a função callback() como a função para ser chamada a cada interrupção
}
void callback()
{
time++;
}

Esse Time++ eu acho que já aciona o contador, quando entra no case e começa a mostrar o tempo, ele já está em 14 segundos, então acho que está contando a partir do momento em que roda o setup. Queria que iniciasse o tempo apenas quando entrasse na case.

Exibições: 548

Responder esta

Respostas a este tópico

Boa tarde R,

a biblioteca TimerOne.h, a qual vc se refere, tem diversos métodos disponíveis.

Entre eles tem:

stop();                          ----> > Para a contagem do timer1

start();  e restart();       ----> > Inicia a contagem a partir do valor zero;

resume();                     ----> > Reinicia uma contagem paralisada.

https://www.pjrc.com/teensy/td_libs_TimerOne.html

RV

Olá, boa tarde. Acabei testando esses comandos mas sem êxito, não sei onde colocar exatamente, estou colocando no meio dos cases mas acaba que ele não reseta o contador. Quando entra no estado em que o tempo é impresso no LCD, o tempo já está na casa dos 15 segundos.

case 5:
lcd.clear();
lcd.home();
lcd.print("Vc escolheu:");
lcd.setCursor(0,1);
lcd.print("Banho Longo");
lcd.setCursor(0,0);
delay(5000);

// A partir daqui aciona o Rele e começa a monitorar o consumo
Timer1.restart();
while ( time <= 90000 )
{
digitalWrite( pino_RELE, LOW ); // Liga o Rele

lcd.setCursor(0,0);
lcd.print("Tempo="); // mostra texto
lcd.setCursor(0,1); // seleciona coluna 0, linha 1
lcd.print("WattHora="); // mostra texto

Irms = EnerMonitor.calcIrms(1480); // calculo da corrente RMS

lcd.setCursor(9,0); // seleciona coluna 9, linha 0
lcd.print(time/100); // mostra o tempo em milisegundos
lcd.setCursor(9,1); // seleciona coluna 9, linha 1
lcd.print( Irms*Vrede*(Tempo/3600) ); // calculo de Watt/hora

Tempo++;
time++;

delay(100);
}

if ( time > 90000 )
{
digitalWrite( pino_RELE, HIGH );

delay(15000);

estado = 2;
}
break;
}

Acabei colocando assim, está certo?

Olá Rodrigo.

      Seu Sistema, apesar de simples, é bastante interessante. Se me permitir, gostaria de ajudá-lo.

      No momento, para o que vc postou até aqui, seguem as seguintes considerações:

      1) a sua forma de implementar a Máquina de Estados está correta. Mas ainda assim há alguns conceitos equivocados na sua implementação. Você precisa corrigir estes conceitos para que sua Máquina funcione conforme vc deseja e sem bugs.

       Os dois elementos principais em uma Máquina de Estados, são o "Estado" em que a Máquina se encontra, e os "Eventos" que provocam as mudanças de estado. E dentro de um "Estado", vc pode fazer duas coisas: pode controlar Dispositivos do seu Sistema (Relés, LEDs, Displays, Motores, o que vc quiser), e pode obter informações (estado de chaves, sensores, etc) que possibilitem controlar os Dispositivos e possivelmente mudar de estado (ou seja, as informações obtidas podem gerar Eventos).

      E claro, vc deve fazer o Diagrama de Estados da Máquina de Estados, que essencialmente é descrever como o seu Sistema irá funcionar, mostrando nele como a Máquina de Estados  controlará seu "fluxo" de forma a fazer o trabalho que vc deseja. Se vc fez um Diagrama de Estados "correto", bastará implementar sua Máquina de Estados a partir desse Diagrama.

      Para que vc se oriente melhor nisso, veja algumas implementações que fiz aqui no LDG, para resolver problemas típicos, que estão nestes links:

      - Máquina de Estados JMelo:  link

      - Máquina de Estados Lucas Piedra:  link

      - Máquina de Estados Luiz Henrique:  link

      - Máquina de Estados Francikleber:  link

      - Máquina de Estados Oziel Marques:  link

      - Máquina DogFeed Marcela:  link

      Este último ("DogFeed"), é um ambiente com maior quantidade de dispositivos e temporizações mais complexas. Por isso aconselho vê-lo apenas depois de ver os demais, que são mais simples.

      2) Como o Minerin ressaltou, há alguns controles principais que vc pode fazer no Timer1. E sim, de fato ele começa a funcionar quase de imediato após a inicialização do código-base do Arduino (o qual vc normalmente não acessa). Mas isso não deveria afetar o funcionamento do seu Sistema. Se vc implementar sua Máquina de Estados corretamente, nem precisará se preocupar se o Timer1 já estava ou não contando. Essencialmente, o resultado funcional da utilização do Timer1, será equivalente à função "millis" do Arduino (analise e chegará a essa conclusão).

       Ah sim:  se sua intenção era o intervalo de 0.01 segundo (como vc disse), então está passando o valor errado para a função "Timer1.initialize", que deveria ser 10000 (10 mil micro-segundos = 10 mili-segundos), e não 100000 (isto seria para 0.1 segundo).

      3) seu conceito da função para "callback" parece confuso, o que é evidenciado quando vc diz "Esse Time++ eu acho que...". Ocorre que um "callback" é executado na taxa do evento que vc programou pra que ele executasse, e que neste caso seria a taxa do "overflow" do Timer1. Se vc programou para 0.01 segundo, essa taxa será o inverso disso, ou seja: 1/0.01 = 100. Logo, a função "callback" seria executada 100 vezes por segundo (taxa de 100Hz). E a cada execução, ela incrementa a variável "time" em uma unidade (devido ao "++"). Mas como no seu código vc estava programando a taxa do Timer1 para 0.1 segundo, então a taxa de execução do "callback" será = 1/0.1 = 10, ou seja, sua variável "time" será incrementada 10 vezes por segundo. Em outra palavras, a cada segundo que passa, a variável  "time" é incrementada em 10.

      Notas importantes: como o "callback" é chamado de dentro de uma "ISR" (Interrupt Service Routine), então vc deve obrigatoriamente declarar a variável "time" como sendo do tipo "volatile", para que seu código funcione corretamente. Mas você declarou apenas assim:  "int time;"  , e deveria ser assim:  "volatile int time;".  Se vc não souber o motivo de ter que ser assim, explico depois (mas não é nada complexo não). Também devido ao mesmo fato do "callbak" ser chamado de dentro de uma "ISR", não execute tarefas demoradas dentro dele. Mas neste caso não tem problema no seu código, pois a única coisa que está sendo feita no seu "callback" é o incremento da variável "time", então está tranquilo isto. Se vc precisar fazer tarefas mais pesadas e demoradas, proceda assim:  sete uma flag dentro do "callback" e use a Máquina de Estados para detectar isso (seria exatamente um Evento) e fazer o trabalho pesado e demorado dentro da "temporização realística" do seu Sistema (claro, imediatamente depois que a tarefa pesada terminar, resete a flag indicadora do evento).

      4) seu código está um tanto "bagunçado". Para fazer uma Máquina de Estados de forma confiável, vc tem que fazer um código "limpo" e organizado. Isto é absolutamente necessário. Veja os exemplos dos códigos dos links que passei em 1), e note como estão super-organizados. Vou citar como exemplo, uma confusão enorme no seu código:  não fica claro o que são o "curto", "medio", e "longo". Há uma mistureba, onde hora vc os usa como variáveis, e hora vc usa para acesso a pinos de I/O do Arduino. Aparentemente existem entradas de Botões associados a estas 3 variáveis, mas sem uma evidência clara disso no código, além do que no "setup", vc programa os mesmos pinos com níveis lógicos "LOW", o que parece sem sentido. Eu assumi que há Botões conectados aos pinos "2", "3" e "4", e com isso organizei o código que vc postou aqui (aquele do Pastebin). O código organizado é esse:  "duvida_TimerOne_01.ino" . Mas claro, eu posso estar enganado, se os Botões não existirem. Mesmo neste caso, vc ainda pode aproveitar o código que eu organizei, pois isso pode te ajudar bastante. Caso faça isso, não o faça apenas pra ganhar tempo, mas principalmente para ver como foi feito e aprender com a implementação.

      5) por fim, para resetar a contagem "time" como aparentemente vc deseja, crie um Estado Inicial na Máquina de Estados, digamos o Estado "0", e dentro deste estado zere o valor do "time". Claro, esse estado executará apenas uma única vez no seu Sistema, e depois seguirá para o Estado "1" que vc já implementou. Ah, vc deve ter colocado o "volatile" na declaração da variável "time", como mostrei em 3).

      Se possível, post aqui algum desenho que esclareça mais seu Sistema (circuito, diagrama, fotos, etc), pois ajudará bastante para que possamos auxiliá-lo aqui no LDG.

      Abrçs

      Elcids

Olá, obrigado desde já pela atenção ao meu projeto, tanto á você quanto ao mineirin.

Esse projeto é o meu TCC do curso técnico de eletrônica, tenho que entregar um protótipo pronto até o fim do mês.

Se trata de um temporizador para chuveiro que iria também medir o consumo de corrente do mesmo.

Utilizei a biblioteca TimerOne para a temporização e separei em máquinas de estado por que acho que funcionaria assim. Estamos utilizando o sensor de corrente SCT-013 com medição máxima de 100A, um relé de 5V no qual não me recordo o modelo exato agora e um display LCD com um módulo I2C, reduzindo os 16 pinos para apenas 2.

Na teoria iriamos ligar o relé em uma contatora, no qual o chuveiro estaria conectado. Entrariamos no menu de seleção de banho e escolheriamos o tempo de banho (O qual se refere botao curto, medio e longo e futuramente irei adicionar um de banho livre, sem tempo limite) com uns botões em conexão pull-down.

Assim que escolhessemos o tipo de banho, ele iria trocar para o estado do banho escolhido, por exemplo, no banho curto iria jogar pro estado 3, no qual ele setaria o tempo de banho para 5 minutos, acionaria o relé para passar corrente ao chuveiro e iria monitorar o consumo da corrente nesse meio tempo. Atingido o tempo limite, o relé iria se desarmar, cortando a corrente do chuveiro e adicionei um delay no final do estado para segurar o consumo de corrente no LCD por alguns segundos e depois voltaria ao estado de seleção de banho.

O código está com as variáveis bagunçadas pois eu peguei de cada módulo individual, usando o "guia" de cada módulo e como não possuo muito conhecimento, deixei assim mesmo pois não sei o que mudar.

Sobre a foto do circuito, no proteus ele não simula com exatidão o relé de 5V, então usei um genérico dele mesmo e o sensor também não, mas dei um jeitinho.

Abaixo é a foto da ligação do sensor e do relé, não com exatidão, claro.

Sobre você citar as portas dos botões setadas pra LOW no inicio do código, é por que quando eu ligava o arduino e rodava o código, no case de seleção de banho ele já escolhia algum automáticamente, mas como elas estão configuradas apenas para entrar quando alguma das portas estivesse em HIGH, elas já iniciavam em HIGH, então corrigi isso setando todas pra LOW no inicio do código.

Por enquanto só tenho isso pra comentar, agradeço pelo código que você separou, ficou muito melhor pra trabalhar agora. Amanha na pausa do almoço do trabalho irei tentar mudar algumas coisas na qual você citou.

Agradeço desde já.

olá novamente Rodrigo.

      Legal seu Projeto. Logo que vi o código percebi que se tratava de algo realmente legal. E melhor ainda que se trata de um TCC, pois espero que isto o incentive ainda mais.

      Eu suspeitei que haviam chaves/botões, conforme escrevi antes. Mas não analisei os detalhes dentro de cada "case" do seu código, e por isso não desconfiava que se tratava de um controle do tempo de banho e também da medição do consumo de energia do mesmo (mas vi sim que tinha alguma medição deste tipo lá). Talvez algumas pessoas possam dizer que não seja original, mas eu achei bem legal o Projeto, principalmente pra vc que está aprendendo. Ele pode te acrescentar muitos conhecimentos importantes.

      Ainda sobre os botões, vc explicou mas ainda não entendi o motivo de vc fazer aquele setting com "LOW" no "setup". Talvez eu não tenha entendido justamente porque eu não analisei o comportamento da sua Máquina de Estados. Pode ser que se eu analisar, isso fique evidente pra mim. Mas independente do problema que vc disse que ocorreu, uma coisa posso te garantir com quase total certeza:  a forma adequada de resolver este tal problema, não é daquela forma que vc fez no seu código (e talvez também no seu Hardware, mas sobre isto é mais difícil afirmar, pois não há no desenho que vc postou a ligação dos tais botões).  Minha sugestão:  aplique a forma adequada de tratar o tal problema, pois a solução que vc aplicou parece "estranha" e pode em algum momento do desenvolvimento do seu código, resultar em efeitos colaterais ainda mais esquisitos. Sem contar que nada melhor do que aprender a aplicar os métodos adequados e confiáveis para resolver um determinado problema. Sobre isso, conte comigo: vou ver se consigo analisar seu código pra ver se entendo que problema "foi" este, e assim poderei postar aqui pra vc uma solução mais "convencional" e sólida.

      Sobre o controle de tempo do banho, aqui vai uma sugestão:  além dos Botões de seleção, vc poderia inserir uma chave "On/Off", e um Potenciômetro (em uma entrada analógica "An" que esteja sobrando). Se a chave estiver na posição "Off" o Sistema ignora o Potenciômetro, e os Botões é que comandam (como já está fazendo atualmente). Mas se a chave estiver na posição "On", então o Sistema ignora os Botões, e passa a usar o valor convertido da posição do Potenciômetro (entre um mínimo e um máximo) pra determinar o tempo do banho, tipo isso: posição mínima seria por exemplo 5 minutos, e posição máxima seria por exemplo 20 minutos. E claro, qualquer posição intermediária do Potenciômetro implicaria em um tempo entre 5 e 20 minutos (basta fazer uma conversão usando a função "map" do Arduino). É algo simples de fazer (principalmente usando uma Máquina de Estados), e também acrescentaria um "feature" a mais no seu Sistema (e vc também aprende mais). Mas é apenas uma sugestão.

      E por falar em Máquina de Estados, certamente ela é a forma de implementação mais simples, mais eficiente, e mais confiável que vc pode usar pra fazer a implementação do seu Sistema. Uma Máquina de Estados é perfeita pra fazer esse controle. Como eu sempre digo, a técnica de Máquina de Estados resolve 99,9% dos problemas de implementação existentes, e ainda de forma simples. E digo isso por experiência.

      E que tal se eu ajudasse na sua implementação?  Vc disse que tem que finalizar até o fim do mês. Então precisa usar técnicas confiáveis e que não resultem em bugs, pois o tempo é precioso pra vc neste momento (e perder tempo com problemas devido a técnicas inadequadas, parece que não é nada bom).

      Note que embora eu tenha ajustado um outro outro nome de variável no seu código (pra ficar mais fácil a leitura), e organizado o mesmo, o funcionamento é exatamente o mesmo que já existia, pois não alterei nenhuma lógica ali existente. Então vc pode partir desse código organizado, e ajustar de forma confiável alguns pontos que mencionei no primeiro post. Se vc concordar, podemos fazer isso de forma eficiente e cadenciada, pra que seu Sistema alcance o resultado que vc espera dele. E pelo que me pareceu, vc já tem o Hardware ok, e só precisa trabalhar mesmo é no código.

      Já foi quase 1/3 do mês, mas me parece que ainda é totalmente possível. Se precisar, posso te ajudar via Skype, fora do meu horário de trabalho.

       E se possível, não deixe de olhar as implementações de Máquinas de Estado que fiz aqui no LDG, nos links que informei no post anterior. Isso pode te ajudar bastante.

      Mais uma vez, parabéns pela ideia, pois achei bem legal.

      Abrçs,

      Elcids

Mais uma vez, obrigado pela atenção. Gostei da sua idéia do potênciometro e quando o projeto ja estiver funcional e sobrar tempo, irei implementar ele no projeto.

Minha preocupação no momento é a montagem física do projeto, visto que meu tempo é muito escasso, mas espero que até semana que vem já esteja montado e pré-testado, bastando apenas terminar o código.

Estou sem a foto da ligação dos botões no momento, mas estou usando o sistema da foto acima.

Irei estudar as outras máquinas de estado que você fez. Agraço mais uma vez pela sua atenção, qualquer novidade irei postar aqui.

R, boa tarde:

Recomendações:


1. Remova seu sketch da área de texto do seu tópico;
2. Leia http://labdegaragem.com/forum/topics/sugest-o-de-como-postar
3. Comente as linhas do seu sketch. Fica mais fácil entender o que vc quer   

    fazer com cada linha e facilita a ajuda.
4. Clique em : " Deseja carregar arquivos? " e depois em " Escolher arquivo" e       

    anexe o arquivo com o seu sketch.

RV

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço