Si ejecuto directamente el programa funciona si lo hago a través de bluetooth no

Buenas tardes,

Realizo un programa para que un robot no choque contra la pared. Es decir detecta con el sensor HC-SR04 que utilizo como medidor de distancias, si la distancia es menor de 20 cm, que se pare, de marcha atrás, gire y continúe recto.

Bien el programa si lo cargo directamente funciona bien. Sin embargo si conecto un módulo bluetooth al robot y cargo un programa con "IF" en el cual le indico que si le envío por ejemplo el nº "5" me ejecute el programa de antes, el robot siempre me continúa recto.

¿Existe algún conflicto con el módulo bluettoh y el sensor HR-SR04? ¿Por qué creeis que no ejecuta bien el programa si la secuencia es la misma?
Muchas gracias

Los pines del bluetooth están conectados a un nano arduino a su entrada RX y tX. El programa se me carga bien y ya se que lo debo desconectar para subirlo.

A continuación os pongo la programación, con el ejemplo 1, que me funciona bien, y que no está iniciado a través del bluetooth y el ejemplo 2, que es el que no me funciona bien si lo inicio a través de un terminal con conexión a bluetooth

Ejemplo 1. Funciona correctamente. Solo ejecutar el evitar chocarse:

#include <Servo.h>
char valor;
Servo myservo_izq;  // crea el objeto servo del lado izq del robot
Servo myservo_der;  // crea el objeto servo del lado derecho del robot
int vel_iz = 0; // velocidad del servo izquierda
int vel_der = 0;// velocidad del servo derecha
const int Trigger = 13;   //Pin digital 13 para el Trigger del sensor HC-SR04, (los ojos)
const int Echo = 7;   //Pin digital 7 para el Echo del sensor HC-SR04, (los ojos)

void setup(){


myservo_izq.attach(9);  // vincula el servo al pin digital 9
myservo_der.attach(5);  // vincula el servo al pin digital 5
myservo_izq.write(90);  // inicio los dos servos a velocidad 0             
myservo_der.write(90);  // inicio los dos servos a velocidad 0
pinMode(Trigger, OUTPUT); //pin como salida sensor HC-SR04, (los ojos)
pinMode(Echo, INPUT);  //pin como entrada sensor HC-SR04, (los ojos)
digitalWrite(Trigger, LOW);//Inicializamos el pin con 0 


}
void loop()  {

long t; //tiempo que demora en llegar el eco
               long d; //distancia en centimetros

               digitalWrite(Trigger, HIGH);
               delay(0.01);          //Enviamos un pulso 
               digitalWrite(Trigger, LOW);
 
               t = pulseIn(Echo, HIGH); //obtenemos el ancho del pulso, lee el tiempo del Eco
               d = t/59;             //escalamos el tiempo a una distancia en cm

               if (d <= 20){    // si la distancia es menor de 20cm, paramos motores 200 milisg
                                     vel_iz= 90;
                                     vel_der=90;
                                     myservo_izq.write(vel_iz);             
                                     myservo_der.write(vel_der);  
                                     delay (200);

                                    // vamos hacia atrás 300 milisg
                                     vel_iz= 0;
                                     vel_der=180;
                                     myservo_izq.write(vel_iz);             
                                     myservo_der.write(vel_der); 
                                     delay (200);

                                     vel_iz= 180; // giramos a la izquierda durante 600 milisegundos
                                     vel_der=90;
                                     myservo_izq.write(vel_iz);             
                                     myservo_der.write(vel_der); 
                                     delay (600);
       
                                     }
                                     else{       // Si no hay obstáculos se desplaza al frente  
                                           vel_iz= 180; 
                                           vel_der=0;
                                           myservo_izq.write(vel_iz);             
                                           myservo_der.write(vel_der);  
                                           }
 }

Ejemplo 2. Con la conexión a bluetooth, que me permita mover el robot en diferentes direcciones. (Esto funciona bien) y luego si pulso el número "5" que inicie el programa de no chocar. Y esto aunque es igual a lo anterior no funciona.

