Terrarium Temperature Sensors with Arduino, Raspberry Pi, InfluxDB and Grafana
First I started with the Arduino and wrote some code to verify the sensors are working, initially using a Breadboard.
After I could read the metrics, I’ve set up InfluxDB on a Raspberry to store the data from the Arduino.
Then I extended the Sketch, so the Arduino connects to our Wifi and pushes the data via UDP to the InfluxDB.
The next step was to set up Grafana to have a nice dashboard view.
As everything was working fine, it was time to solder each DS18B20 sensor to a connector so they can easily be attached and detached if needed.
Then I soldered all the needed cables and the 4.7 KΩ resistor to the prototyping shield that is connected to the Arduino.
Afterwards I added a DHT22 Sensor directly to the shield to measure the room temperature.
Everything was now ready to be put into action.
I placed 3 sensors in the Chameleon enclosure, one in the rain forrest, and one in our smaller aquarium.
To make sure I can access the dashboard from anywhere, I configured a reverse proxy on my server that proxies requests from m1nd.io/terra to the Raspberry.
As I had a screen left, it was placed next to the terrariums. I hooked up another spare Raspberry and configured it to open the dashboard automatically in a browser.
Hardware:
- Arduino Uno Wifi Rev. 2
- Arduino Prototyping shield
- 5x DS18B20 Temperature sensors
- 1x 4.7 KΩ resistor
- 1x DHT22 Temperature / Humidity sensor
- Connectors
- Raspberry Pi (2x)
Software
- Arduino
- Sketch
- Raspberry Pi – 1
- InfluxDB
- Grafana
- Raspberry Pi – 2
- Browser
- Webserver
- Apache2 reverse proxy
Arduino Sketch:
// WIFI
#include <SPI.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h"
#include <WiFiUdp.h>
#include <DHT.h>
#include <OneWire.h>
#include <DallasTemperature.h>
WiFiUDP udp;
int status = WL_IDLE_STATUS; // the Wifi radio’s status
// Network
IPAddress dns(8, 8, 8, 8);
IPAddress influxserver(192, 168, 178, 222);
const int influxport = 8089;
unsigned int localport = 8080;
// DHT22
#define DHTPIN 2 // what pin we’re connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE);
// DS18B20
// Data wire is plugged into digital pin 3 on the Arduino
#define ONE_WIRE_BUS 3
// Setup a oneWire instance to communicate with any OneWire device
OneWire oneWire(ONE_WIRE_BUS);
// Pass oneWire reference to DallasTemperature library
DallasTemperature sensors(&oneWire);
// Addresses of DS18B20s
uint8_t sensor1[8] = { 0x28, 0xF6, 0x84, 0xDB, 0x17, 0x20, 0x06, 0xB3 };
uint8_t sensor2[8] = { 0x28, 0xCF, 0xE5, 0x22, 0x18, 0x20, 0x06, 0xA9 };
uint8_t sensor3[8] = { 0x28, 0x26, 0xCE, 0x22, 0x18, 0x20, 0x06, 0x9E };
uint8_t sensor4[8] = { 0x28, 0xDE, 0xF7, 0x0A, 0x18, 0x20, 0x06, 0x56 };
uint8_t sensor5[8] = { 0x28, 0xA5, 0x2A, 0xF5, 0x17, 0x20, 0x06, 0x30 };
void setup() {
Serial.begin(9600);
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
while (true);
}
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(WIFI_SSID);
status = WiFi.begin(WIFI_SSID, WIFI_PASS);
delay(5000); // wait 5 seconds for connection
}
Serial.println("You’re connected to the network");
WiFi.setDNS(dns);
WiFi.reconnect()
delay(10000);
dht.begin(); // Init DHT22
sensors.begin(); // Init DallasTemperature
udp.begin(localport);
}
void loop() {
delay(5000);
sensors.requestTemperatures();
// DHT22 Temperature
String dht22_tempLine;
dht22_tempLine = String("Temperature,sensor=DHT22,id=1,location=arduino value=" + String(dht.readTemperature()));
Serial.println(dht22_tempLine);
String beginpacket, printpacket, endpacket;
udp.beginPacket(influxserver, influxport);
udp.print(dht22_tempLine);
udp.endPacket();
// DHT22 Humidity
String dht22_humLine;
dht22_humLine = String("Humidity,sensor=DHT22,id=1,location=arduino value=" + String(dht.readHumidity()));
Serial.println(dht22_humLine);
udp.beginPacket(influxserver, influxport);
udp.print(dht22_humLine);
udp.endPacket();
// DS18B20 - 1
String ds18B20_1_tempLine;
float ds18B20_1_temp;
ds18B20_1_temp = getTemperature(sensor1);
if ((ds18B20_1_temp != -127) && (ds18B20_1_temp != 85)) {
ds18B20_1_tempLine = String("Temperature,sensor=DS18B20,id=2,location=Chameleon_top value=" + String(ds18B20_1_temp));
Serial.println(ds18B20_1_tempLine);
udp.beginPacket(influxserver, influxport);
udp.print(ds18B20_1_tempLine);
udp.endPacket();
}
// DS18B20 - 2
String ds18B20_2_tempLine;
float ds18B20_2_temp;
ds18B20_2_temp = getTemperature(sensor2);
if ((ds18B20_2_temp != -127) && (ds18B20_2_temp != 85)) {
ds18B20_2_tempLine = String("Temperature,sensor=DS18B20,id=3,location=Chameleon_mid value=" + String(ds18B20_2_temp));
Serial.println(ds18B20_2_tempLine);
udp.beginPacket(influxserver, influxport);
udp.print(ds18B20_2_tempLine);
udp.endPacket();
}
// DS18B20 - 3
String ds18B20_3_tempLine;
float ds18B20_3_temp;
ds18B20_3_temp = getTemperature(sensor3);
if ((ds18B20_3_temp != -127) && (ds18B20_3_temp != 85)) {
ds18B20_3_tempLine = String("Temperature,sensor=DS18B20,id=4,location=Chameleon_bot value=" + String(ds18B20_3_temp));
Serial.println(ds18B20_3_tempLine);
udp.beginPacket(influxserver, influxport);
udp.print(ds18B20_3_tempLine);
udp.endPacket();
}
// DS18B20 - 4
String ds18B20_4_tempLine;
float ds18B20_4_temp;
ds18B20_4_temp = getTemperature(sensor4);
if ((ds18B20_4_temp != -127) && (ds18B20_4_temp != 85)) {
ds18B20_4_tempLine = String("Temperature,sensor=DS18B20,id=5,location=Rainforrest value=" + String(ds18B20_4_temp));
Serial.println(ds18B20_4_tempLine);
udp.beginPacket(influxserver, influxport);
udp.print(ds18B20_4_tempLine);
udp.endPacket();
}
// DS18B20 - 5
String ds18B20_5_tempLine;
float ds18B20_5_temp;
ds18B20_5_temp = getTemperature(sensor5);
if ((ds18B20_5_temp != -127) && (ds18B20_5_temp != 85)) {
ds18B20_5_tempLine = String("Temperature,sensor=DS18B20,id=6,location=Fishtank value=" + String(ds18B20_5_temp));
Serial.println(ds18B20_5_tempLine);
udp.beginPacket(influxserver, influxport);
udp.print(ds18B20_5_tempLine);
udp.endPacket();
}
}
float getTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
return tempC;
}