Barometer program : Data Logger function includes Barometer & temperature (BMP180), Humidity & temp. (RHT03), Sunshine (Cds), RTC(M41T62) data. : Logging data saves into EEPROM (AT24C1024) using ring buffer function.

Dependencies:   AT24C1024 RHT03 TextLCD BMP180 M41T62

Fork of mbed_blinky by Mbed

Please see https://mbed.org/users/kenjiArai/notebook/mbed-lpc1114fn28-barometer-with-data-logging/#

main.cpp

Committer:
kenjiArai
Date:
2014-06-20
Revision:
12:1e21119688fe
Parent:
11:bccfd75e84a0
Child:
13:950adc9d6d61

File content as of revision 12:1e21119688fe:

/*
 * mbed Application program for the mbed LPC1114FN28
 * Test program -> Check EEPROM
 *
 * Copyright (c) 2014 Kenji Arai / JH1PJL
 *  http://www.page.sannet.ne.jp/kenjia/index.html
 *  http://mbed.org/users/kenjiArai/
 *      Created: June      13th, 2014
 *      Revised: June      21st, 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.
 */

#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 "AT24C1024.h"             // Std. lib./ EEPROM control

#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

I2C         i2c(dp5,dp27);      // SDA, SCL
DigitalOut  myled0(dp28);       // LED for Debug
DigitalOut  myled1(dp14);       // Indicate state transition
DigitalOut  analog_pwr(dp6);    // VCC for analog interface (vol, cds and vref)
DigitalOut  vref_pwr(dp4);      // VCC for Vref
DigitalIn   sw_chng(dp1,PullUp);// SW for select
DigitalIn   sw_mode(dp2,PullUp);// SW for Mode change
AnalogIn    cds(dp11);          // Input / CDS data
AnalogIn    vref(dp9);          // Input / Bandgap 2.5V
AnalogIn    vol(dp10);          // Input / contrast volume
RHT03       humtemp(dp26);      // RHT03 interface
Serial      pc(dp16,dp15);      // UART (vertual COM)
BMP180      bmp180(i2c);        // Bosch sensor
TextLCD_I2C_N i2clcd(&i2c, 0x7c, TextLCD::LCD8x2);  // LCD(Akizuki AQM0802A)
AT24C1024   at24c1024(i2c);     // Atmel 1Mbit EE-PROM 

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

//  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];

// 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}};

// EEPROM test charcters
const uint8_t eep_char[256] =
//0        1         2         3         4         5         6         7
//12345678901234567890123456789012345678901234567890123456789012345678901
 "The AT24C1024 provides 1048576 bits of serial electrically erasable and"
//7       8         9        10        11        12        13        14        15
//2345678901234567890123456789012345678901234567890123456789012345678901234567890123
 " programmable read only memory (EEPROM) organized as 131,072 words of 8 bits each."
//15   16        17        18        19        20        21        22        23        24
//45678901234567890123456789012345678901234567890123456789012345678901234567890123456789012
 " The devices cascadable feature allows up to four devices to share a common two-wire bus."
//24    25   256
//34567890123456
 "  JH1PJL Arai"; // eep_char[255] = 0;

//-------------------------------------------------------------------------------------------------
//  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;
    }
}

// Clear LCD
void cls( void){
    i2clcd.locate(0, 0);
    i2clcd.printf("        ");
    i2clcd.locate(0, 1);
    i2clcd.printf("        ");
}

