Enviando datos al puerto de serie y condicionales if

Muy buenas, tengo un problemilla con el siguiente código que pongo a continuación:

void loop()
{
   if (Serial.available()>0)
   {
     opcion = Serial.read()-48
     switch (opcion)
     {
      case 1:
      //Acciones
      break;
      case 2:
      dato = Serial.read;
      Serial.println(dato);
      break;
     }
   }
}

Como se puede apreciar, se trata de introducir un primer dato que servirá para entrar en una opción del menú y una vez dentro de la opción correspondiente volver a introducir otro dato para que lo que se encuentra dentro de dicha opción trabaje con dicho dato. El problema es que sencillamente no hace nada. He probado a colocar nuevamente el "If serial.available()>0" dentro de la opción, antes de introducir el dato, pero sigue sin recibirlo. He puesto mensajes para que aparezcan por la pantalla y me vayan indicando donde está el programa y efectivamente entra en la opción 2, pero ignora pedir el dato. No sé si al tratarse de pedir un dato "dentro" de haber pedido otro se deba hacer de otra manera o algo.
Un saludo y gracias de antemano.

Hola, en principio con que cambies: "dato = Serial.read;" por "dato = Serial.read();" valdría.

Un saludo.

Yo añadiría también después de cada lectura un Serial.flush(); para asegurarte que dejas el buffer de entrada vació y que en la siguiente lectura no lees datos anteriores.

Saludos!

Hola,

Agrega el ; al final del "opcion = Serial.read()-48".
Agrega un caso defaul para verificar que no este llegando otro valor.

Y en tu Opcion 2, espera hasta que llegue un nuevo dato, while(!Serial.available);

Algo así:

void loop()
{
  if (Serial.available()>0)
  {
    opcion = Serial.read()-48;
    
    switch(opcion)
    {
      case 1:
        //Acciones
        Serial.println("Case 1");
      break;
      
      case 2:
        Serial.println("Case 2");

        while(!Serial.available()); /Luego aquí puedes implementar un timeout que si pasa cierto tiempo se salga

        dato = Serial.read;
        Serial.println(dato);
      break;

      default:
        Serial.println("default");
      break;
    }
  }
}

giltesa:
Yo añadiría también después de cada lectura un Serial.flush(); para asegurarte que dejas el buffer de entrada vació y que en la siguiente lectura no lees datos anteriores.

La instrucción Serial.flush(); ya no vacía el buffer de entrada desde Arduino 1.0 Serial.flush() - Arduino Reference
Y desconozco si ahora hay alguna instrucción que permita borrar el buffer.

Muchas gracias por las respuestas, respecto a los "()" después del "Serial.read" y otros errores sintácticos, lo siento, fue un error mío al copiar el código.
Al final se me ocurrió que la Arduino tendría que tardar algún tiempo por pequeño que fuera en recibir y procesar esos datos, así que se me ocurrió antes de pedir el dato dentro de la opción 2 algo así:

while (Serial.available()<=0)
{
  delayMicroseconds(10);
}
dato = Serial.read();

La idea es que se quede esperando mientras el puerto está ocupado y que una vez libre pase a pedir el dato. Al final, es lo que ha aportado Luis_AM3C, sólo que un poco más chapucero. He caído en que el "If serial.available()" lo que hace es decir "si el puerto está disponible, escribe". Como no lo estaba, sencillamente no escribía y el programa seguía su camino, mientras que con el while lo que hago es decir "espera hasta que el puerto esté disponible y entonces escribe". Comento la conclusión para que todos los que no lo sabíamos podamos tomar nota y aprender de un error más. :slight_smile:
Un saludo

Creo que no vas por la pista... Aunque la traducción de "available" es "disponible" no significa que la instrucción Serial.available() nos indique cuándo el puerto está o deja de estar ocupado. Revisa lo que hacen las instrucciones: Serial.available() - Arduino Reference

Serial.available() devuelve el número de bytes almacenados en el buffer.
Al contrario, si haces:

while (Serial.available()<=0)
{
  delayMicroseconds(10);
}
dato = Serial.read();

tu programa se quedará bloqueado dentro del while siempre que no le estés enviando nada por puerto serie.

Cheyenne:

giltesa:
Yo añadiría también después de cada lectura un Serial.flush(); para asegurarte que dejas el buffer de entrada vació y que en la siguiente lectura no lees datos anteriores.

La instrucción Serial.flush(); ya no vacía el buffer de entrada desde Arduino 1.0 Serial.flush() - Arduino Reference
Y desconozco si ahora hay alguna instrucción que permita borrar el buffer.

Ya veo que ahora si funciona como en otros lenguajes de programación, gracias por el apunte :slight_smile:

Vaya, vaya, muy interesante lo que has comentado Cheyenne. No había interpretado así la función Serial.available() la última vez que la leí. De hecho, al entender ahora como funciona se me ha abierto la puerta para 5 o 6 problemas diferentes más que tenía y que llevaba tiempo pensando como resolver, mira por donde he acabado aprendiendo muchas más cosas nuevas de la cuenta :slight_smile:
Un saludo

Buenas, tengo mas o menos el mismo problema que el compañero, estoy peleandome con el puerto serial... y la verdad es que no entiendo muy bien con los comentarios si al final se llego a una solución o no...

Estoy haciendo un proyecto para hacer una especie de sistema domotico para mi hogar, en el que se controlara temperaturas, humedades, alarmas... de momento, estoy a la espera de que me lleguen componentes, pero he empezado a trastear con el codigo del menu.

int ledPin=44, ledPin1=48;
int opc=0;                                     // opcion para el menu
void setup (){
  pinMode(ledPin,OUTPUT);
  pinMode(ledPin,OUTPUT);

  Serial.begin(9600);

}

void loop (){

  Serial.println("¡Bienvenido!");
  Serial.println("Escoja una opcion de menu:");
  do {
    if (opc != 1 && opc != 2 && opc==3 ) Serial.println("Por favor, introduzca un numero de opcion valido."); // imprime mensaje si opc != 1,2 o 3

    Serial.println("1: Temperatura.");
    Serial.println("2: Humedad");
    Serial.println("3: Alarmas");
    Serial.read();
    opc=Serial.read();
    Serial.println(opc);
    delay(2000);
  } while (opc != 1 || opc!= 2 || opc!=3); // asegura repetir el loop hasta que opc sea = a 1,2 o 3
  
    switch (opc){
      
      case 1:
      
      //  temperatura();                                          //Llamada a la funcion temperatura
        Serial.print("La temperatura es:");
        digitalWrite(ledPin,HIGH);
      case 2:
      //  humedad();                                          //Llamada a la funcion humedad
        Serial.print("La humedad es:");
        digitalWrite(ledPin1,HIGH);
      case 3:
        
      //  alarmas();                                          //Llamada a la funcion alarmas
        Serial.print("La lista de alarmas es:");
      default:
        Serial.println("DEFAULT");
  }                                                            //Fin del switch

}

Siempre me entra en default y no coge valores del puerto serial, simplemente "opc" esta todo el rato igual a -1.

A ver si me podeis echar una manilla..

muchas gracias!