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

Committer:
wkinkeldei
Date:
Mon Dec 31 12:08:24 2012 +0000
Revision:
0:53f05303850a
Child:
1:9e88b2508768
first working version with all needed features implemented: measure, display, post

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wkinkeldei 0:53f05303850a 1 #include "mbed.h"
wkinkeldei 0:53f05303850a 2 #include "rtos.h"
wkinkeldei 0:53f05303850a 3 #include "EthernetInterface.h"
wkinkeldei 0:53f05303850a 4
wkinkeldei 0:53f05303850a 5 #include <list>
wkinkeldei 0:53f05303850a 6
wkinkeldei 0:53f05303850a 7 #include "sparkfun.h"
wkinkeldei 0:53f05303850a 8 #include "ntp_proxy.h"
wkinkeldei 0:53f05303850a 9 #include "collector_proxy.h"
wkinkeldei 0:53f05303850a 10 #include "sensor.h"
wkinkeldei 0:53f05303850a 11 #include "temperature_sensor.h"
wkinkeldei 0:53f05303850a 12
wkinkeldei 0:53f05303850a 13 SparkFun display(p28);
wkinkeldei 0:53f05303850a 14 list<Sensor *> sensors;
wkinkeldei 0:53f05303850a 15
wkinkeldei 0:53f05303850a 16 void wait_minutes(int m = 1) {
wkinkeldei 0:53f05303850a 17 while (m-- > 0)
wkinkeldei 0:53f05303850a 18 Thread::wait(1000 * 60);
wkinkeldei 0:53f05303850a 19 }
wkinkeldei 0:53f05303850a 20
wkinkeldei 0:53f05303850a 21 void wait_seconds(int s = 1) {
wkinkeldei 0:53f05303850a 22 while (s-- > 0)
wkinkeldei 0:53f05303850a 23 Thread::wait(1000);
wkinkeldei 0:53f05303850a 24 }
wkinkeldei 0:53f05303850a 25
wkinkeldei 0:53f05303850a 26 /*
wkinkeldei 0:53f05303850a 27 ntp Thread: poll NTP Server every 3 hours
wkinkeldei 0:53f05303850a 28 */
wkinkeldei 0:53f05303850a 29 void ntp_thread(void const *args) {
wkinkeldei 0:53f05303850a 30 NtpProxy ntp;
wkinkeldei 0:53f05303850a 31
wkinkeldei 0:53f05303850a 32 while (true) {
wkinkeldei 0:53f05303850a 33 display.show_ntp_status('t');
wkinkeldei 0:53f05303850a 34 if (ntp.set_time()) {
wkinkeldei 0:53f05303850a 35 // successful: wait 3 hours
wkinkeldei 0:53f05303850a 36 display.show_ntp_status('T');
wkinkeldei 0:53f05303850a 37 wait_minutes(180);
wkinkeldei 0:53f05303850a 38 } else {
wkinkeldei 0:53f05303850a 39 // failure: retry after 5 minutes
wkinkeldei 0:53f05303850a 40 display.show_ntp_status('?');
wkinkeldei 0:53f05303850a 41 wait_minutes(5);
wkinkeldei 0:53f05303850a 42 }
wkinkeldei 0:53f05303850a 43 }
wkinkeldei 0:53f05303850a 44 }
wkinkeldei 0:53f05303850a 45
wkinkeldei 0:53f05303850a 46 /*
wkinkeldei 0:53f05303850a 47 display Thread: show a sensor every 2 seconds and current time
wkinkeldei 0:53f05303850a 48 */
wkinkeldei 0:53f05303850a 49 void display_thread(void const *args) {
wkinkeldei 0:53f05303850a 50 char buffer[20];
wkinkeldei 0:53f05303850a 51 int last_minute = -1;
wkinkeldei 0:53f05303850a 52 time_t seconds;
wkinkeldei 0:53f05303850a 53 struct tm *t;
wkinkeldei 0:53f05303850a 54 list<Sensor *>::iterator it = sensors.begin();
wkinkeldei 0:53f05303850a 55
wkinkeldei 0:53f05303850a 56 while (true) {
wkinkeldei 0:53f05303850a 57 // display next sensor's measure (if any)
wkinkeldei 0:53f05303850a 58 if (it != sensors.end()) display.show_sensor_measure((*it)->get_name(), (*it)->last_measure());
wkinkeldei 0:53f05303850a 59 it++;
wkinkeldei 0:53f05303850a 60 if (it == sensors.end()) it = sensors.begin();
wkinkeldei 0:53f05303850a 61
wkinkeldei 0:53f05303850a 62 // display time if minute is different from displayed value
wkinkeldei 0:53f05303850a 63 seconds = time(NULL) + 3600; // FIXME: time-zone calculations wanted -- toggle switch?
wkinkeldei 0:53f05303850a 64 t = localtime(&seconds);
wkinkeldei 0:53f05303850a 65 if (last_minute != t->tm_min) {
wkinkeldei 0:53f05303850a 66 last_minute = t->tm_min;
wkinkeldei 0:53f05303850a 67 strftime(buffer, 20, "%H:%M", t);
wkinkeldei 0:53f05303850a 68 display.show_time_text(buffer);
wkinkeldei 0:53f05303850a 69 }
wkinkeldei 0:53f05303850a 70
wkinkeldei 0:53f05303850a 71 wait_seconds(2);
wkinkeldei 0:53f05303850a 72 }
wkinkeldei 0:53f05303850a 73 }
wkinkeldei 0:53f05303850a 74
wkinkeldei 0:53f05303850a 75 /*
wkinkeldei 0:53f05303850a 76 measure Thread: read all sensors every 10 seconds
wkinkeldei 0:53f05303850a 77 */
wkinkeldei 0:53f05303850a 78 void measure_thread(void const *args) {
wkinkeldei 0:53f05303850a 79 while (true) {
wkinkeldei 0:53f05303850a 80 list<Sensor *>::iterator it;
wkinkeldei 0:53f05303850a 81 int nr = 0;
wkinkeldei 0:53f05303850a 82 for (it = sensors.begin(); it != sensors.end(); it++) {
wkinkeldei 0:53f05303850a 83 display.show_current_sensor((*it)->get_kind(), nr, '<');
wkinkeldei 0:53f05303850a 84
wkinkeldei 0:53f05303850a 85 (*it)->prepare_measure();
wkinkeldei 0:53f05303850a 86 display.show_current_status('>');
wkinkeldei 0:53f05303850a 87 (*it)->measure();
wkinkeldei 0:53f05303850a 88 display.show_current_status('='); // oder '?' falls falsch
wkinkeldei 0:53f05303850a 89
wkinkeldei 0:53f05303850a 90 wait_seconds(1);
wkinkeldei 0:53f05303850a 91
wkinkeldei 0:53f05303850a 92 nr++;
wkinkeldei 0:53f05303850a 93 }
wkinkeldei 0:53f05303850a 94 display.clear_current_sensor();
wkinkeldei 0:53f05303850a 95
wkinkeldei 0:53f05303850a 96 wait_seconds(10); // FIXME: increase to 60 seconds
wkinkeldei 0:53f05303850a 97 }
wkinkeldei 0:53f05303850a 98 }
wkinkeldei 0:53f05303850a 99
wkinkeldei 0:53f05303850a 100 /*
wkinkeldei 0:53f05303850a 101 send Thread: post measures to Statistics Collector every 15 minutes
wkinkeldei 0:53f05303850a 102 */
wkinkeldei 0:53f05303850a 103 void send_thread(void const *args) {
wkinkeldei 0:53f05303850a 104 CollectorProxy collector("http://kinkeldei-net.de:81/sensor");
wkinkeldei 0:53f05303850a 105
wkinkeldei 0:53f05303850a 106 while (true) {
wkinkeldei 0:53f05303850a 107 // 10 minute delay with feedback in the last 9 minutes
wkinkeldei 0:53f05303850a 108 for (int i=10; i>=0; i--) {
wkinkeldei 0:53f05303850a 109 display.show_network_status(i > 9 ? ' ' : '0' + i);
wkinkeldei 0:53f05303850a 110 wait_minutes(1);
wkinkeldei 0:53f05303850a 111 }
wkinkeldei 0:53f05303850a 112
wkinkeldei 0:53f05303850a 113 list<Sensor *>::iterator it;
wkinkeldei 0:53f05303850a 114 for (it = sensors.begin(); it != sensors.end(); it++) {
wkinkeldei 0:53f05303850a 115 display.show_network_status('P');
wkinkeldei 0:53f05303850a 116 int ret = collector.send_measure((*it)->get_url_part(), (*it)->get_value());
wkinkeldei 0:53f05303850a 117
wkinkeldei 0:53f05303850a 118 display.show_network_status(ret ? 'O' : 'E');
wkinkeldei 0:53f05303850a 119 wait_seconds(2);
wkinkeldei 0:53f05303850a 120 }
wkinkeldei 0:53f05303850a 121 }
wkinkeldei 0:53f05303850a 122 }
wkinkeldei 0:53f05303850a 123
wkinkeldei 0:53f05303850a 124 /*
wkinkeldei 0:53f05303850a 125 main Thread: initialize and flash a LED
wkinkeldei 0:53f05303850a 126 */
wkinkeldei 0:53f05303850a 127 int main() {
wkinkeldei 0:53f05303850a 128 display.print_init_message();
wkinkeldei 0:53f05303850a 129
wkinkeldei 0:53f05303850a 130 // ConfigReader c('config.ini');
wkinkeldei 0:53f05303850a 131 // c.read_config();
wkinkeldei 0:53f05303850a 132
wkinkeldei 0:53f05303850a 133 sensors.push_back((Sensor *) new TemperatureSensor(p21, "erlangen/temperatur/demo", "demo"));
wkinkeldei 0:53f05303850a 134
wkinkeldei 0:53f05303850a 135 /*
wkinkeldei 0:53f05303850a 136 sensors.push_back((Sensor *) new TemperatureSensor(p21, "trainmeusel/temperatur/heizung", "heizung"));
wkinkeldei 0:53f05303850a 137 sensors.push_back((Sensor *) new TemperatureSensor(p22, "trainmeusel/temperatur/keller", "keller"));
wkinkeldei 0:53f05303850a 138 sensors.push_back((Sensor *) new TemperatureSensor(p23, "trainmeusel/temperatur/flur", "flur"));
wkinkeldei 0:53f05303850a 139 sensors.push_back((Sensor *) new TemperatureSensor(p24, "trainmeusel/temperatur/aussen", "aussen"));
wkinkeldei 0:53f05303850a 140 */
wkinkeldei 0:53f05303850a 141
wkinkeldei 0:53f05303850a 142 // must come from configreader later, then remove:
wkinkeldei 0:53f05303850a 143 EthernetInterface eth;
wkinkeldei 0:53f05303850a 144 eth.init("192.168.2.175", "255.255.255.0", "192.168.2.1");
wkinkeldei 0:53f05303850a 145 eth.connect();
wkinkeldei 0:53f05303850a 146
wkinkeldei 0:53f05303850a 147 Thread t1(ntp_thread);
wkinkeldei 0:53f05303850a 148 Thread t2(display_thread);
wkinkeldei 0:53f05303850a 149 Thread t3(measure_thread);
wkinkeldei 0:53f05303850a 150 Thread t4(send_thread);
wkinkeldei 0:53f05303850a 151
wkinkeldei 0:53f05303850a 152 // a periodical flash should indicate "we are alive"
wkinkeldei 0:53f05303850a 153 DigitalOut led(LED1);
wkinkeldei 0:53f05303850a 154 while (true) {
wkinkeldei 0:53f05303850a 155 led = !led;
wkinkeldei 0:53f05303850a 156 wait_seconds(1);
wkinkeldei 0:53f05303850a 157 }
wkinkeldei 0:53f05303850a 158 }