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/#

Revision:
16:f164f8912201
Parent:
15:065fbeddc305
Child:
18:b3a27f681171
--- a/mon.cpp	Sun Jun 29 06:58:00 2014 +0000
+++ b/mon.cpp	Thu Jul 03 22:01:25 2014 +0000
@@ -7,7 +7,7 @@
  *  http://mbed.org/users/kenjiArai/
  *      Created:  May  	    15th, 2010
  *		Spareted: June		25th, 2014		mon() & mon_hw()
- *      Revised:  June      29th, 2014
+ *      Revised: July        3rd, 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
@@ -18,8 +18,8 @@
 
 //  Include ---------------------------------------------------------------------------------------
 #include "mbed.h"
-#include "m41t62_rtc.h"         // Own lib. / RTC control
-#include "AT24C1024.h"          // Own lib. / EEPROM control
+#include "m41t62_rtc.h"			// Own lib. / RTC control
+#include "AT24C1024.h"			// Own lib. / EEPROM control
 #include "dt_log.h"
 
 //  Object ----------------------------------------------------------------------------------------
@@ -29,24 +29,33 @@
 AT24C1024   at24c1024(xi2c);    // Atmel 1Mbit EE-PROM 
 
 //  Definition ------------------------------------------------------------------------------------
-#define BAUD(x)         	pc.baud(x)
-#define GETC(x)         	pc.getc(x)
-#define PUTC(x)				pc.putc(x)
-#define PRINTF(...)     	pc.printf(__VA_ARGS__)
-#define READABLE(x)     	pc.readable(x)
+#define BAUD(x)         		pc.baud(x)
+#define GETC(x)         		pc.getc(x)
+#define PUTC(x)					pc.putc(x)
+#define PRINTF(...)     		pc.printf(__VA_ARGS__)
+#define READABLE(x)     		pc.readable(x)
 
 // EEPROM
-#define EEP_TOP				0x0
+#define EEP_TOP					0x0
 
 //  RAM -------------------------------------------------------------------------------------------
 char linebuf[64];
 int buf_size = sizeof(linebuf);
 
 // 	for EEPROM control
-uint8_t buf_pointer[PTR_SIZE];
-xEeprom_ptr log_inf;
+int16_t read_pointer;
+
+typedef struct {
+    uint16_t    head;
+    uint16_t    tail;
+} ring_t;
 
-struct one_log{
+union _inf{
+	uint8_t buf_pointer[PTR_SIZE];
+	ring_t log_inf;
+}inf;
+
+typedef struct {
 	uint32_t	time;
 	uint16_t	vcc;
 	uint16_t	baro;
@@ -54,10 +63,12 @@
 	uint16_t	humi;
 	int16_t		h_temp;
 	uint16_t	lux;
-};		// 16 bytes total
+}one_log;		// 16 bytes total
 
-one_log lg;
-uint8_t bf[PKT_SIZE];
+union _one{
+	uint8_t bf[PKT_SIZE];
+	one_log lg;
+}one;
 
 extern float baro;
 extern float baro_temp;
@@ -73,6 +84,7 @@
 //                      $, 2014/6/29,12:43:16,3.293,1004.5,+29.3,45.8,+29.2,1234,*
 char *const log_head = "$,YYYY/MM/DD,HH:MM:SS,Vcc  ,Press ,Temp ,Humi,Temp ,Lux  ,*";
 char *const msg_emty = "Data empty";
+char *const msg_end  = "\r\nreach to end";
 
 //  Function prototypes ---------------------------------------------------------------------------
 extern void mon_hw(void);
@@ -141,47 +153,30 @@
 //-------------------------------------------------------------------------------------------------
 // Data Logging / Save into EEPROM
 //-------------------------------------------------------------------------------------------------
