Using Bluz with Ubidots library


#1

Hello,

I use Ubidots with my photon for data collection over long periods, and I would like to do the same with the Bluz, I’m running into compile errors when I try and include the Ubidots.h library in the particle IDE.

Is this something that has not been added to the Bluz firmware yet?
I’ve tried all the available firmware versions with no luck.

Here’s a snippet of the errors I’m getting if it helps:

lib/Ubidots/Ubidots.cpp:609:0: undefined reference to "inet_gethostbyname"
error
/firmware/wiring/spark_wiring_udp.cpp:93:0: undefined reference to "spark::Network"
error
/firmware/wiring/spark_wiring_udp.cpp:212:0: undefined reference to "spark::Network"
error
/firmware/wiring/spark_wiring_udp.cpp:118:0: undefined reference to "inet_gethostbyname"
error
/firmware/wiring/spark_wiring_udp.cpp:125:0: undefined reference to "spark::Network"
error
/firmware/wiring/spark_wiring_tcpclient.cpp:62:0: undefined reference to "inet_gethostbyname"
error
/firmware/wiring/spark_wiring_tcpclient.cpp:70:0: undefined reference to "spark::Network"
error
/firmware/wiring/spark_wiring_tcpclient.cpp:153:0: undefined reference to "spark::Network"
error
/firmware/wiring/spark_wiring_tcpclient.cpp:97:0: undefined reference to "HAL_NET_SetNetWatchDog"
error
/firmware/wiring/spark_wiring_tcpclient.cpp:101:0: undefined reference to "HAL_NET_SetNetWatchDog"
error
/firmware/wiring/spark_wiring_tcpclient.cpp:110:0: undefined reference to "spark::Network"
error
/firmware/wiring/spark_wiring_tcpclient.cpp:220:0: undefined reference to "spark::Network"

And here’s my code:

#include <Ubidots.h>

#define TOKEN //account token here
Ubidots ubidots(TOKEN);
int pressure_p1 = 0;
int pressure_p2 = 0;
int pressure_p1_scaled = 0;
int pressure_p2_scaled = 0;
int pressure_p1_PSI = 0;
int pressure_p2_PSI = 0;
int p1_cal = 10;
int p2_cal = 3;

void setup() {
    

}

void loop() {
    
     pressure_p1 = analogRead(A0);
     pressure_p2 = analogRead(A1);
     //Sensors are 1-5vdc, so expected analog signal range is from 256 to 1023.
     pressure_p1_PSI = map(pressure_p1, 256, 1023, 0, 5000) + p1_cal;
     pressure_p2_PSI = map(pressure_p2, 256, 1023, 0, 5000) + p2_cal;
     Particle.publish("Pressure P1", String(pressure_p1));
     Particle.publish("Pressure P2", String(pressure_p2));
     ubidots.add("Pressure P1", pressure_p1);
     ubidots.add("Pressure P2", pressure_p2);
     ubidots.sendAll();
     delay(5000);

}

Thanks very much in advance.


#2

Udibots appears to use sockets underneath to send data to their servers. This makes total sense, the Photon and Electron have an IP address and can send data over a network. Bluz, however, doesn’t have an IP address and cannot directly send data over sockets.

Luckily, there is a way to solve this. Each bluz DK can send data to a gateway, which can in turn then send it to Udibots. To do this, you would utilize local communication: http://docs.bluz.io/tutorials/local_communication. On each DK, you can then send data to the gateway with BLE.sendData and the gateway Partile board (Photon or Electron) will receive that data in the handle_custom_data handler. You can then use the Udibots library on the Particle board to send the data to Udibots.

Please let me know if you have any questions on how to make this work.


#3

Thanks for your reply, that makes sense.
How does bluz connect to the particle network? Wouldn’t that require an IP?

My application is for a trade show, in an area without wifi, so my first thought was that I could use the bluz to do the same thing as my photon by using my phone as a bluetooth “hotspot” to connect to the cloud.

In the end I think I’ll just use my photon and connect to a wifi hotspot directly to my phone, rather than use it as a gateway to the wifi for the bluz.

Just FYI, the bluz android app on the play store is still cerfuzzled and crashes whenever you try and connect on android 7+.
I was able to find your beta app on the forums and that fixed the issue, but It might be worth just uploading the beta to the play store, as it’s getting a few bad reviews from users who can’t use it. I know it took me a few hours of testing to determine that it was the App that was crashing, and not the bluz.

Thanks again for the help!


#4

Each DK uses the IP address of the gateway to relay messages to the Particle cloud. It is very similar in concept to the local communication method I mentioned, it is all just built-in for you.

