Llenado de tanque teclado, caudalimetro y relee, problema con ciclo while

Buen día.

Espero me puedan orientar con un proyecto que tengo en preparacion.

Con un sensor de flujo el FS300A y un display 16x2 y su debido codigo me muestra informacion relativamente correcta hemos llenado una cubeta de 20 litros y ha sido muy cercana la cantidad.

Pero al hacer el codigo agregando un teclado matricial y un relee, cambiando el codigo para que despues de cierta cantidad de litros desactive el relee no me regresa al menu principal. Anexo el codigo esperando me puedan orientar por favor gracias.

Solo se ejecuta una vez el codigo si selecciono del menu el 1 si mide abre y cierra el relee pero cuando termina la condicion no me regresa al menu principal.

Tengo arduino uno, teclado matricial 4x4, display 16x2, relevador de 2 canales y sensor de flujo FS300A.

Saludos.

#include <Key.h>
#include <Keypad.h>
#include <LiquidCrystal.h>

const byte filas = 4;     //Numero de filas del teclado
const byte columnas = 4;  //Numero de columnas del teclado
const int sensorPin = 2;
const int measureInterval = 2500;
volatile int pulseConter;
int relay = 11;


// FS300A
const float factorK = 5.5;


float volume = 0;
long t0 = 0;

//Defino una matriz 4x4 con la posicion de las filas y columnas
char matriz[filas][columnas] =
{

 { '1', '2', '3', 'A'},
 { '4', '5', '6', 'B'},
 { '7', '8', '9', 'C'},
 { '*', '0', '#', 'D'},

};

byte pinesFilas[filas] = {10, 9, 8, 7};       //Pines donde van conectadas las filas del teclado
byte pinesColumnas[columnas] = {6, 5, 4, 3}; //Pines donde van conectadas las columnas del teclado

//Inicializo el teclado con el numero de filas, columnas, los pines del Arduino utilizados y la matriz
Keypad teclado = Keypad( makeKeymap(matriz), pinesFilas, pinesColumnas, filas, columnas);

//Variables para el control de la posicion del cursor
int posX = 0;
int posY = 0;

//Variales para el control de las teclas
char presionando;
int veces_presionada = 0;
//Variables para el control del contador, ya que no se usa ningun delay() en este codigo
unsigned long tiempo_anterior = 0;
int periodo = 500;  //500 milisegundos

void ISRCountPulse()
{
  pulseConter++;
}

float GetFrequency()
{
  pulseConter = 0;

  interrupts();
  delay(measureInterval);
  noInterrupts();

  return (float)pulseConter * 1000 / measureInterval;
}

void SumVolume(float dV)
{
  volume += dV / 60 * (millis() - t0) / 1000.0;
  t0 = millis();
}
// iniciamos la libreria con el nimero de pines de la interfas
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);
//Pines donde va conectada la pantalla (RS, E, D4, D5, D6, D7))
void setup() {
 pinMode(relay, OUTPUT);
//indicamos a la LCD el número de columnas y filas
 lcd.begin(16, 2);
 // imprime un mensaje en la LCD
 lcd.print("Medidor de Flujo");
 lcd.setCursor(0,1);
 lcd.print("Sistemas Andalucia");
 delay (1000);
 lcd.clear();
 Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(sensorPin), ISRCountPulse, RISING);
  t0 = millis();
}
void loop() {


  lcd.setCursor(0,0);
  lcd.print("1.- 400l");
  lcd.setCursor(8,0);
  lcd.print("2.- 600l");
  
  char tecla_presionada = teclado.getKey();  //Almacena la tecla presionada


switch (tecla_presionada)        //Switch-case de acuerdo a la tecla presionada
 {
   case '1':                      //La tecla 1 es para 400 l
    do {
     digitalWrite(relay, LOW);
       // obtener frecuencia en Hz
  float frequency = GetFrequency();

  // calcular caudal L/min
  float flow_Lmin = frequency / factorK;
  SumVolume(flow_Lmin);

     lcd.setCursor(0,0);
  lcd.print("Sistemas Andalucia");   
   lcd.setCursor(0,1);
  lcd.print(flow_Lmin, 1);
  lcd.print(" L/m");
  lcd.setCursor(8,1);
 lcd.print("C ");
  lcd.print(volume, 1);
  lcd.print(" L");
     }
    while (volume<3);
       digitalWrite(relay, HIGH);
     break;

   case '2':                      //La tecla 1 es para 400 l
    do {
     digitalWrite(relay, LOW);
       // obtener frecuencia en Hz
  float frequency = GetFrequency();

  // calcular caudal L/min
  float flow_Lmin = frequency / factorK;
  SumVolume(flow_Lmin);

     lcd.setCursor(0,0);
  lcd.print("Sistemas Andalucia");   
   lcd.setCursor(0,1);
  lcd.print(flow_Lmin, 1);
  lcd.print(" L/m");
  lcd.setCursor(8,1);
 lcd.print("C ");
  lcd.print(volume, 1);
  lcd.print(" L");
     }
    while (volume<4);
       digitalWrite(relay, HIGH);
     break;
 }
}

