IoT_watering project - watering unit
Dependencies: DHT11 mbed-rtos mbed ssWi
main.cpp
- Committer:
- mariob
- Date:
- 2017-01-19
- Revision:
- 0:51143a026e2b
- Child:
- 1:7f4af0d73836
File content as of revision 0:51143a026e2b:
#include "mbed.h" #include "rtos.h" #include "config.hpp" #include "DHT11.h" #include "xbee.hpp" #include "ssWiSocket.hpp" LocalFileSystem local("local"); watering_unit_config_t global_config; void thread_sensing_fcn(); void thread_watering_fcn(); ssWiSocket* socket_moisture = NULL; ssWiSocket* socket_temperature = NULL; ssWiSocket* socket_humidity = NULL; ssWiSocket* socket_response = NULL; ssWiSocket* socket_water = NULL; ssWiSocket* socket_command = NULL; bool read_from_port(ssWiSocket *socket, int *value); int main() { Timer t; t.start(); // read configuration #ifdef DEBUG printf("\r\nMAIN - configuration\r\n"); #endif FILE *fp = fopen("/local/cfg.txt", "r"); if (fp == NULL) error("missing configuration file\r\n"); fscanf(fp, "%d", &global_config.address); fclose(fp); global_config.moisture_port = GET_MOISTURE_PORT(global_config); global_config.temperature_port = GET_TEMPERATURE_PORT(global_config); global_config.humidity_port = GET_HUMIDITY_PORT(global_config); global_config.response_port = GET_RESPONSE_PORT(global_config); global_config.water_port = GET_WATER_PORT(global_config); // configure network XBeeModule xbee(p9, p10, 102, 14); xbee.init(5, 10); socket_moisture = ssWiSocket::createSocket(global_config.moisture_port); socket_temperature = ssWiSocket::createSocket(global_config.temperature_port); socket_humidity = ssWiSocket::createSocket(global_config.humidity_port); socket_response = ssWiSocket::createSocket(global_config.response_port); socket_water = ssWiSocket::createSocket(global_config.water_port); socket_command = ssWiSocket::createSocket(PORT_COMMANDS); // threads Thread thread_sensing(osPriorityAboveNormal); thread_sensing.start(&thread_sensing_fcn); Thread thread_watering(osPriorityHigh); thread_watering.start(&thread_watering_fcn); // wait 10 seconds since the board started while(t.read() < TIMEOUT_CONF); t.stop(); #ifdef DEBUG printf("MAIN - board ready\r\n"); #endif // handle messages bool recv_start_sampling = false; bool recv_stop_sampling = false; bool recv_watering = false; int msg = COMM_NO_VALUE; while(true) { if (!read_from_port(socket_command, &msg)) continue; if (!recv_start_sampling && msg == COMM_START_SAMPLING) { recv_start_sampling = true; #ifdef DEBUG printf("MAIN - sampling start command\r\n"); #endif thread_sensing.signal_set(SIGNAL_START_ARRIVED); continue; } if (!recv_stop_sampling && msg == COMM_STOP_SAMPLING) { recv_stop_sampling = true; #ifdef DEBUG printf("MAIN - sampling stop command\r\n"); #endif thread_sensing.signal_set(SIGNAL_STOP_ARRIVED); continue; } if (!recv_watering && msg == GET_WATERING_COMMAND(global_config)) { recv_watering = true; #ifdef DEBUG printf("MAIN - watering start command\r\n"); #endif thread_watering.signal_set(SIGNAL_WATERING_ARRIVED); continue; } if (msg == COMM_SHUTDOWN) { #ifdef DEBUG printf("MAIN - shutdown command\r\n"); #endif recv_start_sampling = false; recv_stop_sampling = false; recv_watering = false; /* socket_moisture->write(COMM_NO_VALUE); socket_temperature->write(COMM_NO_VALUE); socket_humidity->write(COMM_NO_VALUE); */ socket_response->write(COMM_NO_VALUE); continue; } if (msg == COMM_EXIT) { #ifdef DEBUG printf("MAIN - exit command\r\n"); #endif /* socket_moisture->write(COMM_NO_VALUE); socket_temperature->write(COMM_NO_VALUE); socket_humidity->write(COMM_NO_VALUE); */ socket_response->write(COMM_NO_VALUE); break; } } #ifdef DEBUG printf("MAIN - join threads and end\r\n"); #endif thread_sensing.join(); thread_watering.join(); return 0; } void thread_sensing_fcn() { AnalogIn sensor_moisture(HW_PIN_MOISTURE); while (1) { int msg = COMM_SAMPLING_OK; DHT11 sensor_dht(HW_PIN_TEMPERATURE); #ifdef DEBUG printf("SAMP - waiting...\r\n"); #endif // wait supervisor message Thread::signal_wait(SIGNAL_START_ARRIVED); #ifdef DEBUG printf("SAMP - start\r\n"); #endif Timer t; t.start(); // wait two seconds for HDT sensor wait(2.0); // sample values double sens_moisture = 0.0; double sens_temperature = 0.0; double sens_humidity = 0.0; int num_dht_samples = 0; for (int i = 0; i < NUM_SAMPLES; i++) { int error = sensor_dht.readData(); if (error != 0) { printf("SAMP - error %d\r\n", error); msg = COMM_SAMPLING_KO; } else { sens_temperature += sensor_dht.readTemperature(); sens_humidity += sensor_dht.readHumidity(); num_dht_samples += 1; } sens_moisture += sensor_moisture.read() * 100; // if timeout is expired, exit if (t.read() > TIMEOUT_SAMPLING) { msg = COMM_SAMPLING_OUT; break; } Thread::wait(INTERVAL_SAMPLING); } t.stop(); // compute averages sens_moisture = (sens_moisture / NUM_SAMPLES) * 10; if (num_dht_samples > 0) { sens_temperature = (sens_temperature / num_dht_samples) * 10; sens_humidity = (sens_humidity / num_dht_samples) * 10; } #ifdef DEBUG printf("SAMP - %f, %f, %f\r\n", sens_moisture, sens_temperature, sens_humidity); #endif // wait supervisor stop message Thread::signal_wait(SIGNAL_STOP_ARRIVED); // write averages and response int value = (int)sens_moisture; socket_moisture->write(value == 0 ? 1 : value); value = (int)sens_temperature; socket_temperature->write(value == 0 ? 1 : value); value = (int)sens_humidity; socket_humidity->write(value == 0 ? 1 : value); socket_response->write(msg); #ifdef DEBUG printf("SAMP - end\r\n"); #endif } } void thread_watering_fcn() { DigitalOut pump(HW_PIN_PUMP); DigitalIn level_sens(HW_PIN_LOW_WATER_LEVEL); while (1) { pump = 0; #ifdef DEBUG printf("WATR - waiting...\r\n"); #endif Thread::signal_wait(SIGNAL_WATERING_ARRIVED); #ifdef DEBUG printf("WATR - start\r\n"); #endif Timer t; t.start(); // read total second to water int seconds = COMM_NO_VALUE; while(!read_from_port(socket_water, &seconds) && t.read()<TIMEOUT_WATERING); t.stop(); if (t.read() >= TIMEOUT_WATERING) { socket_response->write(COMM_WATERING_KO); continue; } #ifdef DEBUG printf("WATR - required time %ds\r\n", seconds); #endif int msg = COMM_WATERING_OK; double actual_seconds = 0.0; while (actual_seconds < seconds) { if (!level_sens) { pump = 0; #ifdef DEBUG printf("WATR - watering level error\r\n"); #endif msg = COMM_LOW_WATER_LEVEL; t.stop(); break; } t.reset(); t.start(); double scale = seconds > (actual_seconds + 1.0) ? 1.0 : seconds - actual_seconds; pump = 1; Thread::wait((unsigned int)(scale * INTERVAL_WATERING)); t.stop(); actual_seconds += t.read(); } pump = 0; #ifdef DEBUG printf("WATR - elapsed time %fs\r\n", actual_seconds); #endif socket_response->write(msg); #ifdef DEBUG printf("WATR - end\r\n"); #endif } } bool read_from_port(ssWiSocket *socket, int *value) { int prev = *value; *value = socket->read(); return (*value) != prev; }