-// Read buffer pointer
-static void dtlog_pointer_read(void){
-uint8_t i;
-uint8_t *addr;
-
-    /* Read EEPROM and save to buf_pointer[] */
-    for ( i = 0; i < PTR_SIZE; i++ ){
-        addr = (uint8_t *)(EEP_TOP + i);
-        buf_pointer[i]  = at24c1024.read((int)addr);
-        wait(0.002);
-    }
-}
-
+/*
+    head = H, tail =T
+	state 1:	H=1(RING_TOP),T=1(RING_TOP)	-> just after Clear command
+	state 2:	H=1,T=n		-> n = 2 to RING_TAIL-1 (not filled yet)	
+	state 3:	H=1,T=RING_TAIL	-> need to check!!!! (just filled)
+	state 4:	H=2,T=1(RING_TOP) -> start ringed state
+	state 5:	H=n,T=n-1	-> n = 2 to RING_TAIL-1 (ringed)
+	state 6:	H=RING_TAIL,T=RING_TAIL-1 -> need to check!!!!!
+	state 7:	H=1(RING_TOP),T=RING_TAIL -> need to check!!!!!
+	state 8:	same as "state 5"	
+		-> Need to check state 3,6,7
+*/
 //  Make one data packet data structure
 void dtlog_data_pack(void){
 struct tm t;
 
     xm41t62.read_rtc_std(&t);
-    lg.time = mktime(&t);
-    bf[0] = (uint8_t)(lg.time >> 24);
-    bf[1] = (uint8_t)(lg.time >> 16);
-    bf[2] = (uint8_t)(lg.time >> 8);
-    bf[3] = (uint8_t)(lg.time >> 0);
-    lg.vcc = (uint16_t)(cal_vcc * 1000);
-    bf[4] = (uint8_t)(lg.vcc >> 8);
-    bf[5] = (uint8_t)(lg.vcc >> 0);
-    lg.baro = (uint16_t)(baro * 10);
-    bf[6] = (uint8_t)(lg.baro >> 8);
-    bf[7] = (uint8_t)(lg.baro >> 0);
-    lg.b_temp = (int16_t)(baro_temp * 10);
-    bf[8] = (uint8_t)(lg.b_temp >> 8);
-    bf[9] = (uint8_t)(lg.b_temp >> 0);
-    lg.humi = (uint16_t)(humidity * 10);
-    bf[10] = (uint8_t)(lg.humi >> 8);
-    bf[11] = (uint8_t)(lg.humi >> 0);
-    lg.h_temp = (int16_t)(humidity_temp * 10);
-    bf[12] = (uint8_t)(lg.h_temp >> 8);
-    bf[13] = (uint8_t)(lg.h_temp >> 0);
-    lg.lux = (uint16_t)lux;
-    bf[14] = (uint8_t)(lg.lux >> 8);
-    bf[15] = (uint8_t)(lg.lux >> 0);
+    one.lg.time = mktime(&t);
+    one.lg.vcc = (uint16_t)(cal_vcc * 1000);
+    one.lg.baro = (uint16_t)(baro * 10);
+    one.lg.b_temp = (int16_t)(baro_temp * 10);
+    one.lg.humi = (uint16_t)(humidity * 10);
+    one.lg.h_temp = (int16_t)(humidity_temp * 10);
+    one.lg.lux = (uint16_t)lux;
 }
 
 //  Print one packet as normalized data
@@ -194,161 +189,207 @@
     put_rn();
     PUTC( '$' );
     //--- Time