#include <Servo.h>
char valor;
Servo myservo_izq;  // crea el objeto servo del lado izq del robot
Servo myservo_der;  // crea el objeto servo del lado derecho del robot
int vel_iz = 0; // velocidad del servo izquierda
int vel_der = 0;// velocidad del servo derecha
int Trigger = 13;   //Pin digital 13 para el Trigger del sensor HC-SR04, (los ojos)
int Echo = 7;   //Pin digital 7 para el Echo del sensor HC-SR04, (los ojos)
int t; //tiempo que demora en llegar el eco
int d; //distancia en centimetros




void setup(){

Serial.begin(9600);
myservo_izq.attach(9);  // vincula el servo al pin digital 9
myservo_der.attach(5);  // vincula el servo al pin digital 5
myservo_izq.write(90);  // inicio los dos servos a velocidad 0             
myservo_der.write(90);  // inicio los dos servos a velocidad 0
pinMode(Trigger, OUTPUT); //pin como salida sensor HC-SR04, (los ojos)
pinMode(Echo, INPUT);  //pin como entrada sensor HC-SR04, (los ojos)
digitalWrite(Trigger, LOW);//Inicializamos el pin con 0 


}
void loop(){
valor=Serial.read();

if (valor=='F'){            // Boton hacia adelante 
 
  myservo_izq.write(180);             
  myservo_der.write(0);              
 
   
}
if (valor=='L'){            // Girar HACIA LA IZQ
 
vel_iz= 90;
vel_der=0;
myservo_izq.write(vel_iz);              
myservo_der.write(vel_der);            
   
}

if (valor=='S'){            // PARAR
 
vel_iz= 90;
vel_der=90;
myservo_izq.write(vel_iz);             
myservo_der.write(vel_der);            
   
}

if (valor=='R'){            // VA A LA DERECHA
 
  vel_iz= 180;
  vel_der=90;
myservo_izq.write(vel_iz);             
myservo_der.write(vel_der);            
   
}
if (valor=='B'){            // ATRAS
 
  vel_iz= 0;
  vel_der=180;
myservo_izq.write(vel_iz);             
myservo_der.write(vel_der);            
   

}
if (valor=='5'){         // Programar la rutina de no chocar, utilizando el sensor ojos
 

               digitalWrite(Trigger, HIGH);
               delay(0.01);          //Enviamos un pulso de 10us
               digitalWrite(Trigger, LOW);
 
               t = pulseIn(Echo, HIGH); //obtenemos el ancho del pulso, lee el tiempo del Eco
               d = t/59;             //escalamos el tiempo a una distancia en cm

               if (d==0) d=50;
               if (d <= 20){    
      
                       
                                     vel_iz= 90;
                                     vel_der=90;
                                     myservo_izq.write(vel_iz);             
                                     myservo_der.write(vel_der);  
                                     delay (200);

                                     // vamos hacia atrás 300 milisg
                                     vel_iz= 0;
                                     vel_der=180;
                                     myservo_izq.write(vel_iz);             
                                     myservo_der.write(vel_der); 
                                     delay (200);

                                     vel_iz= 180; // giramos a la izquierda durante 600 milisegundos
                                     vel_der=90;
                                     myservo_izq.write(vel_iz);             
                                     myservo_der.write(vel_der); 
                                     delay (600); 
                                         
                                           }
                                    else{       // Si no hay obstáculos se desplaza al frente  
                                           vel_iz= 180; 
                                           vel_der=0;
                                           myservo_izq.write(vel_iz);             
                                           myservo_der.write(vel_der);  
                                           }

                                   
                                           
 }
  
  
  
  
          
   
}

Por favor lee las normas del foro y edita tu post usando etiquetas para código. Nada se pega del modo en que lo has hecho. Los códigos se visualizan de este modo

#include <Servo.h>
char valor;
Servo myservo_izq;  // crea el objeto servo del lado izq del robot
Servo myservo_der;  // crea el objeto servo del lado derecho del robot

Edita por favor!!

Tal vez el inconveniente resida en que cuando entra un byte via bluetooth mediante un Serial.read() y lo guardas en la variable " valor", en realidad estás guardando el valor ascii de la letra que enviaste, por ejemplo, si mandaste una L en "valor" vas a tener el número 76 que corresponde al ascii de esa letra. En los chequeos tendrías que poner if(valor==76) para comprobar que sea la L. Igualmente editá tu post como te dijo Surbyte para que sea fácilmente lejible.

