Uploading incorrect code to Ubidots


#1

Hi,

I am trying to post specific variables to Ubidots, however, I believe that the following code is incorrect. The only value being posted correctly is the UV value. Random large values are being posted for “Wind Vane”, “Anemometer” and “Rain Gauge”. I am trying to post the values of “Dir”, “Wind Speed” and “Rain Fall”, unfortunately, I am not sure on how to alter the code. Any assistance would be greatly appreciated.

This is the code I am using:

#include <SoftwareSerial.h>


//////UV Sensor//////
#include <Wire.h>
#include "Adafruit_SI1145.h"
Adafruit_SI1145 uv1 = Adafruit_SI1145();

/////WIND AND RAIN////

#define uint  unsigned int
#define ulong unsigned long

#define PIN_ANEMOMETER  2     // Digital 2
#define PIN_RAINGAUGE  3     // Digital 3
#define PIN_VANE        3     // Analog 3



// How often we want to calculate wind speed or direction
#define MSECS_CALC_WIND_SPEED 5000
#define MSECS_CALC_WIND_DIR   5000
#define MSECS_CALC_RAIN_FALL  30000

volatile int numRevsAnemometer = 0; // Incremented in the interrupt
volatile int numDropsRainGauge = 0; // Incremented in the interrupt
ulong nextCalcSpeed;                // When we next calc the wind speed
ulong nextCalcDir;                  // When we next calc the direction
ulong nextCalcRain;                  // When we next calc the rain drop
ulong time;                         // Millis() at each start of loop().

// ADC readings:
#define NUMDIRS 8
ulong   adc[NUMDIRS] = {26, 45, 77, 118, 161, 196, 220, 256};

// These directions match 1-for-1 with the values in adc, but
// will have to be adjusted as noted above. Modify 'dirOffset'
// to which direction is 'away' (it's West here).
char *strVals[NUMDIRS] = {"W","NW","N","SW","NE","S","SE","E"};
byte dirOffset=0;

namespace {
  bool flow_control = true; // control the flow of the requests
  const char * USER_AGENT = "NewESP8266"; // Assgin the user agent
  const char * VERSION =  "1.0"; // Assign the version
  const char * METHOD = "POST"; // Set the method
  const char * TOKEN = "A1E-7CDP9Th0hgMGl9i0gb2zYnjFGIoXMS"; // Assign your Ubidots TOKEN
  const char * DEVICE_LABEL = "NewESP"; // Assign the device label
  const char * VARIABLE_LABEL = "UV1"; // Assign the variable label
  const char * VARIABLE_LABEL2 = "Wind Vane"; // Assign the variable label
  const char * VARIABLE_LABEL3 = "Anemometer"; // Assign the variable label
  const char * VARIABLE_LABEL4 = "Rain Gauge"; // Assign the variable label
  
  
}

char telemetry_unit[100]; // response of the telemetry unit

/* Space to store values to send */
char str_sensor1[10];
char str_sensor2[10];
char str_sensor3[10];
char str_sensor4[10];



const int RX1 = 10;
const int TX1 = 11;

SoftwareSerial serial1(RX1,TX1);


/****************************************
 * Main Functions
 ****************************************/
void setup() {
  Serial.begin(9600);
  serial1.begin(115200);

  if (! uv1.begin()) {
    Serial.println("Didn't find Si1145");
    while (1);
  }
   Serial.begin(9600);
   pinMode(PIN_ANEMOMETER, INPUT);
   digitalWrite(PIN_ANEMOMETER, HIGH);
   digitalWrite(PIN_RAINGAUGE, HIGH);
   attachInterrupt(0, countAnemometer, FALLING);
   attachInterrupt(1, countRainGauge, FALLING);
   nextCalcRain = millis() + MSECS_CALC_RAIN_FALL;
   nextCalcSpeed = millis() + MSECS_CALC_WIND_SPEED;
   nextCalcDir   = millis() + MSECS_CALC_WIND_DIR;
  
}

