IoT_watering project - watering unit

Dependencies:   DHT11 mbed-rtos mbed ssWi

Committer:
mariob
Date:
Thu Feb 16 22:08:06 2017 +0000
Revision:
2:0b51e6d879df
Parent:
1:7f4af0d73836
release 1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mariob 0:51143a026e2b 1 #include "mbed.h"
mariob 0:51143a026e2b 2 #include "rtos.h"
mariob 0:51143a026e2b 3
mariob 0:51143a026e2b 4 #include "config.hpp"
mariob 0:51143a026e2b 5
mariob 0:51143a026e2b 6 #include "DHT11.h"
mariob 0:51143a026e2b 7
mariob 0:51143a026e2b 8 #include "xbee.hpp"
mariob 0:51143a026e2b 9 #include "ssWiSocket.hpp"
mariob 0:51143a026e2b 10
mariob 1:7f4af0d73836 11 #ifndef DEBUG
mariob 1:7f4af0d73836 12 #define printf(fmt,...)
mariob 1:7f4af0d73836 13 #endif
mariob 1:7f4af0d73836 14
mariob 0:51143a026e2b 15 LocalFileSystem local("local");
mariob 0:51143a026e2b 16
mariob 2:0b51e6d879df 17 // global configuration
mariob 0:51143a026e2b 18 watering_unit_config_t global_config;
mariob 0:51143a026e2b 19
mariob 2:0b51e6d879df 20 // ssWi sockets
mariob 0:51143a026e2b 21 ssWiSocket* socket_moisture = NULL;
mariob 0:51143a026e2b 22 ssWiSocket* socket_temperature = NULL;
mariob 0:51143a026e2b 23 ssWiSocket* socket_humidity = NULL;
mariob 0:51143a026e2b 24 ssWiSocket* socket_response = NULL;
mariob 0:51143a026e2b 25 ssWiSocket* socket_water = NULL;
mariob 0:51143a026e2b 26 ssWiSocket* socket_command = NULL;
mariob 0:51143a026e2b 27
mariob 2:0b51e6d879df 28 // thread functions
mariob 2:0b51e6d879df 29 void thread_sensing_fcn();
mariob 2:0b51e6d879df 30 void thread_watering_fcn();
mariob 2:0b51e6d879df 31
mariob 2:0b51e6d879df 32 // return true if a new message has been received, false otherwise
mariob 0:51143a026e2b 33 bool read_from_port(ssWiSocket *socket, int *value);
mariob 0:51143a026e2b 34
mariob 0:51143a026e2b 35 int main() {
mariob 0:51143a026e2b 36 Timer t;
mariob 0:51143a026e2b 37 t.start();
mariob 0:51143a026e2b 38
mariob 1:7f4af0d73836 39 printf("MAIN - configuration\r\n");
mariob 2:0b51e6d879df 40
mariob 1:7f4af0d73836 41 // read configuration
mariob 0:51143a026e2b 42 FILE *fp = fopen("/local/cfg.txt", "r");
mariob 0:51143a026e2b 43 if (fp == NULL)
mariob 0:51143a026e2b 44 error("missing configuration file\r\n");
mariob 0:51143a026e2b 45 fscanf(fp, "%d", &global_config.address);
mariob 0:51143a026e2b 46 fclose(fp);
mariob 0:51143a026e2b 47 global_config.moisture_port = GET_MOISTURE_PORT(global_config);
mariob 0:51143a026e2b 48 global_config.temperature_port = GET_TEMPERATURE_PORT(global_config);
mariob 0:51143a026e2b 49 global_config.humidity_port = GET_HUMIDITY_PORT(global_config);
mariob 0:51143a026e2b 50 global_config.response_port = GET_RESPONSE_PORT(global_config);
mariob 0:51143a026e2b 51 global_config.water_port = GET_WATER_PORT(global_config);
mariob 0:51143a026e2b 52
mariob 0:51143a026e2b 53 // configure network
mariob 2:0b51e6d879df 54 XBeeModule xbee(XBEE_PIN_TX, XBEE_PIN_RX, PAN_ID, CHANNEL_ID);
mariob 1:7f4af0d73836 55 xbee.init(XBEE_TX_PER_SECOND, XBEE_RX_PER_SECOND);
mariob 0:51143a026e2b 56 socket_moisture = ssWiSocket::createSocket(global_config.moisture_port);
mariob 0:51143a026e2b 57 socket_temperature =
mariob 0:51143a026e2b 58 ssWiSocket::createSocket(global_config.temperature_port);
mariob 0:51143a026e2b 59 socket_humidity = ssWiSocket::createSocket(global_config.humidity_port);
mariob 0:51143a026e2b 60 socket_response = ssWiSocket::createSocket(global_config.response_port);
mariob 0:51143a026e2b 61 socket_water = ssWiSocket::createSocket(global_config.water_port);
mariob 0:51143a026e2b 62 socket_command = ssWiSocket::createSocket(PORT_COMMANDS);
mariob 0:51143a026e2b 63
mariob 0:51143a026e2b 64 // threads
mariob 0:51143a026e2b 65 Thread thread_sensing(osPriorityAboveNormal);
mariob 0:51143a026e2b 66 thread_sensing.start(&thread_sensing_fcn);
mariob 0:51143a026e2b 67 Thread thread_watering(osPriorityHigh);
mariob 0:51143a026e2b 68 thread_watering.start(&thread_watering_fcn);
mariob 0:51143a026e2b 69
mariob 0:51143a026e2b 70 // wait 10 seconds since the board started
mariob 0:51143a026e2b 71 while(t.read() < TIMEOUT_CONF);
mariob 0:51143a026e2b 72 t.stop();
mariob 0:51143a026e2b 73
mariob 0:51143a026e2b 74 printf("MAIN - board ready\r\n");
mariob 0:51143a026e2b 75
mariob 0:51143a026e2b 76 // handle messages
mariob 0:51143a026e2b 77 bool recv_start_sampling = false;
mariob 0:51143a026e2b 78 bool recv_stop_sampling = false;
mariob 0:51143a026e2b 79 bool recv_watering = false;
mariob 0:51143a026e2b 80 int msg = COMM_NO_VALUE;
mariob 0:51143a026e2b 81 while(true) {
mariob 0:51143a026e2b 82 if (!read_from_port(socket_command, &msg))
mariob 0:51143a026e2b 83 continue;
mariob 0:51143a026e2b 84 if (!recv_start_sampling && msg == COMM_START_SAMPLING) {
mariob 0:51143a026e2b 85 recv_start_sampling = true;
mariob 0:51143a026e2b 86 printf("MAIN - sampling start command\r\n");
mariob 0:51143a026e2b 87 thread_sensing.signal_set(SIGNAL_START_ARRIVED);
mariob 0:51143a026e2b 88 continue;
mariob 0:51143a026e2b 89 }
mariob 0:51143a026e2b 90 if (!recv_stop_sampling && msg == COMM_STOP_SAMPLING) {
mariob 0:51143a026e2b 91 recv_stop_sampling = true;
mariob 0:51143a026e2b 92 printf("MAIN - sampling stop command\r\n");
mariob 0:51143a026e2b 93 thread_sensing.signal_set(SIGNAL_STOP_ARRIVED);
mariob 0:51143a026e2b 94 continue;
mariob 0:51143a026e2b 95 }
mariob 0:51143a026e2b 96 if (!recv_watering && msg == GET_WATERING_COMMAND(global_config)) {
mariob 0:51143a026e2b 97 recv_watering = true;
mariob 0:51143a026e2b 98 printf("MAIN - watering start command\r\n");
mariob 0:51143a026e2b 99 thread_watering.signal_set(SIGNAL_WATERING_ARRIVED);
mariob 0:51143a026e2b 100 continue;
mariob 0:51143a026e2b 101 }
mariob 0:51143a026e2b 102 if (msg == COMM_SHUTDOWN) {
mariob 0:51143a026e2b 103 printf("MAIN - shutdown command\r\n");
mariob 0:51143a026e2b 104 recv_start_sampling = false;
mariob 0:51143a026e2b 105 recv_stop_sampling = false;
mariob 0:51143a026e2b 106 recv_watering = false;
mariob 0:51143a026e2b 107 socket_moisture->write(COMM_NO_VALUE);
mariob 0:51143a026e2b 108 socket_temperature->write(COMM_NO_VALUE);
mariob 0:51143a026e2b 109 socket_humidity->write(COMM_NO_VALUE);
mariob 0:51143a026e2b 110 socket_response->write(COMM_NO_VALUE);
mariob 0:51143a026e2b 111 continue;
mariob 0:51143a026e2b 112 }
mariob 0:51143a026e2b 113 }
mariob 0:51143a026e2b 114
mariob 0:51143a026e2b 115 printf("MAIN - join threads and end\r\n");
mariob 0:51143a026e2b 116
mariob 0:51143a026e2b 117 thread_sensing.join();
mariob 0:51143a026e2b 118 thread_watering.join();
mariob 0:51143a026e2b 119
mariob 0:51143a026e2b 120 return 0;
mariob 0:51143a026e2b 121 }
mariob 0:51143a026e2b 122
mariob 1:7f4af0d73836 123 void thread_sensing_fcn () {
mariob 0:51143a026e2b 124 AnalogIn sensor_moisture(HW_PIN_MOISTURE);
mariob 0:51143a026e2b 125
mariob 0:51143a026e2b 126 while (1) {
mariob 0:51143a026e2b 127 int msg = COMM_SAMPLING_OK;
mariob 0:51143a026e2b 128 DHT11 sensor_dht(HW_PIN_TEMPERATURE);
mariob 0:51143a026e2b 129 printf("SAMP - waiting...\r\n");
mariob 1:7f4af0d73836 130
mariob 0:51143a026e2b 131 // wait supervisor message
mariob 0:51143a026e2b 132 Thread::signal_wait(SIGNAL_START_ARRIVED);
mariob 1:7f4af0d73836 133 printf("SAMP - start\r\n");
mariob 0:51143a026e2b 134
mariob 2:0b51e6d879df 135 DigitalOut l(LED3);
mariob 2:0b51e6d879df 136 l = 1;
mariob 2:0b51e6d879df 137
mariob 0:51143a026e2b 138 Timer t;
mariob 0:51143a026e2b 139 t.start();
mariob 0:51143a026e2b 140 // wait two seconds for HDT sensor
mariob 0:51143a026e2b 141 wait(2.0);
mariob 0:51143a026e2b 142
mariob 0:51143a026e2b 143 // sample values
mariob 1:7f4af0d73836 144 double sens_mois = 0.0;
mariob 1:7f4af0d73836 145 double sens_temp = 0.0;
mariob 1:7f4af0d73836 146 double sens_humi = 0.0;
mariob 0:51143a026e2b 147 for (int i = 0; i < NUM_SAMPLES; i++) {
mariob 1:7f4af0d73836 148 if (sensor_dht.readData() != 0) {
mariob 0:51143a026e2b 149 printf("SAMP - error %d\r\n", error);
mariob 0:51143a026e2b 150 msg = COMM_SAMPLING_KO;
mariob 1:7f4af0d73836 151 break;
mariob 0:51143a026e2b 152 }
mariob 1:7f4af0d73836 153 sens_temp += sensor_dht.readTemperature();
mariob 1:7f4af0d73836 154 sens_humi += sensor_dht.readHumidity();
mariob 1:7f4af0d73836 155 sens_mois += sensor_moisture.read() * 100;
mariob 0:51143a026e2b 156 if (t.read() > TIMEOUT_SAMPLING) {
mariob 1:7f4af0d73836 157 // timeout expired, exit
mariob 0:51143a026e2b 158 msg = COMM_SAMPLING_OUT;
mariob 0:51143a026e2b 159 break;
mariob 0:51143a026e2b 160 }
mariob 0:51143a026e2b 161 Thread::wait(INTERVAL_SAMPLING);
mariob 0:51143a026e2b 162 }
mariob 0:51143a026e2b 163 t.stop();
mariob 1:7f4af0d73836 164
mariob 0:51143a026e2b 165 // compute averages
mariob 1:7f4af0d73836 166 sens_mois = (sens_mois / NUM_SAMPLES) * 10.0;
mariob 1:7f4af0d73836 167 sens_temp = (sens_temp / NUM_SAMPLES) * 10.0;
mariob 1:7f4af0d73836 168 sens_humi = (sens_humi / NUM_SAMPLES) * 10.0;
mariob 1:7f4af0d73836 169 printf("SAMP - %f, %f, %f\r\n", sens_mois, sens_temp, sens_humi);
mariob 1:7f4af0d73836 170
mariob 0:51143a026e2b 171 // wait supervisor stop message
mariob 0:51143a026e2b 172 Thread::signal_wait(SIGNAL_STOP_ARRIVED);
mariob 0:51143a026e2b 173
mariob 0:51143a026e2b 174 // write averages and response
mariob 1:7f4af0d73836 175 int value = (int)sens_mois;
mariob 0:51143a026e2b 176 socket_moisture->write(value == 0 ? 1 : value);
mariob 1:7f4af0d73836 177 value = (int)sens_temp;
mariob 0:51143a026e2b 178 socket_temperature->write(value == 0 ? 1 : value);
mariob 1:7f4af0d73836 179 value = (int)sens_humi;
mariob 0:51143a026e2b 180 socket_humidity->write(value == 0 ? 1 : value);
mariob 0:51143a026e2b 181 socket_response->write(msg);
mariob 0:51143a026e2b 182 printf("SAMP - end\r\n");
mariob 2:0b51e6d879df 183
mariob 2:0b51e6d879df 184 l = 0;
mariob 0:51143a026e2b 185 }
mariob 0:51143a026e2b 186 }
mariob 0:51143a026e2b 187
mariob 0:51143a026e2b 188 void thread_watering_fcn() {
mariob 0:51143a026e2b 189 DigitalOut pump(HW_PIN_PUMP);
mariob 0:51143a026e2b 190 DigitalIn level_sens(HW_PIN_LOW_WATER_LEVEL);
mariob 0:51143a026e2b 191
mariob 0:51143a026e2b 192 while (1) {
mariob 0:51143a026e2b 193 pump = 0;
mariob 0:51143a026e2b 194 printf("WATR - waiting...\r\n");
mariob 1:7f4af0d73836 195
mariob 1:7f4af0d73836 196 // wait watering command
mariob 0:51143a026e2b 197 Thread::signal_wait(SIGNAL_WATERING_ARRIVED);
mariob 0:51143a026e2b 198 printf("WATR - start\r\n");
mariob 0:51143a026e2b 199 Timer t;
mariob 0:51143a026e2b 200 t.start();
mariob 0:51143a026e2b 201
mariob 2:0b51e6d879df 202 DigitalOut l(LED2);
mariob 2:0b51e6d879df 203 l = 1;
mariob 2:0b51e6d879df 204
mariob 0:51143a026e2b 205 // read total second to water
mariob 0:51143a026e2b 206 int seconds = COMM_NO_VALUE;
mariob 0:51143a026e2b 207 while(!read_from_port(socket_water, &seconds) &&
mariob 0:51143a026e2b 208 t.read()<TIMEOUT_WATERING);
mariob 0:51143a026e2b 209 t.stop();
mariob 0:51143a026e2b 210 if (t.read() >= TIMEOUT_WATERING) {
mariob 0:51143a026e2b 211 socket_response->write(COMM_WATERING_KO);
mariob 0:51143a026e2b 212 continue;
mariob 0:51143a026e2b 213 }
mariob 0:51143a026e2b 214 printf("WATR - required time %ds\r\n", seconds);
mariob 1:7f4af0d73836 215
mariob 1:7f4af0d73836 216 // start watering
mariob 0:51143a026e2b 217 int msg = COMM_WATERING_OK;
mariob 0:51143a026e2b 218 double actual_seconds = 0.0;
mariob 0:51143a026e2b 219 while (actual_seconds < seconds) {
mariob 0:51143a026e2b 220 if (!level_sens) {
mariob 1:7f4af0d73836 221 // low water, stop pump and exit
mariob 0:51143a026e2b 222 pump = 0;
mariob 0:51143a026e2b 223 printf("WATR - watering level error\r\n");
mariob 0:51143a026e2b 224 msg = COMM_LOW_WATER_LEVEL;
mariob 0:51143a026e2b 225 break;
mariob 0:51143a026e2b 226 }
mariob 1:7f4af0d73836 227 // water for 1 second
mariob 1:7f4af0d73836 228 t.reset(); t.start();
mariob 0:51143a026e2b 229 double scale = seconds > (actual_seconds + 1.0) ? 1.0 : seconds -
mariob 0:51143a026e2b 230 actual_seconds;
mariob 0:51143a026e2b 231 pump = 1;
mariob 0:51143a026e2b 232 Thread::wait((unsigned int)(scale * INTERVAL_WATERING));
mariob 0:51143a026e2b 233 t.stop();
mariob 0:51143a026e2b 234 actual_seconds += t.read();
mariob 0:51143a026e2b 235 }
mariob 0:51143a026e2b 236 pump = 0;
mariob 0:51143a026e2b 237 printf("WATR - elapsed time %fs\r\n", actual_seconds);
mariob 0:51143a026e2b 238 socket_response->write(msg);
mariob 2:0b51e6d879df 239
mariob 2:0b51e6d879df 240 l = 0;
mariob 0:51143a026e2b 241 }
mariob 0:51143a026e2b 242 }
mariob 0:51143a026e2b 243
mariob 0:51143a026e2b 244 bool read_from_port(ssWiSocket *socket, int *value) {
mariob 0:51143a026e2b 245 int prev = *value;
mariob 0:51143a026e2b 246 *value = socket->read();
mariob 0:51143a026e2b 247 return (*value) != prev;
mariob 0:51143a026e2b 248 }