-    seconds = (time_t)bf[0] * 16777216 + (time_t)bf[1] * 65536 + (time_t)bf[2] * 256 + (time_t)bf[3];
-	//PRINTF(",0x%x,",seconds);
+    seconds = one.lg.time;
     t = localtime(&seconds);
 	PRINTF(",%04d/%02d/%02d,%02d:%02d:%02d,",
 			t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
 	//--- Vcc
-	dt0 = (uint16_t)bf[4] * 256 + (uint16_t)bf[5];
-	//PRINTF("0x%x,",dt0);
+	dt0 = one.lg.vcc;
 	PRINTF("%01d.%03d,", dt0/1000, dt0%1000);
 	//--- Pressure
-	dt0 = (uint16_t)bf[6] * 256 + (uint16_t)bf[7];
-	//PRINTF("0x%x,",dt0);
+	dt0 = one.lg.baro;
 	PRINTF("%04d.%01d,", dt0/10, dt0%10 );
 	//--- Temp.
-	dt1 = (int16_t)bf[8] * 256 + (int16_t)bf[9];
-	//PRINTF("0x%x,",dt1);
+	dt1 = one.lg.b_temp;
 	PRINTF("%\+-03d.%01d,", dt1/10, abs(dt1)%10 );
 	//--- Humidity	   
-	dt0 = (uint16_t)bf[10] * 256 + (uint16_t)bf[11];
-	//PRINTF("0x%x,",dt0);
+	dt0 = one.lg.humi;
 	PRINTF("%02d.%01d,", dt0/10, dt0%10 );
 	//--- Temp.
-	dt1 = (int16_t)bf[12] * 256 + (int16_t)bf[13];
-	//PRINTF("0x%x,",dt1);
+	dt1 = one.lg.h_temp;
 	PRINTF("%\+-03d.%01d,", dt1/10, abs(dt1)%10 );
 	//--- Lux
-	dt0 = (uint16_t)bf[14] * 256 + (uint16_t)bf[15];
-	//PRINTF("0x%x",dt0);
+	dt0 = one.lg.lux;
 	PRINTF("%05d,*", dt0);
 }
 
