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
}