
IoT_watering project - supervisor
Dependencies: mbed-rtos mbed ssWi
Revision 0:cc364516d433, committed 2017-01-18
- Comitter:
- mariob
- Date:
- Wed Jan 18 21:01:38 2017 +0000
- Child:
- 1:dcfe7e79a45c
- Commit message:
- alpha release
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config.hpp Wed Jan 18 21:01:38 2017 +0000 @@ -0,0 +1,55 @@ +#ifndef __SUPERVISOR_CONFIG__ +#define __SUPERVISOR_CONFIG__ + +// TIME +#define TIMEOUT_READ 10.0 +#define INTERVAL_SAMPLING 40.0 +#define INTERVAL_SYNC 5.0 +#define INTERVAL_1_SECOND 1.0 +#define INTERVAL_60_SECONDS 60 + +// COMM VALUES +#define COMM_NO_VALUE 0x0000 +#define COMM_START_SAMPLING 0xAAAA +#define COMM_STOP_SAMPLING 0x1111 +#define COMM_START_WATERING_OFFSET 0xFF00 +#define COMM_SHUTDOWN 0x00FF +#define COMM_EXIT 0x2244 +#define COMM_SAMPLING_KO 0x2222 +#define COMM_SAMPLING_OUT 0x5555 +#define COMM_SAMPLING_OK 0xBBBB +#define COMM_WATERING_KO 0x3333 +#define COMM_WATERING_OK 0xCCCC +#define COMM_LOW_WATER_LEVEL 0x7777 + +// PORTS +#define PORT_COMMANDS 0x00 +#define PORT_HUMIDITY_OFFSET 0x01 +#define PORT_TEMPERATURE_OFFSET 0x02 +#define PORT_MOISTURE_OFFSET 0x03 +#define PORT_WATER_OFFSET 0x04 +#define PORT_RESPONSE_OFFSET 0x05 + +#define MAX_NUM_NODES 10 + +// FILES +#define FILE_CNT "/local/CNT.txt" +#define FILE_CFG "/local/cfg.txt" +#define FILE_SNS "/local/SNS.txt" +#define FILE_WTR "/local/WTR.txt" +#define FILE_BSY "/local/BSY.txt" + +struct watering_unit_node_t { + int address; + int watering_wait; + int watering_seconds; +}; + +struct global_confg_t { + int count; + int wait_minutes; + int num_units; + watering_unit_node_t nodes[MAX_NUM_NODES]; +} global_config; + +#endif //__SUPERVISOR_CONFIG__
--- /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; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Wed Jan 18 21:01:38 2017 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#58563e6cba1e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Jan 18 21:01:38 2017 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/99b5ccf27215 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ssWi.lib Wed Jan 18 21:01:38 2017 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mariob/code/ssWi/#8ba1b278b407