Dudas sobre los datos


#1

Buenas tardes a tod@s. Voy entrando en Thinger, que me parece una plataforma excelente, pero tengo algunas dudas sobre la presentación de datos.

Trabajo con Arduino, una ESP8266 y un sensor BME280, que me da los datos de temperatura, humedad y presión. Tengo otra estación meteo independiente, que también me da estos datos, más afinados y fáciles de leer (imagen 1):

Los datos que me da la descarga de data bucket de Thinger, es cómo se muestra en la imagen 2:

1.- En la primera imagen la fecha y las horas, están en columnas diferencias, lo que facilita la lectura y gestión posterior.
Por contra, en los datos del data bucket sobre la fecha y hora, están en una única columna y pegados, lo que entorpece mucho la lectura y dificulta la gestión. Da mucho trabajo la gestión de esta columna, ya que para gestionarla, hay que modificar demasiados parámetros.

Hay manera de que los datos se presenten como en la primera imagen, sin necesidad de manipulaciones posteriores?

2.- Como se ve en la imagen 1, las horas de impresión de datos, se corresponde exactamente a cada 60 minutos, mientras que en la imagen 2, de tanto en tanto imprime datos de una misma hora en diferentes minutos.

Hay manera que los datos los imprima cada 60 minutos, sin repeticiones separadas por minutos?

3.- Los datos de las columnas de humedad y presión los imprime de forma extraña, por ejemplo:
Humedad Thinger: 541.289, cuando la correcta sería 54.1, es decir, presenta tres dígitos + punto + tres dígitos, cuando debería imprimir únicamente dos dígitos + punto + 1 (o 2) dígitos.

Presión Thinger: 101242 + punto + 0, cuando la correcta sería 1012.42, es decir, presenta seis dígitos + punto +cero, cuando debería imprimir únicamente cuatro dígitos + punto + uno (o dos) dígitos.

Desconozco si este tipo de medidas corresponden a la manera anglosajona de exponer estos datos, o se trata de otra cosa. Hay manera de manipular la presentación de estos valores, en alguna función de Thinger para adaptarlos a lo expuesto?

Bueno, pues por el momento estas son la dudas con las que me encuentro. No se si hay, ni donde (si lo hay), algún apartado donde este tipo de “disfunciones” puedan modificarse a gusto del consumidor.

Venga, pues muchas gracias por la atención y la ayuda. Esta plataforma me gusta mucho y, si logro solucionar estos “detallitos”, ya será la bomba.

Salu2 cordiales.


#2

Yo trunco las posiciones decimales en las variables en el microcontrolador y me va bien, es mas eficiente al momento de que no se envían todos los decimales que logra calcular el microcontrolador, solo 2 posiciones o 1 posición de acuerdo a la precisión que se requiera:

Lo hago con la siguiente función:

float round_to_dp( float in_value, int decimal_place )
{
  float multiplier = powf( 10.0f, decimal_place );
  in_value = roundf( in_value * multiplier ) / multiplier;
  return in_value;
}

Donde
in_value es la variable con todos sus decimales
decimal_place es el número de posiciones después de la coma a conservar.

Y la invoco en la variable que deseo truncar, obviamente antes de que se reporte a thinger.

Éxitos.


#3

Gracias por la respuesta, Ega, pero de donde sacas estas instrucciones? En que lugar están? Yo he adaptado el siguiente sketch a mis necesidades (no me deja subir archivos zip, por eso lo cuelgo entero):


#include <ESP8266WiFi.h>       //Librería de conexión WiFi del módulo ESP8266
#include <ThingerESP8266.h>    //Librería de la plataforma thinger.io

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

// Assignar pins ESP8266 a pins arduino_
#define D1 5
#define D2 4
#define D4 2
#define D3 0

// Assignar SPI als pins_
#define BME_SCK D1  //SCL BME280
#define BME_MOSI D2  //SDA BME280
#define BME_CS D3  //SCB BME280
#define BME_MISO D4 //SD0 BME280

#define SEALEVELPRESSURE_HPA (1013.25)  //Pressió aproximada. Es pot modificar_

Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK);  //Programari SPI_

