In this project, you will be able to display the temperature, humidity of soil and air, luminosity and spectral quality from a dashboard.
Things used in this project
Hardware components
ST STM32L4, STM32F7 Nucleo 144 STM32F7 ×1
DHT22 Temperature Sensor ×1
DFRobot Gravity: TCS34725 RGB Color Sensor For Arduino ×1
DFRobot Gravity: Analog Soil Moisture Sensor For Arduino ×1
Adafruit Waterproof DS18B20 Digital temperature sensor ×1
Li-Ion Battery 100mAh ×1
Solar Panel, 2.5 W ×1
Hand tools and fabrication machines
on line mbed compiler
kicad: shematic editor and pcb layout
SigFox
Ubidots
Story
Firmware
We want the values captured by our sensors to be displayed in a dashboard with an interval of about 10 minutes.
Sensors code :
We have 4 sensors :
DS18B20 used to measure soil temperature
used library : DS1820
Gravity SEN0193 used to measure soil moisture
No library needed
click on this tutorial to calibrate the sensor
DHT22 used to measure air humidity and air temperature
used library : DHT
TCS34725 used to measure light spectrum and brightness
Sending to Sigfox
We are sending 12 bytes every 10 minutes. With these sensors, 12 bytes are enough to send all values at the same time :
brightness = 3 bytes
light spectrum = 1 byte per primary color (RGB)
temperature = 2 bytes for air temperature and 2 bytes for soil temperature
humidity = 1 byte for air humidity and 1 byte for soil humidity
In the Sigfox backend, we can see our values but as you can see it’s not very readable. That’s why we will have to do a callback to a dashboard.
Callback to Ubidots
Now we will configure a callback to receive the rights values in our dashboard (here we choose ubidots because it’s very simple to configure)
The custom payload config is directly dependant on how we send values to Sigfox :
luminosite::uint:24 red::uint:8 green::uint:8 blue::uint:8 tempSol::uint:16 humSol::uint:8 tempAir::uint:16 humAir::uint:8
This means our first 24 bits are dedicated to the brightness, the next 8 bits are for the red value etc...
Lower consumption
Now, we want lower the consumption to make it more autonomous in terms of energy supply. As we use our microcontroller only one time per 10 minutes, we can use the deep sleep mode for 90% of the time ! For that, we use the WakeUp library.
Custom parts and enclosures
Kicad projet Download
You will find. The main circuit and the alimentation circuit. With these pcb layout
Code
AgrotechC/C++
#include "mbed.h"
#include "DS1820.h"
#include "DHT.h"
#include "TSL2561_I2C.h"
#include "Adafruit_TCS34725.h"
#include "WakeUp.h"
Serial wisol(D1, D0); // tx, rx
//debug
Serial pc(USBTX, USBRX);
//tempAir et humAir
DHT dht(D9, 22);
//RGB + luminosite
I2C i2c(PB_7, PB_6);
Adafruit_TCS34725 tcs = Adafruit_TCS34725(&i2c, TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);
//tempSol
DS1820 temp_sol(A4);
//humSol
AnalogIn ain(A3);
int main(){
//WakeUp::calibrate();
//DHT22
int data;
float tempAir, humAir;
//humiditeSol
int hum_sol;
//luminosite
float lux;
//temp_sol
if(temp_sol.unassignedProbe(A4))
{
pc.printf("error temperature_sol");
}
//capteur RGB/luminosite
if(!tcs.begin())
{
pc.printf("No TCS34725 found ... check your connections");
}
while(1){
//Capteur air
data = dht.readData();
humAir = dht.ReadHumidity();
tempAir = dht.ReadTemperature(CELCIUS);
pc.printf("tempAir = %1.f, humAir = %1.f\n", tempAir, humAir);
//capteur humidite sol
hum_sol = (int)(((0.78 - ain.read())*100)/0.38);
pc.printf ("humSol = %d%\n", hum_sol);
//Capteur temperature sol
temp_sol.convertTemperature(true, DS1820::all_devices);
pc.printf("tempSol : %.1f\n", temp_sol.temperature());
///////////////
//////RGB//////
///////////////
uint16_t clear, red, green, blue;
tcs.setInterrupt(false); // turn on LED
tcs.getRawData(&red, &green, &blue, &clear);
tcs.setInterrupt(true); // turn off LED
//pc.printf("clear = %d, red = %d, green = %d, blue = %d\r\n", clear, red, green, blue);
//get hexa value
uint32_t sum = clear;
float r, g, b;
r = red; r /= sum;
g = green; g /= sum;
b = blue; b /= sum;
r *= 256; g *= 256; b *= 256;
pc.printf("clear = %d, red = %d, green = %d, blue = %d\r\n\n", clear, (int)r, (int)g, (int)b);
//luminosite
lux = (int)tcs.calculateLux(red,green,blue);
pc.printf("lux = %d\n", (int)lux);
wisol.printf("AT$SF=%06X%02X%02X%02X%04X%02X%04X%02X\r\n", (int)lux, (int)r, (int)g, (int)b, (int)(10 * temp_sol.temperature()), (int)(hum_sol), (int)(10 * tempAir), (int)(humAir));
//lux : 3 octets
//r, g, b : 1 octet
//tempSol, tempAir : 2 octets
//humSol, humAir : 1 octet
wait(10);
//Set wakeup time for 600 seconds = 10min
WakeUp::set_ms(600000);
deepsleep();
wait(1);
}
}