Comunicación con bluetooth con mucho retraso

Buenas foreros, tengo un problemilla con un proyecto que estoy haciendo, un coche controlado con el móvil vía bluetooth.
El caso es que el coche responde a los comandos que envío desde el teléfono, pero con unos 6 segundos de retraso.
Esta es la tercera versión que hago del proyecto, en la anterior el coche se quedaba como bloqueado por unos segundos y luego de repente hacía todos los movimientos que le había mandado, como si los hubiera almacenado en un buffer y los soltara todos de golpe; así que le puse un comando de respuesta desde arduino al teléfono, ahora hace los movimientos más fluidos, pero con muchísimo retraso.
Os dejo el código que he escrito por si alguien sabe que puede estar mal.

Muchas gracias.

#include <SoftwareSerial.h>
SoftwareSerial BT1(2,3); // RX, TX 

char delimitador;
int PinFDerFow = 4 ; // Pin activación motor derecho adelante
int PinRDerFow = 12 ;
int PinFDerRev = 7 ; // Pin activación motor derecho atras
int PinRDerRev = 13 ;
int PinFIzqFow = 0 ; // Pin activación motor izquierdo adelante
int PinRIzqFow = 8 ;
int PinFIzqRev = 1 ; // Pin activación motor izquierdo atras
int PinRIzqRev = 11 ; 
int PinFVelder = 6 ; // Pin PWM control motor derecho
int PinRVelder = 10 ;
int PinFVelizq = 5 ; // Pin PWM control motor izquierdo
int PinRVelizq = 9 ;
int Dir ;// Variable que indica la dirección del coche 1=adelante 2=atrás
int Velocidad ;
int Vel ; // Variable de control de velocidad
int Gir ; // Variable que indica la direción de giro 3=izquierda 4=derecha
int DifGir ; // Diferencial de velocidad de los motores para el giro
int VelDif ; // Calculo de la velocidad diferencial de giro
int Direccion ; // Subcadena para la variable Dir
int VelDireccion ; // Subcadena para la variable Vel
int Giro ; // Subcadena para la variable Gir
int DifGiro ; // Subcadena para la variable Difgir


void setup()
  {
     
      BT1.begin(115200);
      pinMode (PinFDerFow, OUTPUT );
      pinMode (PinRDerFow, OUTPUT );
      pinMode (PinFDerRev, OUTPUT );
      pinMode (PinRDerRev, OUTPUT );
      pinMode (PinFIzqFow, OUTPUT );
      pinMode (PinRIzqFow, OUTPUT );
      pinMode (PinFIzqRev, OUTPUT );
      pinMode (PinRIzqRev, OUTPUT );
      pinMode (PinFVelder, OUTPUT );
      pinMode (PinRVelder, OUTPUT );
      pinMode (PinFVelizq, OUTPUT );
      pinMode (PinRVelizq, OUTPUT );
  }

