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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  * mbed Application program for the mbed LPC1114FN28
00003  * Barometer program for only for LPC1114FN28
00004  *
00005  * Copyright (c) 2014,'20 Kenji Arai / JH1PJL
00006  *  http://www7b.biglobe.ne.jp/~kenjia/
00007  *  https://os.mbed.com/users/kenjiArai/
00008  *      Created: May       21st, 2014
00009  *      Revised: August     8th, 2020
00010  */
00011 /*
00012  * Function
00013  *  measure atmospheric pressure and temprerature using Bosch BMP180 sensor
00014  *  show measured data on AQM0802A LCD and logging such data in EEPROM
00015  */
00016 
00017 //  Include --------------------------------------------------------------------
00018 #include "mbed.h"
00019 #include "BMP180.h"             // Own lib. / Pressure sensor             
00020 #include "RHT03.h"              // Std. lib./ Humidity sensor
00021 #include "TextLCD.h"            // Std. lib./ LCD control
00022 #include "m41t62_rtc.h"         // Own lib. / RTC control
00023 #include "dt_log.h"
00024 
00025 //  Definition -----------------------------------------------------------------
00026 #define USE_MON                 1
00027 #define USE_BARO                0
00028 
00029 #define BOUND                   5       // chattering
00030 
00031 // Define cyclic period
00032 #define SHOW_LED                1       // Time for LED on x mS
00033 #define CNV_WAIT_T              25      // Waiting time for temp. conversion
00034 #define CNV_WAIT_P              50      // Waiting time for pressure conversion
00035 #define LOOP_WAIT               (1000 - (SHOW_LED + CNV_WAIT_T +CNV_WAIT_P))
00036 
00037 // ADC related definition
00038 #define VREF_VOLT               2.482   // TA76431F Vref real measued data
00039 #define R_FIX                   9930    // 10K ohm <- real measued data
00040 #define VOL_OFFSET              3       // Offset data ,= real measured data
00041 #define CDS_TBL_SIZE            13
00042 
00043 // Waiting time
00044 #define STATE_CHANGE_TIME       3000000 // 3sec
00045 #define TIME_INTERVAL           600     // 10 minutes
00046 
00047 typedef enum {CDS = 0, VREF, VOL} ADC_Select;
00048 
00049 //  Object ---------------------------------------------------------------------
00050 Timeout     to;                // wake-up from sleep()
00051 I2C         i2c(dp5,dp27);      // SDA, SCL
00052 DigitalOut  myled0(dp28);       // LED for Debug
00053 DigitalOut  myled1(dp14);       // Indicate state transition
00054 DigitalOut  analog_pwr(dp6);    // VCC for analog interface (vol, cds and vref)
00055 DigitalOut  vref_pwr(dp4);      // VCC for Vref
00056 DigitalIn   sw_chng(dp1,PullUp);// SW for select
00057 DigitalIn   sw_mode(dp2,PullUp);// SW for Mode change
00058 AnalogIn    cds(dp11);          // Input / CDS data
00059 AnalogIn    vref(dp9);          // Input / Bandgap 2.5V
00060 AnalogIn    vol(dp10);          // Input / contrast volume
00061 RHT03       humtemp(dp26);      // RHT03 interface
00062 BMP180      bmp180(i2c);        // Bosch sensor
00063 M41T62      m41t62(i2c);        // STmicro RTC(M41T62)
00064 TextLCD_I2C_N i2clcd(&i2c, 0x7c, TextLCD::LCD8x2);  // LCD(Akizuki AQM0802A)
00065 
00066 //  Function prototypes --------------------------------------------------------
00067 extern int mon( void);          // only use for debug purpose
00068 
00069 //  RAM ------------------------------------------------------------------------
00070 int flag;
00071 
00072 //  ADC
00073 float av_cds, av_vref, av_vol, cal_vcc;
00074 float r_cds, lux;
00075 uint32_t nor_vol;
00076 
00077 //  Humidity Sensor
00078 float humidity_temp, humidity;
00079 
00080 //  EEPROM
00081 uint8_t eep_buf[256 + 2];
00082 
00083 // Barometer
00084 float baro;
00085 float baro_temp;
00086 
00087 // EEPROM
00088 //extern xEeprom_ptr log_inf;
00089 
00090 //  ROM / Constant data --------------------------------------------------------
00091 // Cds GL5528 (Dark Resistance 1 Mohm type) SENBA OPTICAL & ELECTRONIC CO.,LTD.
00092 //      Table value referrence: http://homepage3.nifty.com/skomo/f35/hp35_20.htm
00093 const float lux_cds[CDS_TBL_SIZE][2] = {
00094     {50,21194},{100,8356},{200,3294},{400,1299},{800,512},{1600,202},
00095     {3200,79.6},{6400,31.4},{12800,12.4},{25600,4.88},{51200,1.92},
00096     {102400,0.758},{409600,0.118}
00097 };
00098 
00099 // LCD screen data
00100 enum Screen {
00101     SCRN_Clear=0, SCRN_Opening, SCRN_Goto_mon, SCRN_Backto_normal
00102 };
00103 //                        Clear       Opening      Goto_mon     Backto_normal
00104 char scrn_1st[4][10] = { "        ", "LPC1114F",  "GOTO MON",  "Back to"};
00105 char scrn_2nd[4][10] = { "        ", " JH1PJL ",  " 9600BPS",  " Normal"};
00106 
00107 // Disply on LCD
00108 enum Disp_num {
00109     DSP_INIT=0, DSP_BARO, DSP_HUMD, DSP_LUX, DSP_TIME, DSP_LOG, DSP_RTURN
00110 };
00111 
00112 // loop time = STATE_CHANGE_TIME * 20 = 3 * 20 = 60 sec (current)
00113 // rule 1) DSP_INIT is top position
00114 //      2) DSP_RTURN is end position
00115 //      3) Total number 20
00116 const uint8_t lcd_disp_tbl[20]
00117 //         1,        2,        3,        4,        5,
00118     = {DSP_INIT, DSP_BARO, DSP_BARO, DSP_BARO, DSP_TIME,
00119 //         6,        7,        8,        9,       10,
00120        DSP_TIME, DSP_HUMD, DSP_HUMD,  DSP_LUX,  DSP_LUX,
00121 //        11,       12,       13,       14,       15,
00122        DSP_BARO, DSP_BARO, DSP_TIME, DSP_TIME, DSP_HUMD,
00123 //        16,      17,        18,       19,        20
00124        DSP_HUMD, DSP_LUX,   DSP_LUX,  DSP_LOG, DSP_RTURN
00125       };
00126 
00127 //------------------------------------------------------------------------------
00128 //  Control Program
00129 //------------------------------------------------------------------------------
00130 // Normalize ADC data
00131 void adc_normalize (ADC_Select n)
00132 {
00133     int i;
00134     float x1,y1,dx;
00135 
00136     switch (n) {
00137         case CDS:
00138             // v_adc = Rfix / (Rcds + Rfix) ->  Rcds = ( Rfix / v_adc ) - Rfix
00139             r_cds = (R_FIX / av_cds) - R_FIX;
00140             // CDS resistance to Lux conversion using convertion table(luc_cds)
00141             for (i =0; i < CDS_TBL_SIZE; i++) { // search table
00142                 if ( r_cds <= lux_cds[i][0]) {
00143                     break;
00144                 }
00145             }
00146             // Check table position
00147             if (i == 0) {
00148                 lux = lux_cds[0][1];
00149                 break;
00150             } else if ( i == CDS_TBL_SIZE ) {
00151                 if ( r_cds <= lux_cds[i][0] ) {
00152                     lux = lux_cds[i-1][1];
00153                     break;
00154                 }
00155             }
00156             //  Linear interpolation
00157             y1 = lux_cds[i-1][1] - lux_cds[i][1];
00158             x1 = lux_cds[i][0] - lux_cds[i-1][0];
00159             dx = r_cds - lux_cds[i-1][0];
00160             lux = lux_cds[i-1][1] - ((dx/x1) * y1);
00161             break;
00162         case VREF:  //  vref = VREF_VOLT / VCC -> VCC = VREF_VOLT / vref
00163             cal_vcc = VREF_VOLT / vref;
00164             break;
00165         case VOL:   // Vol center = 1.00 (actual 100)
00166             nor_vol = (uint32_t)(av_vol * 200) + VOL_OFFSET;
00167             break;
00168     }
00169 }
00170 
00171 //  Read adc data and averaging
00172 void adc_all_read (void)
00173 {
00174     if (av_cds == 0) {
00175         av_cds = cds.read();
00176     } else {
00177         av_cds = av_cds *0.5 + cds.read() * 0.5;
00178     }
00179     if (av_vref == 0) {
00180         av_vref = vref.read();
00181     } else {
00182         av_vref = av_vref *0.9 + vref.read() * 0.1;
00183     }
00184     if (av_vol == 0) {
00185         av_vol = vol.read();
00186     } else {
00187         av_vol = av_vol *0.2 + vol.read() * 0.8;
00188     }
00189 }
00190 
00191 // Read Humidity sensor data
00192 void hum_RHT03_read (void)
00193 {
00194     while (true) {  // wait data
00195         if ( humtemp.readData() == RHT_ERROR_NONE ) {
00196             break;
00197         }
00198     }
00199     if (humidity_temp == 0) {
00200         humidity_temp = humtemp.getTemperatureC();
00201     } else {
00202         humidity_temp = humidity_temp * 0.9 + humtemp.getTemperatureC() * 0.1;
00203     }
00204     if ( humidity == 0 ) {
00205         humidity = humtemp.getHumidity();
00206     } else {
00207         humidity = humidity * 0.9 + humtemp.getHumidity() * 0.1;
00208     }
00209 }
00210 
00211 void set_lcd_screen(int n)
00212 {
00213     i2clcd.locate(0, 0);
00214     i2clcd.printf("%s", scrn_1st[n]);
00215     i2clcd.locate(0, 1);
00216     i2clcd.printf("%s", scrn_2nd[n]);
00217 }
00218 
00219 //------------------------------------------------------------------------------
00220 // Application program
00221 //------------------------------------------------------------------------------
00222 // Nothing is done but just wake-up from sleep condition
00223 void wakeup()
00224 {
00225     flag = 1;
00226     myled1 = !myled1;
00227 }
00228 
00229 // Measure pressure and show it on LCD
00230 void conv_and_disp(void)
00231 {
00232     tm t;
00233     time_t seconds = 0;
00234     time_t old_seconds = 0;
00235     uint32_t step = 0, dt;
00236     uint8_t num;
00237 
00238     while (true) {          // infinit loop for measure and display
00239         // Call wakeup()function after specific time
00240         // this is for wake-up
00241         to.attach(callback(&wakeup), chrono::milliseconds(STATE_CHANGE_TIME));
00242         //---- State Control ----
00243         num = lcd_disp_tbl[step++];
00244         switch (num) {
00245             //  ---------- Initialize data -------------------------------------
00246             case DSP_INIT:
00247                 av_cds = 0;
00248                 av_vref = 0;
00249                 av_vol = 0;
00250                 humidity_temp = 0;
00251                 humidity = 0;
00252                 // RTC
00253                 m41t62.set_sq_wave(RTC_SQW_NONE);
00254                 m41t62.read_rtc_std(&t);
00255                 old_seconds = mktime(&t);
00256                 break;
00257             //  ---------- Cds Sensor, Vref, Volume ----------------------------
00258             case DSP_LUX:
00259                 // Power on / Analog sensor
00260                 analog_pwr = 1;
00261                 vref_pwr = 1;
00262                 ThisThread::sleep_for(200ms);
00263                 adc_all_read();
00264                 // Power off / Analog sensor
00265                 analog_pwr = 0;
00266                 // Normalize
00267                 adc_normalize(CDS);
00268                 adc_normalize(VREF);
00269                 adc_normalize(VOL);
00270                 set_lcd_screen(SCRN_Clear);
00271                 i2clcd.locate(0, 0);    // 1st line top
00272                 //             12345678
00273                 i2clcd.printf("L:%.1f", lux);
00274                 i2clcd.locate(0, 1);    // 2nd line top
00275                 i2clcd.printf("V:%.3f", cal_vcc);
00276                 break;
00277             //  ---------- Barometer Sensor / BMP180 ---------------------------
00278             case DSP_BARO:
00279                 bmp180.normalize();
00280                 baro = bmp180.read_pressure();
00281                 baro_temp = bmp180.read_temperature();
00282                 set_lcd_screen(SCRN_Clear);
00283                 i2clcd.locate(0, 0);    // 1st line top
00284                 i2clcd.printf("P:%.1f", baro);
00285                 i2clcd.locate(0, 1);    // 2nd line top
00286                 i2clcd.printf("T:%+6.1f", baro_temp);
00287                 break;
00288             //  ---------- Humidity Sensor / RHT03 -----------------------------
00289             case DSP_HUMD:
00290                 hum_RHT03_read();       // Read Humidity data then avaraging
00291                 set_lcd_screen(SCRN_Clear);
00292                 i2clcd.locate(0, 0);    // 1st line top
00293                 i2clcd.printf("H:%.1f", humidity);
00294                 i2clcd.locate(0, 1);    // 2nd line top
00295                 i2clcd.printf("T:%+6.1f", humidity_temp);
00296                 break;
00297             //  ---------- RTC -------------------------------------------------
00298             case DSP_TIME:
00299                 m41t62.read_rtc_std(&t);
00300                 seconds = mktime(&t);
00301                 set_lcd_screen(SCRN_Clear);
00302                 i2clcd.locate(0, 0);    // 1st line top
00303                 i2clcd.printf("%02d/%02d/%02d",
00304                               t.tm_year % 100, t.tm_mon + 1, t.tm_mday);
00305                 i2clcd.locate(0, 1);    // 2nd line top
00306                 i2clcd.printf("%02d:%02d:%02d", t.tm_hour, t.tm_min, t.tm_sec);
00307                 break;
00308             //  ---------- EEPROM Logging --------------------------------------
00309             case DSP_LOG:
00310                 if (seconds >= old_seconds + TIME_INTERVAL) {
00311                     // Data Logging action
00312                     old_seconds += TIME_INTERVAL;
00313                     dtlog_data_pack();  // Get EEPROM resource
00314                     dtlog_one_write();  // Write data to EEPROM
00315                     dt = (uint32_t)dtlog_buf_occupation();
00316                     dt = (dt * 1000)/ BLK_NO;
00317                 }
00318                 set_lcd_screen(SCRN_Clear);
00319                 i2clcd.locate(0, 0);    // 1st line top
00320                 i2clcd.printf("Logging");
00321                 i2clcd.locate(0, 1);    // 2nd line top
00322                 i2clcd.printf("%d.%01d%%", dt / 10, dt % 10);
00323                 break;
00324             //  ---------- return (loop) ---------------------------------------
00325             case DSP_RTURN:
00326             default:
00327                 //  <State> State change
00328                 step = 1;   // if something wrong, go to reset condition
00329         }
00330         //  ---------- back to top ---------------------------------------------
00331         myled0 = !myled0;
00332         while (flag == 0) {
00333             ThisThread::sleep_for(10ms);
00334         }
00335         ThisThread::sleep_for(100ms);
00336         myled1 = !myled1;
00337         flag = 0;
00338     }
00339 }
00340 
00341 // Application program starts here
00342 int main()
00343 {
00344     flag = 0;
00345     i2clcd.setContrast(25);
00346     set_lcd_screen(SCRN_Opening);
00347     if (sw_chng == 0) { // SW ON
00348         //--  Enter Monitor Mode  --
00349         myled1 = 1;
00350         ThisThread::sleep_for(500ms);
00351         myled1 = 0;
00352         ThisThread::sleep_for(500ms);
00353         myled1 = 1;
00354         ThisThread::sleep_for(500ms);
00355         if (sw_chng == 0) { // Still SW ON
00356             myled1 = 0;
00357             ThisThread::sleep_for(500ms);
00358             myled1 = 1;
00359             ThisThread::sleep_for(500ms);
00360             if (sw_mode == 0) { // SW ON
00361                 set_lcd_screen(SCRN_Clear);
00362                 set_lcd_screen(SCRN_Goto_mon);
00363                 myled1 = 0;
00364                 mon();          // mon.cpp
00365             }
00366             set_lcd_screen(SCRN_Clear);
00367             set_lcd_screen(SCRN_Backto_normal);
00368         }
00369     }
00370     //--  Enter Normal Mode  --
00371     myled0 = 1;
00372     myled1 = 0;
00373     while (true) {  // Start main program
00374         conv_and_disp();
00375     }
00376 }