A code to drive a 3sensor reading unit for monitoring the operation opf a closed circuit rebreather (CCR) with 3 electrogalvanic sensors. Also uses a DS1307 for realtime clock and an MPX5700 to read the depth (mounted inside the breathing loop to keep it 'dry'). circuit diagrams available on rebreather world.

Dependencies:   DS1307 TextOLED mbed

Revision:
1:9cff4feccbce
Parent:
0:52d05d950581
Child:
2:a1c26faa9103
--- a/Rebmon_main.cpp	Wed Aug 01 15:04:18 2012 +0000
+++ b/Rebmon_main.cpp	Thu Aug 02 14:55:08 2012 +0000
@@ -1,91 +1,237 @@
-//lpc1124lcddemo
-#include "ds1307.h"
-#include "mbed.h"
-#include "TextLCD.h"
-
-//pin assignments and declarations
-// LCD display
-TextLCD g_lcd(p26, p25, p24, p23, p22, p21);  // RS, E, DB4, DB5, DB6, DB7
-
-//onboard leds
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-
-// warning leds
-DigitalOut red(p34);
-DigitalOut green(p33);
-DigitalOut blue(p30);
-
-// switches and buttons
-DigitalIn CAL(p36);
-DigitalIn SW1(p35);
-
-// log data storage
-LocalFileSystem local("local");
-
-// adc inputs for sensors
-AnalogIn depin(p20);
-AnalogIn EG1(p19);
-AnalogIn EG2(p18);
-AnalogIn Vbatt(p17);
-
-// realtime clock
-DS1307 my1307(p28,p27); // start DS1307 class and give it pins for connections of the DS1307 device
-
-// variables for realtime clock
-int sec = 0;
-int min = 0;
-int hours = 0;
-int day = 0;
-int date = 0;
-int month = 0;
-int year = 0;
-
-
-int main() {
-    // get time to log a startup time
-    my1307.gettime( &sec, &min, &hours, &day, &date, &month, &year);
-    int starttime=year*365*24*60*60+month*30*24*60*60+day*24*60*60+hours*60*60+min*60+sec; //simple timestamp = # seconds since midnight jan 1st 2000 if all months were 30 days.
-    
-
-    int seconds;
-    float depth;
-
-// setup local file to store data in
-    FILE *fp = fopen("/local/out.txt", "a");  // Open "out.txt" on the local file system for writing
-
-
-
-
-g_lcd.cls();
-
-g_lcd.locate(0, 0);
-g_lcd.printf( "Hello world!");
-
-while (1) {
-    g_lcd.locate(0, 1);
-    my1307.gettime( &sec, &min, &hours, &day, &date, &month, &year);
-    seconds=day*24*60*60+hours*60*60+min*60+sec; // seconds since the start of this month....
-
-    if (led1==0) led1=1;
-    else led1=0;
-    g_lcd.printf( "%.2d:%.2d:%.2d", hours,min,sec);
-
-    iCounter++;
-    depth=depin/0.020;
-    if (iCounter <=60) {
-        fprintf(fp, "%d\t%e\n",seconds,depth);
-        g_lcd.locate(0,0);
-        g_lcd.printf("Writing data  ");
-    } else {
-        g_lcd.locate(0,0);
-        g_lcd.printf("Closed file  ");
-    }
-    if (iCounter==61) {
-        fclose(fp);
-    }
-    g_lcd.locate(9,1);
-    g_lcd.printf("%3.1f",depth);
-    wait(1.0);
-}
-}
+//lpc1124lcddemo
+#include "ds1307.h"
+#include "mbed.h"
+#include "TextLCD.h"
+
+
+#define METRE 0.02 // change in DEPin for 1m depth
+
+//pin assignments and declarations
+// LCD display
+TextLCD g_lcd(p26, p25, p24, p23, p22, p21);  // RS, E, DB4, DB5, DB6, DB7
+//backlight
+DigitalOut backlight(p29);
+
+//onboard leds
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+
+// warning leds
+DigitalOut red(p34);
+DigitalOut green(p33);
+DigitalOut blue(p30);
+
+// switches and buttons - these are pulled up by resistors so are active low
+DigitalIn CAL(p36);
+DigitalIn SW1(p35);
+
+// log data storage
+LocalFileSystem local("local");
+
+// adc inputs for sensors
+AnalogIn PRESin(p20);
+AnalogIn EG1(p19);
+AnalogIn EG2(p18);
+AnalogIn Vbatt(p17);
+
+// realtime clock
+DS1307 my1307(p28,p27); // start DS1307 class and give it pins for connections of the DS1307 device
+
+// variables for realtime clock
+int sec = 0;
+int min = 0;
+int hours = 0;
+int day = 0;
+int date = 0;
+int month = 0;
+int year = 0;
+
+int scrubtime=0; // these are expressed in minutes
+int divetime=0;
+
+// variables for the eg cells and pressure sensor eg1calamd eg2cal ar reading when the sensor is in 0.21bar O2 and
+//dcal is the reading whe the pressure sensor is at the surface
+float eg1cal=0.09,eg2cal=0.09,pcal=0.1136;
+// NB these are updated from /local/cal.dat so values not so important.... eventually
+
+float depth=0,ppo1=0,ppo2=0,  Vb=0,pressure=0; // depth, 1st o2 sensor second o2 sensor battery voltage,,Pressure
+float fo1=0,fo2=0,mod=55; //%f values,mod
+//===== sub to get time from ds1307 and create the 'seconds' which is a version of timestamp....
+int getseconds() {
+    my1307.gettime( &sec, &min, &hours, &day, &date, &month, &year);
+    //simple timestamp = # seconds since midnight jan 1st 2000 if all months were 30 days.
+    int seconds=year*365*24*60*60+month*30*24*60*60+day*24*60*60+hours*60*60+min*60+sec;
+    //simple timestamp = # seconds since midnight jan 1st 2000 if all months were 30 days....
+    // ie wrong but simpler than the real thing
+    return(seconds);
+}
+
+
+void set_custom_char() {
+    char cgchar[64]={
+        6,9,9,9,9,9,9,15, // battery empty symbol         0
+        6,9,9,9,9,15,15,15, // battery 50% symbol         1
+        6,9,9,15,15,15,15,15, // battery 75% symbol       2
+        6,15,15,15,15,15,15,15, // battery 100% symbol    3
+        31,19,21,21,21,21,19,31,  // diving symbol        4 inverse D
+        6,6,6,6,6,0,0,6,             // warning symbol    5
+        31,17,23,17,29,17,31,0, // surface symbol         6 inverse S
+        0,0,9,9,0,17,14,0 // happy symbol                 7
+    };
+    int i=0;
+// do stuff here to set cstom chars
+    g_lcd.writeCommand(0x40); // set start address for CGRAM
+    for (i=0; i<64; i++) {
+        g_lcd.writeData(cgchar[i]);
+    }
+
+}
+
+
+// subroutine to calibreate o2 sesnors and store ca data in /local/CAL.dat
+void calibrate() {
+    int count=1;
+    float ppo1=0,ppo2=0,pres=0;
+    // average 20 readings for noise reduction
+    g_lcd.cls();
+    for (count=20; count>0; count--) {
+        g_lcd.locate(0,0);
+        g_lcd.printf("Calibrating %.2d",count);
+        ppo1=ppo1+EG1;
+        ppo2=ppo2+EG2;
+        pres=pres+PRESin;
+        g_lcd.locate(0,1);
+        g_lcd.printf("%1.2f: %1.2f: %1.2f",ppo1/(20-count+1),ppo2/(20-count+1),pres/(20-count+1));
+        wait(1);
+    }
+    //average
+    ppo1=ppo1/20;
+    ppo2=ppo2/20;
+    // set calibration variables
+    eg1cal=ppo1;
+    eg2cal=ppo2;
+    pcal=pres/20; // surface pressure....
+    scrubtime=0; // reset the scrubber timer to zero.
+}
+
+// subroutine to write the main display data
+//0123456789abcdef
+
+//x.xx:xx D XX  xx
+//x.xx:xx B XX xxx NB the warning, staus and battery icons are driven by separate subroutines.
+void display() {
+//1st line
+    g_lcd.locate(0,0);
+    g_lcd.printf("%1.2f:%.2d X %.2d  %.2d",ppo1,(int)fo1,(int)depth,(int)mod);
+    //2nd line
+    g_lcd.locate(0,1);
+    g_lcd.printf("%1.2f:%.2d B %.2d  %.2d",ppo2,(int)fo2,(int)depth,(int)mod);
+}
+
+//read battery state and insert the battery symbol
+void battery() {
+    int batsym=0;
+    Vb=Vbatt; // read adc connected to battery via a 1/3 potential divider
+    if (Vb>0.606) batsym=1;
+    if (Vb>0.707) batsym=2;
+    if (Vb>0.808) batsym=3;
+    g_lcd.character(8,1,batsym);
+}
+
+// pick maximum of two values
+float maximum(float a,float b) {
+    float maximum;
+    if (a>b) maximum=a;
+    else maximum=b;
+    return(maximum);
+       }
+       
+// pick minimum  of two values
+float minimum(float a,float b) {
+    float minim;
+    if (a<b) minim=a;
+    else minim=b;
+    return(minim);
+       }
+       
+       
+
+// read sensors and generate calibrated outputs
+void readsensors() {
+    float barometric=0,mod1,mod2;
+    ppo1=EG1*0.21/eg1cal; // eg1cal is 0.21bar ppO2
+    ppo2=EG2*0.21/eg2cal; // second oxygen cell ppO2
+    pressure=(PRESin*3.3-0.024)/(0.0038574); // pressure in kPa assuming standard cal for mpx5700 sensor
+    barometric=(pcal*3.3-0.024)/(0.0038574); // sealevel in kPa assuming standard cal for mpx5700 sensor
+    depth=(pressure-barometric)*0.1;   //100kPa=10m 1kPa=0.1m - this gives depth in m for freshwater.
+    //with two sensors will calculate mod from the largest ppo2 reading
+    mod1=1.4/ppo1;
+    mod2=1.4/ppo2;
+    mod=minimum(mod1,mod2); // pick the 
+}
+
+int main() {
+    // get time to log a startup time
+    //my1307.gettime( &sec, &min, &hours, &day, &date, &month, &year);
+    //int startuptime=year*365*24*60*60+month*30*24*60*60+day*24*60*60+hours*60*60+min*60+sec; //simple timestamp = # seconds since midnight jan 1st 2000 if all months were 30 days.
+
+    int startuptime=getseconds();
+    int startdive=0;
+
+    int seconds=0;; // this will be the divetiem variable eventually.
+    int i=0,j=0; // general loop counting variables
+
+
+    set_custom_char(); // does what it says on the tin really
+    g_lcd.cls();
+    g_lcd.locate(0, 0);
+    g_lcd.printf( "RebMon");
+    g_lcd.locate(0,1);
+    g_lcd.printf("CAL?");
+    battery();
+
+// hang about waiting for the cal switch to be pressed in ccase it is
+    while (seconds-startuptime<20) {
+        seconds=getseconds();
+        g_lcd.locate(5,1);
+        g_lcd.printf("%.2d",21-(seconds-startuptime));
+        battery(); // bung in battery symbol.
+        g_lcd.locate(7,0);
+        g_lcd.printf( "%.2d:%.2d:%.2d", hours,min,sec);
+        if (CAL==0) {
+            calibrate();
+
+        }
+        wait(1);
+    }
+    g_lcd.cls();
+    backlight=1; // backlight on - this driven by bc182l and 50ohm resistor off the 5V supply to send ~ 20mA
+
+    // ok there are three states in this system
+//MAIN LOOP ONCE STARTUP PROTOCOLS ARE COMPLETED
+    while (1) {
+
+        readsensors();
+
+
+        getseconds();
+        battery();
+        g_lcd.locate(0,0);
+        g_lcd.printf( "%.2d:%.2d:%.2d", hours,min,sec);
+        led1=1;
+        wait(0.5);
+        g_lcd.character(i,1,i);
+        g_lcd.character(12,1,j);
+        i=(i+1) % 8;
+        j=(j+1) % 4;
+        // setup local file to store data in
+        //     FILE *fp = fopen("/local/out.txt", "a");  // Open "out.txt" on the local file system for writing
+        //   fclose(fp);
+        led1=0;
+        wait(0.5);
+    } // end while
+} //end main
+
+
+
+