Data logger: Sensors -> Barometer & temperature (BMP180), Humidity & temp. (RHT03), Sunshine (Cds): Display -> 20 chracters x 4 lines: Strage -> EEPROM (AT24C1024): Special functions -> Enter sleep mode to save current, reading the logging data via serial line

Dependencies:   AT24C1024 BMP180 M41T62 RHT03 TextLCD WakeUp mbed

Fork of LPC1114_barometer_with_data_logging by Kenji Arai

Please refer following Notebook.
http://mbed.org/users/kenjiArai/notebook/mbed-lpc1114fn28-data-logger/

main.cpp

Committer:
kenjiArai
Date:
2014-08-11
Revision:
18:2a1d75bc8ebc
Parent:
16:f164f8912201
Child:
19:19dd6332d729

File content as of revision 18:2a1d75bc8ebc:

/*
 * mbed Application program for the mbed LPC1114FN28
 * Barometer program for only for LPC1114FN28  
 *
 * Copyright (c) 2014 Kenji Arai / JH1PJL
 *  http://www.page.sannet.ne.jp/kenjia/index.html
 *  http://mbed.org/users/kenjiArai/
 *      Created: May       21st, 2014
 *      Revised: August    12th, 2014
 *
 * 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.
 */
/*
 * Function
 *  measure atmospheric pressure and temprerature using Bosch BMP180 pressure sensor
 *  show measured data on a LCD and logging such data in I2C EEPROM
 */

//  Include ---------------------------------------------------------------------------------------
#include "mbed.h"
#include "BMP180.h"             // Own lib. / Pressure sensor             
#include "RHT03.h"              // Std. lib./ Humidity sensor
#include "TextLCD.h"            // Std. lib./ LCD control
#include "m41t62_rtc.h"         // Own lib. / RTC control
#include "WakeUp.h"
#include "WakeInterruptIn.h"
#include "dt_log.h"

//  Definition ------------------------------------------------------------------------------------
// ADC related definition
#define VREF_VOLT               2.482   // TA76431F Vref real measued data
#define R_FIX                   9930    // 10K ohm <- real measued data
#define VOL_OFFSET              3       // Offset data ,= real measured data
#define CDS_TBL_SIZE            13

// Waiting time
//#define TIME_INTERVAL           600     // 10 minutes
#define TIME_INTERVAL           60     // 1 minutes

typedef enum {CDS = 0, VREF, VOL} ADC_Select;

#define BAUD(x)                 pcx.baud(x)
#define GETC(x)                 pcx.getc(x)
#define PUTC(x)                 pcx.putc(x)
#define PRINTF(...)             pcx.printf(__VA_ARGS__)
#define READABLE(x)             pcx.readable(x)

//  Object ----------------------------------------------------------------------------------------
Serial      pcx(dp16,dp15);
I2C         i2c(dp5,dp27);      // SDA, SCL
WakeInterruptIn event(dp25);    // wake-up from deepsleep mode by this interrupt
DigitalOut  myled(dp14);        // LED for Debug
DigitalOut  analog_pwr(dp6);    // VCC for analog interface (vol, cds and vref)
DigitalOut  vref_pwr(dp4);      // VCC for Vref
AnalogIn    cds(dp11);          // Input / CDS data
AnalogIn    vref(dp9);          // Input / Bandgap 2.5V
AnalogIn    vol(dp10);          // Input / contrast volume
RHT03       humtemp(dp26);      // RHT03 interface
BMP180      bmp180(i2c);        // Bosch sensor
M41T62      m41t62(i2c);        // STmicro RTC(M41T62)
TextLCD     lcd(dp1, dp28, dp17, dp18, dp2, dp13, TextLCD::LCD20x4); // rs, e, d4-d7

//  Function prototypes ---------------------------------------------------------------------------
extern int mon( void);          // only use for debug purpose

//  RAM -------------------------------------------------------------------------------------------
//  ADC
float av_cds, av_vref, av_vol, cal_vcc;
float r_cds, lux;
uint32_t nor_vol;

//  Humidity Sensor
float humidity_temp, humidity;

//  EEPROM
uint8_t eep_buf[256 + 2];

// Barometer
float baro;
float baro_temp;

