yet another 18B20 Temperature sensor. variable number of sensors working in parasite mode, serial 16x2 display with diagnostic output and post to a rest web service

Dependencies:   EthernetInterface HTTPClient NTPClient mbed-rtos mbed

main.cpp

Committer:
wkinkeldei
Date:
2013-01-03
Revision:
1:9e88b2508768
Parent:
0:53f05303850a

File content as of revision 1:9e88b2508768:

#include "mbed.h"
#include "rtos.h"
#include "EthernetInterface.h"

#include <list>

#include "sparkfun.h"
#include "ntp_proxy.h"
#include "collector_proxy.h"
#include "sensor.h"
#include "temperature_sensor.h"
#include "switch_sensor.h"
#include "local_time.h"

SparkFun display(p28);
list<Sensor *> sensors;

void wait_minutes(int m = 1) {
    while (m-- > 0)
        Thread::wait(1000 * 60);
}

void wait_seconds(int s = 1) {
    while (s-- > 0)
        Thread::wait(1000);
}

/*
    ntp Thread: poll NTP Server every 3 hours
*/
void ntp_thread(void const *args) {
    NtpProxy ntp((const char *) args);
    
    while (true) {
        display.show_ntp_status('t');
        if (ntp.set_time()) {
            // successful: wait 3 hours
            display.show_ntp_status('T');
            wait_minutes(180);
        } else {
            // failure: retry after 5 minutes
            display.show_ntp_status('?');
            wait_minutes(5);
        }
    }
}

/*
    display Thread: show a sensor every 2 seconds and current time
*/
void display_thread(void const *args) {
    char buffer[20];
    int last_minute = -1;
    LocalTime l;
    struct tm *t;
    list<Sensor *>::iterator it = sensors.begin();
    
    while (true) {
        // display next sensor's measure (if any)
        if (it != sensors.end()) display.show_sensor_measure((*it)->get_name(), (*it)->last_measure());
        it++;
        if (it == sensors.end()) it = sensors.begin();
        
        // display time if minute is different from displayed value
        t = l.tm();
        if (last_minute != t->tm_min) {
            last_minute = t->tm_min;
            strftime(buffer, 20, "%H:%M", t);
            display.show_time_text(buffer);
        }

        wait_seconds(2);
    }
}

/*
    measure Thread: read all sensors every 10 seconds
*/
void measure_thread(void const *args) {
    while (true) {
        list<Sensor *>::iterator it;
        int nr = 0;
        for (it = sensors.begin(); it != sensors.end(); it++) {
            display.show_current_sensor((*it)->get_kind(), nr, '<');

            (*it)->prepare_measure();
            display.show_current_status('>');
            (*it)->measure();
            display.show_current_status('='); // oder '?' falls falsch

            wait_seconds(1);

            nr++;
        }
        display.clear_current_sensor();

        wait_seconds(10); // FIXME: increase to 60 seconds
    }
}

/*
    send Thread: post measures to Statistics Collector every 15 minutes
*/
void send_thread(void const *args) {
    CollectorProxy collector((const char *) args);

    while (true) {
        // 11 minute delay with feedback in the last 10 minutes
        for (int i=10; i>=0; i--) {
            display.show_network_status(i > 9 ? ' ' : '0' + i);
            wait_minutes(1);
        }
        
        list<Sensor *>::iterator it;
        for (it = sensors.begin(); it != sensors.end(); it++) {
            display.show_network_status('P');
            int ret = collector.send_measure((*it)->get_url_part(), (*it)->get_value());
            
            display.show_network_status(ret ? 'O' : 'E');
            wait_seconds(2);
        }
    }
}

/*
    main Thread: initialize and flash a LED
    
    TODO: check or modify string constants    
*/
int main() {
    display.print_init_message();

    // testing only:
    sensors.push_back((Sensor *) new TemperatureSensor(p21, "erlangen/temperatur/demo", "Temperatur"));
    sensors.push_back((Sensor *) new SwitchSensor(     p25, "erlangen/schalter/demo",   "Schalter"));

    /* live setting:
    sensors.push_back((Sensor *) new TemperatureSensor(p21, "trainmeusel/heizung/temperatur",     "Heizung"));
    sensors.push_back((Sensor *) new TemperatureSensor(p22, "trainmeusel/waschkueche/temperatur", "Waschkueche"));
    sensors.push_back((Sensor *) new TemperatureSensor(p23, "trainmeusel/flur/temperatur",        "Flur"));
    sensors.push_back((Sensor *) new TemperatureSensor(p24, "trainmeusel/aussen/temperatur",      "Aussen"));
    sensors.push_back((Sensor *) new SwitchSensor(     p25, "trainmeusel/oel/schwimmer",          "Oel"));
    */
    
    EthernetInterface eth;
    eth.init("192.168.2.175", "255.255.255.0", "192.168.2.1");
    eth.connect();

    Thread t1(ntp_thread, (void *)"time.apple.com");
    Thread t2(display_thread);
    Thread t3(measure_thread);
    Thread t4(send_thread, (void *)"http://kinkeldei-net.de:81/sensor");

    // a periodical flash should indicate "we are alive"
    DigitalOut led(LED1);
    while (true) {
        led = !led;
        wait_seconds(1);
    }
}