Go Down

Topic: Problemas con el Serial.read() (Read 1 time) previous topic - next topic

warjazzman

Feb 13, 2019, 07:18 pm Last Edit: Feb 13, 2019, 07:21 pm by warjazzman
Hola buenas

Me mpresento, soy Fer. Hace poco que me he puiesto de nuevo con Arduino por lo que me considero bastante novatillo. Tengo un problema que no se como solucionar, he buscado mucho y he visto gente con un problema similar al mio pero no me han aclarado muy bien como solucionarlo.

Estoy haciendo un programa muy sencillo, que según la letra introducida por el teclado 'A', 'B' o 'C' me enciende 3 leds de la siguiente manera
'A' enciende los 3
'B' enciende cada led 1sg y se queda en este bucle
'C' apaga los 3 leds.

El problema es que cuando uso el serial.read y lo asigno a una variable. Se que esta función si no detecta nada carga en esa variable un -1. por ello lo que hago es que una vez leida la opción la cargo en otra variable, siempre que la primera no sea -1. Lo curioso es que automaticamente me borra el valor de las variables por si solo.
Entiendo que la primera variable se borre por lo comentado antes, pero la segunda si no se cumple la condición del if no debería cambiar.

Os pongo el código a ver si me podéis comentar donde está el problema. porque he intentado todo lo que se y he podido, y no consigo solución.
La idea es que la variable se quede con el ultimo valor que hay inbtroducido y no cambie hasta que se introduzca un nuevo valor de esta manera la oción 'B' lo hará ciclicamente.

Las otras opciones las hace sin problemas

Code: [Select]
int led_y = 2;
int led_r = 3;
int led_g = 4;
char valor = 0;
char letra = 0;

void setup() {
  pinMode(led_y, OUTPUT);
  pinMode(led_r, OUTPUT);
  pinMode(led_g, OUTPUT);
  Serial.begin(9600);
   

}

void loop()
{
   Serial.println("Introduce una opcion A, B o C");
 
      Serial.print("valor: ");
      Serial.println(valor);
      valor = Serial.read();
      Serial.print("letra: ");
      Serial.println(letra);
      delay(1000);
     
     
     if (valor == 'A' || 'B' || 'C')
     {
      letra = valor;
       
        if (letra == 'A')
         {
          digitalWrite(led_y, HIGH);
          digitalWrite(led_r, HIGH);
          digitalWrite(led_g, HIGH);
          delay(1000);
        }
        else if (letra == 'C')
        {
         digitalWrite(led_y, LOW);
         digitalWrite(led_r, LOW);
         digitalWrite(led_g, LOW); 
        }
        else if (letra == 'B')
        {
         digitalWrite(led_y, HIGH);
         delay(1000);
         digitalWrite(led_y, LOW);
         digitalWrite(led_r, HIGH);
         delay(1000);
         digitalWrite(led_r,LOW);
         digitalWrite(led_g, HIGH);
         delay(1000);
         digitalWrite(led_g, LOW);
        }
     
 
  }
}
 

 


Lo dicho muchas gracias por vuestra ayuda

Swift

#1
Feb 13, 2019, 08:00 pm Last Edit: Feb 13, 2019, 08:01 pm by Swift
Hola, en el ejemplo de la página arduino: read()
utiliza una condición para leer cuando hay algo en el puerto serial, entonces tendrías que añadir esto a tu código
Code: [Select]
if (Serial.available() > 0) {
                "aquí tu variable en la que almacenan los caracteres"= Serial.read();
        }

Con eso solo leerá cuando hay valores en el puerto serial.

warjazzman

Hola Swift

lo he probado también pero no funciona. la idea es que el valor que introduzca por el Serial.read se almacene en una variable y que mientras no vuelva a introducir nada más por el teclado esa variable tenga ese valor y no cambie y con ella hacer lo que sea , por ejemplo el bucle de B. Si la variable valor vale B me ejecutará las instrucciones de B de forma continua.

el problema es que solo lo hace una vez y luego se para

Swift

#3
Feb 13, 2019, 08:34 pm Last Edit: Feb 13, 2019, 08:36 pm by Swift
Prueba este código:
Code: [Select]
const byte
led_y = 2,
led_r = 3,
led_g = 4;
char letra;

void setup() {
 Serial.begin(9600);
 pinMode(led_y, OUTPUT);
 pinMode(led_r, OUTPUT);
 pinMode(led_g, OUTPUT);
 Serial.println("Introduce una opcion A, B o C");
}