//  ROM / Constant data ---------------------------------------------------------------------------
// Cds GL5528 (Dark Resistance 1 Mohm type) SENBA OPTICAL & ELECTRONIC CO.,LTD.
//      Table value referrence: http://homepage3.nifty.com/skomo/f35/hp35_20.htm
const float lux_cds[CDS_TBL_SIZE][2] =
    {{50,21194},{100,8356},{200,3294},{400,1299},{800,512},{1600,202},{3200,79.6},{6400,31.4},
    {12800,12.4},{25600,4.88},{51200,1.92},{102400,0.758},{409600,0.118}};

//                              12345678901234567890
static char *const msg_clear = "                    ";
static char *const msg_msg0  = "  mbed LPC1114FN28  ";
static char *const msg_msg1  = "   by JH1PJL K.Arai ";
static char *const msg_msg2  = "  Barometer Logger  ";
static char *const msg_msg3  = "                    ";
static char *const msg_msg4  = "Goto Monitor/9600bps";
static char *const msg_msg5  = "  Back to main      ";

//-------------------------------------------------------------------------------------------------
//  Control Program
//-------------------------------------------------------------------------------------------------
// Normalize ADC data
void adc_normalize (ADC_Select n){
int i;
float x1,y1,dx;

    switch (n){
    case CDS:
        // v_adc = Rfix / (Rcds + Rfix) ->  Rcds = ( Rfix / v_adc ) - Rfix 
        r_cds = (R_FIX / av_cds) - R_FIX;
        // CDS resistance to Lux conversion using convertion table (luc_cds[][])
        for (i =0; i < CDS_TBL_SIZE; i++){  // search table
            if ( r_cds <= lux_cds[i][0]){ break; }
        }
        // Check table position
        if (i == 0){    lux = lux_cds[0][1];    break;
        } else if ( i == CDS_TBL_SIZE ){
            if ( r_cds <= lux_cds[i][0] ){
                lux = lux_cds[i-1][1];
                break;
            }
        }
        //  Linear interpolation
        y1 = lux_cds[i-1][1] - lux_cds[i][1];
        x1 = lux_cds[i][0] - lux_cds[i-1][0];
        dx = r_cds - lux_cds[i-1][0];
        lux = lux_cds[i-1][1] - ((dx/x1) * y1);
        break;
    case VREF:  //  vref = VREF_VOLT / VCC -> VCC = VREF_VOLT / vref
        cal_vcc = VREF_VOLT / vref;
        break;
    case VOL:   // Vol center = 1.00 (actual 100)
        nor_vol = (uint32_t)(av_vol * 200) + VOL_OFFSET;
        break;
    }
}

//  Read adc data and averaging
void adc_all_read (void){
    if (av_cds == 0){   av_cds = cds.read();
    } else {            av_cds = av_cds *0.5 + cds.read() * 0.5;
    }
    if (av_vref == 0){  av_vref = vref.read();
    } else {            av_vref = av_vref *0.9 + vref.read() * 0.1;
    }
    if (av_vol == 0){   av_vol = vol.read();
    } else {            av_vol = av_vol *0.2 + vol.read() * 0.8;
    } 
}

// Read Humidity sensor data
void hum_RHT03_read (void){
    while (true){   // wait data
        if ( humtemp.readData() == RHT_ERROR_NONE ){ break; }
    }
    if (humidity_temp == 0){humidity_temp = humtemp.getTemperatureC();
    } else {                humidity_temp = humidity_temp * 0.9 + humtemp.getTemperatureC() * 0.1;
    }
    if ( humidity == 0 ){   humidity = humtemp.getHumidity();
    } else {                humidity = humidity * 0.9 + humtemp.getHumidity() * 0.1;
    }
}