-//  Read block data
-static void dtlog_blk_read(xEeprom_ptr *read_inf){
+// Read buffer pointer
+static void dtlog_pointer_read(void){
 uint8_t i;
 uint8_t *addr;
 
-    PRINTF( log_head );
-    for ( ; ; ){
-        /* Read EEPROM and save to data_pack[] */
-        for (i = 0; i < PKT_SIZE; i++){
-            addr = (uint8_t *)(EEP_TOP + (read_inf->ptr * PTR_SIZE) + i);
-            bf[i]  =at24c1024.read((int)addr);
-            wait(0.002);
-        }
-        print_one_block_data();
-        wait(0.001);
-        if (++read_inf->ptr >= read_inf->max){
-            break;
-        }
-        if (READABLE() != 0){
-            break;
-        }
+    /* Read EEPROM and save to buf_pointer[] */
+    for ( i = 0; i < PTR_SIZE; i++ ){
+        addr = (uint8_t *)(EEP_TOP + i);
+        inf.buf_pointer[i]  = at24c1024.read((int)addr);
+        wait(0.002);
     }
-    put_rn();
+// PRINTF("head %d, Tail %d\r\n", inf.log_inf.head, inf.log_inf.tail);
 }
 
 //  Write one packet
 void dtlog_one_write(void){
-xEeprom_ptr write_inf;
 uint8_t i;
 uint8_t *addr;
 
-    /* Read buffer pointer */
-    dtlog_pointer_read();
-    write_inf.wr_pointer = READ_POINTER();
-    write_inf.status = RD_STATUS();
-    if (write_inf.status == BUF_FULL){  return;}
-    /* Write data_pack[] into  EEPROM */
+    // Read EEPROM buffer pointer to RAM
+    for ( i = 0; i < PTR_SIZE; i++ ){
+        addr = (uint8_t *)(EEP_TOP + i);
+        inf.buf_pointer[i]  = at24c1024.read((int)addr);
+        wait(0.002);
+    }
+ //PRINTF("head %d, Tail %d\r\n", inf.log_inf.head, inf.log_inf.tail);
+    // Write data_pack[] into  EEPROM
     for (i = 0; i < PKT_SIZE; i++){
-        addr = (uint8_t *)(EEP_TOP + (write_inf.wr_pointer * PTR_SIZE) + i); 
-        at24c1024.write((int)addr, bf[i]);
+        addr = (uint8_t *)(EEP_TOP + (inf.log_inf.tail * PTR_SIZE) + i); 
+        at24c1024.write((int)addr, one.bf[i]);
         wait(0.008);
     }
-    /* Write buffer pointer */
-    if (++write_inf.wr_pointer == BLK_NO){
-        write_inf.status = BUF_FULL;
-    } else {
-        write_inf.status = 0;
+    // Increment buffer pointer in RAM
+    if (inf.log_inf.head == RING_TOP){	// check state 1,2,3
+    	if (inf.log_inf.tail == RING_TAIL){	// check state 3
+			inf.log_inf.tail = RING_TOP;		// set state 4
+			inf.log_inf.head = 2;				// missing one oldest data
+		} else {
+			inf.log_inf.tail++;					// set state 2
+		}
+    } else {	// check state 4,5,6,7
+    	if (inf.log_inf.head == RING_TAIL){ // check state 6
+    		inf.log_inf.head = RING_TOP; 	// set state 7
+    		inf.log_inf.tail = RING_TAIL;
+    	} else if (inf.log_inf.tail == inf.log_inf.head - 1){ // check state 4,5
+			++inf.log_inf.tail;		// continue state 5
+			++inf.log_inf.head;
+		}
     }
-    WRITE_POINTER(write_inf.wr_pointer);
-    WR_STATUS(write_inf.status); 
+    // Write buffer pointer into EEPROM  
     for (i = 0; i < PTR_SIZE; i++){
         addr = (uint8_t *)(EEP_TOP + i);    
-        at24c1024.write((int)addr, buf_pointer[i]);
+        at24c1024.write((int)addr, inf.buf_pointer[i]);
         wait(0.008);
-    }   
+    } 
 }
 
-//  Read Data Pointer Information
-void dtlog_rd_buf_inf(xEeprom_ptr *log_ptr_inf){
+// Read some block from buffer
+void dtlog_block_read(int16_t *pt, uint16_t n){
+uint8_t i;
+uint8_t *addr;
+uint16_t num;
+
     dtlog_pointer_read();
-    log_ptr_inf->wr_pointer = READ_POINTER();
-    log_ptr_inf->status = RD_STATUS();  
+    if (inf.log_inf.tail == inf.log_inf.head){ // Check pointer
+        PRINTF(msg_emty);
+        put_rn();
+        return;
+    }
+	PRINTF("Head:%d, Tail:%d, Start pointer:%d, Number of data:%d\r\n",
+			inf.log_inf.head, inf.log_inf.tail, *pt, n);
+    PRINTF( log_head );
+    for (num = 0; num < n; num++){
+        /* Read EEPROM and save to data_pack[] */
+        for (i = 0; i < PKT_SIZE; i++){
+            addr = (uint8_t *)(EEP_TOP + (*pt * PTR_SIZE) + i);
+            one.bf[i]  =at24c1024.read((int)addr);
+            wait(0.002);
+        }
+        print_one_block_data();
+        if (READABLE()){	GETC(); break;}
+        wait(0.001);
+	    if (inf.log_inf.head == RING_TOP){	// check state 1,2,3
+	        *pt += 1;
+	        if (*pt >= inf.log_inf.tail){ // check state 2,3
+	        	PRINTF(msg_end);
+            	break;
+            }
+	    } else {	// state 4,5,6,7
+	    	if (inf.log_inf.head == RING_TAIL){ // check state 6
+	    		if (inf.log_inf.tail == RING_TAIL -1){ // check state 6
+	    			if (*pt == RING_TAIL){ // same as  :pt += 1
+	    				*pt = RING_TOP;
+	    			} else { // next read
+				    	*pt += 1;
+				        if (*pt >= inf.log_inf.tail){
+				        	PRINTF(msg_end);
+			            	break;
+		            	}
+		            }
+	    		}
+	    	} else if (inf.log_inf.tail == inf.log_inf.head - 1){ // check state 5
+		    	*pt += 1;
+		    	if (*pt > RING_TAIL){ // same as  :pt += 1
+		    		*pt = RING_TOP;
+		    	} else if (*pt == inf.log_inf.tail){ // reach to end
+		        	PRINTF(msg_end);
+	            	break;
+            	}
+			}
+	    }
+    }
+    put_rn();
 }
 
 //  Clear all buffer
-void dtlog_clear_all_buff(xEeprom_ptr *log_ptr_inf){
+void dtlog_clear_all_buff(void){
 uint8_t i;
 uint8_t *addr;
 
     /* Set initial data */
-    WRITE_POINTER(1);
-    log_ptr_inf->wr_pointer = 1;
-    WR_STATUS(0);
-    log_ptr_inf->status = 0;
-    log_ptr_inf->max = BLK_NO;
-    log_ptr_inf->ptr = 1;
-    log_ptr_inf->size = BLK_SIZE;   
+	inf.log_inf.head = inf.log_inf.tail = RING_TOP;  
     /* Write buffer pointer */
     for (i = 0; i < PTR_SIZE; i++){
         addr = (uint8_t *)(EEP_TOP + i);
-        at24c1024.write((int)addr, buf_pointer[i]);
+        at24c1024.write((int)addr, inf.buf_pointer[i]);
         wait(0.008);
     }
 }
 
-// Read some block from buffer
-void dtlog_block_read(xEeprom_ptr *read_inf){
-    if (read_inf->wr_pointer == BUF_HEAD){ // Check pointer
+// EEPROM buffer occupation
+uint16_t dtlog_buf_occupation(void){
+uint16_t i = 0;
+uint16_t dt = 0;
+uint8_t *addr;
+
+    // Read EEPROM buffer pointer to RAM
+    for ( i = 0; i < PTR_SIZE; i++ ){
+        addr = (uint8_t *)(EEP_TOP + i);
+        inf.buf_pointer[i]  = at24c1024.read((int)addr);
+        wait(0.002);
+    }
+    // check buffer pointer
+    if (inf.log_inf.head == inf.log_inf.tail){
         PRINTF(msg_emty);
         put_rn();
-        return;
-    }
-    if (read_inf->ptr >= read_inf->wr_pointer){
-        PRINTF("Reach to end!");
-        put_rn();
-        return;
+        return 0;
     }
-    if (read_inf->wr_pointer > (read_inf->ptr + read_inf->size)){
-        read_inf->max = read_inf->ptr + read_inf->size;
-    } else {
-        read_inf->max = read_inf->wr_pointer;
+    if (inf.log_inf.head == RING_TOP){	// check state 1,2,3
+    	dt = inf.log_inf.tail - inf.log_inf.head;
+    } else {	// state 4,5,6,7
+    	if (inf.log_inf.head == RING_TAIL){	// check state 6
+    		if (inf.log_inf.tail == RING_TAIL - 1){	// check state 6
+			    dt = inf.log_inf.tail - RING_TOP + 1;
+    		}
+    	} else if (inf.log_inf.tail == inf.log_inf.head - 1){ // check state 4,5
+			dt = RING_TAIL;
+		} else {	// error
+		    dt = 0;
+		}
     }
-    dtlog_blk_read(read_inf);
-}
-
-// EEPROM buffer occupation 
-uint16_t dtlog_buf_occupation(void){
-    return (uint16_t)(((uint32_t)READ_POINTER() * 1000 )/ BLK_NO);
+    return dt;
 }
 
 //  Read block number
-void dtlog_num_of_block(xEeprom_ptr *read_inf){
+void dtlog_num_of_block(void){
 uint16_t dt;
 
-    if (read_inf->wr_pointer == BUF_HEAD){
-        PRINTF(msg_emty);
-        put_rn();
-        return;
+	dt = dtlog_buf_occupation();
+	if (dt == 0){
+		PRINTF(msg_emty);
+    } else {
+	    PRINTF("Number of data = %d", dt);    
+	    put_rn();
+	    dt = (uint16_t)(((uint32_t)dt * 1000 )/ (BLK_NO - 2));
+	    PRINTF("EEPROM Occupation = %d.%01d%%", dt / 10, dt % 10);
     }
-    dt = read_inf->wr_pointer - 1;
-    PRINTF("Number of data = %d", dt);    
-    put_rn();
-    dt = dtlog_buf_occupation();
-    PRINTF("EEPROM Occupation = %d.%01d%%", dt/10, dt%10);
     put_rn();
 }
 
@@ -412,6 +453,7 @@
 		xatoi( &ptr, &p1 );
 		t.tm_min    	= (uint8_t)p1;
 		PRINTF("Min:%d ",p1);
+		xatoi( &ptr, &p1 );
 		t.tm_sec 		= (uint8_t)p1;
 		PRINTF("Sec: %d \r\n",p1);
 		xm41t62.write_rtc_std(&t);
@@ -442,24 +484,26 @@
 static void data_logger(char *ptr){
 char c;
 unsigned long dt;
+uint16_t n;
 char *const Msg  = "Data Logger Mode, ?[Help]";
 
 	PRINTF(Msg);
 	put_rn();
 	/* Get EEPROM resource */
-	dtlog_rd_buf_inf(&log_inf);
+	dtlog_pointer_read();
+	dt = inf.log_inf.head;
 	while (1){
+		/* Get EEPROM resource */
+		dtlog_pointer_read();
 		PRINTF("DL>");
         ptr = linebuf;
         get_line(ptr, buf_size);
 		switch (*ptr++) {
 			case 'a' :
 				put_r();
-				log_inf.ptr = BUF_HEAD;
-				log_inf.size = log_inf.wr_pointer;
-				dtlog_block_read(&log_inf);
-				log_inf.ptr = BUF_HEAD;
-				log_inf.size = BLK_SIZE;
+				read_pointer = inf.log_inf.head;
+				n = dtlog_buf_occupation();
+				dtlog_block_read(&read_pointer, n);
 				break;
 			case 'c' :	// Clear data
 				put_r();
@@ -472,7 +516,7 @@
 				put_rn();
 				if (c == 'y'){
 					PRINTF("Cleared all logging data");
-					dtlog_clear_all_buff(&log_inf);
+					dtlog_clear_all_buff();
 				} else {
 					PRINTF("Canceled");
 				}
@@ -480,37 +524,27 @@
 				break;
 			case 'd' :	// d <pointer> [<count>] - Dump buffer
 				put_r();
-				log_inf.size = BLK_SIZE;
-				if (xatoi(&ptr, &dt)){	log_inf.ptr = (uint16_t)dt;
-				} else {				log_inf.ptr = BUF_HEAD;		}	
-				if (xatoi(&ptr, &dt)){	log_inf.size = (uint8_t)dt;				
-				} else {				log_inf.size = BLK_SIZE;	}
-				dtlog_block_read(&log_inf);
+				if (xatoi(&ptr, &dt)){	read_pointer = (uint16_t)dt;
+				} else {				read_pointer = inf.log_inf.head; }	
+				if (xatoi(&ptr, &dt)){	n = (uint8_t)dt;				
+				} else {				n = BLK_SIZE; }
+				if (read_pointer == 0){ read_pointer = 1;}
+				dtlog_block_read(&read_pointer, n);
 				break;
 			case 0x0d :	// CR
 				put_r();
-				log_inf.size = BLK_SIZE;
-				dtlog_block_read(&log_inf);
+				dtlog_block_read(&read_pointer, BLK_SIZE);
 				break;
 			case 'b' :	// Back
 				put_r();
-				log_inf.size = BLK_SIZE;
-				if (log_inf.ptr > log_inf.size){
-					log_inf.ptr -= log_inf.size;
-					if (log_inf.ptr == 0){
-						log_inf.ptr = 1;
-						--log_inf.size;
-					}
-				} else {
-					log_inf.size = log_inf.ptr - 1;
-					log_inf.ptr = 1;
-				}
-				dtlog_block_read(&log_inf);
+				read_pointer -= (BLK_SIZE * 2);
+				if (read_pointer <= 0){ read_pointer = 1;}
+				dtlog_block_read(&read_pointer, n);
 				break;
 			case 'n' :
 			case 's' :	// Status
 				put_r();
-				dtlog_num_of_block(&log_inf);
+				dtlog_num_of_block();
 				break;
 			case 'q' :	// exit
 				linebuf[0] = 0;