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
Please see https://mbed.org/users/kenjiArai/notebook/mbed-lpc1114fn28-barometer-with-data-logging/#
main.cpp
- Committer:
- kenjiArai
- Date:
- 2020-08-08
- Revision:
- 18:b3a27f681171
- Parent:
- 16:f164f8912201
File content as of revision 18:b3a27f681171:
/* * mbed Application program for the mbed LPC1114FN28 * Barometer program for only for LPC1114FN28 * * Copyright (c) 2014,'20 Kenji Arai / JH1PJL * http://www7b.biglobe.ne.jp/~kenjia/ * https://os.mbed.com/users/kenjiArai/ * Created: May 21st, 2014 * Revised: August 8th, 2020 */ /* * Function * measure atmospheric pressure and temprerature using Bosch BMP180 sensor * show measured data on AQM0802A LCD and logging such data in 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 "dt_log.h" // Definition ----------------------------------------------------------------- #define USE_MON 1 #define USE_BARO 0 #define BOUND 5 // chattering // Define cyclic period #define SHOW_LED 1 // Time for LED on x mS #define CNV_WAIT_T 25 // Waiting time for temp. conversion #define CNV_WAIT_P 50 // Waiting time for pressure conversion #define LOOP_WAIT (1000 - (SHOW_LED + CNV_WAIT_T +CNV_WAIT_P)) // 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 STATE_CHANGE_TIME 3000000 // 3sec #define TIME_INTERVAL 600 // 10 minutes typedef enum {CDS = 0, VREF, VOL} ADC_Select; // Object --------------------------------------------------------------------- Timeout to; // wake-up from sleep() 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 BMP180 bmp180(i2c); // Bosch sensor M41T62 m41t62(i2c); // STmicro RTC(M41T62) TextLCD_I2C_N i2clcd(&i2c, 0x7c, TextLCD::LCD8x2); // LCD(Akizuki AQM0802A) // Function prototypes -------------------------------------------------------- extern int mon( void); // only use for debug purpose // RAM ------------------------------------------------------------------------ int flag; // 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; // EEPROM //extern xEeprom_ptr log_inf; // 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} }; // LCD screen data enum Screen { SCRN_Clear=0, SCRN_Opening, SCRN_Goto_mon, SCRN_Backto_normal }; // Clear Opening Goto_mon Backto_normal char scrn_1st[4][10] = { " ", "LPC1114F", "GOTO MON", "Back to"}; char scrn_2nd[4][10] = { " ", " JH1PJL ", " 9600BPS", " Normal"}; // Disply on LCD enum Disp_num { DSP_INIT=0, DSP_BARO, DSP_HUMD, DSP_LUX, DSP_TIME, DSP_LOG, DSP_RTURN }; // loop time = STATE_CHANGE_TIME * 20 = 3 * 20 = 60 sec (current) // rule 1) DSP_INIT is top position // 2) DSP_RTURN is end position // 3) Total number 20 const uint8_t lcd_disp_tbl[20] // 1, 2, 3, 4, 5, = {DSP_INIT, DSP_BARO, DSP_BARO, DSP_BARO, DSP_TIME, // 6, 7, 8, 9, 10, DSP_TIME, DSP_HUMD, DSP_HUMD, DSP_LUX, DSP_LUX, // 11, 12, 13, 14, 15, DSP_BARO, DSP_BARO, DSP_TIME, DSP_TIME, DSP_HUMD, // 16, 17, 18, 19, 20 DSP_HUMD, DSP_LUX, DSP_LUX, DSP_LOG, DSP_RTURN }; //------------------------------------------------------------------------------ // 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; } } void set_lcd_screen(int n) { i2clcd.locate(0, 0); i2clcd.printf("%s", scrn_1st[n]); i2clcd.locate(0, 1); i2clcd.printf("%s", scrn_2nd[n]); } //------------------------------------------------------------------------------ // Application program //------------------------------------------------------------------------------ // Nothing is done but just wake-up from sleep condition void wakeup() { flag = 1; myled1 = !myled1; } // 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 step = 0, dt; uint8_t num; while (true) { // infinit loop for measure and display // Call wakeup()function after specific time // this is for wake-up to.attach(callback(&wakeup), chrono::milliseconds(STATE_CHANGE_TIME)); //---- State Control ---- num = lcd_disp_tbl[step++]; switch (num) { // ---------- Initialize data ------------------------------------- case DSP_INIT: 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); break; // ---------- Cds Sensor, Vref, Volume ---------------------------- case DSP_LUX: // Power on / Analog sensor analog_pwr = 1; vref_pwr = 1; ThisThread::sleep_for(200ms); adc_all_read(); // Power off / Analog sensor analog_pwr = 0; // Normalize adc_normalize(CDS); adc_normalize(VREF); adc_normalize(VOL); set_lcd_screen(SCRN_Clear); 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); break; // ---------- Barometer Sensor / BMP180 --------------------------- case DSP_BARO: bmp180.normalize(); baro = bmp180.read_pressure(); baro_temp = bmp180.read_temperature(); set_lcd_screen(SCRN_Clear); i2clcd.locate(0, 0); // 1st line top i2clcd.printf("P:%.1f", baro); i2clcd.locate(0, 1); // 2nd line top i2clcd.printf("T:%+6.1f", baro_temp); break; // ---------- Humidity Sensor / RHT03 ----------------------------- case DSP_HUMD: hum_RHT03_read(); // Read Humidity data then avaraging set_lcd_screen(SCRN_Clear); 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); break; // ---------- RTC ------------------------------------------------- case DSP_TIME: m41t62.read_rtc_std(&t); seconds = mktime(&t); set_lcd_screen(SCRN_Clear); i2clcd.locate(0, 0); // 1st line top i2clcd.printf("%02d/%02d/%02d", t.tm_year % 100, t.tm_mon + 1, t.tm_mday); i2clcd.locate(0, 1); // 2nd line top i2clcd.printf("%02d:%02d:%02d", t.tm_hour, t.tm_min, t.tm_sec); break; // ---------- EEPROM Logging -------------------------------------- case DSP_LOG: 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; } set_lcd_screen(SCRN_Clear); i2clcd.locate(0, 0); // 1st line top i2clcd.printf("Logging"); i2clcd.locate(0, 1); // 2nd line top i2clcd.printf("%d.%01d%%", dt / 10, dt % 10); break; // ---------- return (loop) --------------------------------------- case DSP_RTURN: default: // <State> State change step = 1; // if something wrong, go to reset condition } // ---------- back to top --------------------------------------------- myled0 = !myled0; while (flag == 0) { ThisThread::sleep_for(10ms); } ThisThread::sleep_for(100ms); myled1 = !myled1; flag = 0; } } // Application program starts here int main() { flag = 0; i2clcd.setContrast(25); set_lcd_screen(SCRN_Opening); if (sw_chng == 0) { // SW ON //-- Enter Monitor Mode -- myled1 = 1; ThisThread::sleep_for(500ms); myled1 = 0; ThisThread::sleep_for(500ms); myled1 = 1; ThisThread::sleep_for(500ms); if (sw_chng == 0) { // Still SW ON myled1 = 0; ThisThread::sleep_for(500ms); myled1 = 1; ThisThread::sleep_for(500ms); if (sw_mode == 0) { // SW ON set_lcd_screen(SCRN_Clear); set_lcd_screen(SCRN_Goto_mon); myled1 = 0; mon(); // mon.cpp } set_lcd_screen(SCRN_Clear); set_lcd_screen(SCRN_Backto_normal); } } //-- Enter Normal Mode -- myled0 = 1; myled1 = 0; while (true) { // Start main program conv_and_disp(); } }