O programa que estou usando é esse:
// OBS: Para fins de analise, omiti as informações de teclado (configurações de teclas, pinos e etc)
#define PortaRele 13 // Pino onde o acionamento do rele
#define PortaBuzzer 7 // Pino onde o acionamento do Buzzer
#define PortaAgua 2 // Pino do Sensor de Fluxo
// Codigo das mensagens do Buzzer
#define ERRO 0
#define TECLA 1
#define CONFIRMA 2
#define FIM 3
volatile int contaPulso; // Inicializa a variavel para contagem do Fluxo de Água
// Função para incrementar o contador de pulsos do sensor de vazão
void Pulso() {
contaPulso++;
}
// Setup Arduino
void setup() {
pinMode(PortaRele,OUTPUT); // Inicializada o RELE
pinMode(PortaBuzzer,OUTPUT); // Inicializada o Buzzer
pinMode(PortaAgua,INPUT); // Inicializa o Sensor de Fluxo
Serial.begin(9600); //INICIALIZA A SERIAL
MenuPrincipal(); //Exibe o menu principal
}
void loop() {
// Verifica se alguma tecla foi pressionada
char tecla_pressionada = meuteclado.getKey(); //VERIFICA SE ALGUMA DAS TECLAS FOI PRESSIONADA
if (tecla_pressionada){
switch(tecla_pressionada){
case 'A':
{
// Emite um "clique" padrão
Buzzer(TECLA);
// Entra em uma função que permite digitar o numero de litros que será contato
SelecionaLitros();
break;
}
case 'B':
{
// ... Continua o case das demais funções (configurações, e etc).
// Não é importante para o problema em questão
}
}
MenuPrincipal(); // Após varrer as opções, exibe o menu novamente
}
}
// Função para aguardar o usuario pressionar quantos litros serão contados
void SelecionaLitros(){
// Inicializa as variáveis
int nLitros, i = 0;
boolean sair = false;
String cLitros = "";
// Verifica se alguma tecla foi pressionada
char tecla_pressionada = meuteclado.getKey();
// Exibe o menu secundario do sistema
MenuLitros();
// Fica rodando neste menu até sair ou confirmar
while (!sair) {
// Verifica se alguma tecla foi pressionada
tecla_pressionada = meuteclado.getKey();
// Se foi pressionada uma tecla
if (tecla_pressionada) {
switch (tecla_pressionada){
// Tecla CONFIRMA foi pressionada
case 'A':
{
if (cLitros != "")
{
// converte de array para int
nLitros = cLitros.toInt();
// Exibe a quant.de litros
Serial.println(cLitros);
// Dispara a função de contagem de litros
AcionaContadorLitros(nLitros);
// Limpa as variáveis
nLitros = 0;
cLitros = "";
// Encerrou, sai do loop e retorna ao menu principal
sair = true;
break;
}
Serial.println("Quant.incorreta");
delay(500); // Aguarda 1/2 segundo
}
// Restante das opções são tratamento das teclas digitadas
}
// Aguarda 1/10 de segundo para ler as teclas novamente
delay(100);
}
}
}
// Função para contar os litros selecionados
void AcionaContadorLitros(int Litros){
// Inicializa as variaveis
float FatorC = 7.5;
boolean _sair = false;
unsigned long OldMillis;
float vazao=0; //Variável para armazenar o valor em L/min
===>>>>>>>>>>>>>> Inicio do problema
// Habilita a interrupção de hardware
attachInterrupt(digitalPinToInterrupt(PortaAgua), Pulso, RISING);
// abre a valvula eletromagnetica
digitalWrite(PortaRele,HIGH);
// vamos executar este loop até atingirmos Litros
while (!_sair){
// zera a variavel de contagem de pulsos do sensor de vazao
contaPulso=0;
sei(); //Habilita interrupção
delay(1000);
cli(); //Desabilita interrupção
vazao += (contaPulso / FatorC / 60); //Converte para L/seg
//verificamos se a quant.de litros esperada já foi alcançada
if (vazao >= Litros){
_sair = true;
}
{
}
// Desabilita a interrupção de hardware
detachInterrupt(digitalPinToInterrupt(PortaAgua));
=====>>>>>>>> Fim do problema
digitalWrite(PortaRele,LOW);
// Quando encerra a contagem, exibe uma mensagem no display
Serial.println("Contagem Encerrada");
}
Se o circuito Início / Fim do problema for substituído por qualquer outro, não apresenta nenhum inconveniente, porém, da maneira que está, para de funcionar outras funções auxiliares (que não utilizam qualquer variável) como Buzzer(MSG) que toca um som diferente de acordo com o programa (confirma, digitação, erro e etc), até mesmo a porta serial para de funcionar.
Eu coloquei um led em diversos pontos do programa para ver até onde a execução ia, e ela chega até a função loop(), porém TODAS as chamadas de funções digitalWrite(), Serial.print() e Serial.println() param de responder, até que o controlador congela.
Uma coisa que observei é que o led utilizado para checar o ponto de excução, quando congelava o controlador, ele ficava com um brilho menor. Pensei que poderia ser um problema de alimentação. Coloquei toda a alimentação dos relês, sensores e etc em uma fonte auxiliar e mesmo assim o problema persiste.
Cheguei a fazer um teste utilizando um loop de contagem de tempo com millis(), pegando o tempo antes de chamar a interrupção (i.e. sei() ) e depois de encerrar a interrupção (i.e. cli() ) e mesmo assim o problema persiste.
O ideal seria se tivesse uma outra maneira de contar os pulsos do sensor, mas ainda não sei como fazê-lo. Se alguém tiver uma ideia diferente...