Ubidots and the Particle Photon

I’ve been looking through projects on here and I’ve seen a lot of people use Ubidots with HTTPclient to send data. However, every time they have used the Core. I only have a photon. I tried doing it with the photon and it didn’t seem to work. Is it possible to use the photon instead of the core (and I just did something wrong) or is ubidots only compatible with the core? Thanks!

Hi,

Perhaps we have the same problem. I am using a photon to send photocell data to Ubidots (as per Ubidots’ simple tutorial for the photon). But it isn’t working. I get the message: This variable is empty. When I look at the variable details it says, Authentication credentials were not supplied. I am using the right Token and am not using the API Key. As far as I can tell everything is as it should be. So, do you really think the Photon can’t do what the Spark Core can?

Thanks!

I was doing the tutorial as well and that’s exactly what is happening to me. It just says the variable is empty. I thought the photon and core were similar enough to just substitute in but maybe not?

I’m sure it is something that we have not set up right (and not the Photon). Perhaps there is an additional library (in addition to the HTTPclient library that we added to the code) that is needed for some unexplainable reason. I am way out of my league here. To whom can we redirect this conversation to, who might actually understand? I am going to paste some error messages and key words in case someone searching Google happens upon our conversation.

detail: Authentication credentials were not provided
This variable is empty
send particle photon data to ubidots

Hi Guys,

The Photon should be able to send data to Ubidots without a problem. Looking at their example, I see something funny that could be a problem on this line:

    request.path = "/api/v1.6/variables/"VARIABLE_ID"/values";

Since the VARIABLE_ID that #define'ed above already has quotes, this looks wrong to me. Can you try something more like this:

    request.path = "/api/v1.6/variables/7lIgBfvGWdCh56j1bcunhfnYrMPLJh1/values";

Where the variable ID from the sample above is replaced by your actual variable ID.

Hi bko,

I tried your suggestion. Thanks! But still get the same error messages. Here is how that block of code looks now. Let us know if you have anything else that we can check up on!

void setup() {
pinMode(A0, INPUT);
request.port = 80;
// dns.begin(dnsServerIP); // Uncomment if having DNS problems
// dns.getHostByName(serverName, remote_addr); // Uncomment if having DNS problems
// request.ip = remote_addr; // Uncomment if having DNS problems
request.path = “/api/v1.6/variables/5658de26mystuffhere25a4e000c/values”;
Serial.begin(9600);
}

thanks for the reply! Unfortunately i get the same error.

@aguspg Is with Ubidots so I pinged him here as a call for help :smile:

Thank you for pinning this. There is also a thread on the Ubidots forum…

I am seeing similar issues, but I have moved past the 403 error but still cannot see any data. Like the other posters, I am using the vanilla sample code on a Photon.

So reading that thread on the Ubidots site, it looks like they have a problem, perhaps with DNS entries between their test and live sites.

It would be really good if you could try with the command-line PC/Mac/Linux tool curl as described in the Ubidots thread to see if that works. If that does not work, you should figure out how to fix that before doing anything with the Photon.

Hey guys, I was able to send data to Ubidots using the Photon, you can find the code below. As @bko suggests, it’s a good idea to test your Ubidots credentials beforehand, for example pasting this into your browser:

http://things.ubidots.com/api/v1.6/variables/?token=YOUR-TOKEN-HERE

This should list all the variables in your account. Once you’ve verified your token works, you can check this code which just worked for me (based on the original example in the http repo but simplified):

#include "HttpClient/HttpClient.h"
#include "application.h"

#define VARIABLE_ID "YOUR-VARIABLE-ID"
#define TOKEN "YOUR-UBIDOTS-TOKEN"

HttpClient http;
int lightLevel = 0;
unsigned int nextTime = 0;    // Next time to contact the server

// Headers currently need to be set at init, useful for API keys etc.
http_header_t headers[] = {
    { "Content-Type", "application/json" },
    { NULL, NULL } // NOTE: Always terminate headers will NULL
};

http_request_t request;
http_response_t response;

void setup() {
    pinMode(A0, INPUT);
    request.hostname = "things.ubidots.com";
    request.port = 80;
    request.path = "/api/v1.6/variables/"VARIABLE_ID"/values?token="TOKEN;
    Serial.begin(9600);
}

void loop() {
    if (nextTime > millis()) {
        return;
    }
    // Read sensor value
    lightLevel = analogRead(A0);

    Serial.println("Sending data ...");
    
    request.body = "{\"value\":" + String(lightLevel) + "}";

    // Post request
    http.post(request, response, headers);
    Serial.println(response.status);
    Serial.println(response.body);

    nextTime = millis() + 1000;
}

Feel free to post an entry in our community in case you think it’s an issue with your account.