//-------------------------------------
// Application program starts here
//-------------------------------------
int main() {
int no =0;
uint8_t dt[4];
AT24C_STATUS status;

    pc.baud(9600);
    pc.printf("\r\nmbed LPC1114FN28 test program by JH1PJL created on "__DATE__"(UTC)\r\n");
    i2clcd.setContrast(25);
    i2clcd.locate(0, 0);
    i2clcd.printf("LPC1114F");
    i2clcd.locate(0, 1);
    i2clcd.printf(" JH1PJL ");
    // Initialize data
    av_cds = 0;
    av_vref = 0;
    av_vol = 0;
    humidity_temp = 0;
    humidity = 0;
    // Show initial screen
    wait(5.0);    
    while(1) {
    //  ---------- Cds Sensor, Vref, Volume ---------------------------------------------------
        // Power on / Analog sensor
        analog_pwr = 1;
        vref_pwr = 1;
        wait(0.2);
        adc_all_read();
        // Power off / Analog sensor
        analog_pwr = 0; 
        // Normalize
        adc_normalize(CDS);
        adc_normalize(VREF);
        adc_normalize(VOL);
        cls();       
        i2clcd.locate(0, 0);    // 1st line top
        //             12345678
        i2clcd.printf("L:%.1f", lux);
        i2clcd.locate(0, 1);    // 2nd line top
        i2clcd.printf("V:%.3f", cal_vcc);       
        myled0 = 1;
        pc.printf( "\r\nCds:%.0fohm -> %.1flux, Vcc:%.3fV, Vol:%d\r\n",
            r_cds, lux, cal_vcc, nor_vol );
        myled0 = 0;
        wait(2.0);
    //  ---------- Barometer Sensor / BMP180 --------------------------------------------------
        bmp180.normalize();
        cls();
        i2clcd.locate(0, 0);    // 1st line top
        i2clcd.printf("P:%.1f", bmp180.read_pressure());
        i2clcd.locate(0, 1);    // 2nd line top
        i2clcd.printf("T:%\+-6.1f", bmp180.read_temperature());
        myled1 = 1;
        pc.printf("Pres:%4.1fhPa, Temp:%\+-0.1fdegC\r\n", bmp180.read_pressure(), bmp180.read_temperature());
        myled1 = 0;
        wait(4.0);
    //  ---------- Humidity Sensor / RHT03 ----------------------------------------------------
        hum_RHT03_read();       // Read Humidity data then avaraging
        cls();
        i2clcd.locate(0, 0);    // 1st line top
        i2clcd.printf("H:%.1f", humidity);
        i2clcd.locate(0, 1);    // 2nd line top
        i2clcd.printf("T:%\+-6.1f", humidity_temp);
        myled1 = 1;
        pc.printf("Humid: %0.1f%%RH, Temp:%\+-0.1fdegC\r\n", humidity, humidity_temp);          
        myled1 = 0; 
        wait(2.0);
    //  ---------- Check EEPROM ----------------------------------------------------
        cls();
        i2clcd.locate(0, 0);    // 1st line top
        //             12345678
        i2clcd.printf(" EEPROM ", humidity);
        pc.printf("EEPROM -> ", humidity, humidity_temp);
        i2clcd.locate(0, 1);    // 2nd line top  
        if (no == 4) {  // check page write mode (part1)
            ++no;
            strcpy((char *)eep_buf,(char *)eep_char);   // copy the data         
            status = at24c1024.write_page(0x100, eep_buf, sizeof(eep_buf)); // 0x100= page address
            pc.printf("(Status: %d) ", status);
            if (status == AT24C_OK){    // wrote without trouble
                wait(1.0);
                for (int i=0; i < 256; i++){    // clear buffer for read data checking
                    eep_buf[i] = 0;
                }
                status = at24c1024.read_page(0x100, eep_buf, sizeof(eep_buf));
                pc.printf("(Status: %d) ", status);
                if (status == AT24C_OK){    // read w/o trouble
                    pc.printf("\r\n%s\r\n", eep_buf);
                    if (strncmp((char *)eep_buf, (char *)eep_char, 256) == 0){ // equal R/W data
                        i2clcd.printf("page-OK");
                        pc.printf("Page access OK\r\n");
                    } else {    // Read != Wrote
                        i2clcd.printf("CMP-NG");
                        pc.printf("Page access Comp NG\r\n");
                    }
                } else {    // read w/ trouble
                    i2clcd.printf("RD-NG");
                    pc.printf("Page access read NG\r\n");
                }
            } else {        // write w/ trouble
                i2clcd.printf("WR -NG");
                pc.printf("Write NG\r\n");
            }
            wait(0.5);       
        } else if (no == 5) {  // check page write mode (part2)
            no = 0;
            for (int i=0; i < 256; i++){    // set writing data 255,254,,,,,3,2,1,0
                eep_buf[i] = 255 - (uint8_t)i;
            }        
            status = at24c1024.write_page(0x1ff00, eep_buf, sizeof(eep_buf));
            pc.printf("(Status: %d) ", status);
            if (status == AT24C_OK){
                wait(1.0);
                for (int i=0; i < 256; i++){    // clear buffer
                    eep_buf[i] = 0;
                }
                status = at24c1024.read_page(0x1ff00, eep_buf, sizeof(eep_buf));
                pc.printf("(Status: %d) ", status);
                if (status == AT24C_OK){
                    pc.printf("\r\n0:%d, 64:%d, 128:%d, 254:%d, 255:%d\r\n",
                            eep_buf[0], eep_buf[64], eep_buf[128], eep_buf[254], eep_buf[255]);
                    if ((eep_buf[0] == 255) && (eep_buf[64] == 255 - 64)
                            && (eep_buf[128] == 255-128) && (eep_buf[255] == 0)){
                        i2clcd.printf("page-OK");
                        pc.printf("Page access OK\r\n");
                    } else {
                        i2clcd.printf("CMP-NG");
                        pc.printf("Page access Comp NG\r\n");
                    }
                } else {
                    i2clcd.printf("RD-NG");
                    pc.printf("Page access read NG\r\n");
                }
            } else {
                i2clcd.printf("WR -NG");
                pc.printf("Write NG\r\n");
            }
            wait(0.5);
        } else {    // Write and read (single byte)
            if (no == 0){   // Initial setting
                // Check EEPROM (step0)
                at24c1024.write(0,no);
                wait(0.1);
                at24c1024.write(1,0);
                wait(0.1);
                at24c1024.write(2,0x55);
                wait(0.1);
                at24c1024.write(3,0xaa);
                wait(0.1);
                dt[0] = 0xff;
                dt[1] = 1;
                dt[2] = 2;
                dt[3] = 3;
            }
            // read 4 bytes
            dt[0] = at24c1024.read(0);
            dt[1] = at24c1024.read(1);
            dt[2] = at24c1024.read(2);
            dt[3] = at24c1024.read(3);     
            if (dt[0] != no){
                i2clcd.locate(0, 1);    // 2nd line top
                i2clcd.printf("NG", humidity_temp);
                pc.printf("NG\r\n", humidity, humidity_temp);
            } else {           
                if ((dt[1] == 0) && (dt[2] == 0x55) && (dt[3] == 0xaa)){
                    i2clcd.printf("-> OK");
                    pc.printf("OK\r\n");        
                } else {
                    i2clcd.printf("-> NG ");
                    pc.printf("NG\r\n");
                }
            }
            pc.printf("EEPROM 0x%x,0x%x,0x%x,0x%x\r\n", dt[0],dt[1],dt[2],dt[3]);
            at24c1024.write(0,++no);    // write sequence number into EEPROM
            wait(1.0);
        }    
    }
}