World Wide Data Logger using mbed.

Dependencies:   mbed ThermistorPack Pachube ConfigFile EthernetNetIf TextLCD SDFileSystem

main.cpp

Committer:
shintamainjp
Date:
2011-04-04
Revision:
0:798c62ea70a3

File content as of revision 0:798c62ea70a3:

/**
 * =============================================================================
 * TORAGI 2011/04 : WEB Data Logger
 * =============================================================================
 * Copyright (c) 2010-2011 Shinichiro Nakamura
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 * =============================================================================
 */

#include "mbed.h"
#include "PachubeV2CSV.h"
#include "EthernetNetIf.h"
#include "HTTPClient.h"
#include "ThermistorMCP9701.h"
#include "TextLCD.h"
#include "appconf.h"
#include "SDFileSystem.h"

/*
 * Definitions for a configuration file.
 */
#define CONFIG_FILENAME "/local/PACHUBE.CFG"
#define DATACSV_FILENAME "/sd/DATA.CSV"
const int PACHUBE_CODE_OK = 200;

LocalFileSystem localfs("local");
SDFileSystem sdfs(p5, p6, p7, p8, "sd");
TextLCD lcd(p24, p26, p27, p28, p29, p30);
EthernetNetIf netif;
BusOut led(LED1, LED2, LED3, LED4);
ThermistorMCP9701 thermistor1(p16);
ThermistorMCP9701 thermistor2(p17);
ThermistorMCP9701 thermistor3(p18);
ThermistorMCP9701 thermistor4(p19);
ThermistorMCP9701 thermistor5(p20);
static appconf_t appconf;

/**
 * Display a splash screen.
 */
void splash(void) {
    lcd.cls();
    lcd.locate(0, 0);
    lcd.printf(" TORAGI 2011/04 ");
    lcd.locate(0, 1);
    lcd.printf("WEB Data Logger ");
    wait(2);

    lcd.cls();
    lcd.locate(0, 0);
    lcd.printf(" Starting up... ");
    lcd.locate(0, 1);
    lcd.printf(" Wait a moment. ");
    wait(2);
}

/**
 * Convert double to char.
 *
 * @param val Value.
 * @param buf A pointer to a buffer.
 * @param bufsiz The buffer size.
 */
void convertDoubleToChar(double val, char *buf, size_t bufsiz) {
    snprintf(buf, bufsiz, "%f", val);
}

/**
 * Post to the feed on Pachube.
 *
 * @param web Pointer to a Pachube object.
 * @param feed_id Feed ID.
 * @param stream_no Stream number.
 * @param value value.
 *
 * @return Pachube code.
 */
int web_post(PachubeV2CSV *web, int feed_id, int stream_no, double value) {
    char value_text[16];
    convertDoubleToChar(value, value_text, sizeof(value_text));
    char stream_no_text[8];
    stream_no_text[0] = "0123456789"[stream_no];
    stream_no_text[1] = '\0';
    return web->updateDataStream(feed_id, stream_no_text, std::string(value_text));
}

/**
 * Write to the file.
 *
 * @param v1 value no. 1.
 * @param v2 value no. 2.
 * @param v3 value no. 3.
 * @param v4 value no. 4.
 * @param v5 value no. 5.
 *
 * @return Return 0 if it succeed.
 */
int file_write(int v1, int v2, int v3, int v4, int v5) {
    FILE *fp = fopen(DATACSV_FILENAME, "a");
    if (fp == NULL) {
        return -1;
    }
    fprintf(fp, "%d, %d, %d, %d, %d\n", v1, v2, v3, v4, v5);
    fclose(fp);
    return 0;
}

/**
 * Entry point.
 */
