switch case anidados (Solucionado)

estoy tratando de hacer funcionar un codigo con switch anidados.
lo subo resumido, el switch simple me funciona perfecto, asi que lo subo con una sola opcion ya que lo demas se refiere a 3 servos mas conectados, la inteniones que por ejemplo preciono la A deberia ir a case A. y yo cargar los grados del movimiento y asi sucesivamente, pero no me funciona ni la primera opcion "A" las demas serian repetitivas de esta. la verdad no se porque no me selecciona las opciones.

#include <Keypad.h>

#include <Servo.h>
Servo miservo;
Servo miservo2;
Servo miservo3;
Servo miservo4;


const byte Filas = 4; //KeyPad de 4 filas
const byte Cols = 4; //y 4 columnas
byte Pins_Filas[] = {33,35,37,39}; //Pines Arduino para las filas.
byte Pins_Cols[] = {41,43,45,47}; // Pines Arduino para las columnas.


char ABCD; 
char pulsacion;
String valor_util = ""; // teclas digitadas
int  datos_ingresado ; // cadena de datos digitados a travez del teclado
//int numero; // datos mostrar puerto serie


char cadena[17];  // la conversion a número
 
char Teclas [Filas][Cols] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'.','0','#','D'}
};
 
Keypad Teclado = Keypad(makeKeymap(Teclas), Pins_Filas, Pins_Cols, Filas, Cols);
 


void setup() {

miservo.attach(5);
miservo.attach(4);
miservo.attach(3);
miservo.attach(2);


 Serial.begin(9600);
}
void loop() {

  ABCD = Teclado.getKey();
  pulsacion =Teclado.getKey();
  
  
 switch (ABCD) {
 case 'A' :
      	switch (pulsacion) {
      		case '0' ... '9':
        	valor_util +=pulsacion; // se agrega a la cadena
        	break;
      		case '#' : // guardo los datos
        	valor_util.toCharArray(cadena, 17);
        	datos_ingresado = atof (cadena);
        	Serial.println(datos_ingresado); // veo el angulo ingresado.
        	break;
        case '*': // teclas para borrar
      	 valor_util ="";
        break;
         }   
case 'B':
 // miservo2
  break;

case 'C':
//miservo3
  break;
case 'D':
//miservo4
  break;  

  }
 miservo.write(datos_ingresado);
}

Lo que ocurre que estas precipitando las cosas.

ABCD = Teclado.getKey();
  pulsacion =Teclado.getKey();

La primera lectura de teclado va a ABCD pero entonces deberías haberte quedado dentro de la primera selección case A: y establecer como vas a salir de esa situación.

La única forma de hacerlo es con un while y entonces debes seguir leyendo el angulo

#include <Keypad.h>
#include <Servo.h>

Servo miservo;
Servo miservo2;
Servo miservo3;
Servo miservo4;

const byte Filas = 4; //KeyPad de 4 filas
const byte Cols = 4; //y 4 columnas
byte Pins_Filas[] = {33,35,37,39}; //Pines Arduino para las filas.
byte Pins_Cols[] = {41,43,45,47}; // Pines Arduino para las columnas.

char ABCD; 
char pulsacion;
String valor_util = ""; // teclas digitadas
int  datos_ingresado ; // cadena de datos digitados a travez del teclado
//int numero; // datos mostrar puerto serie


char cadena[17];  // la conversion a número
 
char Teclas [Filas][Cols] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'.','0','#','D'}
};
 
Keypad Teclado = Keypad(makeKeymap(Teclas), Pins_Filas, Pins_Cols, Filas, Cols);
 


void setup() {

  miservo.attach(5);
  miservo.attach(4);
  miservo.attach(3);
  miservo.attach(2);

  Serial.begin(9600);
}

