Datalogger Arduino a Android Bluetooth (Solucionado)

#1
Hola buenas noches !

Hace tiempo estoy buscando solucionar un simple problema que como debe ser se me complico mucho más de lo normal jajaja.

Mi proyecto consta de un voltímetro el cual mide la tensión de una batería de 12v y envía ese dato por bluetooth, luego se harían acciones con ese valor pero por ahora únicamente quiero visualizarlo.

Para llevar a cabo este proyecto fui dividiéndolo en partes para que al hacerse más complejo tenga seguras las partes anteriores. Estoy utilizando como base un arduino Leonardo.

La primera fue medir una tensión y mostrarla en el serial del arduino, utilice un divisor resistivo para medir con un máximo de 20v y al realizar el cálculo tuve un problema que pude solucionarlo rápidamente gracias a ustedes. Constaba de que tenía dos valores enteros (los valores de las resistencias) y al querer realizar el cálculo para obtener Vout me ayudaron a darme cuenta que estaba haciendo una división del tipo entero dividido un float y eso no es posible.

Terminada la parte de mediciones estáticas quise realizar valores promedios, ya que la batería oscilara en sus valores y necesito un valor de tensión "estable" para realizar las acciones. Ese valor lo obtuve con una subrutina la cual se verá en el código que voy a adjuntar. La misma consta de un array el cual almacena los valores de tensión que va obteniendo cada un tiempo determinado, al completar el espacio del mismo hace un promedio y retorna con ese valor al loop para ser utilizado.

Hasta ahí todo bien, probé todo y funciona perfecto.

Luego comienza la parte de conexión, para ello utilizo un módulo bluetoth basado en el HC-05 con el código GW-040. Previamente a ser utilizado lo puse en modo AT y cargue los comandos para cambiar nombre, contraseña y verificar velocidad. Probé con un sencillo proyecto el cual consta de enviarle un 1 y un 0 desde un dispositivo android y que encienda o apague un led para verificar su funcionamiento. Todo bien, funciono...

Al intentar mostrar el valor sigo con los problemas porque solamente obtenía símbolos. Investigando encontré que hay que enviar el valor como string y no como float porque no es posible, por lo tanto busque como poder hacer una subrutina para esto, encontré en el foro de arduino el siguiente tema:

https://forum.arduino.cc/index.php?topic=277153.0

el cual me ayudo muchísimo. La verdad intente hacer una subrutina propia pero estaba muy bien hecha y no quería arriesgarme a que no funcione. La probé y funciono más que bien mostrando en el serial los valores como string. Lo verifique porque pude agregar decimales que el serial recorta al mostrarlos como float.

Al intentar enviarlo solamente obtuve símbolos en mi aplicación sin tener ningún tipo de resultado. Investigando muchísimo y probando miles de programas ya hechos con aplicaciones que funcionan perfecto a la primera... no me funciono ninguno de ellos...

Por este motivo vengo al foro a ver si me pueden ayudar a terminar y seguir adelante con el proyecto.

Adjunto el código que utilizo y imágenes del diagrama de bloques de la aplicación realizada en App inventor

Código:
#include <SoftwareSerial.h>

float R1 = 10000;
float R2 = 3300;

SoftwareSerial BTest (10,11);

int Num1 = 10;
float Prom1 [10];
float tension1();
float Req = R2/(R1+R2);
String floatToString();


void setup() {

  BTest.begin  (9600);
  Serial.begin (9600);
  
}

void loop() 
{

        float TensionF = tension1();  
        Serial.print("La tension actual de la bateria es: ");
        String valor = floatToString(TensionF,8,6,true);
        Serial.print( valor );
        Serial.println(" V");
        Serial.println("");

        if (BTest.available()>0) 
        {
          BTest.print(TensionF);
          Serial.print("Bluetooth: ");
          Serial.println(valor);
        }            
      
  delay(100);

}


float tension1()
{
       int i, j, k;
      
       float Ten1, Ten2, cont, Tension;
       float Prom1 [Num1];

       Ten1 = 0;
       Ten2 = 0;
       i = 0;
       j = 0;
       k = 0;
       cont = 0;
       
       for (k=0; k<=Num1; k++)
       {
        Prom1 [k] = 0;
       }

       for (i=0; i<=Num1; i++)
       {
        Prom1 [i] = (((analogRead(4) * 4.98)/ 1024)/ Req);

        delay (10);
       }

       for (j=0; j<=Num1; j++)
       {
        Ten1 = Ten1 + Prom1 [j];
        cont = cont + 1;
       }
       
        Ten2 = Ten1 / cont;
        
        return Ten2;
}

