Greenhouse Climate Observation Module

Dependencies:   BSP_DISCO_F746NG DHT

Committer:
chri721u
Date:
Wed Feb 05 13:56:12 2020 +0000
Revision:
8:03ba8074d634
Parent:
7:585a66ea498b
Greenhouse Climate Observation Module; Final version 05/02/2020

Who changed what in which revision?

UserRevisionLine numberNew contents of line
chri721u 0:a5831f680465 1 /*
chri721u 0:a5831f680465 2 Developer: Christian Andresen
chri721u 0:a5831f680465 3
chri721u 0:a5831f680465 4 Project name: Project Greenhouse
chri721u 0:a5831f680465 5
chri721u 0:a5831f680465 6 Brief description:
chri721u 0:a5831f680465 7 Microcontroller observing the climate within a greenhouse, and displaying warnings/information as needed.
chri721u 3:c21057907d21 8 Sensors monitor temperature and humidity.
chri721u 3:c21057907d21 9 To simulate an actual greenhouse, LEDs will be used in place of actual enviromental influences.
chri721u 3:c21057907d21 10 Simulator mode has been added for debugging and presentation purposes.
chri721u 0:a5831f680465 11 */
chri721u 0:a5831f680465 12
chri721u 0:a5831f680465 13 #include "mbed.h" // Mbed header from mbed-os version 5
chri721u 0:a5831f680465 14 #include "stm32746g_discovery_lcd.h" // Last updated 27/11/2019
chri721u 0:a5831f680465 15 #include "DHT.h" // Author: Wim De Roeve
chri721u 3:c21057907d21 16 #include <iostream>
chri721u 0:a5831f680465 17 #include "bootup.h" // Author: Christian Andresen
chri721u 0:a5831f680465 18
chri721u 0:a5831f680465 19 // Call Bootup class from bootup.h as LCD_Start
chri721u 0:a5831f680465 20 bootup LCD_Start;
chri721u 0:a5831f680465 21
chri721u 2:739ba85b7a90 22 /* Inputs */
chri721u 3:c21057907d21 23 AnalogIn Temp_Sensor(A0);
chri721u 3:c21057907d21 24 DHT Humid_Sensor(A1, DHT22);
chri721u 3:c21057907d21 25 InterruptIn simbutton(D2);
chri721u 2:739ba85b7a90 26
chri721u 2:739ba85b7a90 27 /* Outputs */
chri721u 3:c21057907d21 28 DigitalOut Temp_LED(D3); // Red LED
chri721u 3:c21057907d21 29 DigitalOut Humid_LED(D4); // Blue LED
chri721u 4:accd2aab9abf 30 DigitalOut Heat_LED(D5); // Red LED
chri721u 3:c21057907d21 31 DigitalOut Water_LED(D6); // Blue LED
chri721u 2:739ba85b7a90 32
chri721u 2:739ba85b7a90 33 /* Multithreads */
chri721u 2:739ba85b7a90 34 Thread tTimeCounter;
chri721u 3:c21057907d21 35 Thread tLocation_Select;
chri721u 3:c21057907d21 36 Thread tTemp;
chri721u 3:c21057907d21 37 Thread tHumid;
chri721u 3:c21057907d21 38 Thread tTemp_Check;
chri721u 3:c21057907d21 39 Thread tHumid_Check;
chri721u 3:c21057907d21 40
chri721u 3:c21057907d21 41 /* SIMULATION MODE */
chri721u 3:c21057907d21 42 bool simmode = 1;
chri721u 3:c21057907d21 43 void Sim_Toggle();
chri721u 3:c21057907d21 44
chri721u 3:c21057907d21 45 /* Device location */
chri721u 3:c21057907d21 46 void Location_Select();
chri721u 3:c21057907d21 47 int location_id;
chri721u 0:a5831f680465 48
chri721u 2:739ba85b7a90 49 /* Day & Night */
chri721u 2:739ba85b7a90 50 void TimeCounter();
chri721u 2:739ba85b7a90 51 void DayMode();
chri721u 2:739ba85b7a90 52 void NightMode();
chri721u 2:739ba85b7a90 53 int timecount = 0;
chri721u 2:739ba85b7a90 54 bool timeofday = 1;
chri721u 0:a5831f680465 55
chri721u 3:c21057907d21 56 /* Temp and Humidity */
chri721u 3:c21057907d21 57 void Temp_Display(); // Displays temperatures in Celsius on screen
chri721u 3:c21057907d21 58 void Humid_Display(); // Displays humidity in % on screen
chri721u 3:c21057907d21 59 void Temp_Check();
chri721u 3:c21057907d21 60 void Humid_Check();
chri721u 3:c21057907d21 61 float temp;
chri721u 3:c21057907d21 62 float humid;
chri721u 3:c21057907d21 63
chri721u 3:c21057907d21 64 /* Greenhouse mechanisms */
chri721u 8:03ba8074d634 65 void Vent_Air();
chri721u 3:c21057907d21 66 void Heat_Lamp();
chri721u 3:c21057907d21 67 void Dehumidifier();
chri721u 3:c21057907d21 68 void Spray_Water();
chri721u 3:c21057907d21 69
chri721u 3:c21057907d21 70 uint8_t text[30]; // Used to display values with added text.
chri721u 3:c21057907d21 71 uint8_t text2[30]; // Used to display values with added text.
chri721u 3:c21057907d21 72
chri721u 3:c21057907d21 73 void startup()
chri721u 3:c21057907d21 74 {
chri721u 3:c21057907d21 75 cout << "Enter Greenhouse ID: \n \r";
chri721u 3:c21057907d21 76 cin >> location_id;
chri721u 3:c21057907d21 77 }
chri721u 2:739ba85b7a90 78
chri721u 2:739ba85b7a90 79 int main()
chri721u 0:a5831f680465 80 {
chri721u 3:c21057907d21 81 startup();
chri721u 2:739ba85b7a90 82 LCD_Start.LCD_Bootup();
chri721u 2:739ba85b7a90 83 tTimeCounter.start(&TimeCounter);
chri721u 3:c21057907d21 84 tLocation_Select.start(&Location_Select);
chri721u 3:c21057907d21 85 simbutton.rise(&Sim_Toggle);
chri721u 3:c21057907d21 86 tTemp.start(&Temp_Display);
chri721u 3:c21057907d21 87 tHumid.start(&Humid_Display);
chri721u 3:c21057907d21 88 tTemp_Check.start(&Temp_Check);
chri721u 3:c21057907d21 89 tHumid_Check.start(&Humid_Check);
chri721u 2:739ba85b7a90 90 while(1) {}
chri721u 1:4363657c576d 91 }
chri721u 1:4363657c576d 92
chri721u 3:c21057907d21 93 void Sim_Toggle()
chri721u 3:c21057907d21 94 {
chri721u 3:c21057907d21 95 simmode = !simmode;
chri721u 3:c21057907d21 96 }
chri721u 3:c21057907d21 97
chri721u 3:c21057907d21 98 void Location_Select()
chri721u 3:c21057907d21 99 {
chri721u 3:c21057907d21 100 while(1) {
chri721u 3:c21057907d21 101 sprintf((char*)text2, "Greenhouse %d", location_id);
chri721u 3:c21057907d21 102 BSP_LCD_DisplayStringAt(0, 0, (uint8_t *)&text2, LEFT_MODE);
chri721u 3:c21057907d21 103 if(simmode) {
chri721u 3:c21057907d21 104 BSP_LCD_DisplayStringAt(0, 25, (uint8_t *) "SIM MODE", LEFT_MODE);
chri721u 3:c21057907d21 105 } else if(simmode == 0) {
chri721u 3:c21057907d21 106 BSP_LCD_DisplayStringAt(0, 25, (uint8_t *) " ", LEFT_MODE);
chri721u 3:c21057907d21 107 }
chri721u 3:c21057907d21 108 }
chri721u 3:c21057907d21 109 }
chri721u 3:c21057907d21 110
chri721u 2:739ba85b7a90 111 void TimeCounter()
chri721u 0:a5831f680465 112 {
chri721u 8:03ba8074d634 113 // Timecounter counts up to one cycle of
chri721u 8:03ba8074d634 114 // 720 minutes if not in Simulation mode
chri721u 0:a5831f680465 115 while(1) {
chri721u 3:c21057907d21 116 if(simmode) {
chri721u 3:c21057907d21 117 timecount++;
chri721u 8:03ba8074d634 118 wait(0.01); // One tenth of a second per tic
chri721u 3:c21057907d21 119 if (timecount == 721) {
chri721u 3:c21057907d21 120 timeofday = !timeofday;
chri721u 3:c21057907d21 121 printf("Time of day is %d \n \r", timeofday);
chri721u 3:c21057907d21 122 timecount = 0;
chri721u 3:c21057907d21 123 if (timeofday) {
chri721u 3:c21057907d21 124 DayMode();
chri721u 3:c21057907d21 125 } else {
chri721u 3:c21057907d21 126 NightMode();
chri721u 3:c21057907d21 127 }
chri721u 3:c21057907d21 128 }
chri721u 3:c21057907d21 129 } else if(simmode == 0) {
chri721u 3:c21057907d21 130 timecount++;
chri721u 8:03ba8074d634 131 wait(60); // 1 minute per tic
chri721u 3:c21057907d21 132 if (timecount == 721) {
chri721u 3:c21057907d21 133 timeofday = !timeofday;
chri721u 3:c21057907d21 134 timecount = 0;
chri721u 3:c21057907d21 135 if (timeofday) {
chri721u 3:c21057907d21 136 DayMode();
chri721u 3:c21057907d21 137 } else {
chri721u 3:c21057907d21 138 NightMode();
chri721u 3:c21057907d21 139 }
chri721u 2:739ba85b7a90 140 }
chri721u 1:4363657c576d 141 }
chri721u 0:a5831f680465 142 }
chri721u 0:a5831f680465 143 }
chri721u 0:a5831f680465 144
chri721u 2:739ba85b7a90 145 void DayMode()
chri721u 0:a5831f680465 146 {
chri721u 2:739ba85b7a90 147 BSP_LCD_Clear(LCD_COLOR_WHITE);
chri721u 2:739ba85b7a90 148 BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
chri721u 2:739ba85b7a90 149 BSP_LCD_SetTextColor(LCD_COLOR_BLACK);
chri721u 3:c21057907d21 150 BSP_LCD_DisplayStringAt(0, 0, (uint8_t *) " Time: Day ", RIGHT_MODE);
chri721u 0:a5831f680465 151 }
chri721u 2:739ba85b7a90 152
chri721u 2:739ba85b7a90 153 void NightMode()
chri721u 2:739ba85b7a90 154 {
chri721u 2:739ba85b7a90 155 BSP_LCD_Clear(LCD_COLOR_BLACK);
chri721u 2:739ba85b7a90 156 BSP_LCD_SetBackColor(LCD_COLOR_BLACK);
chri721u 2:739ba85b7a90 157 BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
chri721u 3:c21057907d21 158 BSP_LCD_DisplayStringAt(0, 0, (uint8_t *) " Time: Night ", RIGHT_MODE);
chri721u 3:c21057907d21 159 }
chri721u 3:c21057907d21 160
chri721u 3:c21057907d21 161 void Temp_Display()
chri721u 3:c21057907d21 162 {
chri721u 3:c21057907d21 163 while(1) {
chri721u 3:c21057907d21 164 // Monitor temperatures and display results on LCD screen
chri721u 3:c21057907d21 165 sprintf((char*)text, "Temperature: %.1f C ", temp);
chri721u 3:c21057907d21 166 BSP_LCD_DisplayStringAt(0, 150, (uint8_t *)&text, CENTER_MODE);
chri721u 3:c21057907d21 167 wait(1);
chri721u 3:c21057907d21 168 }
chri721u 3:c21057907d21 169 }
chri721u 3:c21057907d21 170
chri721u 3:c21057907d21 171 void Humid_Display()
chri721u 3:c21057907d21 172 {
chri721u 3:c21057907d21 173 while(1) {
chri721u 3:c21057907d21 174 // Monitor humidity and display results on LCD screen
chri721u 3:c21057907d21 175 sprintf((char*)text, "Humidity: %.1f ", humid);
chri721u 3:c21057907d21 176 BSP_LCD_DisplayStringAt(0, 200, (uint8_t *)&text, CENTER_MODE);
chri721u 3:c21057907d21 177 wait(1);
chri721u 3:c21057907d21 178 }
chri721u 3:c21057907d21 179 }
chri721u 3:c21057907d21 180
chri721u 3:c21057907d21 181 void Temp_Check()
chri721u 3:c21057907d21 182 {
chri721u 3:c21057907d21 183 while(1) {
chri721u 8:03ba8074d634 184 temp = Temp_Sensor.read() * 100 / 2;
chri721u 8:03ba8074d634 185 // Read temperature sensor input. Since this is flawed, correct to adjust.
chri721u 8:03ba8074d634 186 if(timeofday) {
chri721u 8:03ba8074d634 187 // If it's daytime, keep temps between 25 and 30 celsius
chri721u 3:c21057907d21 188 if (temp >= 25 && temp <= 30) {
chri721u 8:03ba8074d634 189 Temp_LED = 1;
chri721u 3:c21057907d21 190 } else if (temp < 25) {
chri721u 8:03ba8074d634 191 Temp_LED = 0;
chri721u 8:03ba8074d634 192 Heat_Lamp();
chri721u 8:03ba8074d634 193 // Raise temperature by turning on the heat lamps in the greenhouse
chri721u 3:c21057907d21 194 } else if (temp > 30) {
chri721u 8:03ba8074d634 195
chri721u 8:03ba8074d634 196 Temp_LED = 0;
chri721u 8:03ba8074d634 197 Vent_Air();
chri721u 8:03ba8074d634 198 // Reduce temperature by venting the hot air out of the greenhouse
chri721u 3:c21057907d21 199 }
chri721u 8:03ba8074d634 200 } else if(timeofday == false) {
chri721u 8:03ba8074d634 201 // If it's nighttime, keep temps between 15 and 20
chri721u 3:c21057907d21 202 if (temp >= 15 && temp <= 20) {
chri721u 3:c21057907d21 203 Temp_LED = 1;
chri721u 3:c21057907d21 204 } else if (temp < 15) {
chri721u 8:03ba8074d634 205 Temp_LED = 0;
chri721u 3:c21057907d21 206 Heat_Lamp();
chri721u 3:c21057907d21 207
chri721u 3:c21057907d21 208 } else if (temp > 20) {
chri721u 8:03ba8074d634 209 Temp_LED = 0;
chri721u 3:c21057907d21 210 Vent_Air();
chri721u 3:c21057907d21 211 }
chri721u 3:c21057907d21 212 }
chri721u 3:c21057907d21 213 }
chri721u 3:c21057907d21 214 }
chri721u 3:c21057907d21 215
chri721u 3:c21057907d21 216 void Humid_Check()
chri721u 3:c21057907d21 217 {
chri721u 3:c21057907d21 218 while(1) {
chri721u 3:c21057907d21 219 humid = Humid_Sensor.ReadHumidity();
chri721u 3:c21057907d21 220 int dataread = Humid_Sensor.readData(); // No idea why, but the humidity won't display on screen without it.
chri721u 3:c21057907d21 221 if (humid >= 55 && humid <= 65) { // Check if humidity is within acceptable parameters (55% - 65%)
chri721u 8:03ba8074d634 222 Humid_LED = 1;
chri721u 3:c21057907d21 223 } else if (humid < 55) {
chri721u 8:03ba8074d634 224 Humid_LED = 0;
chri721u 3:c21057907d21 225 Spray_Water(); // Raise humidity by spraying water into the plants and greenhouse.
chri721u 3:c21057907d21 226 } else if ( humid > 65) {
chri721u 8:03ba8074d634 227 Humid_LED = 0;
chri721u 3:c21057907d21 228 Dehumidifier(); // Lower humidity by dehumidifying the greenhouse.
chri721u 3:c21057907d21 229 }
chri721u 3:c21057907d21 230 }
chri721u 3:c21057907d21 231 }
chri721u 3:c21057907d21 232
chri721u 3:c21057907d21 233 void Vent_Air()
chri721u 3:c21057907d21 234 {
chri721u 7:585a66ea498b 235 Heat_LED = 1;
chri721u 5:a551c6a7d99b 236 wait(0.5);
chri721u 7:585a66ea498b 237 Heat_LED = 0;
chri721u 3:c21057907d21 238 if(simmode) {
chri721u 3:c21057907d21 239 printf("Greenhouse temperature above sustainable levels. Venting air from Greenhouse to rectify. \n \r");
chri721u 3:c21057907d21 240 }
chri721u 3:c21057907d21 241 }
chri721u 3:c21057907d21 242
chri721u 3:c21057907d21 243 void Heat_Lamp()
chri721u 3:c21057907d21 244 {
chri721u 7:585a66ea498b 245 Heat_LED = 1;
chri721u 3:c21057907d21 246 wait(1);
chri721u 7:585a66ea498b 247 Heat_LED = 0;
chri721u 3:c21057907d21 248 if(simmode) {
chri721u 3:c21057907d21 249 printf("Greenhouse temperature below acceptable levels. Turning on heat lamps to rectify. \n \r");
chri721u 3:c21057907d21 250 }
chri721u 3:c21057907d21 251 }
chri721u 3:c21057907d21 252
chri721u 3:c21057907d21 253 void Dehumidifier()
chri721u 3:c21057907d21 254 {
chri721u 3:c21057907d21 255 Water_LED = 1;
chri721u 3:c21057907d21 256 wait(0.5);
chri721u 3:c21057907d21 257 Water_LED = 0;
chri721u 3:c21057907d21 258 if(simmode) {
chri721u 3:c21057907d21 259 printf("Greenhouse humidity above acceptable levels. Dehumidifying to rectify. \n \r");
chri721u 3:c21057907d21 260 }
chri721u 3:c21057907d21 261 }
chri721u 3:c21057907d21 262
chri721u 3:c21057907d21 263 void Spray_Water()
chri721u 3:c21057907d21 264 {
chri721u 3:c21057907d21 265 Water_LED = 1;
chri721u 3:c21057907d21 266 wait(1);
chri721u 3:c21057907d21 267 Water_LED = 0;
chri721u 3:c21057907d21 268 if(simmode) {
chri721u 3:c21057907d21 269 printf("Greenhouse humidity below acceptable levels. Spraying water to rectify. \n \r");
chri721u 3:c21057907d21 270 }
chri721u 2:739ba85b7a90 271 }