void loop() {
  char* command = (char *) malloc(sizeof(char) * 128);
  /* Wait for the server response to read the values and built the command */
  /* While the flag is true it will take the sensors readings, build the command,
     and post the command to Ubidots */
     flow_control = true;
  if (flow_control) {
    /* Analog reading */
  float UVindex1 = uv1.readUV();
  //float WindVane;
  //float Anemometer;
  //float RainGauge;
  
 UVindex1 /= 100.0; 

  // Read values from the sensor
    time = millis();

   if (time >= nextCalcSpeed) {
      calcWindSpeed();
      nextCalcSpeed = time + MSECS_CALC_WIND_SPEED;
   }
   if (time >= nextCalcDir) {
      calcWindDir();
      nextCalcDir = time + MSECS_CALC_WIND_DIR;
   }
   if (time >= nextCalcRain) {
      calcRainFall();
      nextCalcRain = time + MSECS_CALC_RAIN_FALL;
   }



    /* 4 is mininum width, 2 is precision; float value is copied onto str_sensor*/

   dtostrf(UVindex1, 4 , 2, str_sensor1);
   dtostrf(nextCalcSpeed, 4, 2, str_sensor2);
   dtostrf(nextCalcDir, 4 , 2, str_sensor3);
   dtostrf(nextCalcRain, 4, 2, str_sensor4);
 
 
    /* Building the logger command */
    sprintf(command, "init#");
    sprintf(command, "%s%s/%s|%s|%s|", command, USER_AGENT, VERSION, METHOD, TOKEN);
    sprintf(command, "%s%s=>", command, DEVICE_LABEL);
    sprintf(command, "%s%s:%s", command, VARIABLE_LABEL, str_sensor1);
    sprintf(command, "%s,\"%s\":%s", command, VARIABLE_LABEL2, str_sensor2);
    sprintf(command, "%s,\"%s\":%s", command, VARIABLE_LABEL3, str_sensor3);
    sprintf(command, "%s,\"%s\":%s", command, VARIABLE_LABEL4, str_sensor4);
    sprintf(command, "%s|end#final", command);


    /* Prints the command sent */
    Serial.println(command);// uncomment this line to print the command


    /* Sends the command to the telemetry unit */
    serial1.print(command);

    /* free memory*/
    free(command);

    /* Change the status of the flag to false. Once the data is sent, the status
       of the flag will change to true again */
    flow_control = false;
  }

  /* Reading the telemetry unit */
  int i = 0;
  while (serial1.available() > 0) {
    telemetry_unit[i++] = (char)serial1.read();
    /* Change the status of the flag; allows the next command to be built */
    flow_control = true;
  }

  if (flow_control) {
    /* Print the server response -> OK */
    Serial.write(telemetry_unit);
    /* free memory */
    memset(telemetry_unit, 0, i);
  }

  delay(2000);
}
//=======================================================
// Interrupt handler for anemometer. Called each time the reed
// switch triggers (one revolution).
//=======================================================
void countAnemometer() {
   numRevsAnemometer++;
}

//=======================================================
// Interrupt handler for rain gauge. Called each time the reed
// switch triggers (one drop).
//=======================================================
void countRainGauge() {
   numDropsRainGauge++;
}


//=======================================================
// Find vane direction.
//=======================================================
void calcWindDir() {
   int val;
   byte x, reading;

   val = analogRead(PIN_VANE);
   val >>=2;                        // Shift to 255 range
   reading = val;

   // Look the reading up in directions table. Find the first value
   // that's >= to what we got.
   for (x=0; x<NUMDIRS; x++) {
      if (adc[x] >= reading)
         break;
   }
   //Serial.println(reading, DEC);
   x = (x + dirOffset) % 8;   // Adjust for orientation
   Serial.print("  Dir: ");
   Serial.println(strVals[x]);
 
}