// Convierte un float en una cadena.
// Val -> número a convertir.
// Lon -> longitud total de la cadena, por defecto 8.
// Dec -> decimales, por defecto 2.
// z -> si se desea rellenar con ceros a la izquierda, por defecto true.
String floatToString( float Val, int Lon, int Dec, boolean z)
{
  char c[Lon+1];
  String St;

  dtostrf(Val,Lon,Dec,c);
  St=String(c);

  if(z==1)
  {
    St.replace(" ","0");
  }

  return St;
}
Las capturas de pantallas del diagrama de bloque de App inventor son las siguientes:





...
 
#2
Cambia Serial.print(valor) y Serial.println(valor) por Serial.print(valor.c_str()) y Serial.println(valor.c_str()) respectivamente. Serial.print espera un puntero a un array de caracteres y tú le estás entregando un puntero a un objeto tipo String. El miembro c_str() da acceso al array de caracteres interno del objeto String.
 
#3
Hola palurdo, te pido mil disculpas por la demora en responder, no estuve en mi casa y queria realizar las pruebas de lo que me recomendaste antes de responder.

Probe cambiando valor por valor.c_str() como enunciaste. Estuve averiguando sobre esta funcion, tengo mis dudas aun pero voy a pulirlas en estos dias averiguandolas.

Al intentar enviar el dato el monitor serial me muestra el valor que devuelve la subrutina que realiza la medicion y sus promedios. Para hacer un debugg puse dentro del if (BTest.available()>0) que si esta habilitado el serial que muestre en el monitor serial la tension que esta enviando y envie ese dato al dispositivo android.

Código:
        if (BTest.available()>0) 
        {
          BTest.print(valor.c_str());
          Serial.print("Bluetooth: ");
          Serial.println(valor.c_str());
        }

Al realizar la primer prueba no envía ningún valor al dispositivo y me doy cuenta por dos cosas:
- No llega ningún dato al disp.
- El monitor serial no muestra el valor entregado.

Para ello decidí saltear el paso de verificar si esta habilitado el serial y enviarlo directamente, obteniendo así que en el monitor serial me muestre la tensión que esta enviando, peeeero...

En el dispositivo me aparecen signos de pregunta o signos raros que varían todo el tiempo, muestro unas imágenes de estos casos:

Screenshot_20171231-003528.jpg

Screenshot_20171231-003529.jpg

Screenshot_20171231-003532.jpg

Ahora voy a mostrar el monitor serial con el if comentado y como queda el código resultante:

Voltimetro.jpg

También estuve pensando en que sea un problema de velocidad de transmisión, que al ser distinto haya errores al entregar los paquetes, pero están seteádos los seriales en 9600 por codigo y con comandos AT lo setié en 9600 baudios. Por las dudas comento como tengo conectado el bluetooth GW-040 a mi arduino Leonardo:

STATE: No conectado
RX: 10
TX: 11
GND: GND
VCC: 5v
EN: No conectado (probe conectando y nada)

Te agradezco mucho la ayuda, espero tu respuesta!
 
Última edición:
#4
Hola gente, paso a contar mi experiencia jaja.

Ayer me indigne con el problema que estuve teniendo sobre este tema ya que lógicamente era un problema simple y me estaba llevando demasiado tiempo (como de costumbre). Así que decidí cambiar la forma...

Probé miles de formas de programación distinta pero siempre cayendo en la duda de: si puedo transmitirlo en el monitor serial podría transmitirlo sin problemas en el serial de bluetooth... pero decidí probar para aprender un poco mas sobre formas de transmitir sobre el serial y estudiar mas las subrutinas que tiene la biblioteca software serial.

Probando TODO, me quede sin opciones temporales y decidí como ultimo recurso pedirle a un amigo un modulo igual al mio para verificar su funcionamiento y... eureka! funciono a la primera sin ningún problema.

Enojado con la situación probé con todas las formas que habia intentado y funciono con todas jajaja.
Verificando el problema con el modulo es que al setearlo con comandos AT en 38400 baudios funcionaba bien pero al llevarlo a 9600 baudios comenzaba a enviar mal los paquetes. El de mi amigo funciono en todas las velocidades, supongo que el oscilador del modulo murió pero bueno... por ahora no me voy a ocupar de eso.

Gracias gente !
 
Última edición:

Temas similares


Arriba