void loop() {

  ABCD = Teclado.getKey();
    
  switch (ABCD) {
  case 'A' :
        while (pulsacion != '*') {
          pulsacion = Teclado.getKey();
          switch(pulsacion) {  
                case '0' ... '9':
                            valor_util +=pulsacion; // se agrega a la cadena
                            break;
                case '#' :  // guardo los datos
                            valor_util.toCharArray(cadena, 17);
                            datos_ingresado = atof (cadena);
                            Serial.println(datos_ingresado); // veo el angulo ingresado.
                            break;
                case '*':   // teclas para borrar
                            valor_util ="";
                            break;
          }   
        }
  case 'B':
            // miservo2
            break;

  case 'C':
            //miservo3
            break;
  case 'D':
            //miservo4
            break;  

  }
  miservo.write(datos_ingresado);
}

subo solo una parte de codigo, me queda en un loop interminable, y ademas no me yo cargo angulo 120 por ejemplo y ahora me lo toma 1 despues 2 luego 0. le agregue un println (ABCD) y cambie * por D. pero nunca sale de loop.

void loop() {

  ABCD = Teclado.getKey();
  Serial.println(ABCD);
    
  switch (ABCD) {
  case 'A' :
        while (pulsacion != 'D') 
        {
          pulsacion = Teclado.getKey();
          switch(pulsacion) {  
                case '0' ... '9':
                            valor_util +=pulsacion; // se agrega a la cadena
                            break;
                case '#' :  // guardo los datos
                            valor_util.toCharArray(cadena, 17);
                            datos_ingresado = atof (cadena);
                            Serial.println(datos_ingresado); // veo el angulo ingresado.
                            break;
                case '*':   // teclas para borrar
                            valor_util ="";
                            break;
          }   
        }

Entonces te malentendí. Que no funcionaba en el primer código tuyo?

Este codigo es con un switch de un solo nivel funciona, pero cuando lo quiero anidar como el anterior empiezan los problemas, una vez que consegui que me funcione decidi anidar para los otros servos,
ya que switch me di cuenta que es de mucha utilidad para algunas pruebas que hago para ir aprendiendo

#include <Keypad.h>

#include <Servo.h>
Servo miservo;



const byte Filas = 4; //KeyPad de 4 filas
const byte Cols = 4; //y 4 columnas
byte Pins_Filas[] = {33,35,37,39}; //Pines Arduino para las filas.
byte Pins_Cols[] = {41,43,45,47}; // Pines Arduino para las columnas.

char pulsacion; 
String valor_util = ""; // teclas digitadas
int  datos_ingresado ; // cadena de datos digitados a travez del teclado
int numero; // datos mostrar puerto serie


char cadena[17];  // la conversion a número
 
char Teclas [Filas][Cols] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'.','0','#','D'}
};
 
Keypad Teclado = Keypad(makeKeymap(Teclas), Pins_Filas, Pins_Cols, Filas, Cols);
 


void setup() {

miservo.attach(5);


 Serial.begin(9600);
}
void loop() {

  pulsacion = Teclado.getKey();

  switch (pulsacion) {
      case '0' ... '9':
        valor_util +=pulsacion; // se agrega a la cadena
        break;
      case '#' : // guardo los datos
        valor_util.toCharArray(cadena, 17);
        datos_ingresado = atof (cadena);
        Serial.println(datos_ingresado); // veo el angulo ingresado.
        break;
      case 'D': // teclas para borrar
      	valor_util ="";
      //default:
        // do something
  }
 miservo.write(datos_ingresado);
}

tenes razon falta la llave de cierre. y tengo unsolo miservo1.write(datos_ingresado); yaque no consigo que funcione uno, menos 4

#include <Keypad.h>
#include <Servo.h>
Servo miservo1;
Servo miservo2;
Servo miservo3;
Servo miservo4;
const byte Filas = 4; //KeyPad de 4 filas
const byte Cols = 4; //y 4 columnas
byte Pins_Filas[] = {33,35,37,39}; //Pines Arduino para las filas.
byte Pins_Cols[] = {41,43,45,47}; // Pines Arduino para las columnas.

char ABCD; 
char pulsacion;
String valor_util = ""; // teclas digitadas
int  datos_ingresado ; // cadena de datos digitados a travez del teclado
//int numero; // datos mostrar puerto serie
char cadena[17];  // la conversion a número
char Teclas [Filas][Cols] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'.','0','#','D'}
};
Keypad Teclado = Keypad(makeKeymap(Teclas), Pins_Filas, Pins_Cols, Filas, Cols);