int main() {

    /*
     * Splash.
     */
    splash();
    wait(5);

    /*
     * Initialize ethernet interface.
     */
    lcd.cls();
    lcd.locate(0, 0);
    lcd.printf("Initializing...");
    lcd.locate(0, 1);
    lcd.printf("Ethernet: ");
    EthernetErr ethErr = netif.setup();
    if (ethErr) {
        lcd.printf("[NG]");
        error("Ethernet setup failed. Done with code %d.\n", ethErr);
    }
    lcd.printf("[OK]");
    wait(3);

    /*
     * Read configuration variables from a file.
     */
    lcd.cls();
    lcd.locate(0, 0);
    lcd.printf("Reading...");
    lcd.locate(0, 1);
    lcd.printf("Setup: ");
    appconf_init(&appconf);
    if (appconf_read(CONFIG_FILENAME, &appconf) != 0) {
        lcd.printf("[NG]");
        error("Failure to read a configuration file.\n");
    }
    lcd.printf("[OK]");
    wait(3);

    /*
     * Initialize objects.
     */
    PachubeV2CSV web(appconf.apikey);
    const int feed_id = atoi(appconf.feedid);

    /*
     * Check the pachube feautures.
     */
    {
        lcd.cls();
        lcd.locate(0, 0);
        lcd.printf("Checking Pachube");
        lcd.locate(0, 1);
        lcd.printf("Status:");
        int errcnt = 0;
        if (web_post(&web, feed_id, 0, thermistor1.read()) == PACHUBE_CODE_OK) {
            lcd.printf("o");
        } else {
            lcd.printf("x");
            errcnt++;
        }
        if (web_post(&web, feed_id, 1, thermistor2.read()) == PACHUBE_CODE_OK) {
            lcd.printf("o");
        } else {
            lcd.printf("x");
            errcnt++;
        }
        if (web_post(&web, feed_id, 2, thermistor3.read()) == PACHUBE_CODE_OK) {
            lcd.printf("o");
        } else {
            lcd.printf("x");
            errcnt++;
        }
        if (web_post(&web, feed_id, 3, thermistor4.read()) == PACHUBE_CODE_OK) {
            lcd.printf("o");
        } else {
            lcd.printf("x");
            errcnt++;
        }
        if (web_post(&web, feed_id, 4, thermistor5.read()) == PACHUBE_CODE_OK) {
            lcd.printf("o");
        } else {
            lcd.printf("x");
            errcnt++;
        }
        if (errcnt == 5) {
            lcd.printf("[NG]");
            error("Inavlid pachube configuration.\n");
        }
        lcd.printf("[OK]");
        wait(3);
    }

    int cnt = 0;
    do {
        /*
         * Sense.
         */
        lcd.cls();
        double v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0;
        for (int i = 0; i < appconf.interval; i++) {
            led = 1 << (i % 4);
            // printf("%d/%d\n", i + 1, appconf.interval);
            v1 += thermistor1.read();
            v2 += thermistor2.read();
            v3 += thermistor3.read();
            v4 += thermistor4.read();
            v5 += thermistor5.read();
            lcd.locate(0, 0);
            lcd.printf("| 0| 1| 2| 3| 4|");
            lcd.locate(0, 1);
            lcd.printf("|%-2.0f|%-2.0f|%-2.0f|%-2.0f|%-2.0f|",
                       v1 / (i + 1),
                       v2 / (i + 1),
                       v3 / (i + 1),
                       v4 / (i + 1),
                       v5 / (i + 1));
            wait(1);
        }
        v1 /= appconf.interval;
        v2 /= appconf.interval;
        v3 /= appconf.interval;
        v4 /= appconf.interval;
        v5 /= appconf.interval;
        cnt++;

        /*
         * Post.
         */
        lcd.cls();
        lcd.locate(0, 0);
        lcd.printf("Posting No.%d", cnt);
        lcd.locate(0, 1);
        lcd.printf("Status:");
        int errcnt = 0;
        if (web_post(&web, feed_id, 0, v1) == PACHUBE_CODE_OK) {
            lcd.printf("o");
        } else {
            lcd.printf("x");
            errcnt++;
        }
        if (web_post(&web, feed_id, 1, v2) == PACHUBE_CODE_OK) {
            lcd.printf("o");
        } else {
            lcd.printf("x");
            errcnt++;
        }
        if (web_post(&web, feed_id, 2, v3) == PACHUBE_CODE_OK) {
            lcd.printf("o");
        } else {
            lcd.printf("x");
            errcnt++;
        }
        if (web_post(&web, feed_id, 3, v4) == PACHUBE_CODE_OK) {
            lcd.printf("o");
        } else {
            lcd.printf("x");
            errcnt++;
        }
        if (web_post(&web, feed_id, 4, v5) == PACHUBE_CODE_OK) {
            lcd.printf("o");
        } else {
            lcd.printf("x");
            errcnt++;
        }
        if (errcnt == 5) {
            lcd.printf("[NG]");
        }
        lcd.printf("[OK]");
        wait(1);

        /*
         * Write.
         */
        lcd.cls();
        lcd.locate(0, 0);
        lcd.printf("Writing No.%d", cnt);
        lcd.locate(0, 1);
        lcd.printf("Status: ");
        if (file_write(v1, v2, v3, v4, v5) == 0) {
            lcd.printf("[OK]");
        } else {
            lcd.printf("[NG]");
        }
        wait(1);
    } while (1);
}