Thanks you so much! worked perfectly. This brings me to another question, how can I get another photon to react to this data by accessing it? I’m really new to all this but I can see how the photon is sending, so there must be a function to enable another photon to download, right? I know particle supplies the particle.publish/subscribe function but the purpose of using the HTTPclient is to avoid using the cloud. Thanks!

Here’s the same code turned into a GET request, based on this Particle GET tutorial from Ubidots:

#include "HttpClient/HttpClient.h"
#include "application.h"

#define VARIABLE_ID "your-variable-id"
#define TOKEN "your-token"

HttpClient http;
int value_index = 0;
String value_string, value;
unsigned int nextTime = 0;    // Next time to contact the server

// Headers currently need to be set at init, useful for API keys etc.
http_header_t headers[] = {
    { "Content-Type", "application/json" },
    { NULL, NULL } // NOTE: Always terminate headers will NULL
};

http_request_t request;
http_response_t response;

void setup() {
    pinMode(A0, INPUT);
    request.hostname = "things.ubidots.com";
    request.port = 80;
    request.path = "/api/v1.6/variables/"VARIABLE_ID"/values?page_size=1&token="TOKEN;
    Serial.begin(9600);
}

void loop() {
    if (nextTime > millis()) {
        return;
    }
    // Read sensor value from Ubidots
    Serial.println("Connecting to Ubi ...");

    // Get request
    http.get(request, response, headers);
    //Serial.println(response.body);
    // Look for the index of the JSON string "value:"
    value_index = response.body.indexOf("\"value\": ");

    // Chop the response from that index, until the end of the response string
    value_string = response.body.substring(value_index);

    // Get the value which is between the nine characters of "\"-v-a-l-u-e-\"-: " , and the next comma
    value = value_string.substring(9, value_string.indexOf(","));

    Serial.print("Last value of variable:");
    Serial.println(value);
    
    nextTime = millis() + 1000;
}

Thank you aguspg!
Your code worked and now my photon is sending/graphing data on Ubidots. Wow, I am so grateful. Since I am a beginner, would you care to share the part of your code that made the difference? I can compare your code with the sample tutorial on the Ubidots site, but I don’t have enough experience to really know what are the key blocks that made it work.

Hi,

This works for me too, but I am still having an issue. Ubidots shows the data as -2 instead of the temperature.

To be clear, I am gathering data from a DHT22. The information (tempFi and humidI) are captured from the DHT22 and then published to a website every 20 seconds and this works perfectly.

I am now trying to add Ubidots to capture the data over time. I know that tempFi and humidI are properly populated because the web page works, but Ubidots shows the data value as -2 for both variables. (Both tempFi and humidI are incorporated in Spark variable later in the code.)

Here is the relevant Ubidots and tempFi and humidI code.

  if (Time.now() - PreviousTime > interval){
      PreviousTime = Time.now();
      DHT.acquireAndWait();
      tempF = DHT.getFahrenheit();
      tempFi = (int) tempF;
      humidF = DHT.getHumidity();
      humidI = (int) humidF;
      tempupdate = true;
      request.body = "{\"value\":" + String(tempFi) + "}";
      http.post(request, response, headers);
    }

Any idea what is going on here?

Thank you!

