Interrupcion UART y bucle while

Buenas tardes estimados,
Estoy usando el serialEvent(), para cargar la variable "dato" y en funcion de eso prender o apagar un led. Ingresando "2", prendo el led, ingresando el "0" lo apago, y con "1" lo prendo pero luego no puedo salir del lazo while. Aparentemente la variable "dato" no se modifica nunca. Esto solo me sucede dentro de ese While.

#define led 13

char dato;

void setup(){

  delay(500);
  //Serial.begin(38400);
  Serial.begin(9600);
  pinMode(led,OUTPUT);
  digitalWrite(led,LOW); 
 
}


void loop(){
  
while (dato=='1') ///¿Como salgo de este blucle?????
{         
 digitalWrite(led, HIGH); 
         
}

if(dato=='0') // Apaga el Led con 0
{
digitalWrite(led,LOW);
}
if(dato=='2') //Enciende el led con 2
{
digitalWrite(led,HIGH);
}

          }


void serialEvent()
{
    dato=Serial.read();
}

[details="Resumen"]
Este texto estará oculto
[/details]

Alguna idea que podria ser. Gracias, uso el led 13 del Nano.

este es un bucle infinito si los datos son '1' ...

  while (dato == '1') ///¿Como salgo de este blucle?????
  {
    digitalWrite(led, HIGH);
  }

no use while, use if

pero podrías hacer esto:

const byte ledPin = 13; // LED_BUILTIN

void setup() {
  Serial.begin(9600);
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
}

void loop() {
  switch (Serial.read()) { // -1 si no hay datos para leer
    case '0': digitalWrite(led, LOW); break;
    case '1': digitalWrite(led, HIGH); break;
    default: break; // ignorar otros valores
  }
}

Gracias! Pero el While es necesario, ya que usare una maquina de estado, encender y apagar el led es solo para resumir el codigo. A lo que quiero llegar es a poder cambiar los valores de la variable dato dentro del bucle while usando la interrupcion de la UART. No he tenido problemas usando interrupciones externas con pulsadores.Saludos

serialEvent no es una interrupción. esta función se llama cuando el bucle finaliza.
Así es como se ve el programa principal (generado por el IDE) (simplificado)

int main(void) {
	setup();  
	for (;;) {
		loop();
		if (Serial.available()) serialEvent();
	}
	return 0;
}

entonces la función main() llama a setup() una vez y luego hay un bucle infinito que llama a la función loop(), y cuando el loop() finaliza, verifica si hay un byte pendiente para leer y llama a la función serialEvent() .

➜ si no sale de la función loop(), nunca se llamará a serialEvent().

no use SerialEvent(), solo maneje el puerto serial cuando lo necesite.

1 Like

Muchas Gracias por la brillante explicacion! Crei que era una interrupcion y eso me confundia.
Logre lo que buscaba usando

if (Serial.available())
   {
    dato=Serial.read();
   }

Dentro de una interrupcion del Timer 1.

Saludos

OK…

esto es extraño, debe hacer esto si el resto del código no es bloqueante