unsigned long delayTime;

//Paràmetres del connexió thinger.io
#define username "XXXXXXX" 
#define deviceId "BME280"
#define deviceCredentials "XXXXXxXXXXX"

ThingerESP8266 thing (username, deviceId, deviceCredentials);

//Paràmetres de connexió WiFi_
_const char WiFi_ssid[] = "MiFibra-86A4";  //Nom de xarxa WiFi_
_const char WiFi_password[] = "cJsbN65Q";  //Clau de xarxa WiFi_



void setup()
{
    Serial.begin (115200);  //Obre connexió amb serial
    Serial.println (F ("BME280 test"));

    bool status;

// Configuració per defecte
    status = bme.begin();
    if (!status) 
    {
    Serial.println ("No es troba el sensor BME280. Verificar cablejat!");
    while (1);
    }

    Serial.println ("-- Test predeterminat --");
    delayTime = 1000;

    Serial.println();

 //Inicialització WiFi per comunicar-se amb l'API
  thing.add_wifi (WiFi_ssid, WiFi_password);

//Inicializació de la lectura de dades des de l'API
  thing["BME280"] >> [](pson& out)

  {  
  out ["Temperatura"] = bme.readTemperature();
  out ["Humitat"] = bme.readHumidity();
  out ["Pressió"] = bme.readPressure();   
  };
}



void loop()  
{ 
   thing.handle();
    printValues();
    delayTime = 1000;  //delay(delayTime);
}


void printValues()   //Impressió valors a serial
{
    Serial.print ("Temperatura = ");
    Serial.print (bme.readTemperature() / 1.12); //*1*(bme.readTemperature());
    Serial.println (" *C");
    Serial.print ("Humitat = ");
    Serial.print (bme.readHumidity() / 0.85);   //*2*(bme.readHumidity());
    Serial.println(" %");

    Serial.print ("Pressió = ");
    Serial.print (bme.readPressure() / 100.0F);  //*3*
    Serial.println (" hPa");

//    Serial.print ("Altura aproximada = ");
//    Serial.print (bme.readAltitude(SEALEVELPRESSURE_HPA));
//    Serial.println (" m");

    delay (1000);

    Serial.println();
}

/*
   *1* Si es puja l'últim valor (10), el graus marquen menys
   *2* Si es puja l'últim valor (84), el percentage marca menys 
   *3* Si es puja l'últim valor (9F), la pressió marca menys
*/

No encuentro el lugar de modificación de decimales en mi sketch, máxime teniendo en cuenta que los envía según la imagen 1, y es Thinger el que los presenta de forma tan rara.

Y sobre la repetición de datos en una hora determinada con variación de minutos, entiendo que el ESP8266 envía datos cada x segundos, los mismos que imprime en el serial, y sería Thinger el que grabaría el dato (un solo dato) cada 60 minutos en data bucket, prescindiendo del resto.

La configuración de la gráfica de la temperatura es la siguiente. Es correcta?

Que te parece?

Gracias por la atención y la ayuda.

Salu2 cordiales


#4

Algo como esto debería funcionar

thing[“BME280”] >> [](pson& out)
{
out [“Temperatura”] = float round_to_dp( bme.readTemperature(), 2);
out [“Humitat”] = float round_to_dp( bme.readHumidity(), 2);
out [“Pressió”] = float round_to_dp( bme.readPressure(), 2);
};

Por supuesto debes incluir la función del post previo en el sketch, fuera del loop.

Avisame si no funciona.

Saludos,


#5

Hola, ega, perdona la demora, pero he tenido otras obligaciones que atender y no me he podido dedicar al tema.

Bueno, he colocado las instrucciones de tu primer post antes del void setup(), y las siguientes antes del void loop():

Pero me da el siguiente error al compilar: expected primary-expression before ‘float’

No consigo dar con el error. He colocado las instrucciones en el lugar correcto?

De que va?

Gracias por la ayuda y la atención.

Salu2 cordiales.


#6

Tienes razón, la palabra float no va, intenta de esta forma y me comentas

