Mario Bambagini / Mbed 2 deprecated supervisor

Dependencies:   mbed-rtos mbed ssWi

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "rtos.h"
00003 
00004 #include "config.h"
00005 
00006 #include "xbee.hpp"
00007 #include "ssWiSocket.hpp"
00008 
00009 #ifndef DEBUG
00010 #define     printf(fmt,...)     
00011 #endif
00012 
00013 // global configuration
00014 global_confg_t global_config;
00015 
00016 // ssWi sockets
00017 ssWiSocket* socket_command;
00018 ssWiSocket* socket_moisture[MAX_NUM_NODES];
00019 ssWiSocket* socket_temperature[MAX_NUM_NODES];
00020 ssWiSocket* socket_humidity[MAX_NUM_NODES];
00021 ssWiSocket* socket_response[MAX_NUM_NODES];
00022 ssWiSocket* socket_water[MAX_NUM_NODES];
00023 
00024 LocalFileSystem local("local");
00025 
00026 // read counter value from file
00027 bool read_counter();
00028 // read board configuration from file
00029 bool read_configuration();
00030 
00031 // return true if a message has been received, false otherwise
00032 bool read_from_port(ssWiSocket *socket, int *value);
00033 // blocking read - timeout after 10 seconds
00034 bool read_timeout(ssWiSocket *socket, int *value);
00035 
00036 void do_sampling();
00037 void do_watering();
00038 
00039 int main() {
00040     DigitalOut power_device(POWER_EN_PIN);
00041     power_device = POWER_OFF;
00042 
00043     // supervisor configuration
00044     printf("SUPERVISOR - config\r\n");
00045 
00046     // read configuration
00047     if (!read_configuration())
00048         error("Impossible to read configuration");
00049 
00050     // network configuration
00051     XBeeModule xbee(XBEE_PIN_TX, XBEE_PIN_RX, PAN_ID, CHANNEL_ID);
00052     xbee.init(XBEE_TX_PER_SECOND, XBEE_RX_PER_SECOND);
00053     socket_command = ssWiSocket::createSocket(PORT_COMMANDS);
00054     for (int i = 0; i < global_config.num_units; i++) {
00055         socket_moisture[i] = ssWiSocket::createSocket(
00056                      global_config.nodes[i].address * 5 + PORT_MOISTURE_OFFSET);
00057         socket_temperature[i] = ssWiSocket::createSocket(
00058                   global_config.nodes[i].address * 5 + PORT_TEMPERATURE_OFFSET);
00059         socket_humidity[i] = ssWiSocket::createSocket(
00060                      global_config.nodes[i].address * 5 + PORT_HUMIDITY_OFFSET);
00061         socket_response[i] = ssWiSocket::createSocket(
00062                      global_config.nodes[i].address * 5 + PORT_RESPONSE_OFFSET);
00063         socket_water[i] = ssWiSocket::createSocket(
00064                         global_config.nodes[i].address * 5 + PORT_WATER_OFFSET);
00065     }
00066 
00067     // start
00068     printf("SUPERVISOR - start\r\n");
00069 
00070     while(1) {
00071         int minute_counters = 0;
00072         printf("SUPERVISOR - waiting\r\n");
00073         do {
00074             // wait 1 minute
00075             Thread::wait(INTERVAL_60_SECONDS * 1000);
00076             minute_counters++;
00077         } while (minute_counters < global_config.wait_minutes);
00078 
00079         printf("SUPERVISOR - active\r\n");
00080 
00081         // mark as busy
00082         DigitalOut led_busy(LED4);
00083         led_busy = 1;
00084         FILE* fp_busy = fopen(FILE_BSY, "w");
00085 
00086         // power watering units
00087         power_device = POWER_ON;
00088         wait(INTERVAL_POWER_START);
00089         
00090         read_counter();
00091 
00092         // sample and water
00093         printf("SUPERVISOR - sampling\r\n");
00094         do_sampling();
00095         printf("SUPERVISOR - watering\r\n");
00096         do_watering();
00097         
00098         // increment counter
00099         global_config.count++;
00100         FILE* fp = fopen(FILE_CNT, "w");
00101         fprintf(fp, "%d\n", global_config.count);
00102         fclose(fp);
00103 
00104         // send shutdown
00105         printf("SUPERVISOR - shutdown\r\n");
00106 
00107         wait(INTERVAL_SYNC);
00108         socket_command->write(COMM_SHUTDOWN);
00109         wait(INTERVAL_SYNC * 2);
00110 
00111         // power off devices
00112         power_device = POWER_OFF;
00113         
00114         // mark as not busy
00115         led_busy = 0;
00116         fclose(fp_busy);
00117     }
00118 }
00119 
00120 void do_sampling () {
00121     FILE* fp = fopen(FILE_SNS, "a");
00122 
00123     socket_command->write(COMM_START_SAMPLING);
00124     wait(INTERVAL_SAMPLING);
00125     
00126     socket_command->write(COMM_STOP_SAMPLING);
00127     wait(INTERVAL_SYNC);
00128 
00129     for (int i = 0; i < global_config.num_units; i++) {
00130         int temp = 0, humi = 0, mois = 0, sampling_feedback = COMM_NO_VALUE;
00131         int code;
00132         if (!read_timeout(socket_response[i], &sampling_feedback))
00133             code = 1;
00134         else {
00135             switch (sampling_feedback) {
00136                 case COMM_SAMPLING_OK:
00137                     code = (read_timeout(socket_temperature[i], &temp) &&
00138                             read_timeout(socket_humidity[i], &humi) &&
00139                             read_timeout(socket_moisture[i], &mois)) ? 0 : 2;
00140                     break;
00141                 case COMM_SAMPLING_KO: code = 3; break;
00142                 case COMM_SAMPLING_OUT: code = 4; break;
00143                 default: code = 5;
00144             }
00145         }
00146         fprintf(fp, "%d %d %d %4.2f %4.2f %4.2f\n", global_config.count,
00147                                                  global_config.nodes[i].address,
00148                                                  code,
00149                                                  (double)humi/10.0,
00150                                                  (double)temp/10.0,
00151                                                  (double)mois/10.0);
00152     }
00153     fclose(fp);
00154 }
00155 
00156 void do_watering () {
00157     FILE* fp = fopen(FILE_WTR, "a");
00158     for (int i = 0; i < global_config.num_units; i++) {
00159         if (global_config.count % global_config.nodes[i].watering_wait)
00160             continue;
00161         // write watering time in seconds
00162         socket_water[i]->write(global_config.nodes[i].watering_seconds);
00163         wait(INTERVAL_SYNC);
00164         // send watering command
00165         socket_command->write(COMM_START_WATERING_OFFSET + 
00166                                                 global_config.nodes[i].address);
00167         wait(global_config.nodes[i].watering_seconds + INTERVAL_SYNC + 
00168                                                                  INTERVAL_SYNC);
00169         
00170         int watering_response = 0;
00171         int code = 4;
00172         if (read_timeout(socket_response[i], &watering_response)) {
00173             switch(watering_response) {
00174                 case COMM_WATERING_KO: code = 1; break;
00175                 case COMM_WATERING_OK: code = 0; break;
00176                 case COMM_LOW_WATER_LEVEL: code = 2; break;
00177                 default: code = 3;
00178             }
00179         }
00180         fprintf(fp, "%d %d %d %d\n", global_config.count,
00181                                      global_config.nodes[i].address,
00182                                      code,
00183                                      global_config.nodes[i].watering_seconds);
00184     }
00185     fclose(fp);
00186 }
00187 
00188 bool read_from_port(ssWiSocket *socket, int *value) {
00189     int prev = *value;
00190     *value = socket->read();
00191     return (*value) != prev;
00192 }
00193 
00194 bool read_timeout(ssWiSocket *socket, int *value) {
00195     Timer t;
00196     t.start();
00197     bool ret;
00198     int v = COMM_NO_VALUE;
00199     double start = t.read();
00200     do {
00201         if ((t.read() - start) > TIMEOUT_READ)
00202             return false;
00203         ret = read_from_port(socket, &v);
00204     } while(!ret);
00205     t.stop();
00206     *value = v;
00207     return true;
00208 }
00209 
00210 bool read_configuration() {
00211     int state = 0;
00212     int n_unit = 0;
00213     
00214     FILE *fp = fopen(FILE_CFG, "r");
00215     if(fp == NULL)
00216         return false;
00217     char line[250];
00218     
00219     while(fgets(line, sizeof(line), fp)) {
00220         if (line[0] == '#')
00221             continue;
00222         switch(state) {
00223             case 0: //read interval length
00224                 sscanf(line, "%d\r", &global_config.wait_minutes);
00225                 state = 1;
00226                 break;
00227             case 1: //read number of watering units
00228                 sscanf(line, "%d\r", &global_config.num_units);
00229                 state = 2;
00230                 break;
00231             case 2: //read number of watering units
00232                 sscanf(line, "%d %d %d\r",
00233                                 &global_config.nodes[n_unit].address,
00234                                 &global_config.nodes[n_unit].watering_wait,
00235                                 &global_config.nodes[n_unit].watering_seconds);
00236                 n_unit++;
00237                 if (n_unit >= global_config.num_units || n_unit >=MAX_NUM_NODES)
00238                     state = 3;
00239                 break;
00240         }
00241     }
00242     fclose(fp);
00243 
00244     return true;
00245 }
00246 
00247 bool read_counter () {
00248     FILE *fp = fopen(FILE_CNT, "r");
00249     if(fp == NULL) {
00250         fp = fopen(FILE_CNT, "w");
00251         if(fp == NULL)
00252             return false;
00253         global_config.count = 0;
00254         fprintf(fp, "0\n");
00255     } else
00256         fscanf(fp, "%d\n", &global_config.count);
00257     fclose(fp);
00258     
00259     return true;
00260 }