Line 93: | Line 93: | ||
/* Set up: DHT22 */ | /* Set up: DHT22 */ | ||
#define DHTTYPE DHT22 // sensor version, we are using DHT22 | #define DHTTYPE DHT22 // sensor version, we are using DHT22 | ||
#define DHT22_PIN1 | #define DHT22_PIN1 4 // Group01 pin GPIO4 | ||
#define DHT22_PIN2 | #define DHT22_PIN2 15 // Group02 pin GPIO15 | ||
#define DHT22_PIN3 | #define DHT22_PIN3 0 // Group03 pin GPIO0 | ||
//Create sensors called "dht..." | //Create sensors called "dht..." | ||
DHT_Unified dht01(DHT22_PIN1, DHTTYPE); | DHT_Unified dht01(DHT22_PIN1, DHTTYPE); |
Revision as of 11:28, 4 February 2025
Project : The Air Between Us
Inspiration
-
Initial Idea
Project Concept
-
Brainstorming
Sketches
Moodboard
Preparation ( 2 Isolated Plant Systems)
MS Media
Agar-agar cultivation describe blah blah...
(Flowers - Plastic Bag - without sugar
Sundew - Glass Jar - with sugar)
Recipe:
1 Liter Water:
Murashige 4.5 g
Gelrite 5 g
D(+) Saccharose 20 g (sugar)
Sterilizing & Transplanting
-
Video:
Images/291123 cleaningHelleborus.mov
Images/051224 observe Helleborus.mov
Plants Observation
-
Prototype
Installation
-
Electronics / Circuits
-
Programming
Code:
/*
Project: The Plant Plant - The Air Between Us
Integration and Conversation between 2 isolated plant systems
By using Microcontroller, sensors and IoT platform (cloud)
--
Board: ESP32 Development Board
Component: MQ-2 Gas Sensor
DHT22 Temperature & Humidity Sensor
Alphanumerisches LCD 16x2, blau
--
Note: After the MQ-2 sensor is powered on, it needs to be preheated for
at least 3 minute before stable measurement readings can be obtained.
It is normal for the sensor to generate heat during operation due to
the presence of a heating wire inside.
*/
//add libraries
#include <Arduino.h>
#include <Adafruit_Sensor.h> // for DHT22
#include <DHT.h>
#include <DHT_U.h>
#include <WiFi.h> // for connecting Wifi
#include "esp_wpa2.h" //wpa2 library for connections to Enterprise networks
#include <ThingSpeak.h> // for publishing Sensor Readings to Thingspeak
#include <Wire.h> // for getting the LCD Address
#include <LiquidCrystal_I2C.h> // for LCD
/* Set up: DHT22 */
#define DHTTYPE DHT22 // sensor version, we are using DHT22
#define DHT22_PIN1 4 // Group01 pin GPIO4
#define DHT22_PIN2 15 // Group02 pin GPIO15
#define DHT22_PIN3 0 // Group03 pin GPIO0
//Create sensors called "dht..."
DHT_Unified dht01(DHT22_PIN1, DHTTYPE);
DHT_Unified dht02(DHT22_PIN2, DHTTYPE);
DHT_Unified dht03(DHT22_PIN3, DHTTYPE);
int delayMS = 1500; // add delay after each reading
/* Set up: MQ2 */
// Define the pin numbers for the Gas Sensor
#define MQ2_PIN1 34 // Group01 pin GPIO34
#define MQ2_PIN2 35 // Group02 pin GPIO35
#define MQ2_PIN3 32 // Group03 pin GPIO32
/* Set up: Thingspeak */
// due to the privacy of the account, won't show the real numbers
unsigned long ChannelNumber1 = XXXXXXX; //Insert Thingspeak Channel's number
unsigned long ChannelNumber2 = XXXXXXX; //Insert 2nd Thingspeak Channel's number
const char *WriteAPIkey1="XXXXXXXXXXXXXXXX"; // Thingspeak Official Channel API Key
const char *WriteAPIkey2="XXXXXXXXXXXXXXXX"; // 2nd Thingspeak Official Channel API Key
/* Set up: Eduroam Wifi */
WiFiClient client;
byte mac[6];
const char* host = "arduino.clanweb.eu"; //webserver test
String url = "/eduroam/data.php"; //URL to target PHP file test
#define EAP_ANONYMOUS_IDENTITY "XXXXXX@uni-weimar.de" //anonymous@example.com, or you can use also nickname@example.com
#define EAP_IDENTITY "XXXXXX" //nickname@example.com,at some organizations should work nickname only without realm, but it is not recommended
#define EAP_PASSWORD "XXXXXX" //password for eduroam account
//SSID NAME
const char* ssid = "eduroam"; // eduroam SSID
/* Set up: LCD */
// set the LCD number of columns and rows
int lcdColumns = 16;
int lcdRows = 2;
// set LCD address, number of columns and rows
// if don't know the display address, run an I2C scanner sketch
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);
// set up display texts
String messageStatic = "Our Dialogue";
String messageScrolling;
// A string variable used to store accumulated ASCII conversations
String dialogue = "";
// for counting characters from ASCII codes
int charCount = 0;
/* Function: Scrolling Texts */
// The function accepts the following arguments:
// row: row number where the text will be displayed
// message: message to scroll
// delayTime: delay between each character shifting
// lcdColumns: number of columns of your LCD
void scrollingText(int row, String message, int delayTime, int lcdColumns) {
for (int i=0; i < lcdColumns; i++) {
message = " " + message;
}
message = message + " ";
for (int pos = 0; pos < message.length(); pos++) {
lcd.setCursor(0, row);
lcd.print(message.substring(pos, pos + lcdColumns));
delay(delayTime);
}
}
/* Functions: Group01 Flowers */
void Group01(){
// Delay between measurements
delay(delayMS);
//Reading DHT22
// Get access to sensor event through custom sensor event type
sensors_event_t event;
// get temperature event (by reference, not by copy) and print its value.
// "event" is - after this - filled with information from the sensor.
dht01.temperature().getEvent(&event);
if (isnan(event.temperature))
{
Serial.println(F("Error reading temperature!"));
}
else
{
Serial.print(F("G1 Temperature: "));
Serial.print(event.temperature);
Serial.println(F("°C"));
ThingSpeak.setField(2, event.temperature); // write to Thingspeak Channel Field 2
}
// get humidity event (by reference, not by copy) and print its value.
// "event" is - after this - filled with information from the sensor.
dht01.humidity().getEvent(&event);
if (isnan(event.relative_humidity))
{
Serial.println(F("Error reading humidity!"));
}
else
{
Serial.print(F("G1 Humidity: "));
Serial.print(event.relative_humidity);
Serial.println(F("%"));
ThingSpeak.setField(3, event.relative_humidity); // write to Thingspeak Channel Field 3
}
//Reading MQ2
int mq2g1V = analogRead(MQ2_PIN1);
Serial.print("G1 MQ2 Analog output: ");
Serial.println(mq2g1V);
Serial.println(" ------------------ ");
delay(1000);
ThingSpeak.setField(1, mq2g1V); // write to Thingspeak Channel Field 1
}
/* Functions: Group02 Sundew */
void Group02(){
delay(delayMS);
//Reading DHT22
sensors_event_t event;
dht02.temperature().getEvent(&event);
if (isnan(event.temperature))
{
Serial.println(F("Error reading temperature!"));
}
else
{
Serial.print(F("G2 Temperature: "));
Serial.print(event.temperature);
Serial.println(F("°C"));
ThingSpeak.setField(5, event.temperature); // write to Thingspeak Channel Field 5
}
dht02.humidity().getEvent(&event);
if (isnan(event.relative_humidity))
{
Serial.println(F("Error reading humidity!"));
}
else
{
Serial.print(F("G2 Humidity: "));
Serial.print(event.relative_humidity);
Serial.println(F("%"));
ThingSpeak.setField(6, event.relative_humidity); // write to Thingspeak Channel Field 6
}
//Reading MQ2
int mq2g2V = analogRead(MQ2_PIN2);
Serial.print("G2 MQ2 Analog output: ");
Serial.println(mq2g2V);
Serial.println(" ------------------ ");
delay(1000);
ThingSpeak.setField(4, mq2g2V); // write to Thingspeak Channel Field 4
}
/* Functions: Group03 Integration */
void Group03(){
delay(delayMS);
//Reading DHT22
sensors_event_t event;
dht03.temperature().getEvent(&event);
if (isnan(event.temperature))
{
Serial.println(F("Error reading temperature!"));
}
else
{
Serial.print(F("G3 Temperature: "));
Serial.print(event.temperature);
Serial.println(F("°C"));
ThingSpeak.setField(7, event.temperature); // write to Thingspeak Channel Field 7
}
dht03.humidity().getEvent(&event);
if (isnan(event.relative_humidity))
{
Serial.println(F("Error reading humidity!"));
}
else
{
Serial.print(F("G3 Humidity: "));
Serial.print(event.relative_humidity);
Serial.println(F("%"));
Serial.println(" ------------------ ");
ThingSpeak.setField(8, event.relative_humidity); // write to Thingspeak Channel Field 8
}
}
void Group03_MQ2(){
//Reading MQ2
int mq2g3V = analogRead(MQ2_PIN3);
Serial.print("G3 MQ2 Analog output: ");
Serial.println(mq2g3V);
delay(500);
ThingSpeak.writeField(ChannelNumber2, 1, mq2g3V, WriteAPIkey2);
// LCD messages
// convert MQ-2's value to ASCII code
int ascii_value = map(mq2g3V, 1000, 2500, 34, 126);
char ascii_char = (char)ascii_value;
// a new character is added to the string (the previous one is kept)
dialogue += ascii_char ;
charCount++; // accumulated character count +1
// Try using spaces to create a variation in sentence length for a more natural dialogue effect.
// when the accumulated character count exceeds 7, insert a space randomly
if (charCount > 7) {
// if the count exceeds 15, force to insert a space
if (random(0, 2) == 1 || charCount >= 15) {
dialogue += " ";
charCount = 0; // after inserting a space, reset the count
}
}
// if the string length exceeds the LCD limit (32 characters)
if (dialogue.length() > 32) {
dialogue = dialogue.substring(1); // remove the oldest character
}
// print scrolling message
lcd.setCursor(0, 1);
messageScrolling = dialogue.substring(0, 16);
scrollingText(1, messageScrolling, 350, lcdColumns);
}
void setup()
{
// initialize serial communication
Serial.begin(9600);
// connect or reconnect to wifi
WiFi.disconnect(true); //disconnect from WiFi to set new WiFi connection
WiFi.mode(WIFI_STA); //init wifi mode
// start wifi connection with eduroam
// WITHOUT CERTIFICATE - WORKING WITH EXCEPTION ON RADIUS SERVER
WiFi.begin(ssid, WPA2_AUTH_PEAP, EAP_ANONYMOUS_IDENTITY, EAP_IDENTITY, EAP_PASSWORD);
// check if wifi connected
// continue after while loop finished
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(F("."));
}
Serial.println("");
Serial.println(F("WiFi is connected!"));
Serial.println(" ");
// initialize DHT22
dht01.begin();
dht02.begin();
dht03.begin();
// initialize ThingSpeak
ThingSpeak.begin(client);
// initialize LCD
lcd.init();
// turn on LCD backlight
lcd.backlight();
}
void loop()
{
yield(); // buffer ESP - stuff
// show LCD
lcd.clear();
// set cursor to position (column and row)
lcd.setCursor(2, 0);
// print static message
lcd.print(messageStatic);
// Execute functions of 3 groups
Group03_MQ2();
Group03();
delay(delayMS);
Group01();
delay(delayMS);
Group02();
delay(delayMS);
// Write to ThingSpeak.
int x = ThingSpeak.writeFields(ChannelNumber1, WriteAPIkey1);
if(x == 200){
Serial.println("Channel update successful.");
}else{
Serial.println("Problem updating channel. HTTP error code " + String(x));
}
delay(15000);
}
Data Visualization
ThingSpeak Screenshots
-
Winterwerkschau (Exhibition)
-photos-
Technical Riders
-
References
ESP32 with DHT22 Temperature and Humidity Sensor
https://randomnerdtutorials.com/esp32-dht11-dht22-temperature-humidity-sensor-arduino-ide/
ESP32 with MQ-2 Gas Sensor
https://docs.sunfounder.com/projects/umsk/en/latest/03_esp32/esp32_lesson04_mq2.html
ESP32 Publish Sensor Readings to ThingSpeak (Wi-Fi)
https://randomnerdtutorials.com/esp32-thingspeak-publish-arduino/#multiple
ESP32 with I2C LCD (Liquid Crystal Display)
https://randomnerdtutorials.com/esp32-esp8266-i2c-lcd-arduino-ide/
https://zhillan-arf.medium.com/getting-lcd-displays-to-work-with-esp32-e7fe8016bffd