thing[“BME280”] >> [](pson& out)
{
out [“Temperatura”] = round_to_dp( bme.readTemperature(), 2);
out [“Humitat”] = round_to_dp( bme.readHumidity(), 2);
out [“Pressió”] = round_to_dp( bme.readPressure(), 2);
};

#7

Gracias por la ayuda, Ega. Ahora complia perfectamente. De momento parece que algo cambia. La humedad se ha reducido a 2 unidades y 2 decimales (de 466.221, ha pasado a 46.57), esto és correcto. Pero no se si hace lo mismo con la presión. Marca 101264.0, cuando debería marcar 1012.64. Tendré que dejar unas horas de progreso a ver como va. Mañana te digo si funciona y qué funciona y qué no.

Venga, muchas gracias de nuevo.


#8

Re-hola, Ega. Bueno, hemos ganado en el tema decimales, pero no del todo. Las instrucciones que me pasaste funcionan para temperatura y humedad, pero en presión no me da decimales en Thinger, pero me añade un cero en excel:

No hay manera que en lugar de 6 dígitos, imprima únicamente 4 + 1 o 2 decimales? La presión real, en la primera línea de excel, por ejemplo, no debería ser 101777.0, si no 1017.77. O dicho de otro modo, no sería posible mover la coma dos posiciones a la izquierda?

Y sobre el tema de separar fecha y hora en diferentes columnas, en origen, es decir, dentro de Thinger, es posible? Como se gestiona la fecha y hora en este programa? A mi solo me interesa, en primera columna, día/mes/año y, en la segunda, hora/minutos, sin la “T”, ni segundos, ni décimas

Muchísimas gracias por tu inestimable ayuda, Ega…

Salu2 cordiales


#9

Por lo que comentas me parece que el caso de la presión la irregularidad esta en la escala y no en el manejo de los datos, si solo hay que correr la coma 2 espacios, puedes dividir entre 100 y listo, quizá algo como esto te funcione:

out [“Pressió”] = round_to_dp( bme.readPressure() / 100, 2);

Si no funciona hay que declarar una variable auxiliar y hacer el cálculo aparte.

La hora y fecha no se puede separar en distintas columnas porque la plataforma maneja el tiempo en formato unix (contado en milisegundos), y es al momento de desplegar la información en pantalla que hace la conversión a fecha, creo que excel de hecho tiene la esa función, en el que se ingresa un numero entero como huella de tiempo y hace la conversión a dia mes año y hora, si quieres extraer algún dato particular como el día, mes o año aparte, debes usar o programar una función para hacerlo (me refiero en excel, en la plataforma actualmente no tienes acceso para programar).

Me comentas que tal te fue,

Saludos,


#10

Ega, eres un crac. Tienes razón, el problema está en la escala. Poniéndole esta división, ya funciona correctamente:


Perfecto.

Entiendo el tema de fecha-hora y ya miraré a ver si consigo modificarlo en excel. Es una lástima que no se pueda gestionar directamente con Thinger, sería una gran cosa.

Y podría ser que la compilación de datos fuera errónea por causa de los milisegundos?

La cosa es que debería imprimir datos cada hora, a partir de que se carga el sketch. Pero realmente va imprimiendo cada hora, a veces se le va la olla e imprime 14 lecturas en 1h, o 8 en 1h o, a veces, se salta alguna hora. No hay manera de anclar la cadencia para que solo imprima un valor cada hora? Sería cuestión del sketch?

Muchas gracias por la ayuda, que resulta inestimable. Te estoy verdaderamente agradecido por qué, además, voy profundizando en Arduino.

Salu2 cordiales


#11

Hay 2 formas de que se registren los datos en un bucket, una es que la plataforma interrogue cada cierto tiempo al dispositivo, y la otra es que el dispositivo escriba cada cierto tiempo en el bucket.

Para el primer caso no hace falta agregar ninguna rutina adicional en el micro (aunque no he visto todo tu sketch, debes publicarlo bien para que sea cómodo leerlo), y al crear el bucket se establece cuá “thing” de cuál dispositivo se va a interrogar en qué lapso de tiempo.

Para el segundo caso el bucket debe ser configurado para que acepte ser escrito directamente por un dispositivo, y hay que programar la rutina para que el dispositivo cada cierto tiempo escriba en el bucket.