Hi,
Mi consejo ya que no se si eres nuevo en el forum es que pases por las reglas de este forum para que tengas una idea de como pedir ayuda y como presentar la data para que se te puede dar un consejo.o sugerencia. Perdona pero es para tu beneficio y los del forum.

Si soy nuevo, y gracias por el consejo segun yo modifique el post espero cumplir con las normas, saludos.

Cada vez que se ejecuta un loop, la variable tecla_presionada toma un valor.
la primera vez lo hace con lo que digitas que será 1 por ejemplo pero si sueltas la tecla, luego sera NO_KEY asi que es lógico creer que se ejecuten algunos ciclos en '1' y luego no lo hace.

Para evitar eso debes evitar que la variable que controla el switch cambie o que lo haga solo cuando presionas un digito diferente.

Así que podrías usar una variable global que cuando detecta 1 o 2 cambie y se ponga a 0 cuando se cumplan las acciones.

Gracias por la respuesta me quedo claro el objetivo, hice modificaciones generales al codigo declare como variable global “keypressed” despues toma el valor de la tecla presionada y se va al switch al caso correspondiente ejecuta el codigo y ahi viene mi duda ya que al finalizar la ejecucion del caso, indico que “keypressed=0;” si es correcta esta declaracion ya que al final me regresa al menu principal pero si selecciono nuevamente el 1 o el 2 no cambia al caso seleccionado.

#include <Key.h>
#include <Keypad.h>
#include <LiquidCrystal.h>

const byte numRows= 4; // Tiene 4 filas
const byte numCols= 4; // Tiene 4 columnas
const int sensorPin = 2;
const int measureInterval = 2500;
volatile int pulseConter;
int relay = 11;
char keypressed;
 
 
// FS300A
const float factorK = 5.5;
 
 
float volume = 0;
long t0 = 0;

//Defino una matriz 4x4 con la posicion de las filas y columnas
char keymap[numRows][numCols]= 
{
{'1', '2', '3', 'A'}, 
{'4', '5', '6', 'B'}, 
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};

byte rowPins[numRows] = {10, 9, 8, 7};       //Pines donde van conectadas las filas del teclado
byte colPins[numCols]= {6, 5, 4, 3}; //Pines donde van conectadas las columnas del teclado

//Inicializo el teclado con el numero de filas, columnas, los pines del Arduino utilizados y la matriz
Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);



void ISRCountPulse()
{
   pulseConter++;
}
 
float GetFrequency()
{
   pulseConter = 0;
 
   interrupts();
   delay(measureInterval);
   noInterrupts();
 
   return (float)pulseConter * 1000 / measureInterval;
}
 