Thanks for pointing out that the app wasn’t rolled out, that is now complete so the app on the Play Store should be working for everyone.


#5

Hi,
Since Bluz uses the Particle cloud, and it has the Particle.publish(), I think you could use a particle webhook to send data from your Bluz DKs to Ubidots.
I do this all the time with Photons, and I think it could work just fine with DKs.
Example:
Check the Map it on Ubidots section on this write-up:

Would this be a valid option @eric ?
Thanks!
Gustavo.


#6

Thanks! Yes, this should work as well. So either method would allow you to integrate with Udibots


#7

hi, maybe you will be interested in my solution which use Ubidots MQTT.
I’m not sure if this is keep any “programming standards” because I’m still learning
and entire example was just for that purpose , to figure out how to sent float value to Ubidots (you can easy modify union to make int instead of float ).
So I’m sending gyroscope XYZ values to Ubidots canvas which has HTML5 a 3D cube object but anyway, abstract from that and what is doing and if this has any sence, (big latency, etc…) I’m able to sent any kind of value to Ubidots. I add all libraries separately on particle IDE because I “freed” com1 so I modify my gateway and bluz_gateway.h for debug purpose then I flashed my gateway I don’t wanna make any mess on so the rest can be found here:

https://drive.google.com/open?id=1F8e7bdAGPs9l8JEv5L_UX2RkY5HVjYn8

I hope will help. best regards Arek

**Bluz DK: (gyro.ino)**
#include "application.h"
#define GYR_ADDRESS 0x6B
#define DEBOUNCE_TIMEOUT 2000
#define DEBOUNCE2_TIMEOUT 20
#define DT  0.018
#define G_GAIN 0.087
#define  INT1_CFG 0x30
#define CTRL_REG1  0x20
#define CTRL_REG4  0x23

float rate_gyr_y = 0.0;   
float rate_gyr_x = 0.0;   
float rate_gyr_z = 0.0;     
float gyroXangle = 0.0;
float gyroYangle = 0.0;
float gyroZangle = 0.0;
float gyroXangle1 = 0.0;
float gyroYangle1 = 0.0;
float gyroZangle1 = 0.0;

long debounce = 0;
long debounce2 = 0;
byte buff[6];
uint8_t Data[13];
byte hold = true;

int gyrRaw[3];
int Dband_minX = -260;
int Dband_maxX = 220;
int Dband_minY = -60;
int Dband_maxY = 60;
int Dband_minZ = -260;
int Dband_maxZ = 260;

union {
  uint8_t a[4];

float val;
   } X;

union {
  uint8_t b[4];
float val1;
   }Y;

union {
  uint8_t c[4];
float val2;
   } Z;


void setup() {

SYSTEM_MODE(AUTOMATIC);
Wire.begin();
uint8_t register1 = 0x0F;

writeReg(CTRL_REG1 , register1 ); // Select control register1 and enable x,y,z 
writeReg(CTRL_REG4, 0x30 ); // Select control register4 and Continous update, FSR = 2000dps
  
X.val = gyroXangle;
Y.val1 = gyroYangle;
Z.val2 = gyroZangle;
}

void loop() {


if (millis() - debounce2 >  DEBOUNCE2_TIMEOUT) {
  if (hold){
            
	readFrom(GYR_ADDRESS, buff);

	gyrRaw[0] = (int)(buff[0]  | (buff[1] << 8)); 
 		if (gyrRaw[0] > 32767){
     	gyrRaw[0] -= 65535;
 		}
	gyrRaw[1] =  (int)(buff[2]  | (buff[3] << 8));
 		if (gyrRaw[1] > 32767){
     	gyrRaw[1] -= 65535;
 		}
	gyrRaw[2] =  (int)(buff[4]  | (buff[5] << 8));
		if (gyrRaw[2] > 32767){
     	gyrRaw[2] -= 65535;
 		}
	
   	 //Convert Gyro raw to degrees per second
	rate_gyr_x = (float) gyrRaw[0] * G_GAIN;
	rate_gyr_y = (float) gyrRaw[1] * G_GAIN;
	rate_gyr_z = (float) gyrRaw[2] * G_GAIN;

	 //Calculate the angles from the gyro
	if ((gyrRaw[0] < Dband_minX) || (gyrRaw[0] > Dband_maxX )){
     	gyroXangle+=rate_gyr_x*DT;
		}
	if ((gyrRaw[1] < Dband_minY) || (gyrRaw[1] > Dband_maxY )){
     	gyroYangle+=rate_gyr_y*DT;
	 	}
 	if ((gyrRaw[2] < Dband_minZ) || (gyrRaw[2] > Dband_maxZ )){
     	gyroZangle+=rate_gyr_z*DT;
		}
 else{
     	gyroXangle = gyroXangle;
     	gyroYangle = gyroYangle;
     	gyroZangle = gyroZangle;
    
		}

    X.val = gyroXangle;
    Y.val1 = gyroYangle;
    Z.val2 = gyroZangle;
 
    debounce2 = millis();
 
 
  }
 
 }


if (millis() - debounce >  DEBOUNCE_TIMEOUT) {
        
        hold = false;
 		Data[0] = X.a[0];
		Data[1] = X.a[1]; 
		Data[2] = X.a[2];
 		Data[3] = X.a[3];
 		Data[4] = Y.b[0];
 		Data[5] = Y.b[1];
 		Data[6] = Y.b[2];
 		Data[7] = Y.b[3];
 		Data[8] = Z.c[0];
 		Data[9] = Z.c[1];
 		Data[10] = Z.c[2];
 		Data[11] = Z.c[3];
 



		BLE.sendData(Data, 12);
		debounce = millis();
        hold = true;
 }

System.sleep(SLEEP_MODE_CPU);

}