Yo te sugiero que uses la primera opción, la 2da pienso que debe usarse al momento en que el dispositivo detecte algún evento particular que lo registre en la nube, si va a ser cada hora, no es un evento particular que se esta registrando.

Cuando los widgets se generan a partir de datos del dispositivo, no tienen nada que ver con los buckets, fijate que al refrescar la pagina se pierden los datos acumulados y se empieza desde cero (cosa que no ocurre cuando es desde un bucket), son 2 cosas diferentes cuando la fuente de datos del widget es un dispositivo a cuando es un bucket.

Me alegra que la ayuda sea valorada, ya casi se resuelve todo lo que genera irregularidades en tu proyecto :wink:

Saludos,


#12

Hola, Ega, yo lo tengo programado con la primera opción, de manera la plataforma interroga cada cierto tiempo al dispositivo:
Imatge2

Este es el sketch (no se si se puede enviar de otra manera), por si te sirve de algo:

------------------------------------------
He eliminado el código mal puesto…
--------------------------------------------

Vale, ya he aprendido que los datos impresos en el widgets a partir de los datos del dispositivo y los impresos en el bucket, son cosas diferentes. Era otra de las dudas que tenía.

Y puedes estar seguro que estás siendo de muchísima ayuda. Estas informaciones que me das, no aparecen en ninguna otra parte o, al menos, no he sabido encontrarlas. Muchas gracias de nuevo.

Salu2 cordiales


#13

Bueno no esta bien compartido el sketch… La idea es que quede en un único bloque de código, particularmente yo no me molesto en leer un código cuando no es compartido de esta forma.

La idea es que lo pegues en la ventana, lo selecciones y en la barra de herramientas hay un boton que permite establecer que es un bloque de código, así es más cómodo leerlo y seguirlo.

Saludos.


#14

JHola, Ega, a ver si ahora…

#define _DEBUG_  //Imprimeix, a serial, l'estat de la connexió WiFi
#define _DISABLE_TLS_  //Imprimeix, a serial, l'estat de la connexió WiFi

#include <ESP8266WiFi.h>       //Librería de conexión WiFi del módulo ESP8266
#include <ThingerESP8266.h>    //Librería de la plataforma thinger.io

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

// Assignar pins ESP8266 a pins arduino
#define D1 5
#define D2 4
#define D4 2
#define D3 0

// Assignar SPI als pins
#define BME_SCK D1  //SCL BME280
#define BME_MOSI D2  //SDA BME280
#define BME_CS D3  //SCB BME280
#define BME_MISO D4 //SD0 BME280

#define SEALEVELPRESSURE_HPA (1013.25)  //Pressió aproximada. Es pot modificar

Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK);  //Programari SPI

unsigned long delayTime;

//Paràmetres del connexió thinger.io
#define username "jaume"  
#define deviceId "BME280"
#define deviceCredentials "jmnnfrr"

ThingerESP8266 thing (username, deviceId, deviceCredentials);
 
//Paràmetres de connexió WiFi
const char WiFi_ssid[] = "MIWIFI_2G_PtG4";  //Nom de xarxa WiFi, A 2.4ghZ
const char WiFi_password[] = "sh96xFX2";  //Clau de xarxa WiFi

//Gestió de decimals a la impressió de Thinger
float round_to_dp( float in_value, int decimal_place )
{
  float multiplier = powf( 10.0f, decimal_place );
  in_value = roundf( in_value * multiplier ) / multiplier;
  return in_value;
}



void setup() 
{
    Serial.begin (115200);  //Obre connexió amb serial
    Serial.println (F ("BME280 test"));

    bool status;
    
 // Configuració per defecte
    status = bme.begin();
    if (!status) 
    {
    Serial.println ("No es troba el sensor BME280. Verificar cablejat!");
    while (1);
    }
    
    Serial.println ("-- Test predeterminat --");
    delayTime = 500;  //1000; Velocitat a la que imprimeix a serial

    Serial.println();

 
  thing.add_wifi (WiFi_ssid, WiFi_password);  //Inicialització WiFi per comunicar-se amb l'API


thing["BME280"] >> [](pson& out)  //Inicializació de la lectura de dades des de l'API
{
out ["Temperatura"] = round_to_dp( bme.readTemperature(), 2);  //*4*
out ["Humitat"] = round_to_dp( bme.readHumidity(), 2); //*4*
out ["Pressió"] = round_to_dp( bme.readPressure() / 100, 2); //,2);  //*4* i *5*
};

}



