IoT_watering project - supervisor
Dependencies: mbed-rtos mbed ssWi
Diff: main.cpp
- Revision:
- 0:cc364516d433
- Child:
- 1:dcfe7e79a45c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Jan 18 21:01:38 2017 +0000 @@ -0,0 +1,262 @@ +#include "mbed.h" +#include "rtos.h" + +#include "config.hpp" + +#include "xbee.hpp" +#include "ssWiSocket.hpp" + +int last_watering[MAX_NUM_NODES]; + +ssWiSocket* socket_command; +ssWiSocket* socket_moisture[MAX_NUM_NODES]; +ssWiSocket* socket_temperature[MAX_NUM_NODES]; +ssWiSocket* socket_humidity[MAX_NUM_NODES]; +ssWiSocket* socket_response[MAX_NUM_NODES]; +ssWiSocket* socket_water[MAX_NUM_NODES]; + +LocalFileSystem local("local"); + +bool read_counter(); +bool read_configuration(); + +bool read_from_port(ssWiSocket *socket, int *value); + +bool read_timeout(ssWiSocket *socket, int *value); + +void do_sampling(); +void do_watering(); + +int main() { + // supervisor configuration +#ifdef DEBUG + printf("SUPERVISOR - config\r\n"); +#endif + if (!read_configuration()) + error("Impossible to read configuration"); + + // network configuration + XBeeModule xbee(p9, p10, 102, 14); + xbee.init(5, 10); + socket_command = ssWiSocket::createSocket(PORT_COMMANDS); + for (int i = 0; i < global_config.num_units; i++) { + socket_moisture[i] = ssWiSocket::createSocket( + global_config.nodes[i].address * 5 + PORT_MOISTURE_OFFSET); + socket_temperature[i] = ssWiSocket::createSocket( + global_config.nodes[i].address * 5 + PORT_TEMPERATURE_OFFSET); + socket_humidity[i] = ssWiSocket::createSocket( + global_config.nodes[i].address * 5 + PORT_HUMIDITY_OFFSET); + socket_response[i] = ssWiSocket::createSocket( + global_config.nodes[i].address * 5 + PORT_RESPONSE_OFFSET); + socket_water[i] = ssWiSocket::createSocket( + global_config.nodes[i].address * 5 + PORT_WATER_OFFSET); + } + + // initialize shared variables + for (int i = 0; i < MAX_NUM_NODES; i++) + last_watering[i] = 1; + + // start +#ifdef DEBUG + printf("SUPERVISOR - start\r\n"); +#endif + while(1) { + int minute_counters = 0; + read_counter(); +#ifdef DEBUG + printf("SUPERVISOR - wait...\r\n"); +#endif + do { + // wait 1 minute + Thread::wait(INTERVAL_60_SECONDS * 1000); + minute_counters++; + } while (minute_counters < global_config.wait_minutes); + + // mark as busy + DigitalOut led_busy(LED4); + led_busy = 1; + FILE* fp_busy = fopen(FILE_BSY, "w"); + + // sample and water +#ifdef DEBUG + printf("SUPERVISOR - sampling\r\n"); +#endif + do_sampling(); +#ifdef DEBUG + printf("SUPERVISOR - watering\r\n"); +#endif + do_watering(); + + // increment counter + global_config.count++; + FILE* fp = fopen(FILE_CNT, "w"); + fprintf(fp, "%d\n", global_config.count); + fclose(fp); + + // send shutdown +#ifdef DEBUG + printf("SUPERVISOR - shutdown\r\n"); +#endif + wait(INTERVAL_SYNC); + socket_command->write(COMM_SHUTDOWN); + wait(INTERVAL_SYNC); + socket_command->write(COMM_NO_VALUE); + wait(INTERVAL_SYNC); + + // mark as not busy + led_busy = 0; + fclose(fp_busy); + } +} + +void do_sampling () { + FILE* fp = fopen(FILE_SNS, "a"); + Timer t; + + socket_command->write(COMM_START_SAMPLING); + t.start(); + while(t.read() < INTERVAL_SAMPLING); + + socket_command->write(COMM_STOP_SAMPLING); + t.reset(); + while(t.read() < INTERVAL_SYNC); + + for (int i = 0; i < global_config.num_units; i++) { + int temp = 0, humi = 0, mois = 0, sampling_feedback = COMM_NO_VALUE; + int code; + if (!read_timeout(socket_response[i], &sampling_feedback)) + code = 1; + else { + switch (sampling_feedback) { + case COMM_SAMPLING_OK: + code = (read_timeout(socket_temperature[i], &temp) && + read_timeout(socket_humidity[i], &humi) && + read_timeout(socket_moisture[i], &mois)) ? 0 : 2; + break; + case COMM_SAMPLING_KO: code = 3; break; + case COMM_SAMPLING_OUT: code = 4; break; + default: code = 5; + } + } + fprintf(fp, "%d %d %d %4.2f %4.2f %4.2f\n", global_config.count, + global_config.nodes[i].address, + code, + (double)humi/10.0, + (double)temp/10.0, + (double)mois/10.0); + } + fclose(fp); +} + +void do_watering () { + for (int i = 0; i < global_config.num_units; i++) { + if (global_config.count % global_config.nodes[i].watering_wait) + continue; + FILE* fp = fopen(FILE_WTR, "a"); + + socket_water[i]->write(global_config.nodes[i].watering_seconds); + + Timer t; + t.start(); + wait(t.read() < INTERVAL_1_SECOND); + + socket_command->write(COMM_START_WATERING_OFFSET + + global_config.nodes[i].address); + t.reset(); + while (t.read() < (global_config.nodes[i].watering_seconds + + INTERVAL_SYNC)); + t.stop(); + + int watering_response = 0; + int code = 4; + if (read_timeout(socket_response[i], &watering_response)) { + switch(watering_response) { + case COMM_WATERING_KO: code = 1; break; + case COMM_WATERING_OK: code = 0; break; + case COMM_LOW_WATER_LEVEL: code = 2; break; + default: code = 3; + } + } + fprintf(fp, "%d %d %d %d\n", global_config.count, + global_config.nodes[i].address, + code, + global_config.nodes[i].watering_seconds); + fclose(fp); + } +} + +bool read_from_port(ssWiSocket *socket, int *value) { + int prev = *value; + *value = socket->read(); + return (*value) != prev; +} + +bool read_timeout(ssWiSocket *socket, int *value) { + Timer t; + t.start(); + bool ret; + int v = COMM_NO_VALUE; + double start = t.read(); + do { + if ((t.read() - start) > TIMEOUT_READ) + return false; + ret = read_from_port(socket, &v); + } while(!ret); + t.stop(); + *value = v; + return true; +} + +bool read_configuration() { + int state = 0; + int n_unit = 0; + + // read configuration file + FILE *fp = fopen(FILE_CFG, "r"); + if(fp == NULL) + return false; + char line[250]; + + while(fgets(line, sizeof(line), fp)) { + if (line[0] == '#') + continue; + switch(state) { + case 0: //read interval length + sscanf(line, "%d\r", &global_config.wait_minutes); + state = 1; + break; + case 1: //read number of watering units + sscanf(line, "%d\r", &global_config.num_units); + state = 2; + break; + case 2: //read number of watering units + sscanf(line, "%d %d %d\r", + &global_config.nodes[n_unit].address, + &global_config.nodes[n_unit].watering_wait, + &global_config.nodes[n_unit].watering_seconds); + n_unit++; + if (n_unit >= global_config.num_units || n_unit >=MAX_NUM_NODES) + state = 3; + break; + } + } + fclose(fp); + + return true; +} + +bool read_counter () { + // read counter + FILE *fp = fopen(FILE_CNT, "r"); + if(fp == NULL) { + fp = fopen(FILE_CNT, "w"); + if(fp == NULL) + return false; + global_config.count = 0; + fprintf(fp, "0\n"); + } else + fscanf(fp, "%d\n", &global_config.count); + fclose(fp); + + return true; +}