147
edits
Line 62: | Line 62: | ||
=== Programming === | === Programming === | ||
Code | Code:<syntaxhighlight lang="arduino"> | ||
/* | |||
Project: The Plant Plant - The Air Between Us | |||
Intergration 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 15 // Group01 pin GPIO15 | |||
#define DHT22_PIN2 0 // Group02 pin GPIO0 | |||
#define DHT22_PIN3 4 // Group03 pin GPIO4 | |||
//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 Channe's number | |||
unsigned long ChannelNumber2 = XXXXXXX; //Insert 2nd Thingspeak Channe'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 "meng-yun.tsai@uni-weimar.de" //anonymous@example.com, or you can use also nickname@example.com | |||
#define EAP_IDENTITY "daro6502" //nickname@example.com,at some organizations should work nickname only without realm, but it is not recommended | |||
#define EAP_PASSWORD "Tuniman86704_Y" //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 you don't know your 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 letters from Ascii code | |||
int charCount = 0; | |||
/* Function: Scrolling Texts */ | |||
// The function acepts 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 Intergration */ | |||
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 Display | |||
// 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++; // a ccumulated 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 display 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 | |||
// LCD Display | |||
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); | |||
} | |||
</syntaxhighlight> | |||
== Winterwerkschau (Exhibition) == | == Winterwerkschau (Exhibition) == |
edits