void setup() {
miservo1.attach(5);
miservo2.attach(4);
miservo3.attach(3);
miservo4.attach(2);
 Serial.begin(9600);
}
void loop() {

  ABCD = Teclado.getKey();
   
  
 switch (ABCD) {

 case 'A' :
        pulsacion =Teclado.getKey();
      	switch (pulsacion) {
      		case '0' ... '9':
        	valor_util +=pulsacion; // se agrega a la cadena
        	break;
      		
          case '#' : // guardo los datos
        	valor_util.toCharArray(cadena, 17);
        	datos_ingresado = atof (cadena);
        	Serial.println(datos_ingresado); // veo el angulo ingresado.
        	break;
        
        case '*': // teclas para borrar
      	 valor_util ="";
          break;
                          }   
         
break;
        
case 'B':
 // miservo2
  break;

case 'C':
//miservo3
  break;
case 'D':
//miservo4
  break;  

 }
 
 miservo1.write(datos_ingresado);
 
}

este codigo me sucede lo mismo si lo hago de un nivel funciona si agrego otro nivel deja de funcionar

#include <Keypad.h>
int led_1 =8;
int led_2 =9;
int led_3=11;
int led_4 =12;

const byte Filas = 4; //KeyPad de 4 filas
const byte Cols = 4; //y 4 columnas
byte Pins_Filas[] = {33,35,37,39}; //Pines Arduino para las filas.
byte Pins_Cols[] = {41,43,45,47}; // Pines Arduino para las columnas.

char pulsacion;
char leds;

char cadena[17]; 
char Teclas [Filas][Cols] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
Keypad Teclado = Keypad(makeKeymap(Teclas), Pins_Filas, Pins_Cols, Filas, Cols);

void setup() {
 Serial.begin(9600);
pinMode(led_1, OUTPUT);
pinMode(led_2, OUTPUT);
pinMode(led_3, OUTPUT);
pinMode(led_4, OUTPUT);

}
void loop() {

	pulsacion = Teclado.getKey();

	switch (pulsacion) {
		
	    case 'A' :
	        leds =Teclado.getKey();
            switch (leds) {
         case '1':
              digitalWrite(led_1, !digitalRead(led_1));
              break;
         case '2':
              digitalWrite(led_2, !digitalRead(led_2));
              break;
               }
           break;            
	    case 'B' :
	    		leds =Teclado.getKey();
	      switch (leds){
	      case '3':
            	digitalWrite(led_3, !digitalRead(led_3));
              break;
          case '4':
            	digitalWrite(led_4, !digitalRead(led_4));
              break;
               }
	      
	break;
	        }
	    
	}
        
        
       
        	





        }

ya no se que inventar, si unas de las variables por ejemplo pulsaciones que pertenece al primer nivel, le de claro como int pulsaciones ='A'; el segundo nivel perfecto con el teclado y lo mismo con la variable leds, pero los dos juntos no me funciona.

#include #include <Keypad.h>
int led_1 =8;
int led_2 =9;
int led_3=11;
int led_4 =12;

const byte Filas = 4; //KeyPad de 4 filas
const byte Cols = 4; //y 4 columnas
byte Pins_Filas[] = {33,35,37,39}; //Pines Arduino para las filas.
byte Pins_Cols[] = {41,43,45,47}; // Pines Arduino para las columnas.



//int pulsacion ='A';
//int leds ='1';

char cadena[17]; 
char Teclas [Filas][Cols] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
Keypad Teclado = Keypad(makeKeymap(Teclas), Pins_Filas, Pins_Cols, Filas, Cols);




