Measuring climatological variables is one of the best projects to start creating IoT integrations. It is fun to know the temperature and humidity status in real time with more precision than the weather services, and its data could be quite useful for other projects.
So with this project, our purpose is to create a simple meteorological station easier than ever thanks to the ClimaStick V2board, that integrates built-in sensors for Temperature, Humidity, Barometric pressure, and luminosity.
On another hand, we have used the OpenWeatherMapAPI to retrieve wind speed and direction, cloud coverage and weather prevision for our zone, so that we will be able to register all environmental variables with just one device. All this data will be sent to Thinger.io platform, allowing to store, visualize and share data with fully a customized dashboard.
How Does it Work?The device retrieves data from sensors and OpenWeatherMap service and sends it all to Thinger.io server using WiFi communication.
The ClimaStick V2This board is a complete Internet of Things development kit, that integrates Wi-Fi connectivity, and a set of powerful sensors to provide environmental and motion sensing measurements.
This board integrates a CP2102 serial port to USB interface, that allows reprogramming the processor with Arduino IDE, using just a micro USB wire. It counts with the next list of sensors, that have been integrated into only one library, so it is quite easy to start reading data and send it to the server, with just a couple code lines:
- BMP280: Temperature, Humidity and Barometric pressure
- TSL2561: Luminosity
- MPU9250: 9 DOF accelerometer, gyroscope and magnetometer
And that's not all! One of the best things of this board is that it integrates a Li-po battery manager and an external Vinport, so it is possible to connect a solar panel and a battery, creating an autonomous power system.
Components AssemblingFor this project we are going to use a little3D printed house, that will protect the board from water and direct sunlight. The assembling process just consists in connecting the solar panel, the battery and optional, the external antenna to increase WiFi gain.
We are using a 0.5 Wats5V solar panel, that provides 100mAh at full power, and a 1000mAh battery which will be enough to supply power to the ClimaStick indefinitely if the processor is normally sleeping and only wakes up to register data every five or ten minutes.
The only problem is, that the weather station should be placed in the shadow, if we place it with direct sunlight, the temperature read increases and it wont be reliable. In this condition, the solar panel will not throw the entire current, but will be enough to charge the battery.
The assembling process is quite simple, just connecting the solar panel and battery to the ClimaStick and placing it in the house with some thermoplastic glue, the hardware is complete.
Thanks to Thinger.ioclient and the climaStick libraries, the source code is quite easy, you can check the structure in this schema:
This is the arduino code for climaStick V2:
#include <ClimaStick.h>
#include <ArduinoJson.h>
#define USERNAME "your_user_name"
#define DEVICE_ID "your_device_id"
#define DEVICE_CREDENTIAL "your_device_credential"
#define SSID "your_wifi_ssid"
#define SSID_PASSWORD "your_wifi_ssid_password"
// JSON
const char* host = "api.openweathermap.org"; // host direction
const char* privateKey = "&appid=6371f8a53d9fc0a81cf66261763035f7";// access token API
String line = ""; //String for API content
const char* json = ""; //JSON for API content
// Variables globales contenedoras para Thinger
String estadoJSON = "";
double direccionViento = 0;
double velocidadVientoJSON = 0;
double estadoNubesJSON = 0;
// Contador de tiempo
unsigned long millisActual = 0;
ClimaStick thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);
int n,t,p,today,ap;
long rssi;
Environmental clima;
void setup() {
Serial.begin(115200);
thing.add_wifi(SSID, SSID_PASSWORD);
thing.init_sensors();
clima = thing.get_clima();
pinMode(0,INPUT_PULLUP);
pinMode(13,HIGH);
thing["environment"] >> [] (pson& out){
out["temperature"]=clima.temperature;
out["humidity"]=clima.humidity;
out["pressure"]=clima.pressure;
out["lux"]=clima.lux;
out["T_cond"]=(pow((clima.humidity/100),0.125)*(float)(112+0.9*clima.temperature)+(float)(0.1*clima.temperature)-112);
out["RSSI"]=rssi;
out["estado"] = estadoJSON;
out["direccionViento"] = direccionViento;
out["velocidadViento"] = velocidadVientoJSON;
out["estadoNubes"] = estadoNubesJSON;
t++;
delay(100);
digitalWrite(13,LOW);
};
}
void loop() {
rssi = WiFi.RSSI();
thing.handle();
if(!ap) {
API();
}
if(!t){
thing.write_bucket("climaStick2", "environment");
Serial.println("sended");
delay(2000);
thing.sleep(60*5);
}
}
void API(){
ap=1;
/************** Peticion WIFI **************/
WiFiClient client; // Crea el cliente Wifi
const int httpPort = 80; // Puerto a utilizar
if (!client.connect(host, httpPort)) { // Comprueba si es capaz de conectarse con el host (la API)
Serial.println("connection failed");
Serial.println("");
return;
}
String url = "/data/2.5/weather?"; // Creamos la peticion a realizar a la API
String localizacion = "q=Galapagar,es";
String unidades = "&units=metric";
String idioma = "&lang=en";
url += localizacion;
url += unidades;
url += idioma;
url += privateKey;
// Enviar peticion
client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
/*Creating connection*/
unsigned long timeout = millis(); // Contamos el tiempo de la peticion
while (client.available() == 0) { // Si pasan mas de 5seg y no responde
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
Serial.println("");
client.stop();
return;
}
}
//Serial.println(host+url); // Imprime la peticion
millisActual = millis(); // actualizo el tiempo actual
boolean encontrado = true;
String aux = "";
while(client.available() || encontrado){ // Cuando el cliente termina
aux = client.readStringUntil('\r'); // Guardo el contenido hasta el salto de linea
for(int i = 0; i < 20; i++){ // Buscamos el comienzo de la respuesta
char caracter = aux.charAt(i);
if(caracter == '{'){
line = aux;
encontrado = false;
break;
}
}
}
Serial.print("Obtenemos la siguiente respuesta: ");
Serial.println(line);
//Serial.println("----------------------- Parseamos a JSON ----------------");
DynamicJsonBuffer jsonBuffer; // Creo un buffer de JSON
JsonObject& root = jsonBuffer.parseObject(line); // Creo el objeto raiz del JSON.
if (!root.success()){ // Si se produce error al parsear
Serial.print("error al parsear el json");
Serial.println("");
return;
}
// Almacenamos en las variables globales los resultados de la peticion
String estado = root["weather"][0]["main"];
estadoJSON = estado;
direccionViento= root["wind"]["deg"];
velocidadVientoJSON = root["wind"]["speed"];
estadoNubesJSON = root["clouds"]["all"];
}
Integration with Thinger.io PlatformNow it is time to open our platform web console and configurate the device. Using the device API explorer we can check all the resources that the device is sending and its values. We have created a data bucket to store all the information every five minutes
Then, it is possible to create a dashboard to show all data using time series and donut charts that will retrieve data from the buckets.
You can have access to this dashboard, on real time, following the next link: DASHBOARD
Credits
Comments