Greenhouse Climate Observation Module
Dependencies: BSP_DISCO_F746NG DHT
main.cpp@6:0cb2e4bacc18, 2020-02-05 (annotated)
- Committer:
- chri721u
- Date:
- Wed Feb 05 12:25:54 2020 +0000
- Revision:
- 6:0cb2e4bacc18
- Parent:
- 5:a551c6a7d99b
- Child:
- 7:585a66ea498b
Final_Version 05/02/2020 13:25
Who changed what in which revision?
User | Revision | Line number | New 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 | 3:c21057907d21 | 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 | cout << "Greenhouse ID is: " << location_id; |
chri721u | 3:c21057907d21 | 78 | } |
chri721u | 2:739ba85b7a90 | 79 | |
chri721u | 2:739ba85b7a90 | 80 | int main() |
chri721u | 0:a5831f680465 | 81 | { |
chri721u | 3:c21057907d21 | 82 | startup(); |
chri721u | 2:739ba85b7a90 | 83 | LCD_Start.LCD_Bootup(); |
chri721u | 2:739ba85b7a90 | 84 | tTimeCounter.start(&TimeCounter); |
chri721u | 3:c21057907d21 | 85 | tLocation_Select.start(&Location_Select); |
chri721u | 3:c21057907d21 | 86 | simbutton.rise(&Sim_Toggle); |
chri721u | 3:c21057907d21 | 87 | tTemp.start(&Temp_Display); |
chri721u | 3:c21057907d21 | 88 | tHumid.start(&Humid_Display); |
chri721u | 3:c21057907d21 | 89 | tTemp_Check.start(&Temp_Check); |
chri721u | 3:c21057907d21 | 90 | tHumid_Check.start(&Humid_Check); |
chri721u | 2:739ba85b7a90 | 91 | while(1) {} |
chri721u | 1:4363657c576d | 92 | } |
chri721u | 1:4363657c576d | 93 | |
chri721u | 3:c21057907d21 | 94 | void Sim_Toggle() |
chri721u | 3:c21057907d21 | 95 | { |
chri721u | 3:c21057907d21 | 96 | simmode = !simmode; |
chri721u | 3:c21057907d21 | 97 | } |
chri721u | 3:c21057907d21 | 98 | |
chri721u | 3:c21057907d21 | 99 | void Location_Select() |
chri721u | 3:c21057907d21 | 100 | { |
chri721u | 3:c21057907d21 | 101 | while(1) { |
chri721u | 3:c21057907d21 | 102 | sprintf((char*)text2, "Greenhouse %d", location_id); |
chri721u | 3:c21057907d21 | 103 | BSP_LCD_DisplayStringAt(0, 0, (uint8_t *)&text2, LEFT_MODE); |
chri721u | 3:c21057907d21 | 104 | if(simmode) { |
chri721u | 3:c21057907d21 | 105 | BSP_LCD_DisplayStringAt(0, 25, (uint8_t *) "SIM MODE", LEFT_MODE); |
chri721u | 3:c21057907d21 | 106 | } else if(simmode == 0) { |
chri721u | 3:c21057907d21 | 107 | BSP_LCD_DisplayStringAt(0, 25, (uint8_t *) " ", LEFT_MODE); |
chri721u | 3:c21057907d21 | 108 | } |
chri721u | 3:c21057907d21 | 109 | } |
chri721u | 3:c21057907d21 | 110 | } |
chri721u | 3:c21057907d21 | 111 | |
chri721u | 2:739ba85b7a90 | 112 | void TimeCounter() |
chri721u | 0:a5831f680465 | 113 | { |
chri721u | 2:739ba85b7a90 | 114 | // Timecounter counts up to one cycle of 720 minutes (Sim 7.20 secs) |
chri721u | 0:a5831f680465 | 115 | while(1) { |
chri721u | 3:c21057907d21 | 116 | if(simmode) { |
chri721u | 3:c21057907d21 | 117 | timecount++; |
chri721u | 3:c21057907d21 | 118 | wait(0.01); |
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 | 3:c21057907d21 | 131 | wait(1); |
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 | 3:c21057907d21 | 184 | temp = Temp_Sensor.read() * 100 / 2; // Read temperature sensor input. Since this is flawed, correct to adjust. |
chri721u | 3:c21057907d21 | 185 | if(timeofday) { // If it's daytime, keep temps between 25 and 30 celsius |
chri721u | 3:c21057907d21 | 186 | if (temp >= 25 && temp <= 30) { |
chri721u | 6:0cb2e4bacc18 | 187 | printf("Greenhouse temperature within acceptable parameters \n \r"); |
chri721u | 3:c21057907d21 | 188 | wait(1); |
chri721u | 3:c21057907d21 | 189 | } else if (temp < 25) { |
chri721u | 3:c21057907d21 | 190 | Heat_Lamp(); // Raise temperature by turning on the heat lamps in the greenhouse |
chri721u | 3:c21057907d21 | 191 | } else if (temp > 30) { |
chri721u | 3:c21057907d21 | 192 | Vent_Air(); // Reduce temperature by venting the hot air out of the greenhouse |
chri721u | 3:c21057907d21 | 193 | } |
chri721u | 3:c21057907d21 | 194 | } else if(timeofday == false) { // If it's nighttime, keep temps between 15 and 20 |
chri721u | 3:c21057907d21 | 195 | if (temp >= 15 && temp <= 20) { |
chri721u | 3:c21057907d21 | 196 | Temp_LED = 1; |
chri721u | 3:c21057907d21 | 197 | wait(1); |
chri721u | 3:c21057907d21 | 198 | } else if (temp < 15) { |
chri721u | 3:c21057907d21 | 199 | Heat_Lamp(); |
chri721u | 3:c21057907d21 | 200 | |
chri721u | 3:c21057907d21 | 201 | } else if (temp > 20) { |
chri721u | 3:c21057907d21 | 202 | Vent_Air(); |
chri721u | 3:c21057907d21 | 203 | } |
chri721u | 3:c21057907d21 | 204 | } |
chri721u | 3:c21057907d21 | 205 | } |
chri721u | 3:c21057907d21 | 206 | } |
chri721u | 3:c21057907d21 | 207 | |
chri721u | 3:c21057907d21 | 208 | void Humid_Check() |
chri721u | 3:c21057907d21 | 209 | { |
chri721u | 3:c21057907d21 | 210 | while(1) { |
chri721u | 3:c21057907d21 | 211 | humid = Humid_Sensor.ReadHumidity(); |
chri721u | 3:c21057907d21 | 212 | int dataread = Humid_Sensor.readData(); // No idea why, but the humidity won't display on screen without it. |
chri721u | 3:c21057907d21 | 213 | if (humid >= 55 && humid <= 65) { // Check if humidity is within acceptable parameters (55% - 65%) |
chri721u | 6:0cb2e4bacc18 | 214 | printf("Greenhouse humidity is within acceptable parameters \n \r"); |
chri721u | 3:c21057907d21 | 215 | } else if (humid < 55) { |
chri721u | 3:c21057907d21 | 216 | Spray_Water(); // Raise humidity by spraying water into the plants and greenhouse. |
chri721u | 3:c21057907d21 | 217 | } else if ( humid > 65) { |
chri721u | 3:c21057907d21 | 218 | Dehumidifier(); // Lower humidity by dehumidifying the greenhouse. |
chri721u | 3:c21057907d21 | 219 | } |
chri721u | 3:c21057907d21 | 220 | } |
chri721u | 3:c21057907d21 | 221 | } |
chri721u | 3:c21057907d21 | 222 | |
chri721u | 3:c21057907d21 | 223 | void Vent_Air() |
chri721u | 3:c21057907d21 | 224 | { |
chri721u | 4:accd2aab9abf | 225 | Temp_LED = 1; |
chri721u | 5:a551c6a7d99b | 226 | wait(0.5); |
chri721u | 4:accd2aab9abf | 227 | Temp_LED = 0; |
chri721u | 3:c21057907d21 | 228 | if(simmode) { |
chri721u | 3:c21057907d21 | 229 | printf("Greenhouse temperature above sustainable levels. Venting air from Greenhouse to rectify. \n \r"); |
chri721u | 3:c21057907d21 | 230 | } |
chri721u | 3:c21057907d21 | 231 | } |
chri721u | 3:c21057907d21 | 232 | |
chri721u | 3:c21057907d21 | 233 | void Heat_Lamp() |
chri721u | 3:c21057907d21 | 234 | { |
chri721u | 4:accd2aab9abf | 235 | Temp_LED = 1; |
chri721u | 3:c21057907d21 | 236 | wait(1); |
chri721u | 4:accd2aab9abf | 237 | Temp_LED = 0; |
chri721u | 3:c21057907d21 | 238 | if(simmode) { |
chri721u | 3:c21057907d21 | 239 | printf("Greenhouse temperature below acceptable levels. Turning on heat lamps to rectify. \n \r"); |
chri721u | 3:c21057907d21 | 240 | } |
chri721u | 3:c21057907d21 | 241 | } |
chri721u | 3:c21057907d21 | 242 | |
chri721u | 3:c21057907d21 | 243 | void Dehumidifier() |
chri721u | 3:c21057907d21 | 244 | { |
chri721u | 3:c21057907d21 | 245 | Water_LED = 1; |
chri721u | 3:c21057907d21 | 246 | wait(0.5); |
chri721u | 3:c21057907d21 | 247 | Water_LED = 0; |
chri721u | 3:c21057907d21 | 248 | if(simmode) { |
chri721u | 3:c21057907d21 | 249 | printf("Greenhouse humidity above acceptable levels. Dehumidifying to rectify. \n \r"); |
chri721u | 3:c21057907d21 | 250 | } |
chri721u | 3:c21057907d21 | 251 | } |
chri721u | 3:c21057907d21 | 252 | |
chri721u | 3:c21057907d21 | 253 | void Spray_Water() |
chri721u | 3:c21057907d21 | 254 | { |
chri721u | 3:c21057907d21 | 255 | Water_LED = 1; |
chri721u | 3:c21057907d21 | 256 | wait(1); |
chri721u | 3:c21057907d21 | 257 | Water_LED = 0; |
chri721u | 3:c21057907d21 | 258 | if(simmode) { |
chri721u | 3:c21057907d21 | 259 | printf("Greenhouse humidity below acceptable levels. Spraying water to rectify. \n \r"); |
chri721u | 3:c21057907d21 | 260 | } |
chri721u | 2:739ba85b7a90 | 261 | } |