void setup() {
 Serial.begin(9600);
pinMode(led_1, OUTPUT);
pinMode(led_2, OUTPUT);
pinMode(led_3, OUTPUT);
pinMode(led_4, OUTPUT);

}
void loop() {
	char pulsacion = Teclado.getKey();
	char leds = Teclado.getKey();

	//pulsacion = Teclado.getKey();
	//leds = Teclado.getKey();
	
	
	switch (pulsacion) {
		
	    case 'A' :
	        
            switch (leds) {
					
         case '1':
              digitalWrite(led_1, !digitalRead(led_1));
              break;
         case '2':
              digitalWrite(led_2, !digitalRead(led_2));
              break;
              }
              break;

	    case 'B' :
	    		
	      switch (leds){
              	
	      case '3':
            	digitalWrite(led_3, !digitalRead(led_3));
              break;
          case '4':
            	digitalWrite(led_4, !digitalRead(led_4));
              break;
               }

	      
	break;

	        }
	    
	}

arranque tempranito, con unos matecitos, pero nada reescribi el codigo me lei como hacerlo en C C# C++, hasta java y no le veo el error.

Señores, creo que no están teniendo en cuenta que la llamada a Teclado.getKey() no es bloqueante y retorna el valor de la tecla que se acaba de pulsar, cero si ya ha retornado ese valor con anterioridad (si se deja pulsada no la retorna sino una sola vez) o también cero si no hay ninguna tecla pulsada. Así que si hacemos dos llamadas seguidas lo más probable es que sólo una de las dos llamadas nos de un valor distinto de cero (siempre que almenos se pulse una tecla) por muy rápido que seamos pulsando más de una tecla. Asumamos pues que nunca vamos a tener como resultado dos teclas distinto a cero si realizamos dos llamadas consecutivas sin ningún tipo de espera entre ellas.

Cosa diferente sería que llamásemos a waitForKey() en lugar de getKey(). Pero esto haría que el programa estuviera detenido mientras está esperando a que pulsemos alguna tecla. Es algo similar a si usamos delay() o millis(), bloqueante vs. no bloqueante. Así que o se utiliza la versión bloqueante (waitForKey()) o no tendremos más remedio que usar la técnica de la máquina de estados, por muy pocos estados que deba de tener.

Para la máquina de estado necesitaremos una variable que nos indique en qué estado estamos y variables auxiliares para almacenar valores "temporales" del resultado.

Supongamos que lo que se quiere es que mediante un teclado de 16 teclas (los dígitos del '0' al '9', letras de la 'A' a la 'D', el '*' y el '#') indicar el ángulo al que queremos posicionar cuatro servos que "etiquetamos" de la 'A' a la 'D' en un ángulo de 0 a 180 grados. Para ello hemos de pulsar primero la letra que "identifica" el servo a posicionar. Luego una cantidad arbitrarias de dígitos del '0' al '9' para indicar los grados y por último la tecla '#' para confirmar que ya hemos tecleado los valores deseado y que ejecute el posicionamiento del servo según esos valores.