//=======================================================
// Calculate the wind speed, and display it (or log it, whatever).
// 1 rev/sec = 1.492 mph = 2.40114125 kph
//=======================================================
void calcWindSpeed() {
   int x, iSpeed;
   // This will produce kph * 10
   // (didn't calc right when done as one statement)
   long speed = 24011;
   speed *= numRevsAnemometer;
   speed /= MSECS_CALC_WIND_SPEED;
   iSpeed = speed;         // Need this for formatting below

   Serial.print("Wind speed: ");
   x = iSpeed / 10;
   Serial.print(x);
   Serial.print('.');
   x = iSpeed % 10;
   Serial.print(x);

   numRevsAnemometer = 0;        // Reset counter
   
}

//=======================================================
// Calculate the rain , and display it (or log it, whatever).
// 1 bucket = 0.2794 mm
//=======================================================
void calcRainFall() {
   int x, iVol;
   // This will produce mm * 10000
   // (didn't calc right when done as one statement)
   long vol = 2794; // 0.2794 mm
   vol *= numDropsRainGauge;
   vol /= MSECS_CALC_RAIN_FALL;
   iVol = vol;         // Need this for formatting below

   Serial.print("Rain fall: ");
   x = iVol / 10000;
   Serial.print(x);
   Serial.print('.');
   x = iVol % 10000;
   Serial.print(x);
   Serial.println();
   
   numDropsRainGauge = 0;        // Reset counter
  
}

#2

Greetings, you have two variables with blank spaces, these characters are not allowed to be posted as API Label so please change them by a middle script, ‘-’.

All the best


#3

Thank you!

That was not the issue, however, I did manage to solve the problem.

Is it possible to post characters to ubidots?
I am trying to post wind directions (eg - N, W, S, E etc.) but I am having no luck achieving this.

Your assistance would be appreciated!

Regards,
Kanushka


#4

Greetings, you should use the variable’s context. You can reference an example here.

All the best


#5

I have tried this but I cannot seem to get it right.

Could you perhaps write a piece of code that is relevant to what I need? I am still using the code above.

Thank you!!


#6

You can reference an example below

 * This example sends hard-coded data to Ubidots for users with devices
 * based on ESP8266 chips
 *
 * This example is given AS-IS with no guarantee
 *
 * Made by Jose García, HTTPS://github.com/jotathebest
 * adapted from the original WiFiClient ESP8266 example
 *************************************************************************************************/



/********************************
 * Libraries included
 *******************************/

#include <ESP8266WiFi.h>

/********************************
 * Constants and objects
 *******************************/
char const * SSID_NAME = "..."; // Put your SSID name here
char const * SSID_PASS = "...."; // Put your password here

char* TOKEN = ""; // Put your TOKEN here

char* DEVICE_LABEL = "truck"; // Your Device label

/* Put your variable labels here */
char const * VARIABLE_LABEL_1 = "position";

/* HTTP Settings */
char const * HTTPSERVER = "industrial.api.ubidots.com";
const int HTTPPORT = 80;
char const * USER_AGENT = "ESP8266";
char const * VERSION = "1.0";

WiFiClient clientUbi;

/********************************
 * Auxiliar Functions
 *******************************/