void readFrom(int device, byte buff[]) {

    
for(int i = 0; i < 6; i++){
// Start I2C Transmission
    Wire.beginTransmission(device);
// Select data register
    Wire.write((40 + i));
// Stop I2C transmission
    Wire.endTransmission();

// Request 1 byte of data
     Wire.requestFrom(device, 1);


     if(Wire.available() == 1){
          buff[i] = Wire.read(); 
   }
 }
}


void writeReg(byte reg, byte value){
  Wire.beginTransmission(GYR_ADDRESS);
    Wire.write(reg);
    Wire.write(value);

  Wire.endTransmission();
}

photon on gateway: (gatewaygyro.ino)

#include "bluz_gateway.h"
#include "UbidotsMQTT.h"
#include "MQTT.h"
#ifndef TOKEN
#define TOKEN "your_token"  // Add here your Ubidots TOKEN
#endif
#define DEBOUNCE_TIMEOUT 2000
long debounce = 0;
STARTUP(WiFi.selectAntenna(ANT_EXTERNAL));
SYSTEM_MODE(SEMI_AUTOMATIC);
bluz_gateway gateway;
Ubidots client(TOKEN, callback);

 void handle_custom_data(uint8_t *data, uint16_t length) {
    //if you use BLE.send from any connected DK, the data will end up here

    union{
     float x;
     uint8_t x_byte[4];
    }X;

    union{
     float  y;
     uint8_t y_byte[4];
    }Y;

    union{
     float z;
     uint8_t z_byte[4];
    }Z;

//And on the receiving end:

    X.x_byte[0] = data[0];
    X.x_byte[1] = data[1];
    X.x_byte[2] = data[2];
    X.x_byte[3] = data[3];
    Y.y_byte[0] = data[4];
    Y.y_byte[1] = data[5];
    Y.y_byte[2] = data[6];
    Y.y_byte[3] = data[7];
        Z.z_byte[0] = data[8];
        Z.z_byte[1] = data[9];
    Z.z_byte[2] = data[10];
    Z.z_byte[3] = data[11];

    float myValue = X.x;
    float myValue1 = Y.y;
    float myValue2 = Z.z;

if (millis() - debounce >  DEBOUNCE_TIMEOUT) {
    gateway.debugPrint("Processing X " + String(myValue));
    gateway.debugPrint("Processing Y " + String(myValue1));
    gateway.debugPrint("Processing Y " + String(myValue2));
    delay(20);
    //gateway.debugPrint("Processing VALREG " + String(val));
    Particle.publish("Processing X", String(myValue));
    Particle.publish("Processing Y ", String(myValue1));
    Particle.publish("Processing Z ", String(myValue2));
    delay(20);
    client.add("gyroxangle", myValue );
    client.add("gyroyangle", myValue1);
    client.add("gyrozangle", myValue2);
    client.ubidotsPublish("your_device_API_label");
    debounce = millis();
 } 
}

void handle_gateway_event(uint8_t event, uint8_t *data, uint16_t length) {
    //will return any polling queries from the gateway here
}

void callback(char* topic, byte* payload, unsigned int length) {   
}

void setup() {
    Serial1.begin(9600);
    client.initialize();
    gateway.init();
    //register the callback functions
    gateway.register_data_callback(handle_custom_data);
    gateway.register_gateway_event(handle_gateway_event);  
}

void loop() {
    gateway.loop();
    if(!client.isConnected()){
	    client.reconnect();
	    }
    client.loop();
    //delay(100);
}

big big sorry but I don’t have clue how to add code :scream:
I think I got it :grin: I mean how to put code inside post