IoT_watering project - supervisor

Dependencies:   mbed-rtos mbed ssWi

Committer:
mariob
Date:
Thu Feb 16 22:08:27 2017 +0000
Revision:
3:e49dd7bf7f1c
Parent:
2:69d2d4c76f02
release 1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mariob 0:cc364516d433 1 #include "mbed.h"
mariob 0:cc364516d433 2 #include "rtos.h"
mariob 0:cc364516d433 3
mariob 1:dcfe7e79a45c 4 #include "config.h"
mariob 0:cc364516d433 5
mariob 0:cc364516d433 6 #include "xbee.hpp"
mariob 0:cc364516d433 7 #include "ssWiSocket.hpp"
mariob 0:cc364516d433 8
mariob 2:69d2d4c76f02 9 #ifndef DEBUG
mariob 2:69d2d4c76f02 10 #define printf(fmt,...)
mariob 2:69d2d4c76f02 11 #endif
mariob 2:69d2d4c76f02 12
mariob 3:e49dd7bf7f1c 13 // global configuration
mariob 1:dcfe7e79a45c 14 global_confg_t global_config;
mariob 1:dcfe7e79a45c 15
mariob 3:e49dd7bf7f1c 16 // ssWi sockets
mariob 0:cc364516d433 17 ssWiSocket* socket_command;
mariob 0:cc364516d433 18 ssWiSocket* socket_moisture[MAX_NUM_NODES];
mariob 0:cc364516d433 19 ssWiSocket* socket_temperature[MAX_NUM_NODES];
mariob 0:cc364516d433 20 ssWiSocket* socket_humidity[MAX_NUM_NODES];
mariob 0:cc364516d433 21 ssWiSocket* socket_response[MAX_NUM_NODES];
mariob 0:cc364516d433 22 ssWiSocket* socket_water[MAX_NUM_NODES];
mariob 0:cc364516d433 23
mariob 0:cc364516d433 24 LocalFileSystem local("local");
mariob 0:cc364516d433 25
mariob 3:e49dd7bf7f1c 26 // read counter value from file
mariob 0:cc364516d433 27 bool read_counter();
mariob 3:e49dd7bf7f1c 28 // read board configuration from file
mariob 0:cc364516d433 29 bool read_configuration();
mariob 0:cc364516d433 30
mariob 3:e49dd7bf7f1c 31 // return true if a message has been received, false otherwise
mariob 0:cc364516d433 32 bool read_from_port(ssWiSocket *socket, int *value);
mariob 3:e49dd7bf7f1c 33 // blocking read - timeout after 10 seconds
mariob 0:cc364516d433 34 bool read_timeout(ssWiSocket *socket, int *value);
mariob 0:cc364516d433 35
mariob 0:cc364516d433 36 void do_sampling();
mariob 0:cc364516d433 37 void do_watering();
mariob 0:cc364516d433 38
mariob 0:cc364516d433 39 int main() {
mariob 3:e49dd7bf7f1c 40 DigitalOut power_device(POWER_EN_PIN);
mariob 3:e49dd7bf7f1c 41 power_device = POWER_OFF;
mariob 3:e49dd7bf7f1c 42
mariob 0:cc364516d433 43 // supervisor configuration
mariob 0:cc364516d433 44 printf("SUPERVISOR - config\r\n");
mariob 2:69d2d4c76f02 45
mariob 2:69d2d4c76f02 46 // read configuration
mariob 0:cc364516d433 47 if (!read_configuration())
mariob 0:cc364516d433 48 error("Impossible to read configuration");
mariob 0:cc364516d433 49
mariob 0:cc364516d433 50 // network configuration
mariob 3:e49dd7bf7f1c 51 XBeeModule xbee(XBEE_PIN_TX, XBEE_PIN_RX, PAN_ID, CHANNEL_ID);
mariob 2:69d2d4c76f02 52 xbee.init(XBEE_TX_PER_SECOND, XBEE_RX_PER_SECOND);
mariob 0:cc364516d433 53 socket_command = ssWiSocket::createSocket(PORT_COMMANDS);
mariob 0:cc364516d433 54 for (int i = 0; i < global_config.num_units; i++) {
mariob 0:cc364516d433 55 socket_moisture[i] = ssWiSocket::createSocket(
mariob 0:cc364516d433 56 global_config.nodes[i].address * 5 + PORT_MOISTURE_OFFSET);
mariob 0:cc364516d433 57 socket_temperature[i] = ssWiSocket::createSocket(
mariob 0:cc364516d433 58 global_config.nodes[i].address * 5 + PORT_TEMPERATURE_OFFSET);
mariob 0:cc364516d433 59 socket_humidity[i] = ssWiSocket::createSocket(
mariob 0:cc364516d433 60 global_config.nodes[i].address * 5 + PORT_HUMIDITY_OFFSET);
mariob 0:cc364516d433 61 socket_response[i] = ssWiSocket::createSocket(
mariob 0:cc364516d433 62 global_config.nodes[i].address * 5 + PORT_RESPONSE_OFFSET);
mariob 0:cc364516d433 63 socket_water[i] = ssWiSocket::createSocket(
mariob 0:cc364516d433 64 global_config.nodes[i].address * 5 + PORT_WATER_OFFSET);
mariob 0:cc364516d433 65 }
mariob 0:cc364516d433 66
mariob 0:cc364516d433 67 // start
mariob 0:cc364516d433 68 printf("SUPERVISOR - start\r\n");
mariob 1:dcfe7e79a45c 69
mariob 0:cc364516d433 70 while(1) {
mariob 0:cc364516d433 71 int minute_counters = 0;
mariob 2:69d2d4c76f02 72 printf("SUPERVISOR - waiting\r\n");
mariob 0:cc364516d433 73 do {
mariob 0:cc364516d433 74 // wait 1 minute
mariob 0:cc364516d433 75 Thread::wait(INTERVAL_60_SECONDS * 1000);
mariob 0:cc364516d433 76 minute_counters++;
mariob 0:cc364516d433 77 } while (minute_counters < global_config.wait_minutes);
mariob 0:cc364516d433 78
mariob 1:dcfe7e79a45c 79 printf("SUPERVISOR - active\r\n");
mariob 1:dcfe7e79a45c 80
mariob 0:cc364516d433 81 // mark as busy
mariob 0:cc364516d433 82 DigitalOut led_busy(LED4);
mariob 0:cc364516d433 83 led_busy = 1;
mariob 0:cc364516d433 84 FILE* fp_busy = fopen(FILE_BSY, "w");
mariob 0:cc364516d433 85
mariob 3:e49dd7bf7f1c 86 // power watering units
mariob 3:e49dd7bf7f1c 87 power_device = POWER_ON;
mariob 3:e49dd7bf7f1c 88 wait(INTERVAL_POWER_START);
mariob 3:e49dd7bf7f1c 89
mariob 3:e49dd7bf7f1c 90 read_counter();
mariob 3:e49dd7bf7f1c 91
mariob 0:cc364516d433 92 // sample and water
mariob 0:cc364516d433 93 printf("SUPERVISOR - sampling\r\n");
mariob 0:cc364516d433 94 do_sampling();
mariob 0:cc364516d433 95 printf("SUPERVISOR - watering\r\n");
mariob 0:cc364516d433 96 do_watering();
mariob 1:dcfe7e79a45c 97
mariob 0:cc364516d433 98 // increment counter
mariob 0:cc364516d433 99 global_config.count++;
mariob 0:cc364516d433 100 FILE* fp = fopen(FILE_CNT, "w");
mariob 0:cc364516d433 101 fprintf(fp, "%d\n", global_config.count);
mariob 0:cc364516d433 102 fclose(fp);
mariob 0:cc364516d433 103
mariob 0:cc364516d433 104 // send shutdown
mariob 0:cc364516d433 105 printf("SUPERVISOR - shutdown\r\n");
mariob 1:dcfe7e79a45c 106
mariob 2:69d2d4c76f02 107 wait(INTERVAL_SYNC);
mariob 0:cc364516d433 108 socket_command->write(COMM_SHUTDOWN);
mariob 3:e49dd7bf7f1c 109 wait(INTERVAL_SYNC * 2);
mariob 1:dcfe7e79a45c 110
mariob 3:e49dd7bf7f1c 111 // power off devices
mariob 3:e49dd7bf7f1c 112 power_device = POWER_OFF;
mariob 3:e49dd7bf7f1c 113
mariob 0:cc364516d433 114 // mark as not busy
mariob 0:cc364516d433 115 led_busy = 0;
mariob 0:cc364516d433 116 fclose(fp_busy);
mariob 0:cc364516d433 117 }
mariob 0:cc364516d433 118 }
mariob 0:cc364516d433 119
mariob 0:cc364516d433 120 void do_sampling () {
mariob 0:cc364516d433 121 FILE* fp = fopen(FILE_SNS, "a");
mariob 0:cc364516d433 122
mariob 0:cc364516d433 123 socket_command->write(COMM_START_SAMPLING);
mariob 2:69d2d4c76f02 124 wait(INTERVAL_SAMPLING);
mariob 0:cc364516d433 125
mariob 0:cc364516d433 126 socket_command->write(COMM_STOP_SAMPLING);
mariob 2:69d2d4c76f02 127 wait(INTERVAL_SYNC);
mariob 0:cc364516d433 128
mariob 0:cc364516d433 129 for (int i = 0; i < global_config.num_units; i++) {
mariob 0:cc364516d433 130 int temp = 0, humi = 0, mois = 0, sampling_feedback = COMM_NO_VALUE;
mariob 0:cc364516d433 131 int code;
mariob 0:cc364516d433 132 if (!read_timeout(socket_response[i], &sampling_feedback))
mariob 0:cc364516d433 133 code = 1;
mariob 0:cc364516d433 134 else {
mariob 0:cc364516d433 135 switch (sampling_feedback) {
mariob 0:cc364516d433 136 case COMM_SAMPLING_OK:
mariob 0:cc364516d433 137 code = (read_timeout(socket_temperature[i], &temp) &&
mariob 0:cc364516d433 138 read_timeout(socket_humidity[i], &humi) &&
mariob 0:cc364516d433 139 read_timeout(socket_moisture[i], &mois)) ? 0 : 2;
mariob 0:cc364516d433 140 break;
mariob 0:cc364516d433 141 case COMM_SAMPLING_KO: code = 3; break;
mariob 0:cc364516d433 142 case COMM_SAMPLING_OUT: code = 4; break;
mariob 0:cc364516d433 143 default: code = 5;
mariob 0:cc364516d433 144 }
mariob 0:cc364516d433 145 }
mariob 0:cc364516d433 146 fprintf(fp, "%d %d %d %4.2f %4.2f %4.2f\n", global_config.count,
mariob 0:cc364516d433 147 global_config.nodes[i].address,
mariob 0:cc364516d433 148 code,
mariob 0:cc364516d433 149 (double)humi/10.0,
mariob 0:cc364516d433 150 (double)temp/10.0,
mariob 0:cc364516d433 151 (double)mois/10.0);
mariob 0:cc364516d433 152 }
mariob 0:cc364516d433 153 fclose(fp);
mariob 0:cc364516d433 154 }
mariob 0:cc364516d433 155
mariob 0:cc364516d433 156 void do_watering () {
mariob 2:69d2d4c76f02 157 FILE* fp = fopen(FILE_WTR, "a");
mariob 0:cc364516d433 158 for (int i = 0; i < global_config.num_units; i++) {
mariob 0:cc364516d433 159 if (global_config.count % global_config.nodes[i].watering_wait)
mariob 0:cc364516d433 160 continue;
mariob 2:69d2d4c76f02 161 // write watering time in seconds
mariob 0:cc364516d433 162 socket_water[i]->write(global_config.nodes[i].watering_seconds);
mariob 2:69d2d4c76f02 163 wait(INTERVAL_SYNC);
mariob 2:69d2d4c76f02 164 // send watering command
mariob 0:cc364516d433 165 socket_command->write(COMM_START_WATERING_OFFSET +
mariob 0:cc364516d433 166 global_config.nodes[i].address);
mariob 2:69d2d4c76f02 167 wait(global_config.nodes[i].watering_seconds + INTERVAL_SYNC +
mariob 2:69d2d4c76f02 168 INTERVAL_SYNC);
mariob 0:cc364516d433 169
mariob 0:cc364516d433 170 int watering_response = 0;
mariob 0:cc364516d433 171 int code = 4;
mariob 0:cc364516d433 172 if (read_timeout(socket_response[i], &watering_response)) {
mariob 0:cc364516d433 173 switch(watering_response) {
mariob 0:cc364516d433 174 case COMM_WATERING_KO: code = 1; break;
mariob 0:cc364516d433 175 case COMM_WATERING_OK: code = 0; break;
mariob 0:cc364516d433 176 case COMM_LOW_WATER_LEVEL: code = 2; break;
mariob 0:cc364516d433 177 default: code = 3;
mariob 0:cc364516d433 178 }
mariob 0:cc364516d433 179 }
mariob 0:cc364516d433 180 fprintf(fp, "%d %d %d %d\n", global_config.count,
mariob 0:cc364516d433 181 global_config.nodes[i].address,
mariob 0:cc364516d433 182 code,
mariob 0:cc364516d433 183 global_config.nodes[i].watering_seconds);
mariob 0:cc364516d433 184 }
mariob 3:e49dd7bf7f1c 185 fclose(fp);
mariob 0:cc364516d433 186 }
mariob 0:cc364516d433 187
mariob 0:cc364516d433 188 bool read_from_port(ssWiSocket *socket, int *value) {
mariob 0:cc364516d433 189 int prev = *value;
mariob 0:cc364516d433 190 *value = socket->read();
mariob 0:cc364516d433 191 return (*value) != prev;
mariob 0:cc364516d433 192 }
mariob 0:cc364516d433 193
mariob 0:cc364516d433 194 bool read_timeout(ssWiSocket *socket, int *value) {
mariob 0:cc364516d433 195 Timer t;
mariob 0:cc364516d433 196 t.start();
mariob 0:cc364516d433 197 bool ret;
mariob 0:cc364516d433 198 int v = COMM_NO_VALUE;
mariob 0:cc364516d433 199 double start = t.read();
mariob 0:cc364516d433 200 do {
mariob 0:cc364516d433 201 if ((t.read() - start) > TIMEOUT_READ)
mariob 0:cc364516d433 202 return false;
mariob 0:cc364516d433 203 ret = read_from_port(socket, &v);
mariob 0:cc364516d433 204 } while(!ret);
mariob 0:cc364516d433 205 t.stop();
mariob 0:cc364516d433 206 *value = v;
mariob 0:cc364516d433 207 return true;
mariob 0:cc364516d433 208 }
mariob 0:cc364516d433 209
mariob 0:cc364516d433 210 bool read_configuration() {
mariob 0:cc364516d433 211 int state = 0;
mariob 0:cc364516d433 212 int n_unit = 0;
mariob 0:cc364516d433 213
mariob 0:cc364516d433 214 FILE *fp = fopen(FILE_CFG, "r");
mariob 0:cc364516d433 215 if(fp == NULL)
mariob 0:cc364516d433 216 return false;
mariob 0:cc364516d433 217 char line[250];
mariob 0:cc364516d433 218
mariob 0:cc364516d433 219 while(fgets(line, sizeof(line), fp)) {
mariob 0:cc364516d433 220 if (line[0] == '#')
mariob 0:cc364516d433 221 continue;
mariob 0:cc364516d433 222 switch(state) {
mariob 0:cc364516d433 223 case 0: //read interval length
mariob 0:cc364516d433 224 sscanf(line, "%d\r", &global_config.wait_minutes);
mariob 0:cc364516d433 225 state = 1;
mariob 0:cc364516d433 226 break;
mariob 0:cc364516d433 227 case 1: //read number of watering units
mariob 0:cc364516d433 228 sscanf(line, "%d\r", &global_config.num_units);
mariob 0:cc364516d433 229 state = 2;
mariob 0:cc364516d433 230 break;
mariob 0:cc364516d433 231 case 2: //read number of watering units
mariob 0:cc364516d433 232 sscanf(line, "%d %d %d\r",
mariob 0:cc364516d433 233 &global_config.nodes[n_unit].address,
mariob 0:cc364516d433 234 &global_config.nodes[n_unit].watering_wait,
mariob 0:cc364516d433 235 &global_config.nodes[n_unit].watering_seconds);
mariob 0:cc364516d433 236 n_unit++;
mariob 0:cc364516d433 237 if (n_unit >= global_config.num_units || n_unit >=MAX_NUM_NODES)
mariob 0:cc364516d433 238 state = 3;
mariob 0:cc364516d433 239 break;
mariob 0:cc364516d433 240 }
mariob 0:cc364516d433 241 }
mariob 0:cc364516d433 242 fclose(fp);
mariob 2:69d2d4c76f02 243
mariob 0:cc364516d433 244 return true;
mariob 0:cc364516d433 245 }
mariob 0:cc364516d433 246
mariob 0:cc364516d433 247 bool read_counter () {
mariob 0:cc364516d433 248 FILE *fp = fopen(FILE_CNT, "r");
mariob 0:cc364516d433 249 if(fp == NULL) {
mariob 0:cc364516d433 250 fp = fopen(FILE_CNT, "w");
mariob 0:cc364516d433 251 if(fp == NULL)
mariob 0:cc364516d433 252 return false;
mariob 0:cc364516d433 253 global_config.count = 0;
mariob 0:cc364516d433 254 fprintf(fp, "0\n");
mariob 0:cc364516d433 255 } else
mariob 0:cc364516d433 256 fscanf(fp, "%d\n", &global_config.count);
mariob 0:cc364516d433 257 fclose(fp);
mariob 0:cc364516d433 258
mariob 0:cc364516d433 259 return true;
mariob 0:cc364516d433 260 }