void loop ()  {  
while (BT1.available ()){
       if (BT1.available() > 0){
          delimitador = BT1.read ();
          if (delimitador == 's' ){
           BT1.print ('t' );
          }
          else if (delimitador == 'a' );
           Dir = BT1.parseInt();
           Vel = BT1.parseInt();
           Gir = BT1.parseInt();
           DifGir = BT1.parseInt();

           
      
        }
         Direccion = Dir;
         Giro = Gir;
         VelDif = (100 - DifGir);
         VelDireccion = map ( Vel , 0, 100, 40, 255);
         Velocidad = ( (VelDireccion * VelDif) / 100 );
         

         Dir = 0 ;
         Vel = 0 ;
         Gir = 0 ;
         DifGir = 0 ;
       
         if ( Direccion == 1 ) {
         digitalWrite (PinFDerRev, LOW ) ;
         digitalWrite (PinRDerRev, LOW ) ;
         digitalWrite (PinFIzqRev, LOW ) ;
         digitalWrite (PinRIzqRev, LOW ) ;
         digitalWrite (PinFDerFow, HIGH ) ;
         digitalWrite (PinRDerFow, HIGH ) ;
         digitalWrite (PinFIzqFow, HIGH ) ;
         digitalWrite (PinRIzqFow, HIGH ) ;
         //Serial.println ("Fow"); 
           switch (Giro){
             case 3:
               analogWrite (PinFVelizq , Velocidad) ;
               analogWrite (PinRVelizq , Velocidad) ;
               analogWrite (PinFVelder , VelDireccion) ;
               analogWrite (PinRVelder , VelDireccion) ;
               //Serial.println (Gir);
               break;
             case 4:
               analogWrite (PinFVelizq , VelDireccion) ;
               analogWrite (PinRVelizq , VelDireccion) ;
               analogWrite (PinFVelder , Velocidad) ;
               analogWrite (PinRVelder , Velocidad) ;
               //Serial.println (Gir);
               break;
           }
         }
         if ( Direccion == 2 ) {
         digitalWrite (PinFDerFow, LOW ) ;
         digitalWrite (PinRDerFow, LOW ) ;
         digitalWrite (PinFIzqFow, LOW ) ;
         digitalWrite (PinRIzqFow, LOW ) ;
         digitalWrite (PinFDerRev, HIGH ) ;
         digitalWrite (PinRDerRev, HIGH ) ;
         digitalWrite (PinFIzqRev, HIGH ) ;
         digitalWrite (PinRIzqRev, HIGH ) ;
         
           switch (Giro){
             case 3:
               analogWrite (PinFVelizq , Velocidad) ;
               analogWrite (PinRVelizq , Velocidad) ;
               analogWrite (PinFVelder , VelDireccion) ;
               analogWrite (PinRVelder , VelDireccion) ;
               break;
             case 4:
               analogWrite (PinFVelizq , VelDireccion) ;
               analogWrite (PinRVelizq , VelDireccion) ;
               analogWrite (PinFVelder , Velocidad) ;
               analogWrite (PinRVelder , Velocidad) ;
               break;
           }
         }
         if ( Direccion == 0){
         digitalWrite (PinFDerRev, LOW ) ;
         digitalWrite (PinRDerRev, LOW ) ;
         digitalWrite (PinFIzqRev, LOW ) ;
         digitalWrite (PinRIzqRev, LOW ) ;
         digitalWrite (PinFDerFow, LOW ) ;
         digitalWrite (PinRDerFow, LOW ) ;
         digitalWrite (PinFIzqFow, LOW ) ;
         digitalWrite (PinRIzqFow, LOW ) ;        
         //Dir = 0;
         //Vel = 0;
         //Gir = 0;
         //Difgir = 0;
         //Velocidad = 0;
         }
         delay (1);
         BT1.print ('t');

}

}

Edito:
He leído un post de un compañero que tenía un problema similar al mío, y lo solucionó cambiando el puerto serie al nativo de la placa UNO en lugar de usar el SofwareSerial. Yo he cambiado el código para hacer lo mismo que él, ya que esto solo lo usaba para la depuración con la consola y he mejorado un poco, sólo se retrasa 2 o 3 segundos en la respuesta, no se si puede tener algo que ver que le he cambiado los baud a 115200, aunque en teoría debería ser más rápida la comunicación.

Primero que nada, códigos entre etiquetas generadas por </>

Segundo: no voy a profundizar demasiado, ya que las optimizaciones necesarias son demasiado evitentes:

  • Si ningún valor sobrepasará los 255, lo ideal sería que todas las variables sean de tipo byte. El microprocesador es de 8 bits, y como 1 byte = 8 bits; entonces es mucho más fácil procesar un byte que dos (int).
  • Si la función digitalWrite se tiene que llamar más de tres veces consecutivas, puede que ya sea hora de aprender el fino arte de la manipulación de puertos.-
Dir = BT1.parseInt();
Gir = BT1.parseInt();

Direccion = Dir;
Giro = Gir;

Esto por qué? Para qué utilizar más variables si las que se trabajan van a acabar con el mismo valor que otras?
No sería más sencillo así?:

Direccion = BT1.parseInt();
Giro = BT1.parseInt();

Hola Lucario, Primero, muchas gracias por dedicarme un poco de tu tiempo y molestarte en analizar mi código y responder.

Segundo, tienes razón, el código está un poco desestructurado, es mi primer proyecto y voy aprendiendo sobre la marcha con tutoriales y demás. El código lo he reescrito una docena de veces y siempre se me va quedando algún trozo que no borro por no volverlo a escribir si tengo que tirar para atrás, por eso las "//", pero tengo entendido que el compilador no hace caso al código que haya detrás de estos símbolos, por lo que no utiliza memoria ni recursos en ellos. Lo de las variables repetidas es un legado de un código anterior, pero estaba más centrado en hacer que funcionara que en la estructura propia.