Cosas a tener en cuenta, si entre que pulsamos la letra y el '#' no hemos pulsado ningún dígito del '0' al '9' asumiremos que queremos posicionarlo a 0 grados. Si entre la letra y el '#' pulsamos más de tres dígitos sólo tendremos en cuenta los últimos tres dígitos (si se teclea 'A13025#' se comportará como si se hubiera pulsado 'A025#' con lo que posicionaría el servo 'A' a 25 grados. Si no se ha pulsado ninguna letra y se pulsa '#' no se hará nada y será como si no se hubiera pulsado nada en ningún momento. Si se empieza pulsando dígitos del '0' al '9' sin haber pulsado antes ninguna letra, no se tendrán en cuenta y será como si no se hubiera pulsado nada. Si en cualquier momento se pulsa una letra de la 'A' a la 'D' se descartará todo lo pulsado hasta ese momento y se considera la letra pulsada (El pulsar 'A123B054#' sería como si sólo se hubiera pulsado 'B054#'). Si se pulsa cualquier otra tecla que no sean los dígitos del '0' al '9', las letras de la 'A' a la 'D' o el '#' se "cancelará" la entrada de datos y volverá a esperar a que se pulse una letra de la 'A' a la 'D'.

Hemos indicado que sólo los tres últimos dígitos del '0' al '9' que se han tecleado son los que se van a tener en cuenta ya que el valor máximo del ángulo ha de ser 180 grados. Si el valor tecleado supera esa cantidad, asumiremos el máximo (180).

Ahora que tenemos más o menos claro cómo queremos que funcione, vemos que la máquina de estado no ha de controlar sino si está esperando por la letra inicial o por el resto (dígito del '0' al '9' o el '#'). Como variables auxiliares necesitamos una para guardar la letra que identifica el servo y otra para guardar el valor del ángulo que se ha tecleado. Para la máquina de estado nos vale un simple boolean que nos indica si ya tenemos una letra o no. Para guardar la letra que se ha pulsado nos basta con una variable de tipo char. Y para el valor del ángulo en principio parece que nos podría valer una variable de tipo byte ya que nos permitiría guardar un valor entre 0 y 255, pero mejor si utilizamos una variable de tipo int ya que en algún momento podríamos tener un valor mayor de 255 (si por ejemplo tecleamos 'A999#' el valor sería 999) y nos será más fácil controlar que supera los 180 grados después.

Realmente la variable que controla el estado de la máquina de estado nos la podríamos ahorrar si usamos un valor no válido para la variable que almacena la letra pulsada. Ese valor nos indicaría que aún estamos esperando una letra. Pero tal vez más adelante queramos controlar la entrada de otros tipos de datos mediante el teclado con lo cual la máquina de estado debería de tener más estados. Así que lo mejor es usar una variable independiente para controlar la máquina de estados. Yo, personalmente, suelo utilizar un tipo enumerado para la variable que controla la máquina de estados. Ya sé que ahora es muy sencilla (sólo tiene dos estados posibles), pero puede que en el futuro el programa necesite hacer más cosas o incluso que queramos usar un tercer estado que nos indique que ya tenemos un valor correcto porque no vamos a usarlo y "descartarlo" sobre la marcha.

Posible implementación de mi propuesta:

Llamemos estado a la variable que guarda el estado de la máquina. A la que guarda la letra la llamamos letra y a la que guarda el ángulo la llamamos cantidad. Yo declararía las tres variables globales algo tal que así:

enum estado_t {
  ESTADO_ESPERANDO_LETRA,
  ESTADO_ESPERANDO_DIGITO
};

estado_t estado = ESTADO_ESPERANDO_LETRA;
char letra;
int cantidad;

Creo el tipo enumerado estado_t e inicializo la variable estado con el valor ESTADO_ESPERANDO_LETRA ya que al inicio aún no tenemos ninguna letra definida. Las otras dos variables no son nesesarias inicializarlas con algún valor ya que no se deben utilizar hasta que no cambiemos al estado ESTADO_ESPERANDO_DIGITO y en el momento del cambio es cuando estableceremos el valor de letra y pondermos a cero el valor de cantidad.

Ahora lo que deberíamos de tener es algo así como:

loop() {
  char tecla = Teclado.getKey()
  switch (tecla) {
    case 'A' ... 'D' :  // Se ha pulsado una letra
      letra = tecla;                     // Ya sabemos qué servo es el que se quiere accionar, lo guardamos
      cantidad = 0;                      // Iniciamos a cero la cantidad
      estado = ESTADO_ESPERANDO_DIGITO;  // Pasamos al estado en se espera a que se ingrese la cantidad
      break;  // Salimos del switch (tecla)

    case '0' ... '9' :  // Se trata de un dígito, así que actualizamos la cantidad
      // No hace falta verificar en que estado estamos ya que si no estamos en ESTADO_ESPERANDO_DIGITO el valor de cantidad no se usará
      cantidad = ((cantidad * 10) + tecla - '0') % 1000; // Desplazamos un dígito a la izquierda (* 10), le sumamos valor la tecla pulsada (+ tecla - '0'), y nos quedamos con los tres dígitos menos significativos (% 1000) al obtener el resto de dividirlo entre 1000
      break;  // Salimos del switch (tecla)

    case '#' :  // Se confirman los valores pulsando el '#'
      if (estado == ESTADO_ESPERANDO_DIGITO) { // Si ya se había ingresado una letra (está esperando por un dígito) procedemos con el valor que tenemos
        cantidad = min(cantidad, 180);       // Nos aseguramos que cantidad valga como máximo 180
        switch (letra) {
          case 'A' :
            miservo.write(cantidad);     // Posicionamos el servo deseado en el ángulo indicado
            break;  // Salimos del switch (letra), pero no del switch (tecla)
          case 'B' :
            miservo2.write(cantidad);    // Posicionamos el servo deseado en el ángulo indicado
            break;  // Salimos del switch (letra), pero no del switch (tecla)
          case 'C' :
            miservo3.write(cantidad);    // Posicionamos el servo deseado en el ángulo indicado
            break;  // Salimos del switch (letra), pero no del switch (tecla)
          case 'D' :
            miservo4.write(cantidad);    // Posicionamos el servo deseado en el ángulo indicado
            break;  // Salimos del switch (letra), pero no del switch (tecla)
        }
      }
      // Ojo, no salimos del switch (tecla) ya que lo siguiente queremos que lo haga también en el caso de ser '#'
    default:
      estado = ESTADO_ESPERANDO_LETRA;    // Si se ha pulsado '#' o cualquier techa no contemplada hasta ahora, pasa al estado de esperar una letra
      break;  // Salimos del switch (tecla). Realmente este break no es necesario ya que no hay más casos
  }
}

En el código se comenta qué hace y porqué. Puede resultar algo "esotérica" la instrucción cantidad = ((cantidad * 10) + tecla - '0') % 1000; por lo que si no se comprende me lo dicen y trato de explicarla.

También hay que tener en cuenta que no hay un break; al final del caso '#' ya que se va a asignar igualmente el valor ESTADO_ESPERANDO_LETRA a la variable estado una vez hecho todo lo anterior, así como si la tecla pulsada no es ninguna de las ya consideradas en el switch, por eso el default:.

No lo he probado, no tengo teclado para ello, pero en teoría debería de funcionar. Claro está que falta el resto del código (el setup(), la declaración de algunas variables e inicialización, etc).

entonces por lo que vos comentas una variable boolean seria la solucion??

Creo que no has visto que cinco minutos después de mi primera respuesta he puesto una propuesta. Es que no me cabía todo en uno, superaba los 9000 caractéres.

:confused: :o , voy a ver si lo puedo implementar primero con los leds, que hay cosas como esto

enum estado_t {
  ESTADO_ESPERANDO_LETRA,
  ESTADO_ESPERANDO_DIGITO
};

ni lo sabia, va al comienzo del skecht?

bueno acabo de leer este post Para qué sirve un enum? - Software - Arduino Forum

ahora menos que menos me doy cuenta como se implementa en ejemplo de los leds, ya que me parece mas basico para entender. cambio el codigo subi uno anterior, sin modificacion

#include <Keypad.h>


int led_1 =8;
int led_2 =9;
int led_3=11;
int led_4 =12;

const byte Filas = 4; //KeyPad de 4 filas
const byte Cols = 4; //y 4 columnas
byte Pins_Filas[] = {33,35,37,39}; //Pines Arduino para las filas.
byte Pins_Cols[] = {41,43,45,47}; // Pines Arduino para las columnas.

char cadena[17]; 
char Teclas [Filas][Cols] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
Keypad Teclado = Keypad(makeKeymap(Teclas), Pins_Filas, Pins_Cols, Filas, Cols);

enum estado_t{
  ESPARANDO_LETRA,
  ESPERANDO_LED
};
estado_t estado = ESPARANDO_LETRA;
char letra;
char led;


void setup() {
 Serial.begin(9600);
pinMode(led_1, OUTPUT);
pinMode(led_2, OUTPUT);
pinMode(led_3, OUTPUT);
pinMode(led_4, OUTPUT);

}
void loop() {
  
  char pulsacion = Teclado.getKey();
 
  
   
  switch (pulsacion) {
      case 'A'...'B':
        letra = pulsacion;
        led="";
        estado = ESPERANDO_LED;
        break;
      case '1'...'4':
       led = pulsacion; 
        break;

      case '#':
         if (estado==ESPERANDO_LED){
          switch (led){

                case '1':
                digitalWrite(led_1,!digitalRead(led_1));
                break;
                case '2' :
                digitalWrite(led_2,!digitalRead(led_2));
                break;
                case '3':
                digitalWrite(led_3,!digitalRead(led_3));
                break;
                case '4':
                digitalWrite(led_4,!digitalRead(led_4));
                break;
          }
         }
      default:
       estado = ESPARANDO_LETRA;
       break;
  }
}

Adrian_E lo del enum no es más que una forma "refinada" de tratar con constantes. En este caso en lugar de usar los valores 0 y 1 se tienen "las constantes" ESTADO_ESPERANDO_LETRA y ESTADO_ESPERANDO_DIGITO. Y digamos que esas constantes son del tipo estado_t. Pero si has leído la entrada que dices verás que ahí lo explico un poco.

Por otro lado, el ejemplo que has puesto del control de los LEDs con el teclado, en teoría, no debería de funcionar bien. Tal vez el delay(300) hace posible que en ocasiones funcione ya que puede que la librería Keypad.h almacene las teclas pulsadas durante el delay(300) (no conozco a fondo esa librería) y de la casualidad que pulses las dos teclas durante esa pausa y luego las provea una detrás de otra. Si fuera así, te funcionaría aveces sí, aveces no. Prueba a quitar el delay(300) o a pulsar las teclas con un segundo de separación entre una pulsación y otra y dime si funciona bien o no funciona en absoluto. Es más ¿te funciona bien el 100% de las veces el código de los LEDs que has puesto, tal cual está? (En lo que escribía esto has cambiado el código que habías puesto, esto ya no procede)

El enum y las variables que puse que han de ser globales lo has de poner al principio, fuera del setup() y del loop().

ok saque el delay(), pero me sigue ganando >:( >:(

Como no consegui hacerlo funcionar, solo de esta manaera, lo malo es que el waitForKey() pe detiene el codigo hasta que precione la opcion elegida

#include <Keypad.h>


int led_1 =8;
int led_2 =9;
int led_3=11;
int led_4 =12;

const byte Filas = 4; //KeyPad de 4 filas
const byte Cols = 4; //y 4 columnas
byte Pins_Filas[] = {33,35,37,39}; //Pines Arduino para las filas.
byte Pins_Cols[] = {41,43,45,47}; // Pines Arduino para las columnas.

int tiempo = 250;
unsigned long inicia=0;


char cadena[17]; 
char Teclas [Filas][Cols] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
Keypad Teclado = Keypad(makeKeymap(Teclas), Pins_Filas, Pins_Cols, Filas, Cols);

char leds;
char pulsacion;


void setup() {
 Serial.begin(9600);
pinMode(led_1, OUTPUT);
pinMode(led_2, OUTPUT);
pinMode(led_3, OUTPUT);
pinMode(led_4, OUTPUT);
pinMode(6, OUTPUT);
}
void loop() {
  
  pulsacion = Teclado.getKey();
  
  if(millis() - inicia>=tiempo){
      inicia = millis();
      digitalWrite(6, !digitalRead(6));
  }
  
  switch (pulsacion) {
    
      case 'A' :
            leds = Teclado.waitForKey();
            switch (leds) 
               {
          
         case '1':
              digitalWrite(led_1, !digitalRead(led_1));
              break;
         case '2':
              digitalWrite(led_2, !digitalRead(led_2));
              break;
              }
              break;
           
      case 'B' :
          leds = Teclado.waitForKey();
        switch (leds){
                
        case '3':
              digitalWrite(led_3, !digitalRead(led_3));
              break;
          case '4':
              digitalWrite(led_4, !digitalRead(led_4));
              break;
               }
              break;

       }   
  
  }

¿Qué es exactamente lo que quieres hacer que no te funciona?

Es anidar switch como el ejemplo que postee pero si tener que usar waitforkey que detiene la ejecución