//-------------------------------------------------------------------------------------------------
// Application program
//-------------------------------------------------------------------------------------------------
// Measure pressure and show it on LCD
void conv_and_disp(void) {
tm t;
time_t seconds = 0;
time_t old_seconds = 0;
uint32_t dt;

    // Wakeup from deep sleep
    WakeUp::calibrate();
    // Initialize data
    av_cds = 0;
    av_vref = 0;
    av_vol = 0;
    humidity_temp = 0;
    humidity = 0;
    // RTC
    m41t62.set_sq_wave(RTC_SQW_NONE);
    m41t62.read_rtc_std(&t);
    old_seconds = mktime(&t);
    while (true) {          // infinit loop for measure and display
    //  ---------- Barometer Sensor / BMP180 ------------------------------------------------------
        bmp180.normalize();
        baro = bmp180.read_pressure();
        baro_temp = bmp180.read_temperature();
    //  ---------- Humidity Sensor / RHT03 --------------------------------------------------------
        hum_RHT03_read();       // Read Humidity data then avaraging
    //  ---------- Cds Sensor, Vref, Volume -------------------------------------------------------
        wait(0.2);
        adc_all_read();
        // Normalize
        adc_normalize(CDS);
        adc_normalize(VREF);
        adc_normalize(VOL);
    //  ---------- RTC ----------------------------------------------------------------------------
        m41t62.read_rtc_std(&t);
        seconds = mktime(&t);
    //  ---------- EEPROM Logging -----------------------------------------------------------------
        if (seconds >= old_seconds + TIME_INTERVAL){
            // Data Logging action
            old_seconds += TIME_INTERVAL;
            dtlog_data_pack();  // Get EEPROM resource
            dtlog_one_write();  // Write data to EEPROM
        }
        dt = (uint32_t)dtlog_buf_occupation();
        dt = (dt * 1000)/ BLK_NO;
    //  ---------- Display all data on a LCD ------------------------------------------------------      
        //  Printf:: Barometer Sensor / BMP180
        lcd.locate(0, 0);    // 1st line top
        lcd.printf("%s", msg_clear);
        lcd.locate(0, 0);    // 1st line top
        lcd.printf("%6.1fhPa    %\+-5.1f%cC", baro, baro_temp, 0xdf);
        //  Printf:: Humidity Sensor / RHT03 + Vcc
        lcd.locate(0, 1);    // 2nd line top
        lcd.printf("%s", msg_clear);
        lcd.locate(0, 1);    // 2nd line top
#if 0
        lcd.printf("%4.1f%%(%\+-4.1f%cC) %.2fV", humidity, humidity_temp, 0xdf, cal_vcc);
#else
        lcd.printf("%.2fV  %4.1f%% %\+-4.1f%cC", cal_vcc, humidity, humidity_temp, 0xdf);
#endif
        //  Printf:: Cds Sensor + EEPROM Logging
        lcd.locate(0, 2);    // 3rd line top
        lcd.printf("%s", msg_clear);
        lcd.locate(0, 2);    // 3rd line top
        if (dt <= 998){
            lcd.printf("%8.1fLx Log:%2d.%01d%%", lux,  dt / 10, dt % 10);
        } else {
            lcd.printf("%8.1fLx Log: full", lux);
        }
        //  Printf:: RTC (Date & Time)
        lcd.locate(0, 3);    // 4th line top
        lcd.printf("%s", msg_clear);
        lcd.locate(0, 3);    // 4th line top
#if 0
        lcd.printf("20%02d/%02d/%02d  %02d:%02d:%02d",
                    t.tm_year % 100, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
#else
        lcd.printf("20%02d/%02d/%02d %02d:%02d PJL",
                    t.tm_year % 100, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min);
#endif
    //  ---------- back to top --------------------------------------------------------------------
        myled = 1;
        wait(0.001);
        myled = 0;
        // Power off - Analog sensor
        analog_pwr = 0;
        vref_pwr = 0;
        // Wait with sleep
        WakeUp::set(10);
        wait(0.001);    // looks important for works well
        myled = 1;
        wait(0.001);
        myled = 0;
        // Power on - Analog sensor
        analog_pwr = 1;
        vref_pwr = 1;
    }
}

// Application program starts here
int main() {
    // Initial screen
    lcd.locate(0, 0);
    lcd.printf(msg_msg0);
    lcd.printf(msg_msg1);
    lcd.printf(msg_msg2);
    lcd.printf(msg_msg3);
    myled = 1;
    wait(3);    // show initial screen and wait serial input
    myled = 0;
    //--  Enter Monitor Mode  --
    if (READABLE()){
        lcd.locate(0, 0);
        lcd.printf(msg_msg4);
        mon();          // mon.cpp
        lcd.locate(0, 0);
        lcd.printf(msg_msg5);
        wait(0.5);
    }
    //--  Enter Normal Mode  --
    while (true) {  // Start main program
        conv_and_disp();
    }
}