Gracias, acabo de editarlo para que se vea tal y como me comentabais el post con code

Por otro lado cambio el valor de las letras por la codificación ASCII tal y como me comentas

y aunque me sube el programa me salta el error de : "forbids comparison between pointer and integer".

De todas maneras que no se si me expliqué bien, el programa tal y como lo tengo si mando las letras:F, S, L, R o B. Se ejecuta bien ya que me realiza lo indicado.
Con "L"--> El coche gira las dos ruedas correctamente y va para adelante. Con las demás también ejecuta bien y gira izquierda y derecha, para y va para atrás.

El problema es cuando le mando el número "5". Probé anteriormente con otras letras también y otros números. Que es ahí cuando se tendría que activar el bucle donde si la distancia es menor de 20 cm, para, retrocede y gira y si no encuentra obstáculos activar los dos servos para adelante seguido.

Lo que sucede en ese momento es que parece que el detector de obstáculos no funciona, ya que el robot va todo el rato hacia adelante aunque existan obstáculos.

Comprobaciones que hago:
1º. Meter código en ese bucle "IF" para que me lea la distancia por pantalla.
Si realizo esto y accedo desde bluetooth para que se me active ese código, me aparece una sola medida de distancia y claro al ser esta mayor de 20 cm, inicia los dos servos para adelante, pero no vuelve a hacer ninguna medida más de distancia, lo cual me sorprende.

2º Comprobación, si le mando por un terminal por bluetooth, varias veces el mismo "5". ( solo por aclaración, el "5" nos lleva a la rutina "IF" que evita los choques) repetido un montón de veces ya parece que empieza a funcionar bien, ya que comprueba las distancias varias veces, supongo que el mismo número de veces que he repetido la entrada número "5". Pero esto no lo entiendo ya que si ejecuto el código solo en el arduino sin conectarlo por bluetooth y sin las opciones del IF, ya directamente el código se repite y comprueba una y otra vez las distancias. No entiendo porque dentro del código IF, solo la comprueba una vez si se supone que tendría que repetirlo sin parar, ¿no?
Muchas gracias por vuestra valiosa ayuda!

dentro de tu rutina de comprobación de distancia, después de calcular la misma ponés