void loop()  
{ 
    thing.handle();
    printValues();
    delay(delayTime);
}



void printValues() //Impressió valors a serial
{
    Serial.print ("Temperatura = ");
    Serial.print (bme.readTemperature() / 1.12); //*1*(bme.readTemperature());
    Serial.println (" *C");

    Serial.print ("Humitat = ");
    Serial.print (bme.readHumidity() / 0.85);   //*2*(bme.readHumidity());
    Serial.println(" %");
 
    Serial.print ("Pressió = ");
    Serial.print (bme.readPressure() / 100.0F);  //*3*
    Serial.println (" hPa");

//    Serial.print ("Altura aproximada = ");
//    Serial.print (bme.readAltitude(SEALEVELPRESSURE_HPA));
//    Serial.println (" m");

    Serial.println();

}


#15

Indudablemente mucho mejor :+1:

Saludos


#16

Bueno, es que en cada foro es diferente y si no se avisa…


#17

jajajaj a mí también me sangra la vista cuando veo el texto plano. Me he tomado la libertad de editarlo para la posteridad.

otra forma de poner el formato código es poniendo “```cpp” antes y sólo los tres acentos después.

Me alegra ver que conseguisteis resolver el problema! muchas gracias por el soporte @ega!!


#18

Vaaaaaale, perdón por el error de colocación del texto, todo se aprende, no? Ya he eliminado el texto plano para que nadie se ofenda, jajajajajajaja… Y pido perdón.

Vale, pues queda el pié la pregunta de cómo solucionar la cadencia exacta de la recogida de datos en el bucket. Estos días, además de imprimir los datos de forma loca, como indico al principio, se permite el lujo de saltarse alguna hora que otra. No hay manera de afinar estos temas?
Gracias por la atención y la ayuda.

Salu2 cordiales


#19

Jejejejeje si bueno, así provoca más ayudar que cuando lanzan el código y ya, recuerda que la programación es bastante artesanal y cualquier rutina que te inventes hacer algún procedimiento no necesariamente es intuitiva para todo el mundo, y si a eso le sumas que el texto cambia de formato y aleatoriamente… Por supuesto que es incómodo seguir la rutina del código.

Me parece muy extraño que no esté guardando los datos cada hora como debería interrogar la plataforma.

Lo único que no me convence es el delay que tienes. de cuánto es ese delay(delayTime);? No es recomendable usar este comando porque esto detiene absolutamente todo en el micro, y si coincide el momento que la plataforma interroga al dispositivo estando en esta instrucción, no va a recibir la solicitud.


#20

Hola, Ega, muchas gracias por la ayuda, y pues claro que entiendo el tema del texto plano. Estuve buscando la manera pero, al principio, no di con el modo. Entiendo perfectamente el por qué de publicarlo así, ya que a mi también me molesta y lía ver el texto plano.

Y bueno, volviendo al tema, puede que tengas razón. Ya que lo comentas, me viene a la cabeza que leí, no se si con referencia a Thinger o a alguna otra plataforma, que había que evitar colocar delays dentro del void loop(). En un principio no entendí el por qué del aviso, pero ahora lo veo claro. Y es muy posible que estos fallos sean debidos a esta pausa. Si coincide con alguna pausa el momento de lanzar los datos, Thinger no los recibe. Por eso (y es solo una conjetura), había horas de lectura inexistentes. Lo que está por ver, una vez eliminado el delay es si sigue imprimiendo datos entre horas. Tendré que dejar pasar unos días a ver cómo se comporta.

Bueno, pues de momento estaremos a la espera de ver el comportamiento.

Muchas gracias y te digo algo en cuanto tenga unas horas almacenadas.

Venga, hasta ahora. Salu2 cordiales.