IoT_watering project - supervisor
Dependencies: mbed-rtos mbed ssWi
main.cpp
- Committer:
- mariob
- Date:
- 2017-02-16
- Revision:
- 3:e49dd7bf7f1c
- Parent:
- 2:69d2d4c76f02
File content as of revision 3:e49dd7bf7f1c:
#include "mbed.h" #include "rtos.h" #include "config.h" #include "xbee.hpp" #include "ssWiSocket.hpp" #ifndef DEBUG #define printf(fmt,...) #endif // global configuration global_confg_t global_config; // ssWi sockets 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"); // read counter value from file bool read_counter(); // read board configuration from file bool read_configuration(); // return true if a message has been received, false otherwise bool read_from_port(ssWiSocket *socket, int *value); // blocking read - timeout after 10 seconds bool read_timeout(ssWiSocket *socket, int *value); void do_sampling(); void do_watering(); int main() { DigitalOut power_device(POWER_EN_PIN); power_device = POWER_OFF; // supervisor configuration printf("SUPERVISOR - config\r\n"); // read configuration if (!read_configuration()) error("Impossible to read configuration"); // network configuration XBeeModule xbee(XBEE_PIN_TX, XBEE_PIN_RX, PAN_ID, CHANNEL_ID); xbee.init(XBEE_TX_PER_SECOND, XBEE_RX_PER_SECOND); 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); } // start printf("SUPERVISOR - start\r\n"); while(1) { int minute_counters = 0; printf("SUPERVISOR - waiting\r\n"); do { // wait 1 minute Thread::wait(INTERVAL_60_SECONDS * 1000); minute_counters++; } while (minute_counters < global_config.wait_minutes); printf("SUPERVISOR - active\r\n"); // mark as busy DigitalOut led_busy(LED4); led_busy = 1; FILE* fp_busy = fopen(FILE_BSY, "w"); // power watering units power_device = POWER_ON; wait(INTERVAL_POWER_START); read_counter(); // sample and water printf("SUPERVISOR - sampling\r\n"); do_sampling(); printf("SUPERVISOR - watering\r\n"); do_watering(); // increment counter global_config.count++; FILE* fp = fopen(FILE_CNT, "w"); fprintf(fp, "%d\n", global_config.count); fclose(fp); // send shutdown printf("SUPERVISOR - shutdown\r\n"); wait(INTERVAL_SYNC); socket_command->write(COMM_SHUTDOWN); wait(INTERVAL_SYNC * 2); // power off devices power_device = POWER_OFF; // mark as not busy led_busy = 0; fclose(fp_busy); } } void do_sampling () { FILE* fp = fopen(FILE_SNS, "a"); socket_command->write(COMM_START_SAMPLING); wait(INTERVAL_SAMPLING); socket_command->write(COMM_STOP_SAMPLING); wait(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 () { FILE* fp = fopen(FILE_WTR, "a"); for (int i = 0; i < global_config.num_units; i++) { if (global_config.count % global_config.nodes[i].watering_wait) continue; // write watering time in seconds socket_water[i]->write(global_config.nodes[i].watering_seconds); wait(INTERVAL_SYNC); // send watering command socket_command->write(COMM_START_WATERING_OFFSET + global_config.nodes[i].address); wait(global_config.nodes[i].watering_seconds + INTERVAL_SYNC + INTERVAL_SYNC); 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; 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 () { 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; }