void loop()
{
 if (Serial.available() > 0) {
 letra = Serial.read();
 Serial.print("Letra: ");
 Serial.println(letra);
 }

 switch (letra)
 {
 case 'A':
 digitalWrite(led_y, HIGH);
 digitalWrite(led_r, HIGH);
 digitalWrite(led_g, HIGH);
 break;
 case 'C':
 digitalWrite(led_y, LOW);
 digitalWrite(led_r, LOW);
 digitalWrite(led_g, LOW);
 break;
 case 'B':
 digitalWrite(led_y, HIGH);
 delay(1000);
 digitalWrite(led_y, LOW);
 digitalWrite(led_r, HIGH);
 delay(1000);
 digitalWrite(led_r, LOW);
 digitalWrite(led_g, HIGH);
 delay(1000);
 digitalWrite(led_g, LOW);
 break;
 }
}

Kike_GL

warjazzman, estas mal interpretando las condiciones en los OR (||).

Code: [Select]

if (valor == 'A' || 'B' || 'C')


La primera es una condición, pero las otras dos no lo son. Lo correcto seria.

Code: [Select]

if (valor == 'A' || valor == 'B' || valor == 'C')


Prueba el código de Swift que funciona bien.
Saludos, Kike_GL

warjazzman

Hola de nuevo

He probado el programa de Swift y funciona pero a medias, me explico. La idea es que en el caso de la 'B' si escojo esta opción mientras que no vuelva a introducir nada por el teclado quiero que se quede en ese bucle, y el proble es que solo lo hace una vez y luego se apaga. Si muestreo el valor de la variable "letra" en el monitor. es como que el valor que hay guardado en esa variable desaparece, es muy extraño

Alguien me puede explicar que puede estar pasando??. si yo cargo por ejemplo 'B' en  al variable "letra". hasta que no vuelva a cargar otro valor la variable "letra" debería de valer 'B', pero no es asi.

warjazzman

Bueno al final lo he conseguido. La variable se queda con el último valor introducido hasta que le vuelvas a meter otro valor. Juararía que esto ya lo había probado, pero  no había funcionado

Cuelgo el código

Hecho en falta en el Arduino IDE poder consultar el valor de las variables o emular el programa paso a paso. Sería una grandisima mejora para poder ver que está pasando cuando hay problemas

Code: [Select]
const byte
led_y = 2,
led_r = 3,
led_g = 4;
char valor = 0;
char letra;

void setup() {
 Serial.begin(9600);
 pinMode(led_y, OUTPUT);
 pinMode(led_r, OUTPUT);
 pinMode(led_g, OUTPUT);
 Serial.println("Introduce una opcion A, B o C");
}

void loop()
{
 if (Serial.available() > 0)
 {
  valor = Serial.read();
  Serial.print("valor: ");
  Serial.println(valor);
 }
 if (valor == 'A' || valor == 'B' || valor == 'C')
 {
   letra = valor;
   Serial.print("letra: ");
   Serial.println(letra);
   
   if (letra == 'A')
    {
     digitalWrite(led_y, HIGH);
     digitalWrite(led_r, HIGH);
     digitalWrite(led_g, HIGH);
    }
    if (letra == 'C')
     {
      digitalWrite(led_y, LOW);
      digitalWrite(led_r, LOW);
      digitalWrite(led_g, LOW);
     }
    if (letra == 'B')
     {
      digitalWrite(led_y, HIGH);
      delay(1000);
      digitalWrite(led_y, LOW);
      digitalWrite(led_r, HIGH);
      delay(1000);
      digitalWrite(led_r, LOW);
      digitalWrite(led_g, HIGH);
      delay(1000);
      digitalWrite(led_g, LOW);
      letra = Serial.read();
     }
  }
     
}


gracias a todos por la ayuda

Swift

#7
Feb 14, 2019, 07:28 pm Last Edit: Feb 14, 2019, 07:28 pm by Swift
El código está funcionando tal como lo planteaste, eso no es el problema.
Quote
Alguien me puede explicar que puede estar pasando??.
Para que te funcione en el monitor serie de Arduino debes seleccionar sin ajuste de línea, ya que si selecciona otra opción te enviará más caracteres como "\r" "\n"


jbasseda2

Yo tambien tenia problemas con el Serial.read(). El programa en una computadora funcionaba bien y en otra no. Ciertamente la solución fue la indicada por Swift. Gracias.

Go Up