Btserial.read en hc05 da espacios en blancos y no puedo entrar en un bucle while

Buenass, estoy intentando hacer un efecto con unas tiras de leds, (programadas por pwm) conectados como los típicos leds por medio de un transistor, e intento hacer un efecto de fade en un while, que mientras que yo ingrese por ejemplo: “M”, el bucle entre y haga lo suyo, hasta que yo ingrese otra letra. El problema es que en el proceso, el Btserial.read, me lee espacios en blanco (o eso creo yo) y no continua el ciclo while por eso. Ya probé casi todo lo que veo posible, aca hice una demostración de las cosas que probé, también puse Serial.println(Letra) antes de que termine el while para confirmar que la letra sigue siendo M, y solo había un espacio en blanco, agradecería cualquier tipo de ayuda, realmente no hay apuro, así que nada, gracias de antemano! :smiley:

#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10,11);
int r, g, b;
int ledRojo = 5;
char Letra;
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
  BTSerial.begin(9600);
  pinMode(ledAzul, OUTPUT);
  pinMode(ledRojo, OUTPUT);
  pinMode(ledVerde, OUTPUT);
}

void loop() {
  void loop()

{ 
if (BTSerial.available()) 
    {    
Letra = BTSerial.read();

//////////////////////////////////PROBE CON ESTO
while(Letra == 'M')//PROBE CON ESTO
    {
    for(r=0;r<255;r++)
    {
        analogWrite(ledRojo,r);
        Serial.println(r);
        delay(10);
        
    }
if (BTSerial.available()) 
    {     
Letra = BTSerial.read();
if(Letra!='M'){
break;
}
Serial.println("La letra es:);
Serial.println(Letra);
    
    }
    }
    }
    }

}
//////////////////////////////////PROBE CON ESTO
while(Letra == 'M')
    {
    for(r=0;r<255;r++)
    {
        analogWrite(ledRojo,r);
        Serial.println(r);
        delay(10);
        
    }
Letra = BTSerial.read();
if(Letra!='M'){
break;
}
Serial.println("La letra es:);
Serial.println(Letra);
    
    }
    }
    }
    }

}
//////////////////////////////////PROBE CON ESTO
while(Letra == 'M')
    {
    for(r=0;r<255;r++)
    {
        analogWrite(ledRojo,r);
        Serial.println(r);
        delay(10);
        
    }
Letra = BTSerial.read();
Serial.println("La letra es:);
Serial.println(Letra);

}
    
    }
    }
    }
    }

}

Buen dia
Bueno para empezar el código que subiste ni siquiera compila, tienes varios errores de sintaxis, no declaraste los led, y repites el void loop() y no es necesario que repitas varias veces la lectura del puerto serial, con una vez basta. Ahora, el while solo debes usarlo en casos muy específicos, el propio void loop() de arduino es un while(1), por lo que en tu caso, no es necesario hacer un bucle dentro otro bucle, con solo un condicional if() es mas que suficiente.
prueba esto:

#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10,11);
int r, g, b;
int ledRojo = 5;
char Letra;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  BTSerial.begin(9600);
  //pinMode(ledAzul, OUTPUT);
  pinMode(ledRojo, OUTPUT);
  //pinMode(ledVerde, OUTPUT);
}

void loop() {
    
    if (BTSerial.available())
    Letra = BTSerial.read();

    if(Letra == 'M'){         //PROBE CON ESTO

      for(r=0;r<255;r++)
      {
        analogWrite(ledRojo,r);
        Serial.println(r);
        delay(10);
        
      }
    }
    else 
    digitalWrite(ledRojo, LOW);

  }

Una cosa mas, en el monitor serial debes seleccionar sin ajuste de linea

Buenas noches, perdón por el código así, lo que pasa es que mi código es un código pesado y de como 700 lineas, y no quería subirlo para que no tengan que andar buscando, yo ahora lo subo pero obviamente les digo las lineas en las que tengo el problema.