if (d==0) d=50;
               if (d <= 20){

el if(d==0) ¿ no debería seguir con { y cerrarlo después del d=50; ?

Hola,

Pongo lo que me indicas pero tampoco funciona correctamente.

Gracias igualmente : )

Prueba con esto:

#include <Servo.h>
char valor;
boolean automatico = false;
Servo myservo_izq;  // crea el objeto servo del lado izq del robot
Servo myservo_der;  // crea el objeto servo del lado derecho del robot
int vel_iz = 0; // velocidad del servo izquierda
int vel_der = 0;// velocidad del servo derecha
int Trigger = 13;   //Pin digital 13 para el Trigger del sensor HC-SR04, (los ojos)
int Echo = 7;   //Pin digital 7 para el Echo del sensor HC-SR04, (los ojos)
int t; //tiempo que demora en llegar el eco
int d; //distancia en centimetros




void setup(){

Serial.begin(9600);
myservo_izq.attach(9);  // vincula el servo al pin digital 9
myservo_der.attach(5);  // vincula el servo al pin digital 5
myservo_izq.write(90);  // inicio los dos servos a velocidad 0            
myservo_der.write(90);  // inicio los dos servos a velocidad 0
pinMode(Trigger, OUTPUT); //pin como salida sensor HC-SR04, (los ojos)
pinMode(Echo, INPUT);  //pin como entrada sensor HC-SR04, (los ojos)
digitalWrite(Trigger, LOW);//Inicializamos el pin con 0


}
void loop(){
valor=Serial.read();

if (valor=='F'){            // Boton hacia adelante
 
  myservo_izq.write(180);            
  myservo_der.write(0);              
 
   
}
if (valor=='L'){            // Girar HACIA LA IZQ
 
vel_iz= 90;
vel_der=0;
myservo_izq.write(vel_iz);              
myservo_der.write(vel_der);            
   
}

if (valor=='S'){            // PARAR
 
vel_iz= 90;
vel_der=90;
myservo_izq.write(vel_iz);            
myservo_der.write(vel_der);            
   
}

if (valor=='R'){            // VA A LA DERECHA
 
  vel_iz= 180;
  vel_der=90;
myservo_izq.write(vel_iz);            
myservo_der.write(vel_der);            
   
}
if (valor=='B'){            // ATRAS
 
  vel_iz= 0;
  vel_der=180;
myservo_izq.write(vel_iz);            
myservo_der.write(vel_der);            
   

}

if (valor=='5') {
	automatico = true;
}
else if (valor > 13) {
	automatico = false;
}
if (automatico) {         // Programar la rutina de no chocar, utilizando el sensor ojos
 

               digitalWrite(Trigger, HIGH);
               delay(0.01);          //Enviamos un pulso de 10us
               digitalWrite(Trigger, LOW);
 
               t = pulseIn(Echo, HIGH); //obtenemos el ancho del pulso, lee el tiempo del Eco
               d = t/59;             //escalamos el tiempo a una distancia en cm

               if (d==0) d=50;
               if (d <= 20){    
     
                       
                                     vel_iz= 90;
                                     vel_der=90;
                                     myservo_izq.write(vel_iz);            
                                     myservo_der.write(vel_der);  
                                     delay (200);

                                     // vamos hacia atrás 300 milisg
                                     vel_iz= 0;
                                     vel_der=180;
                                     myservo_izq.write(vel_iz);            
                                     myservo_der.write(vel_der);
                                     delay (200);

                                     vel_iz= 180; // giramos a la izquierda durante 600 milisegundos
                                     vel_der=90;
                                     myservo_izq.write(vel_iz);            
                                     myservo_der.write(vel_der);
                                     delay (600);
                                         
                                           }
                                    else{       // Si no hay obstáculos se desplaza al frente  
                                           vel_iz= 180;
                                           vel_der=0;
                                           myservo_izq.write(vel_iz);            
                                           myservo_der.write(vel_der);  
                                           }

                                   
                                           
 }
 
 
 
 
         
   
}

He añadido la variable automatico para controlar cuándo está en "modo automático". Con el "5" pasa a modo automático y con cualquier otra cosa que le llegue del Bluetooth, "abandona" el modo automático.

Genial! Con esto funciona!

Serías tan amable de aclararme el modo automático que has incluído, como funciona?
No se si lo entiendo bien. Declaras una variable que se pone a TRUE cuando detecte el "5" enviado por bluetooth, y mientras esté a TRUE me ejecuta el código del IF repetidamente

Sin embargo se pone a FALSE si la variable automatico>13. ¿Esto qué es exactamente? No se si será que cuando detecte un valor por encima del 13 de ASCI, que salga de mi bucle IF. Como todas las letras anteriores que puse en codificación ASCI, se traducen por un nº mayor de 13, es así su funcionamiento? Podría poner otro nº que no sea el 13? o pones el 13 porque este número es el salto de carro y eso si que lo hace automáticamente?
Te pregunto todo esto, porque es mi primer proyecto y estoy perdido buscando información.

Por cierto mil gracias : ) :slight_smile: :slight_smile:

Llello, es todo tal como dices. Como no estaba seguro de si las órdenes se las dabas mandando un único carácter o si le mandabas el retorno de carro o avance de línea después del carácter (pudiera ser que lo probaras con el monitor serie con el envío del retorno de carro activado), opté por "filtrar" todo lo que llegase con un valor igual o menor al del retorno de carro (13), y de paso filtra el avance de línea (10).

De todas formas, como mínimo hay de "filtrar" el valor -1. Es el valor que retorna Serial.read() cuando no hay un dato disponible. Es lo bueno que tiene Serial.read(), que no te bloquea la ejecución del programa hasta que llegue un dato, sino que te indica con el valor -1 que no hay dato y continúa. La idea, efectivamente, es que mientras no llegue un dato continúe en modo "automático" ejecutando la parte del código que lo controla.

Muchas gracias por tu ayuda! Me ha sido muy útil y muy amable por re-contestarme. : )

Voy a ver si encuentro información de como se envía información de solo un carácter, o con el retorno de carro o con el avance de línea para enterarme mejor.

¡Gracias!