Greenhouse Climate Observation Module
Dependencies: BSP_DISCO_F746NG DHT
main.cpp@3:c21057907d21, 2020-02-05 (annotated)
- Committer:
- chri721u
- Date:
- Wed Feb 05 12:15:21 2020 +0000
- Revision:
- 3:c21057907d21
- Parent:
- 2:739ba85b7a90
- Child:
- 4:accd2aab9abf
Final Version;
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 | 3:c21057907d21 | 30 | DigitalOut Light_LED(D5); // Yellow LED |
chri721u | 3:c21057907d21 | 31 | DigitalOut Water_LED(D6); // Blue LED |
chri721u | 3:c21057907d21 | 32 | DigitalOut Window_LED(D7); // Green LED |
chri721u | 2:739ba85b7a90 | 33 | |
chri721u | 2:739ba85b7a90 | 34 | /* Multithreads */ |
chri721u | 2:739ba85b7a90 | 35 | Thread tTimeCounter; |
chri721u | 3:c21057907d21 | 36 | Thread tLocation_Select; |
chri721u | 3:c21057907d21 | 37 | Thread tTemp; |
chri721u | 3:c21057907d21 | 38 | Thread tHumid; |
chri721u | 3:c21057907d21 | 39 | Thread tTemp_Check; |
chri721u | 3:c21057907d21 | 40 | Thread tHumid_Check; |
chri721u | 3:c21057907d21 | 41 | |
chri721u | 3:c21057907d21 | 42 | /* SIMULATION MODE */ |
chri721u | 3:c21057907d21 | 43 | bool simmode = 1; |
chri721u | 3:c21057907d21 | 44 | void Sim_Toggle(); |
chri721u | 3:c21057907d21 | 45 | |
chri721u | 3:c21057907d21 | 46 | /* Device location */ |
chri721u | 3:c21057907d21 | 47 | void Location_Select(); |
chri721u | 3:c21057907d21 | 48 | int location_id; |
chri721u | 0:a5831f680465 | 49 | |
chri721u | 2:739ba85b7a90 | 50 | /* Day & Night */ |
chri721u | 2:739ba85b7a90 | 51 | void TimeCounter(); |
chri721u | 2:739ba85b7a90 | 52 | void DayMode(); |
chri721u | 2:739ba85b7a90 | 53 | void NightMode(); |
chri721u | 2:739ba85b7a90 | 54 | int timecount = 0; |
chri721u | 2:739ba85b7a90 | 55 | bool timeofday = 1; |
chri721u | 0:a5831f680465 | 56 | |
chri721u | 3:c21057907d21 | 57 | /* Temp and Humidity */ |
chri721u | 3:c21057907d21 | 58 | void Temp_Display(); // Displays temperatures in Celsius on screen |
chri721u | 3:c21057907d21 | 59 | void Humid_Display(); // Displays humidity in % on screen |
chri721u | 3:c21057907d21 | 60 | void Temp_Check(); |
chri721u | 3:c21057907d21 | 61 | void Humid_Check(); |
chri721u | 3:c21057907d21 | 62 | float temp; |
chri721u | 3:c21057907d21 | 63 | float humid; |
chri721u | 3:c21057907d21 | 64 | |
chri721u | 3:c21057907d21 | 65 | /* Greenhouse mechanisms */ |
chri721u | 3:c21057907d21 | 66 | void Vent_Air(); |
chri721u | 3:c21057907d21 | 67 | void Heat_Lamp(); |
chri721u | 3:c21057907d21 | 68 | void Dehumidifier(); |
chri721u | 3:c21057907d21 | 69 | void Spray_Water(); |
chri721u | 3:c21057907d21 | 70 | |
chri721u | 3:c21057907d21 | 71 | uint8_t text[30]; // Used to display values with added text. |
chri721u | 3:c21057907d21 | 72 | uint8_t text2[30]; // Used to display values with added text. |
chri721u | 3:c21057907d21 | 73 | |
chri721u | 3:c21057907d21 | 74 | void startup() |
chri721u | 3:c21057907d21 | 75 | { |
chri721u | 3:c21057907d21 | 76 | cout << "Enter Greenhouse ID: \n \r"; |
chri721u | 3:c21057907d21 | 77 | cin >> location_id; |
chri721u | 3:c21057907d21 | 78 | cout << "Greenhouse ID is: " << location_id; |
chri721u | 3:c21057907d21 | 79 | } |
chri721u | 2:739ba85b7a90 | 80 | |
chri721u | 2:739ba85b7a90 | 81 | int main() |
chri721u | 0:a5831f680465 | 82 | { |
chri721u | 3:c21057907d21 | 83 | startup(); |
chri721u | 2:739ba85b7a90 | 84 | LCD_Start.LCD_Bootup(); |
chri721u | 2:739ba85b7a90 | 85 | tTimeCounter.start(&TimeCounter); |
chri721u | 3:c21057907d21 | 86 | tLocation_Select.start(&Location_Select); |
chri721u | 3:c21057907d21 | 87 | simbutton.rise(&Sim_Toggle); |
chri721u | 3:c21057907d21 | 88 | tTemp.start(&Temp_Display); |
chri721u | 3:c21057907d21 | 89 | tHumid.start(&Humid_Display); |
chri721u | 3:c21057907d21 | 90 | tTemp_Check.start(&Temp_Check); |
chri721u | 3:c21057907d21 | 91 | tHumid_Check.start(&Humid_Check); |
chri721u | 2:739ba85b7a90 | 92 | while(1) {} |
chri721u | 1:4363657c576d | 93 | } |
chri721u | 1:4363657c576d | 94 | |
chri721u | 3:c21057907d21 | 95 | void Sim_Toggle() |
chri721u | 3:c21057907d21 | 96 | { |
chri721u | 3:c21057907d21 | 97 | simmode = !simmode; |
chri721u | 3:c21057907d21 | 98 | } |
chri721u | 3:c21057907d21 | 99 | |
chri721u | 3:c21057907d21 | 100 | void Location_Select() |
chri721u | 3:c21057907d21 | 101 | { |
chri721u | 3:c21057907d21 | 102 | while(1) { |
chri721u | 3:c21057907d21 | 103 | sprintf((char*)text2, "Greenhouse %d", location_id); |
chri721u | 3:c21057907d21 | 104 | BSP_LCD_DisplayStringAt(0, 0, (uint8_t *)&text2, LEFT_MODE); |
chri721u | 3:c21057907d21 | 105 | if(simmode) { |
chri721u | 3:c21057907d21 | 106 | BSP_LCD_DisplayStringAt(0, 25, (uint8_t *) "SIM MODE", LEFT_MODE); |
chri721u | 3:c21057907d21 | 107 | } else if(simmode == 0) { |
chri721u | 3:c21057907d21 | 108 | BSP_LCD_DisplayStringAt(0, 25, (uint8_t *) " ", LEFT_MODE); |
chri721u | 3:c21057907d21 | 109 | } |
chri721u | 3:c21057907d21 | 110 | } |
chri721u | 3:c21057907d21 | 111 | } |
chri721u | 3:c21057907d21 | 112 | |
chri721u | 2:739ba85b7a90 | 113 | void TimeCounter() |
chri721u | 0:a5831f680465 | 114 | { |
chri721u | 2:739ba85b7a90 | 115 | // Timecounter counts up to one cycle of 720 minutes (Sim 7.20 secs) |
chri721u | 0:a5831f680465 | 116 | while(1) { |
chri721u | 3:c21057907d21 | 117 | if(simmode) { |
chri721u | 3:c21057907d21 | 118 | timecount++; |
chri721u | 3:c21057907d21 | 119 | wait(0.01); |
chri721u | 3:c21057907d21 | 120 | if (timecount == 721) { |
chri721u | 3:c21057907d21 | 121 | timeofday = !timeofday; |
chri721u | 3:c21057907d21 | 122 | printf("Time of day is %d \n \r", timeofday); |
chri721u | 3:c21057907d21 | 123 | timecount = 0; |
chri721u | 3:c21057907d21 | 124 | if (timeofday) { |
chri721u | 3:c21057907d21 | 125 | DayMode(); |
chri721u | 3:c21057907d21 | 126 | } else { |
chri721u | 3:c21057907d21 | 127 | NightMode(); |
chri721u | 3:c21057907d21 | 128 | } |
chri721u | 3:c21057907d21 | 129 | } |
chri721u | 3:c21057907d21 | 130 | } else if(simmode == 0) { |
chri721u | 3:c21057907d21 | 131 | timecount++; |
chri721u | 3:c21057907d21 | 132 | wait(1); |
chri721u | 3:c21057907d21 | 133 | if (timecount == 721) { |
chri721u | 3:c21057907d21 | 134 | timeofday = !timeofday; |
chri721u | 3:c21057907d21 | 135 | timecount = 0; |
chri721u | 3:c21057907d21 | 136 | if (timeofday) { |
chri721u | 3:c21057907d21 | 137 | DayMode(); |
chri721u | 3:c21057907d21 | 138 | } else { |
chri721u | 3:c21057907d21 | 139 | NightMode(); |
chri721u | 3:c21057907d21 | 140 | } |
chri721u | 2:739ba85b7a90 | 141 | } |
chri721u | 1:4363657c576d | 142 | } |
chri721u | 0:a5831f680465 | 143 | } |
chri721u | 0:a5831f680465 | 144 | } |
chri721u | 0:a5831f680465 | 145 | |
chri721u | 2:739ba85b7a90 | 146 | void DayMode() |
chri721u | 0:a5831f680465 | 147 | { |
chri721u | 2:739ba85b7a90 | 148 | BSP_LCD_Clear(LCD_COLOR_WHITE); |
chri721u | 2:739ba85b7a90 | 149 | BSP_LCD_SetBackColor(LCD_COLOR_WHITE); |
chri721u | 2:739ba85b7a90 | 150 | BSP_LCD_SetTextColor(LCD_COLOR_BLACK); |
chri721u | 3:c21057907d21 | 151 | BSP_LCD_DisplayStringAt(0, 0, (uint8_t *) " Time: Day ", RIGHT_MODE); |
chri721u | 0:a5831f680465 | 152 | } |
chri721u | 2:739ba85b7a90 | 153 | |
chri721u | 2:739ba85b7a90 | 154 | void NightMode() |
chri721u | 2:739ba85b7a90 | 155 | { |
chri721u | 2:739ba85b7a90 | 156 | BSP_LCD_Clear(LCD_COLOR_BLACK); |
chri721u | 2:739ba85b7a90 | 157 | BSP_LCD_SetBackColor(LCD_COLOR_BLACK); |
chri721u | 2:739ba85b7a90 | 158 | BSP_LCD_SetTextColor(LCD_COLOR_WHITE); |
chri721u | 3:c21057907d21 | 159 | BSP_LCD_DisplayStringAt(0, 0, (uint8_t *) " Time: Night ", RIGHT_MODE); |
chri721u | 3:c21057907d21 | 160 | } |
chri721u | 3:c21057907d21 | 161 | |
chri721u | 3:c21057907d21 | 162 | void Temp_Display() |
chri721u | 3:c21057907d21 | 163 | { |
chri721u | 3:c21057907d21 | 164 | while(1) { |
chri721u | 3:c21057907d21 | 165 | // Monitor temperatures and display results on LCD screen |
chri721u | 3:c21057907d21 | 166 | sprintf((char*)text, "Temperature: %.1f C ", temp); |
chri721u | 3:c21057907d21 | 167 | BSP_LCD_DisplayStringAt(0, 150, (uint8_t *)&text, CENTER_MODE); |
chri721u | 3:c21057907d21 | 168 | wait(1); |
chri721u | 3:c21057907d21 | 169 | } |
chri721u | 3:c21057907d21 | 170 | } |
chri721u | 3:c21057907d21 | 171 | |
chri721u | 3:c21057907d21 | 172 | void Humid_Display() |
chri721u | 3:c21057907d21 | 173 | { |
chri721u | 3:c21057907d21 | 174 | while(1) { |
chri721u | 3:c21057907d21 | 175 | // Monitor humidity and display results on LCD screen |
chri721u | 3:c21057907d21 | 176 | sprintf((char*)text, "Humidity: %.1f ", humid); |
chri721u | 3:c21057907d21 | 177 | BSP_LCD_DisplayStringAt(0, 200, (uint8_t *)&text, CENTER_MODE); |
chri721u | 3:c21057907d21 | 178 | wait(1); |
chri721u | 3:c21057907d21 | 179 | } |
chri721u | 3:c21057907d21 | 180 | } |
chri721u | 3:c21057907d21 | 181 | |
chri721u | 3:c21057907d21 | 182 | void Temp_Check() |
chri721u | 3:c21057907d21 | 183 | { |
chri721u | 3:c21057907d21 | 184 | while(1) { |
chri721u | 3:c21057907d21 | 185 | temp = Temp_Sensor.read() * 100 / 2; // Read temperature sensor input. Since this is flawed, correct to adjust. |
chri721u | 3:c21057907d21 | 186 | if(timeofday) { // If it's daytime, keep temps between 25 and 30 celsius |
chri721u | 3:c21057907d21 | 187 | if (temp >= 25 && temp <= 30) { |
chri721u | 3:c21057907d21 | 188 | printf("Greenhouse temperature within acceptable parameters"); |
chri721u | 3:c21057907d21 | 189 | wait(1); |
chri721u | 3:c21057907d21 | 190 | } else if (temp < 25) { |
chri721u | 3:c21057907d21 | 191 | Heat_Lamp(); // Raise temperature by turning on the heat lamps in the greenhouse |
chri721u | 3:c21057907d21 | 192 | } else if (temp > 30) { |
chri721u | 3:c21057907d21 | 193 | Vent_Air(); // Reduce temperature by venting the hot air out of the greenhouse |
chri721u | 3:c21057907d21 | 194 | } |
chri721u | 3:c21057907d21 | 195 | } else if(timeofday == false) { // If it's nighttime, keep temps between 15 and 20 |
chri721u | 3:c21057907d21 | 196 | if (temp >= 15 && temp <= 20) { |
chri721u | 3:c21057907d21 | 197 | Temp_LED = 1; |
chri721u | 3:c21057907d21 | 198 | wait(1); |
chri721u | 3:c21057907d21 | 199 | } else if (temp < 15) { |
chri721u | 3:c21057907d21 | 200 | Heat_Lamp(); |
chri721u | 3:c21057907d21 | 201 | |
chri721u | 3:c21057907d21 | 202 | } else if (temp > 20) { |
chri721u | 3:c21057907d21 | 203 | Vent_Air(); |
chri721u | 3:c21057907d21 | 204 | } |
chri721u | 3:c21057907d21 | 205 | } |
chri721u | 3:c21057907d21 | 206 | } |
chri721u | 3:c21057907d21 | 207 | } |
chri721u | 3:c21057907d21 | 208 | |
chri721u | 3:c21057907d21 | 209 | void Humid_Check() |
chri721u | 3:c21057907d21 | 210 | { |
chri721u | 3:c21057907d21 | 211 | while(1) { |
chri721u | 3:c21057907d21 | 212 | humid = Humid_Sensor.ReadHumidity(); |
chri721u | 3:c21057907d21 | 213 | int dataread = Humid_Sensor.readData(); // No idea why, but the humidity won't display on screen without it. |
chri721u | 3:c21057907d21 | 214 | if (humid >= 55 && humid <= 65) { // Check if humidity is within acceptable parameters (55% - 65%) |
chri721u | 3:c21057907d21 | 215 | printf("Greenhouse humidity is within acceptable parameters"); |
chri721u | 3:c21057907d21 | 216 | } else if (humid < 55) { |
chri721u | 3:c21057907d21 | 217 | Spray_Water(); // Raise humidity by spraying water into the plants and greenhouse. |
chri721u | 3:c21057907d21 | 218 | } else if ( humid > 65) { |
chri721u | 3:c21057907d21 | 219 | Dehumidifier(); // Lower humidity by dehumidifying the greenhouse. |
chri721u | 3:c21057907d21 | 220 | } |
chri721u | 3:c21057907d21 | 221 | } |
chri721u | 3:c21057907d21 | 222 | } |
chri721u | 3:c21057907d21 | 223 | |
chri721u | 3:c21057907d21 | 224 | void Vent_Air() |
chri721u | 3:c21057907d21 | 225 | { |
chri721u | 3:c21057907d21 | 226 | Window_LED = 1; |
chri721u | 3:c21057907d21 | 227 | wait(1); |
chri721u | 3:c21057907d21 | 228 | Window_LED = 0; |
chri721u | 3:c21057907d21 | 229 | if(simmode) { |
chri721u | 3:c21057907d21 | 230 | printf("Greenhouse temperature above sustainable levels. Venting air from Greenhouse to rectify. \n \r"); |
chri721u | 3:c21057907d21 | 231 | } |
chri721u | 3:c21057907d21 | 232 | } |
chri721u | 3:c21057907d21 | 233 | |
chri721u | 3:c21057907d21 | 234 | void Heat_Lamp() |
chri721u | 3:c21057907d21 | 235 | { |
chri721u | 2:739ba85b7a90 | 236 | Light_LED = 1; |
chri721u | 3:c21057907d21 | 237 | wait(1); |
chri721u | 3:c21057907d21 | 238 | Light_LED = 0; |
chri721u | 3:c21057907d21 | 239 | if(simmode) { |
chri721u | 3:c21057907d21 | 240 | printf("Greenhouse temperature below acceptable levels. Turning on heat lamps to rectify. \n \r"); |
chri721u | 3:c21057907d21 | 241 | } |
chri721u | 3:c21057907d21 | 242 | } |
chri721u | 3:c21057907d21 | 243 | |
chri721u | 3:c21057907d21 | 244 | void Dehumidifier() |
chri721u | 3:c21057907d21 | 245 | { |
chri721u | 3:c21057907d21 | 246 | Water_LED = 1; |
chri721u | 3:c21057907d21 | 247 | wait(0.5); |
chri721u | 3:c21057907d21 | 248 | Water_LED = 0; |
chri721u | 3:c21057907d21 | 249 | if(simmode) { |
chri721u | 3:c21057907d21 | 250 | printf("Greenhouse humidity above acceptable levels. Dehumidifying to rectify. \n \r"); |
chri721u | 3:c21057907d21 | 251 | } |
chri721u | 3:c21057907d21 | 252 | } |
chri721u | 3:c21057907d21 | 253 | |
chri721u | 3:c21057907d21 | 254 | void Spray_Water() |
chri721u | 3:c21057907d21 | 255 | { |
chri721u | 3:c21057907d21 | 256 | Water_LED = 1; |
chri721u | 3:c21057907d21 | 257 | wait(1); |
chri721u | 3:c21057907d21 | 258 | Water_LED = 0; |
chri721u | 3:c21057907d21 | 259 | if(simmode) { |
chri721u | 3:c21057907d21 | 260 | printf("Greenhouse humidity below acceptable levels. Spraying water to rectify. \n \r"); |
chri721u | 3:c21057907d21 | 261 | } |
chri721u | 2:739ba85b7a90 | 262 | } |