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-13
Revision:
9:ce80da60884a
Parent:
8:f6aa5561f219
Child:
10:398f62bb41f7

File content as of revision 9:ce80da60884a:

/*
 * mbed Application program for the mbed LPC1114FN28
 * Test program -> Check LED & Switch function 
 *
 * 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      13th, 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"

#define DEBUG_L1       1        // 1=Debug, 0=Normal
#define DEBUG_L2       1        // 1=Debug, 0=Normal

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

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
Serial pc(dp16,dp15);

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;

//  LCD
extern unsigned char contrast;
char buf[16];

//  Barometer
extern uint32_t baro_pressure_ave_data; // Temperature /normalized
extern int16_t  baro_temp_ave_data;
extern uint32_t baro_pres_data;         // Barometer /normalized
extern int16_t  baro_temp_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}};

#if DEBUG_L2
char *const imsg0 = "-->Control Reg.";
char *const imsg1 = "-->Status Reg.";
char *const imsg2 = "-->Data Reg.";
char *const imsg3 = "-->Clock control Reg.";
static char *const io_port_name0 = "PIO0_";
static char *const iomsg0 = "Func->select ";
static char *const iomsg1 = "IO";
static char *const iomsg2 = "Reserved";
static char *const iomsg3 = "Std/F-md I2C";
#endif  // DEBUG_L2

// Functions
//      Barometer
void baro_st_conv_temp( void );         // Start Conversion
void baro_st_conv_press( void );        // Start Conversion
void baro_rd_temp( void );              // Receive Press. & Temp.
void baro_rd_press( void );             // Receive Press. & Temp.
void baro_rd_coefficient( void );       // Receive Coefficient data
void baro_rd_id( void );                // Receive Chip ID 
void cal_pressure( void );              // Calculate Pressure
//      LCD
void lcd_init();                        // Initialize LCD
void lcd_printStr(const char *s);       // Put strings
void lcd_setCursor(unsigned char x,unsigned char y);    // Set cursor position
void setContrast(unsigned char c);      // Set contrast

//-------------------------------------------------------------------------------------------------
//  Control Program
//-------------------------------------------------------------------------------------------------
#if DEBUG_L2
//  Put \r\n
void put_rn ( void ){
    pc.putc('\r');
    pc.putc('\n');
}

//  Put \r
void put_r ( void ){
    pc.putc('\r');
}

// Put ", "
void put_lin ( void ){
    pc.printf(", ");
}

void debug_port_check( void ){
uint32_t r0,r1,r2,r3,r4,r5,r6,r7;
    // Show registers
    put_rn();
    pc.printf( "------- Show Registers -------" );
    put_rn(); 
    pc.printf( "**** P0_4,P0_5 Port usage ****" );
    put_rn();
    // P0_4
    r0 = LPC_IOCON->PIO0_4;
    pc.printf( "%s4(dp27)",io_port_name0 );
    pc.printf( " 0x%08x", r0 );
    put_rn();
    pc.printf( iomsg0 );
    switch ( r0 & 0x7 ){
    case 0:        pc.printf( iomsg1 );     break;
    case 1:        pc.printf("SCL");        break;
    }
    put_lin();
    switch ( ( r0 >> 8 ) & 0x3 ){
    case 0:        pc.printf( iomsg3 );     break;
    case 1:        pc.printf( iomsg1);      break;
    case 2:        pc.printf("Fast md");    break;
    case 3:        pc.printf( iomsg2 );     break;
    }
    put_rn();
    // P0_5
    r0 = LPC_IOCON->PIO0_5;
    pc.printf( "%s5(dp5)",io_port_name0 );
    pc.printf( " 0x%08x", r0 );
    put_rn();
    pc.printf( iomsg0 );
    switch ( r0 & 0x7 ){
    case 0:        pc.printf( iomsg1 );     break;
    case 1:        pc.printf("SDA");        break;
    }
    put_lin();
    switch ( ( r0 >> 8 ) & 0x3 ){
    case 0:        pc.printf( iomsg3 );     break;
    case 1:        pc.printf( iomsg1 );     break;
    case 2:        pc.printf("Fast md");    break;
    case 3:        pc.printf( iomsg2 );     break;
    }
    put_rn();
    // I2C Control register
    r0 = LPC_I2C->CONSET;
    r1 = LPC_I2C->STAT;
    r2 = LPC_I2C->DAT;
    r3 = LPC_I2C->SCLH;
    r4 = LPC_I2C->SCLL;
    r5 = LPC_I2C->CONCLR;
    r6 = LPC_I2C->MMCTRL;
    r7 = LPC_I2C->DATA_BUFFER;
    pc.printf( "**** Show I2C Registers ****" );
    put_rn();
    pc.printf( "CONSET" );
    pc.printf( imsg0 );
    pc.printf( " 0x%08x", r0 );
    put_rn();
    pc.printf( "STAT" );
    pc.printf( imsg1 );
    pc.printf( " 0x%08x", r1 );
    put_rn();
    pc.printf( "DAT" );
    pc.printf( imsg2 );
    pc.printf( " 0x%08x", r2 );
    put_rn();
    pc.printf( "ADR0--Not support" );
    put_rn();
    pc.printf( "SCLH" );
    pc.printf( imsg0 );
    pc.printf( " 0x%08x", r3 );
    put_rn();
    pc.printf( "SCLL" );
    pc.printf( imsg0 );
    pc.printf( " 0x%08x", r4 );
    put_rn();
    pc.printf( "CONCLR" );
    pc.printf( imsg0 );
    pc.printf( " 0x%08x", r5 );
    put_rn();
    pc.printf( "MMCTRL" );
    pc.printf( imsg0 );
    pc.printf( " 0x%08x", r6 );
    put_rn();
    pc.printf( "ADR1,2,3--Not support" );
    put_rn();
    pc.printf( "DATA_BUFFER" );
    pc.printf( imsg3 );
    pc.printf( " 0x%08x", r7 );
    put_rn();
    pc.printf( "MASK0,1,2,3--Not support" );
    put_rn();
}
#endif  // DEBUG_L2

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[][])
        //  with Linear interpolation method
        for (i =0; i < CDS_TBL_SIZE; i++){
            if ( r_cds <= lux_cds[i][0]){
                break;
            }
        }
#if DEBUG_L1
        pc.printf( "i=%d, ", i );
#endif  // DEBUG_L1
        if (i == 0){
            lux = lux_cds[0][1];
#if DEBUG_L1
            pc.printf( "range over!\r\n" );
#endif // DEBUG_L1
        } else if ( i == CDS_TBL_SIZE ){
            if ( r_cds <= lux_cds[i][0] ){
                lux = lux_cds[i-1][1];
            }
        } else {
            if ( i == CDS_TBL_SIZE ){
                if ( r_cds <= lux_cds[i][0] ){
                    lux = lux_cds[i-1][1];
#if DEBUG_L1
                    pc.printf("range over!\r\n");
#endif // DEBUG_L1
                    break;
                }
            }
            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);
#if DEBUG_L1
            pc.printf( "y1:%f, x1:%f, dx:%f, lux_tbl:%f\r\n", y1, x1, dx, lux_cds[i-1][1] );
#endif // DEBUG_L1
        }
        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;
    }
}

void adc_all_read( void){
    av_cds = av_cds *0.5 + cds.read() * 0.5;
    av_vref = av_vref *0.9 + vref.read() * 0.1;
    av_vol = av_vol *0.2 + vol.read() * 0.8;
}

void adc_init( void){
    analog_pwr = 1;
    vref_pwr = 1;
    wait(0.2);  
    av_cds = cds.read();
    av_vref = vref.read();
    av_vol = vol.read();
    wait(0.1);
    adc_all_read();
    wait(0.1);
    adc_all_read();
    analog_pwr = 0;
    vref_pwr = 0;
}

int main() {
uint16_t dt;

    pc.baud(9600);
    pc.printf( "\r\nmbed LPC1114FN28 test program by JH1PJL created on "__DATE__"\r\n" );
    // Initialize ADC
    adc_init();
    // Initialize LCD
    lcd_init();
    contrast = 25;
    setContrast(contrast);
    //Initial screen shot
    lcd_setCursor(0, 0);
    //            12345678
    lcd_printStr("LPC1114F");
    lcd_setCursor(0, 1);
    //            12345678
    lcd_printStr(" JH1PJL ");
    // Read BMP180 data / only once
    baro_rd_id();
    baro_rd_coefficient();
    wait(5.0);
    while(1) {
        // Power on / Analog sensor
        analog_pwr = 1;
        vref_pwr = 1;
        wait(0.2);
        adc_all_read();
        // Power off / Analog sensor
        analog_pwr = 0;
        //vref_pwr = 0; 
        // Normalize
        adc_normalize( CDS );
        adc_normalize( VREF );
        adc_normalize( VOL );       
        myled0 = 1;
        if (sw_chng == 1){  // SW Off
            pc.printf( "\r\nCds:%.0fohm -> %.1flux, Vcc:%.3fV, Vol:%d\r\n",
                r_cds, lux, cal_vcc, nor_vol );
        } else {            // SW On
            pc.printf( "\r\nCds:%f, Vref:%f, Vol:%f\r\n", av_cds, av_vref, av_vol );
        }
        myled0 = 0;
        lcd_setCursor(0, 0);    // 1st line top
        dt = (uint16_t)(lux * 10);
        //sprintf( buf,"l: %4.1f ", lux );
        sprintf( buf,"L:%4d.%01d ", dt / 10, dt % 10 );
        lcd_printStr(buf);
        lcd_setCursor(0, 1);    // 2nd line top
        sprintf( buf,"V: %1.3f ", cal_vcc );
        lcd_printStr(buf);
        wait(4.0);
        baro_st_conv_temp();    // start temprerature measurment
        wait(0.25);       // wait for convertion
        baro_rd_temp();         // read it
        baro_st_conv_press();   // start pressure measurement
        wait(0.5);       // wait for convertion
        baro_rd_press();        // read it
        cal_pressure();         // Calculate baro & temp.
        lcd_setCursor(0, 0);    // 1st line top
        sprintf( buf,"P:%4d.%01d  ", baro_pres_data / 100, ( baro_pres_data % 100 ) /10 );
        lcd_printStr(buf);
        lcd_setCursor(0, 1);    // 2nd line top
        if (sw_chng == 0){      // SW ON
            baro_temp_data = -100;  // Dummy -10.0 degC -> Test printf() minus display
        }
        sprintf( buf,"T: %\+-d.%01d ", baro_temp_data / 10, baro_temp_data% 10 );
        lcd_printStr(buf);
        myled1 = 1;
        pc.printf( "Pres:%4d.%01dhPa, Temp:%\+-d.%01ddegC\r\n",
             baro_pres_data / 100, ( baro_pres_data % 100 ) /10,
             baro_temp_data / 10, baro_temp_data% 10 );
        myled1 = 0;
        wait(3.0);
#if DEBUG_L2
        debug_port_check();
#endif  // DEBUG_L2
        wait(1.0);     
    }
}