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

Revision:
0:53f05303850a
Child:
1:9e88b2508768
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Dec 31 12:08:24 2012 +0000
@@ -0,0 +1,158 @@
+#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);
+    }
+}