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@0:53f05303850a, 2012-12-31 (annotated)
- 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?
User | Revision | Line number | New 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 | } |