World Wide Data Logger using mbed.

Dependencies:   mbed ThermistorPack Pachube ConfigFile EthernetNetIf TextLCD SDFileSystem

Committer:
shintamainjp
Date:
Mon Apr 04 21:33:25 2011 +0000
Revision:
0:798c62ea70a3
Initial version.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shintamainjp 0:798c62ea70a3 1 /**
shintamainjp 0:798c62ea70a3 2 * =============================================================================
shintamainjp 0:798c62ea70a3 3 * TORAGI 2011/04 : WEB Data Logger
shintamainjp 0:798c62ea70a3 4 * =============================================================================
shintamainjp 0:798c62ea70a3 5 * Copyright (c) 2010-2011 Shinichiro Nakamura
shintamainjp 0:798c62ea70a3 6 *
shintamainjp 0:798c62ea70a3 7 * Permission is hereby granted, free of charge, to any person obtaining a copy
shintamainjp 0:798c62ea70a3 8 * of this software and associated documentation files (the "Software"), to deal
shintamainjp 0:798c62ea70a3 9 * in the Software without restriction, including without limitation the rights
shintamainjp 0:798c62ea70a3 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
shintamainjp 0:798c62ea70a3 11 * copies of the Software, and to permit persons to whom the Software is
shintamainjp 0:798c62ea70a3 12 * furnished to do so, subject to the following conditions:
shintamainjp 0:798c62ea70a3 13 *
shintamainjp 0:798c62ea70a3 14 * The above copyright notice and this permission notice shall be included in
shintamainjp 0:798c62ea70a3 15 * all copies or substantial portions of the Software.
shintamainjp 0:798c62ea70a3 16 *
shintamainjp 0:798c62ea70a3 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
shintamainjp 0:798c62ea70a3 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
shintamainjp 0:798c62ea70a3 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
shintamainjp 0:798c62ea70a3 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
shintamainjp 0:798c62ea70a3 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
shintamainjp 0:798c62ea70a3 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
shintamainjp 0:798c62ea70a3 23 * THE SOFTWARE.
shintamainjp 0:798c62ea70a3 24 * =============================================================================
shintamainjp 0:798c62ea70a3 25 */
shintamainjp 0:798c62ea70a3 26
shintamainjp 0:798c62ea70a3 27 #include "mbed.h"
shintamainjp 0:798c62ea70a3 28 #include "PachubeV2CSV.h"
shintamainjp 0:798c62ea70a3 29 #include "EthernetNetIf.h"
shintamainjp 0:798c62ea70a3 30 #include "HTTPClient.h"
shintamainjp 0:798c62ea70a3 31 #include "ThermistorMCP9701.h"
shintamainjp 0:798c62ea70a3 32 #include "TextLCD.h"
shintamainjp 0:798c62ea70a3 33 #include "appconf.h"
shintamainjp 0:798c62ea70a3 34 #include "SDFileSystem.h"
shintamainjp 0:798c62ea70a3 35
shintamainjp 0:798c62ea70a3 36 /*
shintamainjp 0:798c62ea70a3 37 * Definitions for a configuration file.
shintamainjp 0:798c62ea70a3 38 */
shintamainjp 0:798c62ea70a3 39 #define CONFIG_FILENAME "/local/PACHUBE.CFG"
shintamainjp 0:798c62ea70a3 40 #define DATACSV_FILENAME "/sd/DATA.CSV"
shintamainjp 0:798c62ea70a3 41 const int PACHUBE_CODE_OK = 200;
shintamainjp 0:798c62ea70a3 42
shintamainjp 0:798c62ea70a3 43 LocalFileSystem localfs("local");
shintamainjp 0:798c62ea70a3 44 SDFileSystem sdfs(p5, p6, p7, p8, "sd");
shintamainjp 0:798c62ea70a3 45 TextLCD lcd(p24, p26, p27, p28, p29, p30);
shintamainjp 0:798c62ea70a3 46 EthernetNetIf netif;
shintamainjp 0:798c62ea70a3 47 BusOut led(LED1, LED2, LED3, LED4);
shintamainjp 0:798c62ea70a3 48 ThermistorMCP9701 thermistor1(p16);
shintamainjp 0:798c62ea70a3 49 ThermistorMCP9701 thermistor2(p17);
shintamainjp 0:798c62ea70a3 50 ThermistorMCP9701 thermistor3(p18);
shintamainjp 0:798c62ea70a3 51 ThermistorMCP9701 thermistor4(p19);
shintamainjp 0:798c62ea70a3 52 ThermistorMCP9701 thermistor5(p20);
shintamainjp 0:798c62ea70a3 53 static appconf_t appconf;
shintamainjp 0:798c62ea70a3 54
shintamainjp 0:798c62ea70a3 55 /**
shintamainjp 0:798c62ea70a3 56 * Display a splash screen.
shintamainjp 0:798c62ea70a3 57 */
shintamainjp 0:798c62ea70a3 58 void splash(void) {
shintamainjp 0:798c62ea70a3 59 lcd.cls();
shintamainjp 0:798c62ea70a3 60 lcd.locate(0, 0);
shintamainjp 0:798c62ea70a3 61 lcd.printf(" TORAGI 2011/04 ");
shintamainjp 0:798c62ea70a3 62 lcd.locate(0, 1);
shintamainjp 0:798c62ea70a3 63 lcd.printf("WEB Data Logger ");
shintamainjp 0:798c62ea70a3 64 wait(2);
shintamainjp 0:798c62ea70a3 65
shintamainjp 0:798c62ea70a3 66 lcd.cls();
shintamainjp 0:798c62ea70a3 67 lcd.locate(0, 0);
shintamainjp 0:798c62ea70a3 68 lcd.printf(" Starting up... ");
shintamainjp 0:798c62ea70a3 69 lcd.locate(0, 1);
shintamainjp 0:798c62ea70a3 70 lcd.printf(" Wait a moment. ");
shintamainjp 0:798c62ea70a3 71 wait(2);
shintamainjp 0:798c62ea70a3 72 }
shintamainjp 0:798c62ea70a3 73
shintamainjp 0:798c62ea70a3 74 /**
shintamainjp 0:798c62ea70a3 75 * Convert double to char.
shintamainjp 0:798c62ea70a3 76 *
shintamainjp 0:798c62ea70a3 77 * @param val Value.
shintamainjp 0:798c62ea70a3 78 * @param buf A pointer to a buffer.
shintamainjp 0:798c62ea70a3 79 * @param bufsiz The buffer size.
shintamainjp 0:798c62ea70a3 80 */
shintamainjp 0:798c62ea70a3 81 void convertDoubleToChar(double val, char *buf, size_t bufsiz) {
shintamainjp 0:798c62ea70a3 82 snprintf(buf, bufsiz, "%f", val);
shintamainjp 0:798c62ea70a3 83 }
shintamainjp 0:798c62ea70a3 84
shintamainjp 0:798c62ea70a3 85 /**
shintamainjp 0:798c62ea70a3 86 * Post to the feed on Pachube.
shintamainjp 0:798c62ea70a3 87 *
shintamainjp 0:798c62ea70a3 88 * @param web Pointer to a Pachube object.
shintamainjp 0:798c62ea70a3 89 * @param feed_id Feed ID.
shintamainjp 0:798c62ea70a3 90 * @param stream_no Stream number.
shintamainjp 0:798c62ea70a3 91 * @param value value.
shintamainjp 0:798c62ea70a3 92 *
shintamainjp 0:798c62ea70a3 93 * @return Pachube code.
shintamainjp 0:798c62ea70a3 94 */
shintamainjp 0:798c62ea70a3 95 int web_post(PachubeV2CSV *web, int feed_id, int stream_no, double value) {
shintamainjp 0:798c62ea70a3 96 char value_text[16];
shintamainjp 0:798c62ea70a3 97 convertDoubleToChar(value, value_text, sizeof(value_text));
shintamainjp 0:798c62ea70a3 98 char stream_no_text[8];
shintamainjp 0:798c62ea70a3 99 stream_no_text[0] = "0123456789"[stream_no];
shintamainjp 0:798c62ea70a3 100 stream_no_text[1] = '\0';
shintamainjp 0:798c62ea70a3 101 return web->updateDataStream(feed_id, stream_no_text, std::string(value_text));
shintamainjp 0:798c62ea70a3 102 }
shintamainjp 0:798c62ea70a3 103
shintamainjp 0:798c62ea70a3 104 /**
shintamainjp 0:798c62ea70a3 105 * Write to the file.
shintamainjp 0:798c62ea70a3 106 *
shintamainjp 0:798c62ea70a3 107 * @param v1 value no. 1.
shintamainjp 0:798c62ea70a3 108 * @param v2 value no. 2.
shintamainjp 0:798c62ea70a3 109 * @param v3 value no. 3.
shintamainjp 0:798c62ea70a3 110 * @param v4 value no. 4.
shintamainjp 0:798c62ea70a3 111 * @param v5 value no. 5.
shintamainjp 0:798c62ea70a3 112 *
shintamainjp 0:798c62ea70a3 113 * @return Return 0 if it succeed.
shintamainjp 0:798c62ea70a3 114 */
shintamainjp 0:798c62ea70a3 115 int file_write(int v1, int v2, int v3, int v4, int v5) {
shintamainjp 0:798c62ea70a3 116 FILE *fp = fopen(DATACSV_FILENAME, "a");
shintamainjp 0:798c62ea70a3 117 if (fp == NULL) {
shintamainjp 0:798c62ea70a3 118 return -1;
shintamainjp 0:798c62ea70a3 119 }
shintamainjp 0:798c62ea70a3 120 fprintf(fp, "%d, %d, %d, %d, %d\n", v1, v2, v3, v4, v5);
shintamainjp 0:798c62ea70a3 121 fclose(fp);
shintamainjp 0:798c62ea70a3 122 return 0;
shintamainjp 0:798c62ea70a3 123 }
shintamainjp 0:798c62ea70a3 124
shintamainjp 0:798c62ea70a3 125 /**
shintamainjp 0:798c62ea70a3 126 * Entry point.
shintamainjp 0:798c62ea70a3 127 */
shintamainjp 0:798c62ea70a3 128 int main() {
shintamainjp 0:798c62ea70a3 129
shintamainjp 0:798c62ea70a3 130 /*
shintamainjp 0:798c62ea70a3 131 * Splash.
shintamainjp 0:798c62ea70a3 132 */
shintamainjp 0:798c62ea70a3 133 splash();
shintamainjp 0:798c62ea70a3 134 wait(5);
shintamainjp 0:798c62ea70a3 135
shintamainjp 0:798c62ea70a3 136 /*
shintamainjp 0:798c62ea70a3 137 * Initialize ethernet interface.
shintamainjp 0:798c62ea70a3 138 */
shintamainjp 0:798c62ea70a3 139 lcd.cls();
shintamainjp 0:798c62ea70a3 140 lcd.locate(0, 0);
shintamainjp 0:798c62ea70a3 141 lcd.printf("Initializing...");
shintamainjp 0:798c62ea70a3 142 lcd.locate(0, 1);
shintamainjp 0:798c62ea70a3 143 lcd.printf("Ethernet: ");
shintamainjp 0:798c62ea70a3 144 EthernetErr ethErr = netif.setup();
shintamainjp 0:798c62ea70a3 145 if (ethErr) {
shintamainjp 0:798c62ea70a3 146 lcd.printf("[NG]");
shintamainjp 0:798c62ea70a3 147 error("Ethernet setup failed. Done with code %d.\n", ethErr);
shintamainjp 0:798c62ea70a3 148 }
shintamainjp 0:798c62ea70a3 149 lcd.printf("[OK]");
shintamainjp 0:798c62ea70a3 150 wait(3);
shintamainjp 0:798c62ea70a3 151
shintamainjp 0:798c62ea70a3 152 /*
shintamainjp 0:798c62ea70a3 153 * Read configuration variables from a file.
shintamainjp 0:798c62ea70a3 154 */
shintamainjp 0:798c62ea70a3 155 lcd.cls();
shintamainjp 0:798c62ea70a3 156 lcd.locate(0, 0);
shintamainjp 0:798c62ea70a3 157 lcd.printf("Reading...");
shintamainjp 0:798c62ea70a3 158 lcd.locate(0, 1);
shintamainjp 0:798c62ea70a3 159 lcd.printf("Setup: ");
shintamainjp 0:798c62ea70a3 160 appconf_init(&appconf);
shintamainjp 0:798c62ea70a3 161 if (appconf_read(CONFIG_FILENAME, &appconf) != 0) {
shintamainjp 0:798c62ea70a3 162 lcd.printf("[NG]");
shintamainjp 0:798c62ea70a3 163 error("Failure to read a configuration file.\n");
shintamainjp 0:798c62ea70a3 164 }
shintamainjp 0:798c62ea70a3 165 lcd.printf("[OK]");
shintamainjp 0:798c62ea70a3 166 wait(3);
shintamainjp 0:798c62ea70a3 167
shintamainjp 0:798c62ea70a3 168 /*
shintamainjp 0:798c62ea70a3 169 * Initialize objects.
shintamainjp 0:798c62ea70a3 170 */
shintamainjp 0:798c62ea70a3 171 PachubeV2CSV web(appconf.apikey);
shintamainjp 0:798c62ea70a3 172 const int feed_id = atoi(appconf.feedid);
shintamainjp 0:798c62ea70a3 173
shintamainjp 0:798c62ea70a3 174 /*
shintamainjp 0:798c62ea70a3 175 * Check the pachube feautures.
shintamainjp 0:798c62ea70a3 176 */
shintamainjp 0:798c62ea70a3 177 {
shintamainjp 0:798c62ea70a3 178 lcd.cls();
shintamainjp 0:798c62ea70a3 179 lcd.locate(0, 0);
shintamainjp 0:798c62ea70a3 180 lcd.printf("Checking Pachube");
shintamainjp 0:798c62ea70a3 181 lcd.locate(0, 1);
shintamainjp 0:798c62ea70a3 182 lcd.printf("Status:");
shintamainjp 0:798c62ea70a3 183 int errcnt = 0;
shintamainjp 0:798c62ea70a3 184 if (web_post(&web, feed_id, 0, thermistor1.read()) == PACHUBE_CODE_OK) {
shintamainjp 0:798c62ea70a3 185 lcd.printf("o");
shintamainjp 0:798c62ea70a3 186 } else {
shintamainjp 0:798c62ea70a3 187 lcd.printf("x");
shintamainjp 0:798c62ea70a3 188 errcnt++;
shintamainjp 0:798c62ea70a3 189 }
shintamainjp 0:798c62ea70a3 190 if (web_post(&web, feed_id, 1, thermistor2.read()) == PACHUBE_CODE_OK) {
shintamainjp 0:798c62ea70a3 191 lcd.printf("o");
shintamainjp 0:798c62ea70a3 192 } else {
shintamainjp 0:798c62ea70a3 193 lcd.printf("x");
shintamainjp 0:798c62ea70a3 194 errcnt++;
shintamainjp 0:798c62ea70a3 195 }
shintamainjp 0:798c62ea70a3 196 if (web_post(&web, feed_id, 2, thermistor3.read()) == PACHUBE_CODE_OK) {
shintamainjp 0:798c62ea70a3 197 lcd.printf("o");
shintamainjp 0:798c62ea70a3 198 } else {
shintamainjp 0:798c62ea70a3 199 lcd.printf("x");
shintamainjp 0:798c62ea70a3 200 errcnt++;
shintamainjp 0:798c62ea70a3 201 }
shintamainjp 0:798c62ea70a3 202 if (web_post(&web, feed_id, 3, thermistor4.read()) == PACHUBE_CODE_OK) {
shintamainjp 0:798c62ea70a3 203 lcd.printf("o");
shintamainjp 0:798c62ea70a3 204 } else {
shintamainjp 0:798c62ea70a3 205 lcd.printf("x");
shintamainjp 0:798c62ea70a3 206 errcnt++;
shintamainjp 0:798c62ea70a3 207 }
shintamainjp 0:798c62ea70a3 208 if (web_post(&web, feed_id, 4, thermistor5.read()) == PACHUBE_CODE_OK) {
shintamainjp 0:798c62ea70a3 209 lcd.printf("o");
shintamainjp 0:798c62ea70a3 210 } else {
shintamainjp 0:798c62ea70a3 211 lcd.printf("x");
shintamainjp 0:798c62ea70a3 212 errcnt++;
shintamainjp 0:798c62ea70a3 213 }
shintamainjp 0:798c62ea70a3 214 if (errcnt == 5) {
shintamainjp 0:798c62ea70a3 215 lcd.printf("[NG]");
shintamainjp 0:798c62ea70a3 216 error("Inavlid pachube configuration.\n");
shintamainjp 0:798c62ea70a3 217 }
shintamainjp 0:798c62ea70a3 218 lcd.printf("[OK]");
shintamainjp 0:798c62ea70a3 219 wait(3);
shintamainjp 0:798c62ea70a3 220 }
shintamainjp 0:798c62ea70a3 221
shintamainjp 0:798c62ea70a3 222 int cnt = 0;
shintamainjp 0:798c62ea70a3 223 do {
shintamainjp 0:798c62ea70a3 224 /*
shintamainjp 0:798c62ea70a3 225 * Sense.
shintamainjp 0:798c62ea70a3 226 */
shintamainjp 0:798c62ea70a3 227 lcd.cls();
shintamainjp 0:798c62ea70a3 228 double v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0;
shintamainjp 0:798c62ea70a3 229 for (int i = 0; i < appconf.interval; i++) {
shintamainjp 0:798c62ea70a3 230 led = 1 << (i % 4);
shintamainjp 0:798c62ea70a3 231 // printf("%d/%d\n", i + 1, appconf.interval);
shintamainjp 0:798c62ea70a3 232 v1 += thermistor1.read();
shintamainjp 0:798c62ea70a3 233 v2 += thermistor2.read();
shintamainjp 0:798c62ea70a3 234 v3 += thermistor3.read();
shintamainjp 0:798c62ea70a3 235 v4 += thermistor4.read();
shintamainjp 0:798c62ea70a3 236 v5 += thermistor5.read();
shintamainjp 0:798c62ea70a3 237 lcd.locate(0, 0);
shintamainjp 0:798c62ea70a3 238 lcd.printf("| 0| 1| 2| 3| 4|");
shintamainjp 0:798c62ea70a3 239 lcd.locate(0, 1);
shintamainjp 0:798c62ea70a3 240 lcd.printf("|%-2.0f|%-2.0f|%-2.0f|%-2.0f|%-2.0f|",
shintamainjp 0:798c62ea70a3 241 v1 / (i + 1),
shintamainjp 0:798c62ea70a3 242 v2 / (i + 1),
shintamainjp 0:798c62ea70a3 243 v3 / (i + 1),
shintamainjp 0:798c62ea70a3 244 v4 / (i + 1),
shintamainjp 0:798c62ea70a3 245 v5 / (i + 1));
shintamainjp 0:798c62ea70a3 246 wait(1);
shintamainjp 0:798c62ea70a3 247 }
shintamainjp 0:798c62ea70a3 248 v1 /= appconf.interval;
shintamainjp 0:798c62ea70a3 249 v2 /= appconf.interval;
shintamainjp 0:798c62ea70a3 250 v3 /= appconf.interval;
shintamainjp 0:798c62ea70a3 251 v4 /= appconf.interval;
shintamainjp 0:798c62ea70a3 252 v5 /= appconf.interval;
shintamainjp 0:798c62ea70a3 253 cnt++;
shintamainjp 0:798c62ea70a3 254
shintamainjp 0:798c62ea70a3 255 /*
shintamainjp 0:798c62ea70a3 256 * Post.
shintamainjp 0:798c62ea70a3 257 */
shintamainjp 0:798c62ea70a3 258 lcd.cls();
shintamainjp 0:798c62ea70a3 259 lcd.locate(0, 0);
shintamainjp 0:798c62ea70a3 260 lcd.printf("Posting No.%d", cnt);
shintamainjp 0:798c62ea70a3 261 lcd.locate(0, 1);
shintamainjp 0:798c62ea70a3 262 lcd.printf("Status:");
shintamainjp 0:798c62ea70a3 263 int errcnt = 0;
shintamainjp 0:798c62ea70a3 264 if (web_post(&web, feed_id, 0, v1) == PACHUBE_CODE_OK) {
shintamainjp 0:798c62ea70a3 265 lcd.printf("o");
shintamainjp 0:798c62ea70a3 266 } else {
shintamainjp 0:798c62ea70a3 267 lcd.printf("x");
shintamainjp 0:798c62ea70a3 268 errcnt++;
shintamainjp 0:798c62ea70a3 269 }
shintamainjp 0:798c62ea70a3 270 if (web_post(&web, feed_id, 1, v2) == PACHUBE_CODE_OK) {
shintamainjp 0:798c62ea70a3 271 lcd.printf("o");
shintamainjp 0:798c62ea70a3 272 } else {
shintamainjp 0:798c62ea70a3 273 lcd.printf("x");
shintamainjp 0:798c62ea70a3 274 errcnt++;
shintamainjp 0:798c62ea70a3 275 }
shintamainjp 0:798c62ea70a3 276 if (web_post(&web, feed_id, 2, v3) == PACHUBE_CODE_OK) {
shintamainjp 0:798c62ea70a3 277 lcd.printf("o");
shintamainjp 0:798c62ea70a3 278 } else {
shintamainjp 0:798c62ea70a3 279 lcd.printf("x");
shintamainjp 0:798c62ea70a3 280 errcnt++;
shintamainjp 0:798c62ea70a3 281 }
shintamainjp 0:798c62ea70a3 282 if (web_post(&web, feed_id, 3, v4) == PACHUBE_CODE_OK) {
shintamainjp 0:798c62ea70a3 283 lcd.printf("o");
shintamainjp 0:798c62ea70a3 284 } else {
shintamainjp 0:798c62ea70a3 285 lcd.printf("x");
shintamainjp 0:798c62ea70a3 286 errcnt++;
shintamainjp 0:798c62ea70a3 287 }
shintamainjp 0:798c62ea70a3 288 if (web_post(&web, feed_id, 4, v5) == PACHUBE_CODE_OK) {
shintamainjp 0:798c62ea70a3 289 lcd.printf("o");
shintamainjp 0:798c62ea70a3 290 } else {
shintamainjp 0:798c62ea70a3 291 lcd.printf("x");
shintamainjp 0:798c62ea70a3 292 errcnt++;
shintamainjp 0:798c62ea70a3 293 }
shintamainjp 0:798c62ea70a3 294 if (errcnt == 5) {
shintamainjp 0:798c62ea70a3 295 lcd.printf("[NG]");
shintamainjp 0:798c62ea70a3 296 }
shintamainjp 0:798c62ea70a3 297 lcd.printf("[OK]");
shintamainjp 0:798c62ea70a3 298 wait(1);
shintamainjp 0:798c62ea70a3 299
shintamainjp 0:798c62ea70a3 300 /*
shintamainjp 0:798c62ea70a3 301 * Write.
shintamainjp 0:798c62ea70a3 302 */
shintamainjp 0:798c62ea70a3 303 lcd.cls();
shintamainjp 0:798c62ea70a3 304 lcd.locate(0, 0);
shintamainjp 0:798c62ea70a3 305 lcd.printf("Writing No.%d", cnt);
shintamainjp 0:798c62ea70a3 306 lcd.locate(0, 1);
shintamainjp 0:798c62ea70a3 307 lcd.printf("Status: ");
shintamainjp 0:798c62ea70a3 308 if (file_write(v1, v2, v3, v4, v5) == 0) {
shintamainjp 0:798c62ea70a3 309 lcd.printf("[OK]");
shintamainjp 0:798c62ea70a3 310 } else {
shintamainjp 0:798c62ea70a3 311 lcd.printf("[NG]");
shintamainjp 0:798c62ea70a3 312 }
shintamainjp 0:798c62ea70a3 313 wait(1);
shintamainjp 0:798c62ea70a3 314 } while (1);
shintamainjp 0:798c62ea70a3 315 }