Im am attempting to download temperature from an OpenWeather station then upload the temperature to Thingspeak. I have created three functions (1) openWeather that creates json buffer and parses data and (2) passTemp which creates pass by reference function for temperature and (3) thingSpeak that uploads the temperature. I am having problems passing the temp data by reference from the openWeather function to the thingsSpeak function. The openWeather function parses and prints the temp data correctly. When I try and call the passTemp function and pass the temp data to thingsSpeak I receive compiler area in thingSpeak function 'root not declared in this scope'. I have spent considerable time finding and trying different json and pass by reference syntax but cannot get this to work. Any suggestions would be welcome.
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
//Connection info to Internet
const char* ssid = "SSID";
const char* password = "Password";
//Connection info to Open Weather
String nameOfCity = "City, US";
String apiKey = "Apikey";
WiFiClient client;
int status = WL_IDLE_STATUS;
char server[] = "api.openweathermap.org";
void setup() {
Serial.println ("Start Void Setup");
Serial.begin(115200);
delay(10);
}
void loop() {
openWeather();
thingSpeak();
delay(1 * 60 * 10000);
}
void openWeather() {
Serial.println("\nStarting connection to server...");
// close any connection before send a new request to allow client make connection to server
client.stop();
// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println("connected to server");
client.print("GET /data/2.5/forecast?");
client.print("q=" + nameOfCity);
client.print("&appid=" + apiKey);
client.print("&cnt=3");
client.println("&units=imperial");
client.println("Host: api.openweathermap.org");
client.println("Connection: close");
client.println();
} else {
Serial.println("unable to connect");
}
delay(1000);
String line = "";
while (client.connected()) {
line = client.readStringUntil('\n');
Serial.println("parsingValues");
//create a json buffer where to store the json data
DynamicJsonBuffer jsonBuffer(4000);
JsonObject& root = jsonBuffer.parseObject(line);
if (!root.success()) {
Serial.println("parseObject() failed");
return;
}
//get the data from the json tree
String city = root["city"]["name"];
float tempNow = root["list"][0]["main"]["temp"];
Serial.println(" ");
Serial.println(city);
Serial.print ("Current temperature = ");
Serial.println(tempNow);
client.stop();
}
}
void passTemp(JsonObject& root) { //Pass temp by reference
float tempNow = root["temp"];
}
void thingSpeak() {
passTemp(root); //’root not declared in this scope’
Serial.print("City temperature: ");
Serial.println(tempNow);
}
I declared jsonObject and root as global variables and commented out the passTemp function. The problem is when they are called in thingSpeak using a ['list'][0] I get a compiler error indicated" Invalid types 'cont char[int]' for array subscript". i tried obtaining the number from the json array using other methods without the list number but just get wrong numbers that do not match the temp shown in openWeather. I tried including the passTemp function and called in thingSpeak but receive error "Invalid initialization of reference of type 'Ardunio:JasonObject' from expression of type 'char'". Not sure how to implement jsonObject and root as global variables?
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
//Connection info to Internet
const char* ssid = "SSID";
const char* password = "Password";
//Connection info to Open Weather
String nameOfCity = "City, US";
String apiKey = "Apikey";
//Declare global variables
char jsonObject;
char root;
WiFiClient client;
int status = WL_IDLE_STATUS;
char server[] = "api.openweathermap.org";
void setup() {
Serial.println ("Start Void Setup");
Serial.begin(115200);
delay(10);
}
void loop() {
openWeather();
thingSpeak();
delay(1 * 60 * 10000);
}
void openWeather() {
Serial.println("\nStarting connection to server...");
// close any connection before send a new request to allow client make connection to server
client.stop();
// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println("connected to server");
client.print("GET /data/2.5/forecast?");
client.print("q=" + nameOfCity);
client.print("&appid=" + apiKey);
client.print("&cnt=3");
client.println("&units=imperial");
client.println("Host: api.openweathermap.org");
client.println("Connection: close");
client.println();
} else {
Serial.println("unable to connect");
}
delay(1000);
String line = "";
while (client.connected()) {
line = client.readStringUntil('\n');
Serial.println("parsingValues");
//create a json buffer where to store the json data
DynamicJsonBuffer jsonBuffer(4000);
JsonObject& root = jsonBuffer.parseObject(line);
if (!root.success()) {
Serial.println("parseObject() failed");
return;
}
//get the data from the json tree
String city = root["city"]["name"];
float tempNow = root["list"][0]["main"]["temp"];
Serial.println(" ");
Serial.println(city);
Serial.print ("Current temperature = ");
Serial.println(tempNow);
client.stop();
}
}
void passTemp(JsonObject& root) { //Pass temp by reference
float tempNow = root["temp"];
}
void thingSpeak() {
//float tempNow = root["temp"]; //Produces wrong number (No passTemp function)
// float tempNow = root["base"]["stations"]["main"]["temp"]; //Produces different wrong number (No
passTemp function)
// float tempNow = root["list"][0]["main"]["temp"]; //Invalid types 'cont char[int]' for array subscript
(No passTemp function)
// passTemp(root); // Invalid initialization of reference of type 'Ardunio:JasonObject' from expression of
Serial.print("City temperature: ");
Serial.println(tempNow);
}
Thanks so much for the help bln64 and danangs. I am looking over my json parsing (I'm learning a lot about this). and seeing why mine doesn't match yours and will get this working. Its a good way to make this function. I was able to pass the json variable by creating a pointer. I added float tempNow as a global variable, then added float *PRtemp in the openWeather declaration. Within openWeather after the temp was parsed I added *PRtemp = tempNow;. Then finally called openWeather(&tempNow) in thingSpeak.
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
//Connection info to Internet
const char* ssid = "SSID";
const char* password = "Password";
//Connection info to Open Weather
String nameOfCity = "City, US";
String apiKey = "Apikey";
//Declare global variable
float tempNow = 0; //add tempNow as global
WiFiClient client;
int status = WL_IDLE_STATUS;
char server[] = "api.openweathermap.org";
void setup() {
Serial.println ("Start Void Setup");
Serial.begin(115200);
delay(10);
}
void loop() {
openWeather();
thingSpeak();
delay(1 * 60 * 10000);
}
void openWeather (float *PRtemp) { //add *PRtemp pointer to declaration
Serial.println("\nStarting connection to server...");
// close any connection before send a new request to allow client make connection to server
client.stop();
// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println("connected to server");
client.print("GET /data/2.5/forecast?");
client.print("q=" + nameOfCity);
client.print("&appid=" + apiKey);
client.print("&cnt=3");
client.println("&units=imperial");
client.println("Host: api.openweathermap.org");
client.println("Connection: close");
client.println();
} else {
Serial.println("unable to connect");
}
delay(1000);
String line = "";
while (client.connected()) {
line = client.readStringUntil('\n');
Serial.println("parsingValues");
//create a json buffer where to store the json data
DynamicJsonBuffer jsonBuffer(4000);
JsonObject& root = jsonBuffer.parseObject(line);
if (!root.success()) {
Serial.println("parseObject() failed");
return;
}
//get the data from the json tree
String city = root["city"]["name"];
float tempNow = root["list"][0]["main"]["temp"];
*PRtemp = tempNow; //Assign tempNow value to pointer
Serial.println(" ");
Serial.println(city);
Serial.print ("Current temperature = ");
Serial.println(tempNow);
client.stop();
}
}
void passTemp(JsonObject& root) { //Pass temp by reference
float tempNow = root["temp"];
}
void thingSpeak() {
openWeather(&tempNow); //call value at *PRtemp ointer and assign to tempNow
Serial.print("City temperature: ");
Serial.println(tempNow);
}