Como digo voy aprendiendo sobre la marcha, gracias a gente como tú que me va guiando y explicando cosas que desconozco, como lo de la manipulación de puertos, que está genial, lo que se agradece muchísimo.

Por último, no pensaba que el Arduino estuviera tan limitado de recursos, con 20 variables y 50 líneas de código no creo que sea para tardar 3 segundos en realizar un ciclo y actualizar las salidas. He probado con delay (1), con delay (20) y sin delay.

Hasta que no envío la letra "t" el arduino no me devuelve otro paquete de datos, para no saturar los buffer del bluetooth ni del arduino.

De todas formas he vuelto a escribir el código (¡¡YA VOY POR LA VERSION 4, YUHU!!), y el resultado es el mismo, un retardo entre 2 y 3 segundos. Voy a probar con algo más sencillo, como cuatro botones para marcha adelante, marcha atrás, giro izquierda y giro derecha, y comprobaré si desaparece el retardo.

También puede ser que el problema esté en la aplicación Android, que he programado yo mismo desde la página MIT App Inventor2. También sin experiencia y autodidacta, puede salir cualquier cosa.

Bueno no me enrollo más, te dejo el nuevo código y si te apetece me lo comentas.

Muchas gracias.

char delimitador;
byte PinFVelder = 6 ; // Pin PWM control motor derecho
byte PinRVelder = 10 ;
byte PinFVelizq = 5 ; // Pin PWM control motor izquierdo
byte PinRVelizq = 9 ;
byte Velocidad ;
byte Vel ; // Variable de control de velocidad
byte DifGir ; // Diferencial de velocidad de los motores para el giro
byte VelDif ; // Calculo de la velocidad diferencial de giro
byte Direccion ; // Subcadena para la variable Dir
byte VelDireccion ; // Subcadena para la variable Vel
byte Giro ; // Subcadena para la variable Gir



void setup()
 {
     Serial.begin(115200);
     DDRD = DDRD | B11111100 ; 
     DDRB = B00111111 ;
     PORTD = B00000000 ;
     PORTB = B00000000 ;
 }

void loop ()  {  
while (Serial.available ()){
      if (Serial.available() > 0){
         delimitador = Serial.read ();
         if (delimitador == 's' ){
          Serial.print ('t' );
         }
         else if (delimitador == 'a' );
          Direccion = Serial.parseInt();
          Vel = Serial.parseInt();
          Giro = Serial.parseInt();
          DifGir = Serial.parseInt();

          
     
       }
        VelDif = (100 - DifGir);
        VelDireccion = map ( Vel , 0, 100, 40, 255);
        Velocidad = ( (VelDireccion * VelDif) / 100 );
        


      
        if ( Direccion == 1 ) {
        PORTB = B00010001 ;
        PORTD = B00010100 ;
          switch (Giro){
            case 3:
              analogWrite (PinFVelizq , Velocidad) ;
              analogWrite (PinRVelizq , Velocidad) ;
              analogWrite (PinFVelder , VelDireccion) ;
              analogWrite (PinRVelder , VelDireccion) ;
              break;
            case 4:
              analogWrite (PinFVelizq , VelDireccion) ;
              analogWrite (PinRVelizq , VelDireccion) ;
              analogWrite (PinFVelder , Velocidad) ;
              analogWrite (PinRVelder , Velocidad) ;
              break;
          }
        }
        if ( Direccion == 2 ) {
        PORTB = B00101000 ;
        PORTD = B10001000 ;
        
          switch (Giro){
            case 3:
              analogWrite (PinFVelizq , Velocidad) ;
              analogWrite (PinRVelizq , Velocidad) ;
              analogWrite (PinFVelder , VelDireccion) ;
              analogWrite (PinRVelder , VelDireccion) ;
              break;
            case 4:
              analogWrite (PinFVelizq , VelDireccion) ;
              analogWrite (PinRVelizq , VelDireccion) ;
              analogWrite (PinFVelder , Velocidad) ;
              analogWrite (PinRVelder , Velocidad) ;
              break;
          }
        }
        if ( Direccion == 0){
        PORTB = B00000000 ;
        PORTD = B00000000 ;        
        }
        Direccion = 0;
        Vel = 0;
        Giro = 0 ;
        DifGir = 0 ;
        //delay (20);
        Serial.print ('t');
  
}

}

Oh mira, por qué no lo había notado antes?