Agradezco tu respuesta pero la cuestión esta en que con solo el if estoy en el mismo problema, solo hace el loop 1 sola vez, yo lo que buscaba con el while, era que haga el loop mientras que yo solo le haya mandado esa letra, y cuando esa letra cambie, el loop termine.
No tengo problema si tengo que esperar a que el loop termine para que cambie, pero lo que si quiero es poder entrar a el loop, que lo haga tantas veces como la letra este igual, y que cuando yo lo cambie, salga.
Muchas gracias!

(Lo de el ajuste de linea lo probé, y en efecto pasan de ser 3 espacios en blanco a solo ser uno, pero el problema sigue estando ahí)

(Linea 678, al final de todo, lo pongo en pastebin porque excede el limite de caracteres):

Btserial.ino (14.9 KB)

A ver prueba el mismo código pero por el puerto serial, no por bluetoth, quedaria asi:

//#include <SoftwareSerial.h>
//SoftwareSerial BTSerial(10,11);
int r, g, b;
int ledRojo = 5;
char Letra;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  //BTSerial.begin(9600);
  //pinMode(ledAzul, OUTPUT);
  pinMode(ledRojo, OUTPUT);
  //pinMode(ledVerde, OUTPUT);
}

void loop() {
    
    if (Serial.available())
    Letra = Serial.read();

    if(Letra == 'M'){         //PROBE CON ESTO

      for(r=0;r<255;r++)
      {
        analogWrite(ledRojo,r);
        Serial.println(r);
        delay(10);
        
      }
    }
    else 
    digitalWrite(ledRojo, LOW);

  }

lo acabo de probar y hace esto que mencionas aqui

haga el loop mientras que yo solo le haya mandado esa letra, y cuando esa letra cambie, el loop termine.

asi que lo mas probable es que por el bluetooth esté entrando mas aparte de la letran ‘M’
Como te dije no es necesario el uso del while, y mas en tu caso que usas 700 lineas un error en un while te puede hacer caer en un bucle infinito y con un codigo grande puede llegarte a causar problemas encontrar el error

Así si funciona, pero no encuentro alguna forma de poder ingresarlo con Bluetooth, de todas formas se lo agradece la ayuda! :slight_smile:

A ver… ingresar cosas por BT es lo mismo que hacerlo por teclado usando el monitor Serie.
Practica con el monitor Serie y podrás resolver tu problema por BT.

Al código ultimo que vi le falta un juego de llaves al terminar el if {}

void loop() {
    
    if (Serial.available()) {  // <== ACA FALTA LLAVE
        Letra = Serial.read();
        if (Letra == 'M'){         //PROBE CON ESTO
          for (r=0;r<255;r++) {
              analogWrite(ledRojo,r);
              Serial.println(r);
              delay(10);
          }
        }
        else 
          digitalWrite(ledRojo, LOW);
    }   // // FIN DEL IF <== ACA FALTA LLAVE
}

Entiendo el hecho de que lo que entra por BT es lo mismo que si lo ingresara en el serial monitor, pero no se si es algún fallo mio en el código, o algún tipo de ruido que tenga el modulo que no me permita tener la misma la letra fija, porque lo que pasa es que al salir de el if, o while o lo que sea, en vez de volver a entrar (porque la letra no la cambié en ningún momento, sale y la letra queda en un limbo o en un espacio en blanco, no lo sé)
Gracias por las respuestas!

asi que lo mas probable es que por el bluetooth esté entrando mas aparte de la letran 'M'

Te envié un privado para que edites el post#2, por favor hazlo!!

Al código ultimo que vi le falta un juego de llaves al terminar el if {}

Que paso, que paso? lo probé antes de subirlo, quizá viste como que me falto llave porque tengo la mala costumbre de no poner llaves cuando solo hay una linea después del if, si miras bien el código solo asigno el valor leído del puerto serial a la variable Letra y ese valor no cambia hasta recibir otro dato por el puerto

Sisi, no hay problema con ingresarlo por serial, pero bueno esta ese problema de el "ruido"

Bueno acabo de hacer una pequeña app solo para probar y el resultado es el esperado: funciona
Aquí el código,

