Sending data to Ubidots using Arduino Nano

Hi everyone. I am learning to send data to Ubidots from my Arduino Nano.I am using the following program.

include "SoftwareSerial.h"
String ssid ="MySSID";

String password="Password";

SoftwareSerial esp(5, 4);// RX, TX

String data;

String server = "https://app.ubidots.com";

String uri = "/api/v1.6/variables/(id of the variable)/values/?token=(token taken from API credential)";
void setup() {

esp.begin(9600);

Serial.begin(9600);

reset();

connectWifi();

}

void reset() {

esp.println("AT+RST");

delay(1000);

if(esp.find("OK") ) Serial.println("Module Reset");

}

void connectWifi() {

String cmd = "AT+CWJAP=\"" +ssid+"\",\"" + password + "\"";

esp.println(cmd);

delay(4000);

if(esp.find("OK")) {

Serial.println("Connected!");

}

else {

connectWifi();

Serial.println("Cannot connect to wifi"); }

}

void loop () {

httppost();

delay(1000);

}

void httppost () {

esp.println("AT+CIPSTART=\"TCP\",\"" + server + "\",80");//start a TCP connection.

if( esp.find("OK")) {

Serial.println("TCP connection ready");

} delay(1000);
data="humidity=" + 10;

String postRequest =

"POST " + uri + " HTTP/1.1\r\n" +

"Host: things.ubidots.com \r\n" +

"Content-Type: application/json \r\n" +

"Content-Length: 17 \r\n" +

"{\"value\": 50.5}\r\n";

String sendCmd = "AT+CIPSEND=";//determine the number of characters to be sent.

esp.print(sendCmd);

esp.println(postRequest.length() );

delay(500);

if(esp.find(">")) { Serial.println("Sending.."); esp.print(postRequest);

if( esp.find("SEND OK")) { Serial.println("Packet sent");

while (esp.available()) {

String tmpResp = esp.readString();

Serial.println(tmpResp);

}

// close the connection

esp.println("AT+CIPCLOSE");

}

}}

However, the code doesn't work and the output in the serial monitor is

Module Reset
Connected
Cannot connect to Wifi
Cannot connect to Wifi
Sending..
Packet sent
+IPD,311:HTTP/1.1 400 BAD REQUEST
Server:nginx
Date://date and time
Content-Type: text/html
Content-Length:166
Connection: close


400 Bad Request

400 Bad Request

nginx
CLOSED
Sending..

Packet sent

+IPD..and the same thing continues

Also,the value is still not posted in the Ubidots variable. Are the content length and value ok?

Thanks again for your help.Cheers.

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.

I am not familiar with web stuff on Arduinos so I have not looked at your code.

...R

Hi there!

Looking at Ubidots API response codes, this is the meaning of your error:

Code Meaning 200 Ok – Successful request. 201 Created – Successful request + an item was created. 400 Bad Request – Error due to an invalid body in your request. Please verify it’s a valid JSON string and that the fields are the ones expected by the endpoint (string, object or float).

So it seems the payload or body is not right. Looking at their documentation on how to send an HTTP POST, it seems the correct request is this:

POST /api/v1.6/devices/{LABEL_DEVICE}/?token={TOKEN} HTTP/1.1
Host: things.ubidots.com
Content-Type: application/json
Content-Length: 18

{"temperature":10}

So in your code, I can suspect some reasons why it doesn't work:

  • You're not separating the HTTP headers from the body. Try adding an additional "/n" at the end of Content-Length header.
  • An additional "/n" might be needed after the payload to tell the server that you're done with the request, so try adding one after the Json payload.
  • Your request should work using variable ID, but it's simpler to use the device label and then send a single JSON string with several variables. For example: {\"temp\":24,\"batt\":24}

See this example to see how they setup a post request manually: http://help.ubidots.com/connect-your-devices/connect-your-linkit-one-to-ubidots-over-wi-fi