@1eb13 the code is very similar, but I read somewhere in the forums that new Http examples are including the " #include “application.h” " line, and also I erase the X-Auth-Token header which is in the Ubidots example, and sent the token inside the URL of the request path ("&token=“TOKEN…”). We’ll create a new tutorial for the Photon inside the Ubidots docs to reflect this.

The Photon is very stable. I remember we had lots of issues with this library and the initial Spark device. For example, the line “request.body = “{“value”:” + String(lightLevel) + “}”;” had issues because it started filling up the internal memory due to the concatenation of strings (a.k.a heap fragmentation). Now the Photon seems to have a garbage collector in the background that prevents this to happen and allows the user to concatenate strings easily (no fixed char arrays necessary). Mine has been running straight for two days sending data every second.

1 Like

Thanks, aguspg! I see what you did and took notes; hopefully this will slowly be easier for me to understand. I am grateful for you help. My Photon has been gathering light sensor data for a few days now and has also been running straight, for days, without a hiccup.

I need advice on a related project and perhaps you can direct me to a tutorial or doc that might help. My current app collects the photocell data and graphs it on uibidots (that’s the code you worked out for us). I have another app that I worked out in which I can turn an LED on or off, using either a curl command or an http request. I don’t know how to blend together the two apps such that I could turn on (or off) the LED and then see how the photocell reacts to the light emitted from the LED (of course I’d aim the photocell at the LED). Let me know if you have any suggestions.
1eb13

@1eb13 I know you can do that with Ubidots but I can’t remember the link that shows you how to do this. Ubidots is helping me do exactly that with a hard wired project now.

Sure @1eb13, let’s assume this scenario:

  1. Photon #1 measures light, sends it to a Ubidots variable called "Light"
  2. Photon #2 controls an LED, reads a Ubidots variable called "LED"

In this case you need to create two events in your Ubidots account; one to turn the LED on, another one to turn it off:

  • IF light > xxx THEN “Set a variable” --> Select the LED variable --> Set variable to: 1
  • IF light >= xxx THEN “Set a variable” --> Select the LED variable --> Set variable to: 0

Example:


…choose variable…

Thanks for your suggestion. I didn’t realize that Ubidots could do all that!

In case anyone is interested, I figured out how to use the code that you generated (photocell) into one app on the Particle Photon that both reads light level from a photosensor and also enables one to turn on a nearby LED on the same Photon using a block of html. code in a browser window. I’ll paste it here in case it helps anyone. In this fashion I can turn the LED on or off, remotely, and watch what happens on Ubidots as the data get graphed.
1eb13

//directions
//turn on or off LED with html code and read photocell data using ubidots
// For each block, I’ll copy the photocell code first, and second, incude the LED code

// This #include statement was automatically added by the Particle IDE.
#include “HttpClient/HttpClient.h”
#include “application.h” ////This kind of comes along with above. Don’t know what it is.
//aguspg says new http examples ineed to include #include “application.h”

#define VARIABLE_ID “put in your variable id” //the specific variable set up with photocell
#define TOKEN “put in your token generated” //generated from ubidots

HttpClient http; //what is this?
int lightLevel = 0;
unsigned int nextTime = 0; // Next time to contact the server
//it adds a second each time through the loop

// Headers currently need to be set at init, useful for API keys etc.
http_header_t headers[] = {
{ “Content-Type”, “application/json” },
{ NULL, NULL } // NOTE: Always terminate headers will NULL
};

http_request_t request;
http_response_t response;

//this single line is the first line of code in the turn led on or off
int led1 = D7;

// Last time, we only needed to declare pins in the setup function.
// This time, we are also going to register our Spark function

//These directions were from the led app
// We’re going to have a super cool function now that gets called when a matching API request is sent
// This is the ledToggle function we registered to the “led” Spark.function earlier.

int ledToggle(String command) {
/* Spark.functions always take a string as an argument and return an integer.
Since we can pass a string, it means that we can give the program commands on how the function should be used.
In this case, telling the function “on” will turn the LED on and telling it “off” will turn the LED off.
Then, the function returns a value to us to let us know what happened.
In this case, it will return 1 for the LEDs turning on, 0 for the LEDs turning off,
and -1 if we received a totally bogus command that didn’t do anything to the LEDs.
*/

if (command=="on") {
    digitalWrite(led1,HIGH);
    return 1;
}
else if (command=="off") {
    digitalWrite(led1,LOW);
    return 0;
}
else {
    return -1;
}

}

void setup() { //should this be moved to right after setup()?

//these lines, ending with Serial.begin(9600); are from photocell app

pinMode(A0, INPUT);
request.hostname = "things.ubidots.com"; //he added this line.  What is it?
request.port = 80;
request.path = "/api/v1.6/variables/" VARIABLE_ID "/values?token=" TOKEN;  //JB had me put in 3 spaces @ quotes
//aguspg took out the { "x-Auth-TOKEN" , token } line from the space
//just above NULL, NULL and put it here after /values.  He says he put the token
//inside the requested path
Serial.begin(9600);

//These three lines are from turn led on or off
// Here’s the pin configuration, same as last time
pinMode(led1, OUTPUT);

// We are also going to declare a Spark.function so that we can turn the LED on and off from the cloud.
Particle.function(“led”,ledToggle); //jb had me change spark to Particle
// This is saying that when we ask the cloud for the function “led”, it will employ the function ledToggle() from this app.

// For good measure, let’s also make sure both LEDs are off when we start:
digitalWrite(led1, LOW);

}

//These directions are for the turn led on or off and not for the photocell app
// Last time, we wanted to continously blink the LED on and off
// Since we’re waiting for input through the cloud this time,
// we don’t actually need to put anything in the loop

void loop() { //this stuff in the loop is for the photocell app
if (nextTime > millis()) { //he added this line.
return;
} //this is not the end of loop() but just the end of return above

// Read sensor value, again, this code is from photocell app
lightLevel = analogRead(A0);

Serial.println("Sending data ...");
//original has this line: sprintf(resultstr, "{\"value\":%.4f}", lightLevel);

request.body = "{\"value\":" + String(lightLevel) + "}"; 
//original said request.body = resultstr;

//These last directions from the photocell app were at the very end, just before the final }

// Post request
http.post(request, response, headers);
Serial.println(response.status);
Serial.println(response.body);

nextTime = millis() + 1000; //original said delay(1000)
2 Likes