void SendToUbidots(char* payload) {

  int contentLength = strlen(payload);

  /* Connecting the client */
  clientUbi.connect(HTTPSERVER, HTTPPORT);

  if (clientUbi.connected()) {
    /* Builds the POST request - For all request structures, refer to https://ubidots.com/docs/api/ */
    clientUbi.print(F("POST /api/v1.6/devices/"));
    clientUbi.print(DEVICE_LABEL);
    clientUbi.print(F(" HTTP/1.1\r\n"));
    clientUbi.print(F("Host: "));
    clientUbi.print(HTTPSERVER);
    clientUbi.print(F("\r\n"));
    clientUbi.print(F("User-Agent: "));
    clientUbi.print(USER_AGENT);
    clientUbi.print(F("/"));
    clientUbi.print(VERSION);
    clientUbi.print(F("\r\n"));
    clientUbi.print(F("X-Auth-Token: "));
    clientUbi.print(TOKEN);
    clientUbi.print(F("\r\n"));
    clientUbi.print(F("Connection: close\r\n"));
    clientUbi.print(F("Content-Type: application/json\r\n"));
    clientUbi.print(F("Content-Length: "));
    clientUbi.print(contentLength);
    clientUbi.print(F("\r\n\r\n"));
    clientUbi.print(payload);
    clientUbi.print(F("\r\n"));

    Serial.println(F("Making request to Ubidots:\n"));
    Serial.print("POST /api/v1.6/devices/");
    Serial.print(DEVICE_LABEL);
    Serial.print(" HTTP/1.1\r\n");
    Serial.print("Host: ");
    Serial.print(HTTPSERVER);
    Serial.print("\r\n");
    Serial.print("User-Agent: ");
    Serial.print(USER_AGENT);
    Serial.print("/");
    Serial.print(VERSION);
    Serial.print("\r\n");
    Serial.print("X-Auth-Token: ");
    Serial.print(TOKEN);
    Serial.print("\r\n");
    Serial.print("Connection: close\r\n");
    Serial.print("Content-Type: application/json\r\n");
    Serial.print("Content-Length: ");
    Serial.print(contentLength);
    Serial.print("\r\n\r\n");
    Serial.print(payload);
    Serial.print("\r\n");
  } else {
    Serial.println("Connection Failed ubidots - Try Again");
  }

  /* Reach timeout when the server is unavailable */
  int timeout = 0;
  while (!clientUbi.available() && timeout < 5000) {
    timeout++;
    delay(1);
    if (timeout >= 5000) {
      Serial.println(F("Error, max timeout reached"));
      break;
    }
  }

  /* Reads the response from the server */
  Serial.println(F("\nUbidots' Server response:\n"));
  while (clientUbi.available()) {
    char c = clientUbi.read();
    Serial.print(c); // Uncomment this line to visualize the response on the Serial Monitor
  }

  /* Disconnecting the client */
  clientUbi.stop();
}

/********************************
 * Main Functions
 *******************************/

void setup() {
  Serial.begin(115200);
  /* Connects to AP */
  WiFi.begin(SSID_NAME, SSID_PASS);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    }

  WiFi.setAutoReconnect(true);
  Serial.println(F("WiFi connected"));
  Serial.println(F("IP address: "));
  Serial.println(WiFi.localIP());

  if (clientUbi.connect(HTTPSERVER, HTTPPORT)) {
    Serial.println("connected to Ubidots cloud");
  } else {
    Serial.println("could not connect to Ubidots cloud");
  }

}

void loop() {

  // Space to store values to send
  char payload[200];
  char str_val_1[30];
  char str_lat[30];
  char str_lng[30];

  /*---- Simulates sensors values -----*/
  float sensor_value_1 = random(0, 1000)*1.0;
  float lat = -6.256;
  float lng = 75.236;

  /*---- Transforms sensor values to char type -----*/

  /* 4 is mininum width, 2 is precision; float value is copied onto str_val*/
  dtostrf(sensor_value_1, 4, 2, str_val_1);
  dtostrf(lat, 4, 2, str_lat);
  dtostrf(lng, 4, 2, str_lng);

  /* IMPORTANT : Avoid sending a very long char as it take up a lot of memory. Send small char arrays instead */
  sprintf(payload, "{\"");
  sprintf(payload, "%s%s\":{\"value\":%s", payload, VARIABLE_LABEL_1, str_val_1);
  sprintf(payload, "%s,\"context\":{\"lat\":%s, \"lng\":%s}}", payload, str_lat, str_lng);
  sprintf(payload, "%s}", payload);

  /* Calls the Ubidots POST function */
  SendToUbidots(payload);

  delay(5000);

}

All the best