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:
2012-12-31
Revision:
0:53f05303850a
Child:
1:9e88b2508768

File content as of revision 0:53f05303850a:

#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"

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;
    
    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;
    time_t seconds;
    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
        seconds = time(NULL) + 3600; // FIXME: time-zone calculations wanted -- toggle switch?
        t = localtime(&seconds);
        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("http://kinkeldei-net.de:81/sensor");

    while (true) {
        // 10 minute delay with feedback in the last 9 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
*/
int main() {
    display.print_init_message();

    // ConfigReader c('config.ini');
    // c.read_config();
    
    sensors.push_back((Sensor *) new TemperatureSensor(p21, "erlangen/temperatur/demo", "demo"));

    /*
    sensors.push_back((Sensor *) new TemperatureSensor(p21, "trainmeusel/temperatur/heizung", "heizung"));
    sensors.push_back((Sensor *) new TemperatureSensor(p22, "trainmeusel/temperatur/keller",  "keller"));
    sensors.push_back((Sensor *) new TemperatureSensor(p23, "trainmeusel/temperatur/flur",    "flur"));
    sensors.push_back((Sensor *) new TemperatureSensor(p24, "trainmeusel/temperatur/aussen",  "aussen"));
    */
    
    // must come from configreader later, then remove:
    EthernetInterface eth;
    eth.init("192.168.2.175", "255.255.255.0", "192.168.2.1");
    eth.connect();

    Thread t1(ntp_thread);
    Thread t2(display_thread);
    Thread t3(measure_thread);
    Thread t4(send_thread);

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