#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10,11);
int r, g, b;
int ledRojo = 5;
char Letra;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  BTSerial.begin(38400);  // <<<<   pon Atención aquí
  //pinMode(ledAzul, OUTPUT);
  pinMode(ledRojo, OUTPUT);
  //pinMode(ledVerde, OUTPUT);
}

void loop() {
    
    if (BTSerial.available()){
    Letra = BTSerial.read(); 
     Serial.println(Letra);    //  <<<<<<<< agregue esta linea para ver que recibe el puerto 

}

    if(Letra == 'M'){        

      for(r=0;r<255;r++)
      {
        analogWrite(ledRojo,r);
        Serial.println(r);
        delay(10);
        
      }
    }
    else 
    digitalWrite(ledRojo, LOW);

  }

aqui una imagen de la app que hice:

mira los comentarios en el código, agregue una linea para ver que se recibe en el puerto, y algo importante que quizá pueda estar pasando, revisa los baudios que tienes en el BTserial.begin(9600); creo que por ahí puede estar el error quizá no tienes esa velocidad en el modulo bluetooth, mira que yo uso 38400
prueba el código y mira que te escribe cuando mandas algo por el bluetooth

Si a lo que te referís con eso es que si mi HC-05 usa 9600, sisi, siempre lo use así, pero a mi con el:

Serial.begin(9600);
BTSerial.begin(9600);

simplemente no me funciona, pero si vos decís que a vos te funciona, entonces ya será cosa del modulo en si?
Sea así o no, agradezco todo el trabajo que hiciste para sacar esa conclusión!

[entonces ya será cosa del modulo en si?

Bueno prueba el código, solo cambia la velocidad a 9600 y dime que sale en el monitor serial cuando envias un dato por el bluetooth

Ahí lo hice, y seguimos en la misma:
r va de 0 a 254, termina el loop y ya no entra más. A menos claro que vuelva a enviar una M, su codigo si lograba volver a entrar sin necesidad de darle otra vez a la M?

y el resultado es el esperado: funciona

A mi en los lugares que marqué con comentarios, me da eso.

#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10,11);
int r, g, b;
int ledRojo = 5;
char Letra;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  BTSerial.begin(9600);  // <<<<   pon Atención aquí
  //pinMode(ledAzul, OUTPUT);
  pinMode(ledRojo, OUTPUT);
  //pinMode(ledVerde, OUTPUT);
}

void loop() {
    
    if (BTSerial.available()){
    Letra = BTSerial.read(); 
     Serial.println(Letra);    //  <<<<<<<< aca apenas inicio la variable me da "M"

}

    if(Letra == 'M'){        

      for(r=0;r<255;r++)
      {
        analogWrite(ledRojo,r);
        Serial.println(r);
        delay(10);
        
      }
    }else {
    digitalWrite(ledRojo, LOW);
    }
    Serial.println(Letra); <<<<<<<<aca, despues de terminar el for, me da un espacio en blanco
    
  }

Ah por cierto, yo tengo otro modulo hc-05 y lo probé, y con ese me pasa lo mismo, osea que tal vez descarto la posibilidad de que sea el modulo

su codigo si lograba volver a entrar sin necesidad de darle otra vez a la M?

claro, mientras no mande ningún otro numero, el programa se queda ejecutando el for

Ok, entonces estoy casi seguro que el problema es la app, quizá esta mandando mas de un byte, por eso mandas la M entra al for, pero como viene algo más detrás, sales del if
como mandas el caracter desde la app?
Edito:
Me imagino que usas app inventor, entonces revisa si no dejaste espacios en blanco después de la M en el bloque donde envias el caracter

Que maldito genio!
Tenia razón! Siempre estuvo en la maldita app, era un bt terminal especificamente hecho para los hc-05 por lo cual nunca le tuve desconfianza en vez de usar la app que habia hecho yo.
No sabria como agradecerselo. La verdad que muchisimas muchisimas gracias!!!! ;D ;D ;D ;D ;D