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@4:46ad190e6328, 2011-10-07 (annotated)
- Committer:
- okini3939
- Date:
- Fri Oct 07 14:55:17 2011 +0000
- Revision:
- 4:46ad190e6328
- Parent:
- 2:a3e5edf84f74
- Child:
- 6:898c306f7990
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 | 2:a3e5edf84f74 | 19 | struct 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 | 0:bdb53686c194 | 29 | |
okini3939 | 0:bdb53686c194 | 30 | float get_light (AnalogIn &ain) { |
okini3939 | 0:bdb53686c194 | 31 | float f; |
okini3939 | 0:bdb53686c194 | 32 | |
okini3939 | 4:46ad190e6328 | 33 | f = ain * AREF / REG_LIGHT; // A |
okini3939 | 4:46ad190e6328 | 34 | return f / 0.0026; // lx |
okini3939 | 0:bdb53686c194 | 35 | } |
okini3939 | 0:bdb53686c194 | 36 | |
okini3939 | 0:bdb53686c194 | 37 | float get_uv (AnalogIn &ain) { |
okini3939 | 0:bdb53686c194 | 38 | float f; |
okini3939 | 0:bdb53686c194 | 39 | |
okini3939 | 4:46ad190e6328 | 40 | f = ain * AREF / REG_UV; // A |
okini3939 | 0:bdb53686c194 | 41 | f = f / 0.000384; // mW/cm2 |
okini3939 | 0:bdb53686c194 | 42 | if (f < 0) f = 0; |
okini3939 | 0:bdb53686c194 | 43 | return f; |
okini3939 | 0:bdb53686c194 | 44 | } |
okini3939 | 0:bdb53686c194 | 45 | |
okini3939 | 0:bdb53686c194 | 46 | float get_moist (AnalogIn &ain) { |
okini3939 | 0:bdb53686c194 | 47 | float f; |
okini3939 | 0:bdb53686c194 | 48 | |
okini3939 | 0:bdb53686c194 | 49 | f = ain * AREF; // V |
okini3939 | 4:46ad190e6328 | 50 | f = f / ((AREF - f) / REG_MOIST); // k ohm |
okini3939 | 0:bdb53686c194 | 51 | if (f < 0) f = 0; |
okini3939 | 0:bdb53686c194 | 52 | return f; |
okini3939 | 0:bdb53686c194 | 53 | } |
okini3939 | 0:bdb53686c194 | 54 | |
okini3939 | 0:bdb53686c194 | 55 | void isr_counter () { |
okini3939 | 0:bdb53686c194 | 56 | count_counter ++; |
okini3939 | 0:bdb53686c194 | 57 | } |
okini3939 | 0:bdb53686c194 | 58 | |
okini3939 | 0:bdb53686c194 | 59 | float get_counter (char flg) { |
okini3939 | 0:bdb53686c194 | 60 | float t; |
okini3939 | 0:bdb53686c194 | 61 | |
okini3939 | 0:bdb53686c194 | 62 | if (flg) { |
okini3939 | 0:bdb53686c194 | 63 | // count |
okini3939 | 0:bdb53686c194 | 64 | t = (float)count_counter; |
okini3939 | 0:bdb53686c194 | 65 | } else { |
okini3939 | 0:bdb53686c194 | 66 | // count/min |
okini3939 | 0:bdb53686c194 | 67 | if (locUpTime > lastCountTime) { |
okini3939 | 0:bdb53686c194 | 68 | t = (float)(locUpTime - lastCountTime) / 6000.0; |
okini3939 | 0:bdb53686c194 | 69 | } else { |
okini3939 | 0:bdb53686c194 | 70 | t = (float)(0xffffffff - lastCountTime + locUpTime) / 6000.0; |
okini3939 | 0:bdb53686c194 | 71 | } |
okini3939 | 0:bdb53686c194 | 72 | t = (float)count_counter / t; |
okini3939 | 0:bdb53686c194 | 73 | } |
okini3939 | 0:bdb53686c194 | 74 | lastCountTime = locUpTime; |
okini3939 | 0:bdb53686c194 | 75 | count_counter = 0; |
okini3939 | 0:bdb53686c194 | 76 | return t; |
okini3939 | 0:bdb53686c194 | 77 | } |
okini3939 | 0:bdb53686c194 | 78 | |
okini3939 | 0:bdb53686c194 | 79 | int update_sensor () { |
okini3939 | 0:bdb53686c194 | 80 | |
okini3939 | 0:bdb53686c194 | 81 | sensor.sec = time(NULL); |
okini3939 | 0:bdb53686c194 | 82 | |
okini3939 | 0:bdb53686c194 | 83 | bmp085.update(); |
okini3939 | 0:bdb53686c194 | 84 | sensor.pres = bmp085.get_pressure() + offset.pres; |
okini3939 | 0:bdb53686c194 | 85 | sensor.temp2 = bmp085.get_temperature(); |
okini3939 | 0:bdb53686c194 | 86 | |
okini3939 | 0:bdb53686c194 | 87 | sht15.update(SHT_high); |
okini3939 | 0:bdb53686c194 | 88 | sensor.temp = sht15.get_temperature() + offset.temp; |
okini3939 | 0:bdb53686c194 | 89 | sensor.humi = sht15.get_humidity() + offset.humi; |
okini3939 | 0:bdb53686c194 | 90 | |
okini3939 | 0:bdb53686c194 | 91 | sensor.anemo = wmeters.get_windspeed(); |
okini3939 | 0:bdb53686c194 | 92 | sensor.vane = wmeters.get_windvane(); |
okini3939 | 0:bdb53686c194 | 93 | sensor.rain = wmeters.get_raingauge(); |
okini3939 | 0:bdb53686c194 | 94 | |
okini3939 | 0:bdb53686c194 | 95 | sensor.light = get_light(ailight); |
okini3939 | 0:bdb53686c194 | 96 | sensor.uv = get_uv(aiuv); |
okini3939 | 0:bdb53686c194 | 97 | |
okini3939 | 2:a3e5edf84f74 | 98 | if (conf.inputtype == INPUT_MOIST) { |
okini3939 | 1:6c7141895545 | 99 | // moist sensor |
okini3939 | 1:6c7141895545 | 100 | sensor.moist = get_moist(*aimoist); |
okini3939 | 1:6c7141895545 | 101 | } else |
okini3939 | 2:a3e5edf84f74 | 102 | if (conf.inputtype == INPUT_MOIST) { |
okini3939 | 0:bdb53686c194 | 103 | // counter |
okini3939 | 2:a3e5edf84f74 | 104 | sensor.moist = get_counter(conf.inputtype & INPUT_CPM ? 0 : 1); |
okini3939 | 0:bdb53686c194 | 105 | } |
okini3939 | 0:bdb53686c194 | 106 | |
okini3939 | 0:bdb53686c194 | 107 | return 0; |
okini3939 | 0:bdb53686c194 | 108 | } |
okini3939 | 0:bdb53686c194 | 109 | |
okini3939 | 0:bdb53686c194 | 110 | int init_sensor () { |
okini3939 | 0:bdb53686c194 | 111 | |
okini3939 | 0:bdb53686c194 | 112 | memset(&sensor, 0, sizeof(sensor)); |
okini3939 | 0:bdb53686c194 | 113 | sensor.sec = time(NULL); |
okini3939 | 0:bdb53686c194 | 114 | sensor_old = sensor; |
okini3939 | 0:bdb53686c194 | 115 | offset = sensor; |
okini3939 | 0:bdb53686c194 | 116 | |
okini3939 | 0:bdb53686c194 | 117 | // moist sensor or counter |
okini3939 | 2:a3e5edf84f74 | 118 | if (conf.inputtype == INPUT_MOIST) { |
okini3939 | 0:bdb53686c194 | 119 | // moist |
okini3939 | 0:bdb53686c194 | 120 | aimoist = new AnalogIn(p18); |
okini3939 | 2:a3e5edf84f74 | 121 | } else |
okini3939 | 2:a3e5edf84f74 | 122 | if (conf.inputtype & (INPUT_FALL|INPUT_RISE)) { |
okini3939 | 2:a3e5edf84f74 | 123 | // counter |
okini3939 | 2:a3e5edf84f74 | 124 | intin->fall(&isr_counter); |
okini3939 | 2:a3e5edf84f74 | 125 | if (conf.inputtype & INPUT_FALL) { |
okini3939 | 2:a3e5edf84f74 | 126 | intin = new InterruptIn(p18); |
okini3939 | 2:a3e5edf84f74 | 127 | } |
okini3939 | 2:a3e5edf84f74 | 128 | if (conf.inputtype & INPUT_RISE) { |
okini3939 | 2:a3e5edf84f74 | 129 | intin = new InterruptIn(p18); |
okini3939 | 2:a3e5edf84f74 | 130 | } |
okini3939 | 0:bdb53686c194 | 131 | } |
okini3939 | 0:bdb53686c194 | 132 | |
okini3939 | 0:bdb53686c194 | 133 | return 0; |
okini3939 | 0:bdb53686c194 | 134 | } |
okini3939 | 0:bdb53686c194 | 135 | |
okini3939 | 0:bdb53686c194 | 136 | char *format_str (const char *fmt, char *buf, int len) { |
okini3939 | 0:bdb53686c194 | 137 | int i, j, flg; |
okini3939 | 0:bdb53686c194 | 138 | char c; |
okini3939 | 0:bdb53686c194 | 139 | float value; |
okini3939 | 0:bdb53686c194 | 140 | time_t sec = time(NULL); |
okini3939 | 0:bdb53686c194 | 141 | struct tm *tim = localtime(&sec); |
okini3939 | 0:bdb53686c194 | 142 | |
okini3939 | 0:bdb53686c194 | 143 | j = 0; |
okini3939 | 0:bdb53686c194 | 144 | for (i = 0; i < strlen(fmt) && j < len; i ++) { |
okini3939 | 0:bdb53686c194 | 145 | c = fmt[i]; |
okini3939 | 0:bdb53686c194 | 146 | if (c == '%') { |
okini3939 | 0:bdb53686c194 | 147 | flg = 0; |
okini3939 | 0:bdb53686c194 | 148 | i ++; |
okini3939 | 0:bdb53686c194 | 149 | c = fmt[i]; |
okini3939 | 0:bdb53686c194 | 150 | |
okini3939 | 0:bdb53686c194 | 151 | if (c == '.') { |
okini3939 | 0:bdb53686c194 | 152 | // float format |
okini3939 | 0:bdb53686c194 | 153 | if (fmt[i + 1] >= '0' && fmt[i + 1] <= '9') { |
okini3939 | 0:bdb53686c194 | 154 | flg = fmt[i + 1] - '0'; |
okini3939 | 0:bdb53686c194 | 155 | i ++; |
okini3939 | 0:bdb53686c194 | 156 | |
okini3939 | 1:6c7141895545 | 157 | // next char |
okini3939 | 0:bdb53686c194 | 158 | c = fmt[i + 1]; |
okini3939 | 0:bdb53686c194 | 159 | i ++; |
okini3939 | 0:bdb53686c194 | 160 | } |
okini3939 | 0:bdb53686c194 | 161 | } |
okini3939 | 0:bdb53686c194 | 162 | |
okini3939 | 0:bdb53686c194 | 163 | switch (c) { |
okini3939 | 0:bdb53686c194 | 164 | case 'P': |
okini3939 | 0:bdb53686c194 | 165 | value = sensor.pres; |
okini3939 | 0:bdb53686c194 | 166 | break; |
okini3939 | 0:bdb53686c194 | 167 | case 'T': |
okini3939 | 0:bdb53686c194 | 168 | value = sensor.temp; |
okini3939 | 0:bdb53686c194 | 169 | break; |
okini3939 | 0:bdb53686c194 | 170 | case 'H': |
okini3939 | 0:bdb53686c194 | 171 | value = sensor.humi; |
okini3939 | 0:bdb53686c194 | 172 | break; |
okini3939 | 0:bdb53686c194 | 173 | case 'A': |
okini3939 | 0:bdb53686c194 | 174 | value = sensor.anemo; |
okini3939 | 0:bdb53686c194 | 175 | break; |
okini3939 | 0:bdb53686c194 | 176 | case 'V': |
okini3939 | 0:bdb53686c194 | 177 | value = sensor.vane; |
okini3939 | 0:bdb53686c194 | 178 | break; |
okini3939 | 0:bdb53686c194 | 179 | case 'R': |
okini3939 | 0:bdb53686c194 | 180 | value = sensor.rain; |
okini3939 | 0:bdb53686c194 | 181 | break; |
okini3939 | 0:bdb53686c194 | 182 | case 'L': |
okini3939 | 0:bdb53686c194 | 183 | value = sensor.light; |
okini3939 | 0:bdb53686c194 | 184 | break; |
okini3939 | 0:bdb53686c194 | 185 | case 'U': |
okini3939 | 0:bdb53686c194 | 186 | value = sensor.uv; |
okini3939 | 0:bdb53686c194 | 187 | break; |
okini3939 | 0:bdb53686c194 | 188 | case 'M': |
okini3939 | 0:bdb53686c194 | 189 | value = sensor.moist; |
okini3939 | 0:bdb53686c194 | 190 | break; |
okini3939 | 0:bdb53686c194 | 191 | case 'p': |
okini3939 | 1:6c7141895545 | 192 | value = sensor.temp2; |
okini3939 | 0:bdb53686c194 | 193 | break; |
okini3939 | 0:bdb53686c194 | 194 | |
okini3939 | 0:bdb53686c194 | 195 | case 'y': |
okini3939 | 0:bdb53686c194 | 196 | value = tim->tm_year + 1900; |
okini3939 | 0:bdb53686c194 | 197 | flg = -1; |
okini3939 | 0:bdb53686c194 | 198 | break; |
okini3939 | 0:bdb53686c194 | 199 | case 'm': |
okini3939 | 4:46ad190e6328 | 200 | value = tim->tm_mon + 1; |
okini3939 | 0:bdb53686c194 | 201 | flg = -1; |
okini3939 | 0:bdb53686c194 | 202 | break; |
okini3939 | 0:bdb53686c194 | 203 | case 'd': |
okini3939 | 0:bdb53686c194 | 204 | value = tim->tm_mday; |
okini3939 | 0:bdb53686c194 | 205 | flg = -1; |
okini3939 | 0:bdb53686c194 | 206 | break; |
okini3939 | 0:bdb53686c194 | 207 | case 'h': |
okini3939 | 0:bdb53686c194 | 208 | value = tim->tm_hour; |
okini3939 | 0:bdb53686c194 | 209 | flg = -1; |
okini3939 | 0:bdb53686c194 | 210 | break; |
okini3939 | 0:bdb53686c194 | 211 | case 'i': |
okini3939 | 0:bdb53686c194 | 212 | value = tim->tm_min; |
okini3939 | 0:bdb53686c194 | 213 | flg = -1; |
okini3939 | 0:bdb53686c194 | 214 | break; |
okini3939 | 0:bdb53686c194 | 215 | case 's': |
okini3939 | 0:bdb53686c194 | 216 | value = tim->tm_sec; |
okini3939 | 0:bdb53686c194 | 217 | flg = -1; |
okini3939 | 0:bdb53686c194 | 218 | break; |
okini3939 | 0:bdb53686c194 | 219 | |
okini3939 | 0:bdb53686c194 | 220 | case '0': |
okini3939 | 0:bdb53686c194 | 221 | case '1': |
okini3939 | 0:bdb53686c194 | 222 | case '2': |
okini3939 | 0:bdb53686c194 | 223 | case '3': |
okini3939 | 0:bdb53686c194 | 224 | case '4': |
okini3939 | 0:bdb53686c194 | 225 | case '5': |
okini3939 | 0:bdb53686c194 | 226 | case '6': |
okini3939 | 0:bdb53686c194 | 227 | case '7': |
okini3939 | 0:bdb53686c194 | 228 | case '8': |
okini3939 | 0:bdb53686c194 | 229 | case '9': |
okini3939 | 0:bdb53686c194 | 230 | // Ascii code |
okini3939 | 0:bdb53686c194 | 231 | c = c - '0'; |
okini3939 | 0:bdb53686c194 | 232 | if (fmt[i + 1] >= '0' && fmt[i + 1] <= '9') { |
okini3939 | 0:bdb53686c194 | 233 | c = (c << 3) | (fmt[i + 1] - '0'); |
okini3939 | 0:bdb53686c194 | 234 | i ++; |
okini3939 | 0:bdb53686c194 | 235 | if (fmt[i + 1] >= '0' && fmt[i + 1] <= '9') { |
okini3939 | 0:bdb53686c194 | 236 | c = (c << 3) | (fmt[i + 1] - '0'); |
okini3939 | 0:bdb53686c194 | 237 | i ++; |
okini3939 | 0:bdb53686c194 | 238 | } |
okini3939 | 0:bdb53686c194 | 239 | } |
okini3939 | 0:bdb53686c194 | 240 | buf[j] = c; |
okini3939 | 0:bdb53686c194 | 241 | j ++; |
okini3939 | 0:bdb53686c194 | 242 | continue; |
okini3939 | 0:bdb53686c194 | 243 | |
okini3939 | 1:6c7141895545 | 244 | case 'n': |
okini3939 | 1:6c7141895545 | 245 | buf[j] = '\n'; |
okini3939 | 1:6c7141895545 | 246 | j ++; |
okini3939 | 1:6c7141895545 | 247 | continue; |
okini3939 | 1:6c7141895545 | 248 | case 'r': |
okini3939 | 1:6c7141895545 | 249 | buf[j] = '\r'; |
okini3939 | 1:6c7141895545 | 250 | j ++; |
okini3939 | 1:6c7141895545 | 251 | continue; |
okini3939 | 0:bdb53686c194 | 252 | default: |
okini3939 | 0:bdb53686c194 | 253 | buf[j] = c; |
okini3939 | 0:bdb53686c194 | 254 | j ++; |
okini3939 | 0:bdb53686c194 | 255 | continue; |
okini3939 | 0:bdb53686c194 | 256 | } |
okini3939 | 0:bdb53686c194 | 257 | |
okini3939 | 0:bdb53686c194 | 258 | switch (flg) { |
okini3939 | 0:bdb53686c194 | 259 | case 1: |
okini3939 | 2:a3e5edf84f74 | 260 | snprintf(&buf[j], len - j, "%.1f", value); |
okini3939 | 0:bdb53686c194 | 261 | break; |
okini3939 | 0:bdb53686c194 | 262 | case 2: |
okini3939 | 2:a3e5edf84f74 | 263 | snprintf(&buf[j], len - j, "%.2f", value); |
okini3939 | 0:bdb53686c194 | 264 | break; |
okini3939 | 0:bdb53686c194 | 265 | case -1: |
okini3939 | 2:a3e5edf84f74 | 266 | snprintf(&buf[j], len - j, "%02d", (int)value); |
okini3939 | 0:bdb53686c194 | 267 | break; |
okini3939 | 0:bdb53686c194 | 268 | default: |
okini3939 | 2:a3e5edf84f74 | 269 | snprintf(&buf[j], len - j, "%d", (int)value); |
okini3939 | 0:bdb53686c194 | 270 | break; |
okini3939 | 0:bdb53686c194 | 271 | } |
okini3939 | 0:bdb53686c194 | 272 | j = strlen(buf); |
okini3939 | 0:bdb53686c194 | 273 | } else { |
okini3939 | 0:bdb53686c194 | 274 | // plain |
okini3939 | 0:bdb53686c194 | 275 | buf[j] = c; |
okini3939 | 0:bdb53686c194 | 276 | j ++; |
okini3939 | 0:bdb53686c194 | 277 | } |
okini3939 | 0:bdb53686c194 | 278 | } |
okini3939 | 0:bdb53686c194 | 279 | buf[j] = 0; |
okini3939 | 0:bdb53686c194 | 280 | return buf; |
okini3939 | 0:bdb53686c194 | 281 | } |