else if (delimitador == 'a' );
Direccion = Serial.parseInt();
Vel = Serial.parseInt();
Giro = Serial.parseInt();
DifGir = Serial.parseInt();

La función parseInt tarda en ejecutarse lo que dure el “timeout” del puerto Serial (por defecto, un segundo).
CADA VEZ QUE TE TOPABAS EN ESTA PARTE, OCURREN 4 SEGUNDOS DE RETRASO!!!

Para solucionar esta parte, necesito que respondas a estas dos preguntas:

  • Podrás hacer que tu aplicación envíe estos valores como bytes (binario) y no como texto?
  • Podrías mostrarme el “formato” de un “paquete” de información?

Para lograr lo segundo, puedes hacer lo siguiente:

  • Desocupa todos los pines digitales que tengas ocupados (solo será por un momento).
  • Conecta el pin TX del módulo bluetooth al pin 10 del Arduino.
  • Conecta el pin RX del módulo bluetooth al pin 11 del Arduino.
  • Conecta el resto de pines del módulo, como corresponde.
  • Carga al Arduino, el código que pondré al final del post.
  • Enciende todo, y has que vas a controlar el coche con la aplicación.
  • Abre el monitor serie (con el Arduino aún conectado a la PC), selecciona la tasa de baudios correcta, y dime qué ves.

Aquí el susodicho código del quinto punto:

// Useful as a "USB to UART TTL converter", BUT NOT FOR SKETCH UPLOADING (unless reset is not auto-triggered)

#include <SoftwareSerial.h> // On some boards (like the Arduino Mega), this library is not necessary. Use Serial1 instead

#define BAUD_RATE 115200 // Set the baud rate for the serial communication

SoftwareSerial virtualSerial(10, 11); // virtualSerial(RX, TX)

void setup() {
  Serial.begin(BAUD_RATE); // USB UART (pin 0 and 1)
  virtualSerial.begin(BAUD_RATE); // External UART
  // Serial1.begin(BAUD_RATE); // External UART only for boards like the Arduino Mega,

}

void loop() {
  if (Serial.available()) {
    virtualSerial.write(Serial.read());
    // Serial1.write(Serial.read());
  }

  if (virtualSerial.available()) {
    Serial.write(virtualSerial.read());
  }

  /*if (Serial1.available()) {
    Serial.write(Serial1.read());
  }*/

}

Hola Lucario, no he descubierto (creo que no se puede) la forma de mandar los datos de la app en otro formato que no sea código ASCII, manda un byte por cada caracter que yo envío.

He probado el código que has colgado, pero el formato del paquete te lo puedo decir yo, que soy el que se lo ha inventado, primero manda una “a” para informar del inicio del paquete, luego manda un número ( 1 o 2) para indicar si el joystick manda hacia adelante o hacia atrás, luego mando una “b” como delimitador para el parseInt, seguido de tres caracteres que convierto en un número entre “000” y “100”, otra “b” delimitador, un número ( 3 o 4) para indicar giro a derecha o izquierda, otro delimitador “b” y por último tres caracteres más entre “000” y “100” para indicar si el giro es más suave o más brusco.

Al final lo que recibo es “a0b000b0b000” pero los 0 no son numéricos, son texto (ASCII)

Trabajo con la función parseInt porque los otros códigos que he probado no me funcionan a la hora de convertir esa cadena ASCII en un numeral. Y he probado varios códigos diferentes, con varias formas de capturar las cadenas; juntas, separadas, multiplicando y encadenando , etc.

Por cierto ¿Que te parece el código ahora? Está más ordenado y limpio.

Otra pregunta ¿Que me recomiendas para aprender un poco de algoritmos? Para mejorar en la estructuración del código.

Muchas gracias.

Edito: Esto también me sirve para aprender una lección : Tengo que esforzarme en perder un par de minutos en leer TODA la descripción de las funciones que voy a usar y no conozco, ya que en la ayuda de ARDUINO explica lo del TimeOut y como configurarlo.