void SumVolume(float dV)
{
   volume += dV / 60 * (millis() - t0) / 1000.0;
   t0 = millis();
}
// iniciamos la libreria con el nimero de pines de la interfas
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);
//Pines donde va conectada la pantalla (RS, E, D4, D5, D6, D7))
void setup() {
  pinMode(relay, OUTPUT); 
//indicamos a la LCD el número de columnas y filas
  lcd.begin(16, 2);
  // imprime un mensaje en la LCD
  lcd.print("Medidor de Flujo");
  lcd.setCursor(0,1);
  lcd.print("Sistemas Andalucia");
  delay (1000);
  lcd.clear();
   attachInterrupt(digitalPinToInterrupt(sensorPin), ISRCountPulse, RISING);
   t0 = millis();
}
void loop() {

 char keypressed;
   lcd.setCursor(0,0);
   lcd.print("1.- 400l");
   lcd.setCursor(8,0);
   lcd.print("2.- 600l");
   lcd.setCursor(0,1);
   lcd.print(keypressed);


   keypressed = myKeypad.getKey();

if (keypressed) {
switch (keypressed)        //Switch-case de acuerdo a la tecla presionada
  {
    case '1':                      //La tecla 1 es para 400 l
     while  (volume<3) {
      digitalWrite(relay, LOW);
        // obtener frecuencia en Hz
   float frequency = GetFrequency();
 
   // calcular caudal L/min
   float flow_Lmin = frequency / factorK;
   SumVolume(flow_Lmin);

      lcd.setCursor(0,0);
   lcd.print("Sistemas Andalucia");   
    lcd.setCursor(0,1);
   lcd.print(flow_Lmin, 1);
   lcd.print(" L/m");
   lcd.setCursor(8,1);
  lcd.print("C ");
   lcd.print(volume, 1);
   lcd.print(" L");
      }
        lcd.clear();
        digitalWrite(relay, HIGH);
      keypressed = 0;
      break;

    case '2':                      //La tecla 2 es para 600 l
     while  (volume<3) {
      digitalWrite(relay, LOW);
        // obtener frecuencia en Hz
   float frequency = GetFrequency();
 
   // calcular caudal L/min
   float flow_Lmin = frequency / factorK;
   SumVolume(flow_Lmin);

      lcd.setCursor(0,0);
   lcd.print("Sistemas Andalucia");   
    lcd.setCursor(0,1);
   lcd.print(flow_Lmin, 1);
   lcd.print(" L/m");
   lcd.setCursor(8,1);
  lcd.print("C ");
   lcd.print(volume, 1);
   lcd.print(" L");
      }
        lcd.clear();
        digitalWrite(relay, HIGH);
      keypressed = 0;
      break;

      
  }}
}

bueno, justamente.. lo que debes hacer te lo expliqué en mi post.

Para evitar eso debes evitar que la variable que controla el switch cambie o que lo haga solo cuando presionas un digito diferente.

Así que podrías usar una variable global que cuando detecta 1 o 2 cambie y se ponga a 0 cuando se cumplan las acciones.

Esto no es global, esto es local al loop

void loop() {
 char keypressed;

Global es antes del setup()
Cada vez que el loop completa un ciclo se inicializa keypress con 0.

Perfecto, de hecho si lo habia compilado asi pero aun asi se quedaba en el menu y aun presionando nuevamente alguna tecla de las opciones no entraba al case seleccionado.

Pude resolverlo quiza no de la forma adecuada lamento si moleste a alguien con esta peticion de ayuda.

Saludos.

PD
Este es el codigo que me funciono.

#include <Key.h>
#include <Keypad.h>
#include <LiquidCrystal.h>
#define RESTART asm("jmp 0x0000")

const byte numRows= 4; // Tiene 4 filas
const byte numCols= 4; // Tiene 4 columnas
const int sensorPin = 2;
const int measureInterval = 2500;
volatile int pulseConter;
int relay = 11;
char keypressed;
 
 
// FS300A
const float factorK = 5.5;
 
 
float volume = 0;
long t0 = 0;

//Defino una matriz 4x4 con la posicion de las filas y columnas
char keymap[numRows][numCols]= 
{
{'1', '2', '3', 'A'}, 
{'4', '5', '6', 'B'}, 
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};

byte rowPins[numRows] = {10, 9, 8, 7};       //Pines donde van conectadas las filas del teclado
byte colPins[numCols]= {6, 5, 4, 3}; //Pines donde van conectadas las columnas del teclado

//Inicializo el teclado con el numero de filas, columnas, los pines del Arduino utilizados y la matriz
Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);



void ISRCountPulse()
{
   pulseConter++;
}
 
float GetFrequency()
{
   pulseConter = 0;
 
   interrupts();
   delay(measureInterval);
   noInterrupts();
 
   return (float)pulseConter * 1000 / measureInterval;
}

