mbed Weather Platform firmware http://mbed.org/users/okini3939/notebook/mbed-weather-platform-firmware/
Dependencies: ChaNFSSD EthernetNetIf I2CLEDDisp Agentbed ChaNFSUSB ILinterpreter mbed BMP085 WeatherMeters ConfigFile ChaNFS I2CLCD
sensor.cpp@1:6c7141895545, 2011-07-10 (annotated)
- Committer:
- okini3939
- Date:
- Sun Jul 10 15:36:46 2011 +0000
- Revision:
- 1:6c7141895545
- Parent:
- 0:bdb53686c194
- Child:
- 2:a3e5edf84f74
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
okini3939 | 1:6c7141895545 | 1 | /* |
okini3939 | 1:6c7141895545 | 2 | * Weather Station - mbed Weather Platform |
okini3939 | 1:6c7141895545 | 3 | * Copyright (c) 2011 Hiroshi Suga |
okini3939 | 1:6c7141895545 | 4 | * Released under the MIT License: http://mbed.org/license/mit |
okini3939 | 1:6c7141895545 | 5 | */ |
okini3939 | 1:6c7141895545 | 6 | |
okini3939 | 1:6c7141895545 | 7 | /** @file |
okini3939 | 1:6c7141895545 | 8 | * @brief Weather Station |
okini3939 | 1:6c7141895545 | 9 | */ |
okini3939 | 1:6c7141895545 | 10 | |
okini3939 | 0:bdb53686c194 | 11 | #include "mbed.h" |
okini3939 | 0:bdb53686c194 | 12 | #include "weather.h" |
okini3939 | 0:bdb53686c194 | 13 | #include "BMP085.h" |
okini3939 | 0:bdb53686c194 | 14 | #include "SHT.h" |
okini3939 | 0:bdb53686c194 | 15 | #include "WeatherMeters.h" |
okini3939 | 0:bdb53686c194 | 16 | |
okini3939 | 0:bdb53686c194 | 17 | #define AREF 3.3 // V |
okini3939 | 0:bdb53686c194 | 18 | |
okini3939 | 0:bdb53686c194 | 19 | Sensor sensor, offset, sensor_old; |
okini3939 | 0:bdb53686c194 | 20 | I2C i2c(p9, p10); |
okini3939 | 0:bdb53686c194 | 21 | static BMP085 bmp085(i2c, BMP085_oss4); |
okini3939 | 0:bdb53686c194 | 22 | static SHT sht15(p12, p11, SHT_high); // sclock, data |
okini3939 | 0:bdb53686c194 | 23 | static WeatherMeters wmeters(p21, p15, p22); // anemo, vane, rain |
okini3939 | 0:bdb53686c194 | 24 | static AnalogIn ailight(p16), aiuv(p17); |
okini3939 | 0:bdb53686c194 | 25 | static AnalogIn *aimoist; |
okini3939 | 0:bdb53686c194 | 26 | static InterruptIn *intin; |
okini3939 | 1:6c7141895545 | 27 | static volatile int count_counter = 0; |
okini3939 | 1:6c7141895545 | 28 | static volatile unsigned long lastCountTime = 0; |
okini3939 | 1:6c7141895545 | 29 | static volatile enum eINPUTTYPE inputtype = INPUT_MOIST; |
okini3939 | 0:bdb53686c194 | 30 | |
okini3939 | 0:bdb53686c194 | 31 | float get_light (AnalogIn &ain) { |
okini3939 | 0:bdb53686c194 | 32 | float f; |
okini3939 | 0:bdb53686c194 | 33 | |
okini3939 | 0:bdb53686c194 | 34 | f = ain * AREF / 1000; // A |
okini3939 | 0:bdb53686c194 | 35 | return f / 0.0000026; // lx |
okini3939 | 0:bdb53686c194 | 36 | } |
okini3939 | 0:bdb53686c194 | 37 | |
okini3939 | 0:bdb53686c194 | 38 | float get_uv (AnalogIn &ain) { |
okini3939 | 0:bdb53686c194 | 39 | float f; |
okini3939 | 0:bdb53686c194 | 40 | |
okini3939 | 0:bdb53686c194 | 41 | f = ain * AREF / 100000; // A |
okini3939 | 0:bdb53686c194 | 42 | f = f / 0.000384; // mW/cm2 |
okini3939 | 0:bdb53686c194 | 43 | if (f < 0) f = 0; |
okini3939 | 0:bdb53686c194 | 44 | return f; |
okini3939 | 0:bdb53686c194 | 45 | } |
okini3939 | 0:bdb53686c194 | 46 | |
okini3939 | 0:bdb53686c194 | 47 | float get_moist (AnalogIn &ain) { |
okini3939 | 0:bdb53686c194 | 48 | float f; |
okini3939 | 0:bdb53686c194 | 49 | |
okini3939 | 0:bdb53686c194 | 50 | f = ain * AREF; // V |
okini3939 | 0:bdb53686c194 | 51 | f = f / ((AREF - f) / 10.0); // k ohm |
okini3939 | 0:bdb53686c194 | 52 | if (f < 0) f = 0; |
okini3939 | 0:bdb53686c194 | 53 | return f; |
okini3939 | 0:bdb53686c194 | 54 | } |
okini3939 | 0:bdb53686c194 | 55 | |
okini3939 | 0:bdb53686c194 | 56 | void isr_counter () { |
okini3939 | 0:bdb53686c194 | 57 | count_counter ++; |
okini3939 | 0:bdb53686c194 | 58 | } |
okini3939 | 0:bdb53686c194 | 59 | |
okini3939 | 0:bdb53686c194 | 60 | float get_counter (char flg) { |
okini3939 | 0:bdb53686c194 | 61 | float t; |
okini3939 | 0:bdb53686c194 | 62 | |
okini3939 | 0:bdb53686c194 | 63 | if (flg) { |
okini3939 | 0:bdb53686c194 | 64 | // count |
okini3939 | 0:bdb53686c194 | 65 | t = (float)count_counter; |
okini3939 | 0:bdb53686c194 | 66 | } else { |
okini3939 | 0:bdb53686c194 | 67 | // count/min |
okini3939 | 0:bdb53686c194 | 68 | if (locUpTime > lastCountTime) { |
okini3939 | 0:bdb53686c194 | 69 | t = (float)(locUpTime - lastCountTime) / 6000.0; |
okini3939 | 0:bdb53686c194 | 70 | } else { |
okini3939 | 0:bdb53686c194 | 71 | t = (float)(0xffffffff - lastCountTime + locUpTime) / 6000.0; |
okini3939 | 0:bdb53686c194 | 72 | } |
okini3939 | 0:bdb53686c194 | 73 | t = (float)count_counter / t; |
okini3939 | 0:bdb53686c194 | 74 | } |
okini3939 | 0:bdb53686c194 | 75 | lastCountTime = locUpTime; |
okini3939 | 0:bdb53686c194 | 76 | count_counter = 0; |
okini3939 | 0:bdb53686c194 | 77 | return t; |
okini3939 | 0:bdb53686c194 | 78 | } |
okini3939 | 0:bdb53686c194 | 79 | |
okini3939 | 0:bdb53686c194 | 80 | int update_sensor () { |
okini3939 | 0:bdb53686c194 | 81 | |
okini3939 | 0:bdb53686c194 | 82 | sensor.sec = time(NULL); |
okini3939 | 0:bdb53686c194 | 83 | |
okini3939 | 0:bdb53686c194 | 84 | bmp085.update(); |
okini3939 | 0:bdb53686c194 | 85 | sensor.pres = bmp085.get_pressure() + offset.pres; |
okini3939 | 0:bdb53686c194 | 86 | sensor.temp2 = bmp085.get_temperature(); |
okini3939 | 0:bdb53686c194 | 87 | |
okini3939 | 0:bdb53686c194 | 88 | sht15.update(SHT_high); |
okini3939 | 0:bdb53686c194 | 89 | sensor.temp = sht15.get_temperature() + offset.temp; |
okini3939 | 0:bdb53686c194 | 90 | sensor.humi = sht15.get_humidity() + offset.humi; |
okini3939 | 0:bdb53686c194 | 91 | |
okini3939 | 0:bdb53686c194 | 92 | sensor.anemo = wmeters.get_windspeed(); |
okini3939 | 0:bdb53686c194 | 93 | sensor.vane = wmeters.get_windvane(); |
okini3939 | 0:bdb53686c194 | 94 | sensor.rain = wmeters.get_raingauge(); |
okini3939 | 0:bdb53686c194 | 95 | |
okini3939 | 0:bdb53686c194 | 96 | sensor.light = get_light(ailight); |
okini3939 | 0:bdb53686c194 | 97 | sensor.uv = get_uv(aiuv); |
okini3939 | 0:bdb53686c194 | 98 | |
okini3939 | 1:6c7141895545 | 99 | if (inputtype == INPUT_MOIST) { |
okini3939 | 1:6c7141895545 | 100 | // moist sensor |
okini3939 | 1:6c7141895545 | 101 | sensor.moist = get_moist(*aimoist); |
okini3939 | 1:6c7141895545 | 102 | } else |
okini3939 | 1:6c7141895545 | 103 | if (inputtype == INPUT_MOIST) { |
okini3939 | 0:bdb53686c194 | 104 | // counter |
okini3939 | 0:bdb53686c194 | 105 | sensor.moist = get_counter(inputtype & INPUT_CPM ? 0 : 1); |
okini3939 | 0:bdb53686c194 | 106 | } |
okini3939 | 0:bdb53686c194 | 107 | |
okini3939 | 0:bdb53686c194 | 108 | return 0; |
okini3939 | 0:bdb53686c194 | 109 | } |
okini3939 | 0:bdb53686c194 | 110 | |
okini3939 | 0:bdb53686c194 | 111 | int init_sensor () { |
okini3939 | 0:bdb53686c194 | 112 | char buf[20]; |
okini3939 | 0:bdb53686c194 | 113 | |
okini3939 | 0:bdb53686c194 | 114 | memset(&sensor, 0, sizeof(sensor)); |
okini3939 | 0:bdb53686c194 | 115 | sensor.sec = time(NULL); |
okini3939 | 0:bdb53686c194 | 116 | sensor_old = sensor; |
okini3939 | 0:bdb53686c194 | 117 | offset = sensor; |
okini3939 | 0:bdb53686c194 | 118 | |
okini3939 | 0:bdb53686c194 | 119 | // moist sensor or counter |
okini3939 | 0:bdb53686c194 | 120 | if (cfg.getValue("INPUT", buf, sizeof(buf))) { |
okini3939 | 0:bdb53686c194 | 121 | // counter |
okini3939 | 1:6c7141895545 | 122 | inputtype = (eINPUTTYPE)atoi(buf); |
okini3939 | 1:6c7141895545 | 123 | if (inputtype & (INPUT_FALL|INPUT_RISE)) { |
okini3939 | 0:bdb53686c194 | 124 | intin->fall(&isr_counter); |
okini3939 | 1:6c7141895545 | 125 | if (inputtype & INPUT_FALL) { |
okini3939 | 1:6c7141895545 | 126 | intin = new InterruptIn(p18); |
okini3939 | 1:6c7141895545 | 127 | } |
okini3939 | 1:6c7141895545 | 128 | if (inputtype & INPUT_RISE) { |
okini3939 | 1:6c7141895545 | 129 | intin = new InterruptIn(p18); |
okini3939 | 1:6c7141895545 | 130 | } |
okini3939 | 0:bdb53686c194 | 131 | } |
okini3939 | 0:bdb53686c194 | 132 | } else { |
okini3939 | 0:bdb53686c194 | 133 | // moist |
okini3939 | 0:bdb53686c194 | 134 | aimoist = new AnalogIn(p18); |
okini3939 | 0:bdb53686c194 | 135 | } |
okini3939 | 0:bdb53686c194 | 136 | |
okini3939 | 0:bdb53686c194 | 137 | if (cfg.getValue("OFFSET[P]", buf, sizeof(buf))) { |
okini3939 | 0:bdb53686c194 | 138 | offset.pres = atof(buf); |
okini3939 | 0:bdb53686c194 | 139 | } |
okini3939 | 0:bdb53686c194 | 140 | if (cfg.getValue("OFFSET[T]", buf, sizeof(buf))) { |
okini3939 | 0:bdb53686c194 | 141 | offset.temp = atof(buf); |
okini3939 | 0:bdb53686c194 | 142 | } |
okini3939 | 0:bdb53686c194 | 143 | if (cfg.getValue("OFFSET[H]", buf, sizeof(buf))) { |
okini3939 | 0:bdb53686c194 | 144 | offset.humi = atof(buf); |
okini3939 | 0:bdb53686c194 | 145 | } |
okini3939 | 0:bdb53686c194 | 146 | |
okini3939 | 0:bdb53686c194 | 147 | return 0; |
okini3939 | 0:bdb53686c194 | 148 | } |
okini3939 | 0:bdb53686c194 | 149 | |
okini3939 | 0:bdb53686c194 | 150 | char *format_str (const char *fmt, char *buf, int len) { |
okini3939 | 0:bdb53686c194 | 151 | int i, j, flg; |
okini3939 | 0:bdb53686c194 | 152 | char c; |
okini3939 | 0:bdb53686c194 | 153 | float value; |
okini3939 | 0:bdb53686c194 | 154 | time_t sec = time(NULL); |
okini3939 | 0:bdb53686c194 | 155 | struct tm *tim = localtime(&sec); |
okini3939 | 0:bdb53686c194 | 156 | |
okini3939 | 0:bdb53686c194 | 157 | j = 0; |
okini3939 | 0:bdb53686c194 | 158 | for (i = 0; i < strlen(fmt) && j < len; i ++) { |
okini3939 | 0:bdb53686c194 | 159 | c = fmt[i]; |
okini3939 | 0:bdb53686c194 | 160 | if (c == '%') { |
okini3939 | 0:bdb53686c194 | 161 | flg = 0; |
okini3939 | 0:bdb53686c194 | 162 | i ++; |
okini3939 | 0:bdb53686c194 | 163 | c = fmt[i]; |
okini3939 | 0:bdb53686c194 | 164 | |
okini3939 | 0:bdb53686c194 | 165 | if (c == '.') { |
okini3939 | 0:bdb53686c194 | 166 | // float format |
okini3939 | 0:bdb53686c194 | 167 | if (fmt[i + 1] >= '0' && fmt[i + 1] <= '9') { |
okini3939 | 0:bdb53686c194 | 168 | flg = fmt[i + 1] - '0'; |
okini3939 | 0:bdb53686c194 | 169 | i ++; |
okini3939 | 0:bdb53686c194 | 170 | |
okini3939 | 1:6c7141895545 | 171 | // next char |
okini3939 | 0:bdb53686c194 | 172 | c = fmt[i + 1]; |
okini3939 | 0:bdb53686c194 | 173 | i ++; |
okini3939 | 0:bdb53686c194 | 174 | } |
okini3939 | 0:bdb53686c194 | 175 | } |
okini3939 | 0:bdb53686c194 | 176 | |
okini3939 | 0:bdb53686c194 | 177 | switch (c) { |
okini3939 | 0:bdb53686c194 | 178 | case 'P': |
okini3939 | 0:bdb53686c194 | 179 | value = sensor.pres; |
okini3939 | 0:bdb53686c194 | 180 | break; |
okini3939 | 0:bdb53686c194 | 181 | case 'T': |
okini3939 | 0:bdb53686c194 | 182 | value = sensor.temp; |
okini3939 | 0:bdb53686c194 | 183 | break; |
okini3939 | 0:bdb53686c194 | 184 | case 'H': |
okini3939 | 0:bdb53686c194 | 185 | value = sensor.humi; |
okini3939 | 0:bdb53686c194 | 186 | break; |
okini3939 | 0:bdb53686c194 | 187 | case 'A': |
okini3939 | 0:bdb53686c194 | 188 | value = sensor.anemo; |
okini3939 | 0:bdb53686c194 | 189 | break; |
okini3939 | 0:bdb53686c194 | 190 | case 'V': |
okini3939 | 0:bdb53686c194 | 191 | value = sensor.vane; |
okini3939 | 0:bdb53686c194 | 192 | break; |
okini3939 | 0:bdb53686c194 | 193 | case 'R': |
okini3939 | 0:bdb53686c194 | 194 | value = sensor.rain; |
okini3939 | 0:bdb53686c194 | 195 | break; |
okini3939 | 0:bdb53686c194 | 196 | case 'L': |
okini3939 | 0:bdb53686c194 | 197 | value = sensor.light; |
okini3939 | 0:bdb53686c194 | 198 | break; |
okini3939 | 0:bdb53686c194 | 199 | case 'U': |
okini3939 | 0:bdb53686c194 | 200 | value = sensor.uv; |
okini3939 | 0:bdb53686c194 | 201 | break; |
okini3939 | 0:bdb53686c194 | 202 | case 'M': |
okini3939 | 0:bdb53686c194 | 203 | value = sensor.moist; |
okini3939 | 0:bdb53686c194 | 204 | break; |
okini3939 | 0:bdb53686c194 | 205 | case 'p': |
okini3939 | 1:6c7141895545 | 206 | value = sensor.temp2; |
okini3939 | 0:bdb53686c194 | 207 | break; |
okini3939 | 0:bdb53686c194 | 208 | |
okini3939 | 0:bdb53686c194 | 209 | case 'y': |
okini3939 | 0:bdb53686c194 | 210 | value = tim->tm_year + 1900; |
okini3939 | 0:bdb53686c194 | 211 | flg = -1; |
okini3939 | 0:bdb53686c194 | 212 | break; |
okini3939 | 0:bdb53686c194 | 213 | case 'm': |
okini3939 | 0:bdb53686c194 | 214 | value = tim->tm_mon; |
okini3939 | 0:bdb53686c194 | 215 | flg = -1; |
okini3939 | 0:bdb53686c194 | 216 | break; |
okini3939 | 0:bdb53686c194 | 217 | case 'd': |
okini3939 | 0:bdb53686c194 | 218 | value = tim->tm_mday; |
okini3939 | 0:bdb53686c194 | 219 | flg = -1; |
okini3939 | 0:bdb53686c194 | 220 | break; |
okini3939 | 0:bdb53686c194 | 221 | case 'h': |
okini3939 | 0:bdb53686c194 | 222 | value = tim->tm_hour; |
okini3939 | 0:bdb53686c194 | 223 | flg = -1; |
okini3939 | 0:bdb53686c194 | 224 | break; |
okini3939 | 0:bdb53686c194 | 225 | case 'i': |
okini3939 | 0:bdb53686c194 | 226 | value = tim->tm_min; |
okini3939 | 0:bdb53686c194 | 227 | flg = -1; |
okini3939 | 0:bdb53686c194 | 228 | break; |
okini3939 | 0:bdb53686c194 | 229 | case 's': |
okini3939 | 0:bdb53686c194 | 230 | value = tim->tm_sec; |
okini3939 | 0:bdb53686c194 | 231 | flg = -1; |
okini3939 | 0:bdb53686c194 | 232 | break; |
okini3939 | 0:bdb53686c194 | 233 | |
okini3939 | 0:bdb53686c194 | 234 | case '0': |
okini3939 | 0:bdb53686c194 | 235 | case '1': |
okini3939 | 0:bdb53686c194 | 236 | case '2': |
okini3939 | 0:bdb53686c194 | 237 | case '3': |
okini3939 | 0:bdb53686c194 | 238 | case '4': |
okini3939 | 0:bdb53686c194 | 239 | case '5': |
okini3939 | 0:bdb53686c194 | 240 | case '6': |
okini3939 | 0:bdb53686c194 | 241 | case '7': |
okini3939 | 0:bdb53686c194 | 242 | case '8': |
okini3939 | 0:bdb53686c194 | 243 | case '9': |
okini3939 | 0:bdb53686c194 | 244 | // Ascii code |
okini3939 | 0:bdb53686c194 | 245 | c = c - '0'; |
okini3939 | 0:bdb53686c194 | 246 | if (fmt[i + 1] >= '0' && fmt[i + 1] <= '9') { |
okini3939 | 0:bdb53686c194 | 247 | c = (c << 3) | (fmt[i + 1] - '0'); |
okini3939 | 0:bdb53686c194 | 248 | i ++; |
okini3939 | 0:bdb53686c194 | 249 | if (fmt[i + 1] >= '0' && fmt[i + 1] <= '9') { |
okini3939 | 0:bdb53686c194 | 250 | c = (c << 3) | (fmt[i + 1] - '0'); |
okini3939 | 0:bdb53686c194 | 251 | i ++; |
okini3939 | 0:bdb53686c194 | 252 | } |
okini3939 | 0:bdb53686c194 | 253 | } |
okini3939 | 0:bdb53686c194 | 254 | buf[j] = c; |
okini3939 | 0:bdb53686c194 | 255 | j ++; |
okini3939 | 0:bdb53686c194 | 256 | continue; |
okini3939 | 0:bdb53686c194 | 257 | |
okini3939 | 1:6c7141895545 | 258 | case 'n': |
okini3939 | 1:6c7141895545 | 259 | buf[j] = '\n'; |
okini3939 | 1:6c7141895545 | 260 | j ++; |
okini3939 | 1:6c7141895545 | 261 | continue; |
okini3939 | 1:6c7141895545 | 262 | case 'r': |
okini3939 | 1:6c7141895545 | 263 | buf[j] = '\r'; |
okini3939 | 1:6c7141895545 | 264 | j ++; |
okini3939 | 1:6c7141895545 | 265 | continue; |
okini3939 | 0:bdb53686c194 | 266 | default: |
okini3939 | 0:bdb53686c194 | 267 | buf[j] = c; |
okini3939 | 0:bdb53686c194 | 268 | j ++; |
okini3939 | 0:bdb53686c194 | 269 | continue; |
okini3939 | 0:bdb53686c194 | 270 | } |
okini3939 | 0:bdb53686c194 | 271 | |
okini3939 | 0:bdb53686c194 | 272 | switch (flg) { |
okini3939 | 0:bdb53686c194 | 273 | case 1: |
okini3939 | 0:bdb53686c194 | 274 | sprintf(&buf[j], "%.1f", value); |
okini3939 | 0:bdb53686c194 | 275 | break; |
okini3939 | 0:bdb53686c194 | 276 | case 2: |
okini3939 | 0:bdb53686c194 | 277 | sprintf(&buf[j], "%.2f", value); |
okini3939 | 0:bdb53686c194 | 278 | break; |
okini3939 | 0:bdb53686c194 | 279 | case -1: |
okini3939 | 0:bdb53686c194 | 280 | sprintf(&buf[j], "%02d", (int)value); |
okini3939 | 0:bdb53686c194 | 281 | break; |
okini3939 | 0:bdb53686c194 | 282 | default: |
okini3939 | 0:bdb53686c194 | 283 | sprintf(&buf[j], "%d", (int)value); |
okini3939 | 0:bdb53686c194 | 284 | break; |
okini3939 | 0:bdb53686c194 | 285 | } |
okini3939 | 0:bdb53686c194 | 286 | j = strlen(buf); |
okini3939 | 0:bdb53686c194 | 287 | } else { |
okini3939 | 0:bdb53686c194 | 288 | // plain |
okini3939 | 0:bdb53686c194 | 289 | buf[j] = c; |
okini3939 | 0:bdb53686c194 | 290 | j ++; |
okini3939 | 0:bdb53686c194 | 291 | } |
okini3939 | 0:bdb53686c194 | 292 | } |
okini3939 | 0:bdb53686c194 | 293 | buf[j] = 0; |
okini3939 | 0:bdb53686c194 | 294 | return buf; |
okini3939 | 0:bdb53686c194 | 295 | } |