while (BT1.available ()){
        if (BT1.available() > 0){
           delimitador = BT1.read ();
           if (delimitador == 'a' );
            BT1.readBytes ( S , 8 );
            for ( byte i=0; i<8; i ++){
              Datosleidos += S[i];
            }
            Serial.println ( S ); 
            Direccion = (Datosleidos.substring (0,1));
            VelDireccion = (Datosleidos.substring (1,4));
            Giro = (Datosleidos.substring (4,5));
            DifGiro = (Datosleidos.substring (5));

            Dir = Direccion.toInt ();
            Vel = VelDireccion.toInt ();
            Gir = Giro.toInt ();
            Difgir = DifGiro.toInt ();
while ( BT1.available () ) {
    //delay ( 10 ) ;
    if ( BT1.available () > 0 ) {
          Ready = BT1.read ();
          Serial.println ( Ready );
          switch ( Ready ) {
            case 'a' :
              Dir = BT1.read () ;
              a = BT1.read ();
              b = BT1.read () ;
              c = BT1.read () ;
              Vel = int ( a+b+c);
              Gir = BT1.read () ;
              d = BT1.read () ;
              e = BT1.read () ;
              f = BT1.read () ;
              DifGir = int (d+e+f);
              VelDiferencial = ( Vel - DifGir ) ;
              if (VelDiferencial <= 0 ) {
                VelDiferencial = 0 ;
              }
while ( BT1.available () ) {
          Ready = BT1.read ();
          if (Ready == 'a' ) {
             Serial.println ( Ready );
             for ( byte i = 0; i<8 ; i ++){
              Dir = BT1.read ();
              //Dir = Dir - 48;
              Serial.println (Dir);
              a = BT1.read ();
              a = ( (a - 48) * 100);
              b = BT1.read ();
              b = ((b-48)*10);
              c = BT1.read ();
              c = c - 48;
              Vel = a+b+c;
              Serial.println (Vel);
              //Serial.print ( a );
              }

Hola otra vez, acabo de modificar el timeOut de la función parseInt (he probado varios valores y el más bajo y que funciona bien es 50 ms con un delay de 20 ms al final) y ahora funciona genial el proyecto.

Muchas gracias de nuevo por tu ayuda y tu tiempo.

El código final es este:

char delimitador;
byte PinFDerFow = 4 ; // Pin activación motor derecho adelante
byte PinRDerFow = 12 ;
byte PinFDerRev = 7 ; // Pin activación motor derecho atras
byte PinRDerRev = 13 ;
byte PinFIzqFow = 2 ; // Pin activación motor izquierdo adelante
byte PinRIzqFow = 8 ;
byte PinFIzqRev = 3 ; // Pin activación motor izquierdo atras
byte PinRIzqRev = 11 ; 
byte PinFVelder = 6 ; // Pin PWM control motor derecho
byte PinRVelder = 10 ;
byte PinFVelizq = 5 ; // Pin PWM control motor izquierdo
byte PinRVelizq = 9 ;
byte Velocidad ;
byte Vel ; // Variable de control de velocidad
byte DifGir ; // Diferencial de velocidad de los motores para el giro
byte VelDif ; // Calculo de la velocidad diferencial de giro
byte Direccion ; // Subcadena para la variable Dir
byte VelDireccion ; // Subcadena para la variable Vel
byte Giro ; // Subcadena para la variable Gir



void setup()
   {
       Serial.begin(115200);
       Serial.setTimeout (50);
       pinMode (PinFDerFow, OUTPUT );
       pinMode (PinRDerFow, OUTPUT );
       pinMode (PinFDerRev, OUTPUT );
       pinMode (PinRDerRev, OUTPUT );
       pinMode (PinFIzqFow, OUTPUT );
       pinMode (PinRIzqFow, OUTPUT );
       pinMode (PinFIzqRev, OUTPUT );
       pinMode (PinRIzqRev, OUTPUT );
       pinMode (PinFVelder, OUTPUT );
       pinMode (PinRVelder, OUTPUT );
       pinMode (PinFVelizq, OUTPUT );
       pinMode (PinRVelizq, OUTPUT );
   }

void loop ()  {  
while (Serial.available ()){
        if (Serial.available() > 0){
           delimitador = Serial.read ();
           if (delimitador == 's' ){
            Serial.print ('t' );
           }
           else if (delimitador == 'a' );
            Direccion = Serial.parseInt();
            Vel = Serial.parseInt();
            Giro = Serial.parseInt();
            DifGir = Serial.parseInt();

            
       
         }
          VelDif = (100 - DifGir);
          VelDireccion = map ( Vel , 0, 100, 40, 255);
          Velocidad = ( (VelDireccion * VelDif) / 100 );
          


        
          if ( Direccion == 1 ) {
          digitalWrite (PinFDerRev, LOW ) ;
          digitalWrite (PinRDerRev, LOW ) ;
          digitalWrite (PinFIzqRev, LOW ) ;
          digitalWrite (PinRIzqRev, LOW ) ;
          digitalWrite (PinFDerFow, HIGH ) ;
          digitalWrite (PinRDerFow, HIGH ) ;
          digitalWrite (PinFIzqFow, HIGH ) ;
          digitalWrite (PinRIzqFow, HIGH ) ;
            switch (Giro){
              case 3:
                analogWrite (PinFVelizq , Velocidad) ;
                analogWrite (PinRVelizq , Velocidad) ;
                analogWrite (PinFVelder , VelDireccion) ;
                analogWrite (PinRVelder , VelDireccion) ;
                //Serial.println (Gir);
                break;
              case 4:
                analogWrite (PinFVelizq , VelDireccion) ;
                analogWrite (PinRVelizq , VelDireccion) ;
                analogWrite (PinFVelder , Velocidad) ;
                analogWrite (PinRVelder , Velocidad) ;
                break;
            }
          }
          if ( Direccion == 2 ) {
          digitalWrite (PinFDerFow, LOW ) ;
          digitalWrite (PinRDerFow, LOW ) ;
          digitalWrite (PinFIzqFow, LOW ) ;
          digitalWrite (PinRIzqFow, LOW ) ;
          digitalWrite (PinFDerRev, HIGH ) ;
          digitalWrite (PinRDerRev, HIGH ) ;
          digitalWrite (PinFIzqRev, HIGH ) ;
          digitalWrite (PinRIzqRev, HIGH ) ;
          
            switch (Giro){
              case 3:
                analogWrite (PinFVelizq , Velocidad) ;
                analogWrite (PinRVelizq , Velocidad) ;
                analogWrite (PinFVelder , VelDireccion) ;
                analogWrite (PinRVelder , VelDireccion) ;
                break;
              case 4:
                analogWrite (PinFVelizq , VelDireccion) ;
                analogWrite (PinRVelizq , VelDireccion) ;
                analogWrite (PinFVelder , Velocidad) ;
                analogWrite (PinRVelder , Velocidad) ;
                break;
            }
          }
          if ( Direccion == 0){
          digitalWrite (PinFDerRev, LOW ) ;
          digitalWrite (PinRDerRev, LOW ) ;
          digitalWrite (PinFIzqRev, LOW ) ;
          digitalWrite (PinRIzqRev, LOW ) ;
          digitalWrite (PinFDerFow, LOW ) ;
          digitalWrite (PinRDerFow, LOW ) ;
          digitalWrite (PinFIzqFow, LOW ) ;
          digitalWrite (PinRIzqFow, LOW ) ;        
          }
          Direccion = 0;
          Vel = 0;
          Giro = 0 ;
          DifGir = 0 ;
          delay (20);
          Serial.print ('t');
    
}

}

Me alegro de que ya lo tengas, pero de todas formas aquí va mi respuesta:

GuillermoA: Hola Lucario, no he descubierto (creo que no se puede) la forma de mandar los datos de la app en otro formato que no sea código ASCII, manda un byte por cada caracter que yo envío.

Con qué herramienta has desarrollado la aplicación? Porque en la "clase" puerto serial debería haber alguna función write y no print. Una "función write" envía el valor de una variable en su forma binaria (así, hasta se podría enviar el número 100 con solo un byte). Una "función print" convierte el valor de una variable, en texto reconocible para el ser humano (de ahí que se tenga que enviar un byte por dígito).

El chiste de poder trabajar recibiendo solo bytes, es que se agilizan las cosas y se reducen las líneas de código.

GuillermoA: Al final lo que recibo es "a0b000b0b000" pero los 0 no son numéricos, son texto (ASCII)

Si el paquete estuviera completamente en forma binaria, sería de 5 bytes y no de 12. La letra 'a' no la podemos obviar ya que marca el inicio del paquete (y dónde acaba es deducible si tiene una longitud constante).

Por qué 5? Recuerda que si es en forma binaria, cada número ocuparía un byte (si no sobrepasa los 255). Entonces el formato sería el siguiente:

'a' dir vel gir difGir byte0 byte1 byte2 byte3 byte4

GuillermoA: Trabajo con la función parseInt porque los otros códigos que he probado no me funcionan a la hora de convertir esa cadena ASCII en un numeral. Y he probado varios códigos diferentes, con varias formas de capturar las cadenas; juntas, separadas, multiplicando y encadenando , etc.

Seguramente intentaste "reinventar la rueda", porque pareciera como si te estuvieran enseñando cómo funciona un "parser".

GuillermoA: Por cierto ¿Que te parece el código ahora? Está más ordenado y limpio.

Empezando por reducir las líneas de código sin afectar la funcionalidad del programa. Y ahora está más comprensible. Buen trabajo! ;)

GuillermoA: Otra pregunta ¿Que me recomiendas para aprender un poco de algoritmos? Para mejorar en la estructuración del código.

Qué aprender? O dónde aprender?

Qué aprender? Bueno, lo que tengas que; porque de qué sirve romperte la cabeza para saberlo todo, si solo usarás el 2% de lo aprendido?

Dónde aprender? Entonces para qué tenemos internet? El 99% de tus dudas en programación ya deben estar aclaradas en el algún lugar en la internet; es solo cuestión de buscar.

En mi caso, yo he aprendido de tres maneras:

  • Experiencia adquirida en la universidad en la que estudio.
  • De manera auto-didáctica (experimentando y todo eso).
  • Y por supuesto, internet.

GuillermoA: Edito: Esto también me sirve para aprender una lección : Tengo que esforzarme en perder un par de minutos en leer TODA la descripción de las funciones que voy a usar y no conozco, ya que en la ayuda de ARDUINO explica lo del TimeOut y como configurarlo.

Te felicito!!!

Eres del 10% de usuarios nuevos, de los que se esfuerzan por aprender; y eso, a nosotros los foreros, nos motiva a ayudar a la gente :)

PD: No sé por qué los "parsers" del serial se esperan hasta que se agote el "timeout", en vez de acabar cuando se topen algún caracter no válido (en tu caso, ese sería la 'b'). Quizá sea algo que deban mejorar en futuras versiones de la IDE, supongo...

Gracias, como te he comentado no soy informático ni he estudiado programación. No se lo que es un parser, solo encontré la función intentando averiguar porqué no funcionaban ninguno de los otros códigos. La app la he programado utilizando una aplicación por bloques (bastante intuitiva) que facilitan desde el MIT y funciona online, aunque es bastante básica (demasiado diría yo) y solo tiene las funciones que ellos han querido poner. Tampoco me he metido mucho a aprenderla porque por trabajo y turnos y los nenes y la familia solo le puedo dedicar unas pocas horas al mes, (llevo 6 meses para hacer este proyecto a ratos, una semana 2 o 3 horas, a los 15 días otras 3 o 4 horas y así) no he querido meterme en otro "fregao" aprendiendo a programar android cuando todavía voy en pañales con arduino.

Reitero lo dicho, muchas gracias y mis dieses para ti y la gente como tú que nos ayudáis tanto.

WOW Lucario, que buena data que pasaste.. se agradece muchisimo!

GuillermoA: Gracias, como te he comentado no soy informático ni he estudiado programación. No se lo que es un parser

Lo olvidaba. Bueno entonces iré más despacio.

Según don Traductor de Google, la palabra "parse" se traduce del inglés como "analizar gramaticalmente". En el área informática, "parse" es el proceso de convertir un dato de un "lenguaje" a otro. En este caso, convertir un texto que contiene un número, a ese mismo número pero en una forma aceptable para una variable (binaria).

También se podría decir que un compilador es una especie de "parser"; porque convierte un código de lenguaje más "humano", a uno entendible para la máquina.

GuillermoA: La app la he programado utilizando una aplicación por bloques (bastante intuitiva) que facilitan desde el MIT y funciona online, aunque es bastante básica (demasiado diría yo) y solo tiene las funciones que ellos han querido poner.

Sí, hablas del AppInventor.

Pero oye, hay un bloque que dice: "call Bluetooth.send1ByteNumber" y en "number" colocas el valor correspondiente. Hablo de este bloque:

ASÍ ES COMO SE ENVÍA UN NÚMERO DE FORMA BINARIA!!!

GuillermoA: Tampoco me he metido mucho a aprenderla porque por trabajo y turnos y los nenes y la familia solo le puedo dedicar unas pocas horas al mes, (llevo 6 meses para hacer este proyecto a ratos, una semana 2 o 3 horas, a los 15 días otras 3 o 4 horas y así) no he querido meterme en otro "fregao" aprendiendo a programar android cuando todavía voy en pañales con arduino.

Con más razón te felicito, porque a pesar de todo eso, te empeñas en aprender.

Tienes mi apoyo!!! ;)