IoT_watering project - watering unit
Dependencies: DHT11 mbed-rtos mbed ssWi
main.cpp
- Committer:
- mariob
- Date:
- 2017-02-16
- Revision:
- 2:0b51e6d879df
- Parent:
- 1:7f4af0d73836
File content as of revision 2:0b51e6d879df:
#include "mbed.h"
#include "rtos.h"
#include "config.hpp"
#include "DHT11.h"
#include "xbee.hpp"
#include "ssWiSocket.hpp"
#ifndef DEBUG
#define printf(fmt,...)
#endif
LocalFileSystem local("local");
// global configuration
watering_unit_config_t global_config;
// ssWi sockets
ssWiSocket* socket_moisture = NULL;
ssWiSocket* socket_temperature = NULL;
ssWiSocket* socket_humidity = NULL;
ssWiSocket* socket_response = NULL;
ssWiSocket* socket_water = NULL;
ssWiSocket* socket_command = NULL;
// thread functions
void thread_sensing_fcn();
void thread_watering_fcn();
// return true if a new message has been received, false otherwise
bool read_from_port(ssWiSocket *socket, int *value);
int main() {
Timer t;
t.start();
printf("MAIN - configuration\r\n");
// read configuration
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(XBEE_PIN_TX, XBEE_PIN_RX, PAN_ID, CHANNEL_ID);
xbee.init(XBEE_TX_PER_SECOND, XBEE_RX_PER_SECOND);
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();
printf("MAIN - board ready\r\n");
// 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;
printf("MAIN - sampling start command\r\n");
thread_sensing.signal_set(SIGNAL_START_ARRIVED);
continue;
}
if (!recv_stop_sampling && msg == COMM_STOP_SAMPLING) {
recv_stop_sampling = true;
printf("MAIN - sampling stop command\r\n");
thread_sensing.signal_set(SIGNAL_STOP_ARRIVED);
continue;
}
if (!recv_watering && msg == GET_WATERING_COMMAND(global_config)) {
recv_watering = true;
printf("MAIN - watering start command\r\n");
thread_watering.signal_set(SIGNAL_WATERING_ARRIVED);
continue;
}
if (msg == COMM_SHUTDOWN) {
printf("MAIN - shutdown command\r\n");
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;
}
}
printf("MAIN - join threads and end\r\n");
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);
printf("SAMP - waiting...\r\n");
// wait supervisor message
Thread::signal_wait(SIGNAL_START_ARRIVED);
printf("SAMP - start\r\n");
DigitalOut l(LED3);
l = 1;
Timer t;
t.start();
// wait two seconds for HDT sensor
wait(2.0);
// sample values
double sens_mois = 0.0;
double sens_temp = 0.0;
double sens_humi = 0.0;
for (int i = 0; i < NUM_SAMPLES; i++) {
if (sensor_dht.readData() != 0) {
printf("SAMP - error %d\r\n", error);
msg = COMM_SAMPLING_KO;
break;
}
sens_temp += sensor_dht.readTemperature();
sens_humi += sensor_dht.readHumidity();
sens_mois += sensor_moisture.read() * 100;
if (t.read() > TIMEOUT_SAMPLING) {
// timeout expired, exit
msg = COMM_SAMPLING_OUT;
break;
}
Thread::wait(INTERVAL_SAMPLING);
}
t.stop();
// compute averages
sens_mois = (sens_mois / NUM_SAMPLES) * 10.0;
sens_temp = (sens_temp / NUM_SAMPLES) * 10.0;
sens_humi = (sens_humi / NUM_SAMPLES) * 10.0;
printf("SAMP - %f, %f, %f\r\n", sens_mois, sens_temp, sens_humi);
// wait supervisor stop message
Thread::signal_wait(SIGNAL_STOP_ARRIVED);
// write averages and response
int value = (int)sens_mois;
socket_moisture->write(value == 0 ? 1 : value);
value = (int)sens_temp;
socket_temperature->write(value == 0 ? 1 : value);
value = (int)sens_humi;
socket_humidity->write(value == 0 ? 1 : value);
socket_response->write(msg);
printf("SAMP - end\r\n");
l = 0;
}
}
void thread_watering_fcn() {
DigitalOut pump(HW_PIN_PUMP);
DigitalIn level_sens(HW_PIN_LOW_WATER_LEVEL);
while (1) {
pump = 0;
printf("WATR - waiting...\r\n");
// wait watering command
Thread::signal_wait(SIGNAL_WATERING_ARRIVED);
printf("WATR - start\r\n");
Timer t;
t.start();
DigitalOut l(LED2);
l = 1;
// 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;
}
printf("WATR - required time %ds\r\n", seconds);
// start watering
int msg = COMM_WATERING_OK;
double actual_seconds = 0.0;
while (actual_seconds < seconds) {
if (!level_sens) {
// low water, stop pump and exit
pump = 0;
printf("WATR - watering level error\r\n");
msg = COMM_LOW_WATER_LEVEL;
break;
}
// water for 1 second
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;
printf("WATR - elapsed time %fs\r\n", actual_seconds);
socket_response->write(msg);
l = 0;
}
}
bool read_from_port(ssWiSocket *socket, int *value) {
int prev = *value;
*value = socket->read();
return (*value) != prev;
}
Mario Bambagini