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;
}
Mario Bambagini