void SumVolume(float dV)
{
   volume += dV / 60 * (millis() - t0) / 1000.0;
   t0 = millis();
}
// iniciamos la libreria con el nimero de pines de la interfas
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);
//Pines donde va conectada la pantalla (RS, E, D4, D5, D6, D7))
void setup() {
  digitalWrite(relay, HIGH);
  pinMode(relay, OUTPUT); 
//indicamos a la LCD el número de columnas y filas
  lcd.begin(16, 2);
  // imprime un mensaje en la LCD
  lcd.print("Medidor de Flujo");
  lcd.setCursor(0,1);
  lcd.print("Sistemas Andalucia");
  delay (2000);
  lcd.clear();
   attachInterrupt(digitalPinToInterrupt(sensorPin), ISRCountPulse, RISING);
   t0 = millis();
}
void loop() {

 digitalWrite(relay, HIGH);
   lcd.setCursor(0,0);
   lcd.print("1.- 400l");
   lcd.setCursor(9,0);
   lcd.print("2.- 600l");
   lcd.setCursor(0,1);
   lcd.print("3.- 500l");
   lcd.setCursor(9,1);
   lcd.print("4.- 800l");



   keypressed = myKeypad.getKey();

if (keypressed) {
switch (keypressed)        //Switch-case de acuerdo a la tecla presionada
  {
    case '1':                      //La tecla 1 es para 400 l
     while  (volume<3) {
      digitalWrite(relay, LOW);
        // obtener frecuencia en Hz
   float frequency = GetFrequency();
 
   // calcular caudal L/min
   float flow_Lmin = frequency / factorK;
   SumVolume(flow_Lmin);

      lcd.setCursor(0,0);
   lcd.print("Sistemas Andalucia");   
    lcd.setCursor(0,1);
   lcd.print(flow_Lmin, 1);
   lcd.print(" L/m");
   lcd.setCursor(8,1);
  lcd.print("C ");
   lcd.print(volume, 1);
   lcd.print(" L");
      }
        lcd.clear();
        digitalWrite(relay, HIGH);
        RESTART;
      break;

    case '2':                      //La tecla 2 es para 600 l
     while  (volume<4) {
      digitalWrite(relay, LOW);
        // obtener frecuencia en Hz
   float frequency = GetFrequency();
 
   // calcular caudal L/min
   float flow_Lmin = frequency / factorK;
   SumVolume(flow_Lmin);

      lcd.setCursor(0,0);
   lcd.print("Sistemas Andalucia");   
    lcd.setCursor(0,1);
   lcd.print(flow_Lmin, 1);
   lcd.print(" L/m");
   lcd.setCursor(8,1);
  lcd.print("C ");
   lcd.print(volume, 1);
   lcd.print(" L");
      }
        lcd.clear();
        digitalWrite(relay, HIGH);
        RESTART;
      break;

case '3':                      //La tecla 2 es para 600 l
     while  (volume<5) {
      digitalWrite(relay, LOW);
        // obtener frecuencia en Hz
   float frequency = GetFrequency();
 
   // calcular caudal L/min
   float flow_Lmin = frequency / factorK;
   SumVolume(flow_Lmin);

      lcd.setCursor(0,0);
   lcd.print("Sistemas Andalucia");   
    lcd.setCursor(0,1);
   lcd.print(flow_Lmin, 1);
   lcd.print(" L/m");
   lcd.setCursor(8,1);
  lcd.print("C ");
   lcd.print(volume, 1);
   lcd.print(" L");
      }
        lcd.clear();
        digitalWrite(relay, HIGH);
        RESTART;
      break;

case '4':                      //La tecla 2 es para 600 l
     while  (volume<1000) {
      digitalWrite(relay, LOW);
        // obtener frecuencia en Hz
   float frequency = GetFrequency();
 
   // calcular caudal L/min
   float flow_Lmin = frequency / factorK;
   SumVolume(flow_Lmin);

      lcd.setCursor(0,0);
   lcd.print("Sistemas Andalucia");   
    lcd.setCursor(0,1);
   lcd.print(flow_Lmin, 1);
   lcd.print(" L/m");
   lcd.setCursor(8,1);
  lcd.print("C ");
   lcd.print(volume, 1);
   lcd.print(" L");
      }
        lcd.clear();
        digitalWrite(relay, HIGH);
        RESTART;
      break;
      
  }}
}