Software to drive a monitor unit for a closed circuit rebreather using 3 electrogalvanic oxygen sensor cells run through an amplifier (lm324) . Uses a separate ds1307 clock IC to get timestamp values for logged data.

Dependencies:   DS1307 TextOLED_custom mbed

The main electornics is housed in another pod mounted on the back of the unit. I'm using an mbed lpc11u24 to drive everything which comes with a flash drive for data logging built in. It has an external ds1307 clock chip added and a very cheapo lm324 quad op-amp to amplify the o2 sensor signals from the 10s of mV range by 30x so that ppo2=0.21 corresponds to about 0.3V. I still have to do some ADC averaging with this amplifier and do have to calibrate out the individual offsets of the chip but this works ok now that I've worked out which amp is on which adc...

Files at this revision

API Documentation at this revision

Comitter:
pegcjs
Date:
Thu Aug 02 14:55:08 2012 +0000
Parent:
0:52d05d950581
Child:
2:a1c26faa9103
Commit message:
barebones in place - max and min functions just added along wtih readsesnors display etc

Changed in this revision

Rebmon_main.cpp Show annotated file Show diff for this revision Revisions of this file
TextLCD.lib Show annotated file Show diff for this revision Revisions of this file
--- 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
+
+
+
+
--- a/TextLCD.lib	Wed Aug 01 15:04:18 2012 +0000
+++ b/TextLCD.lib	Thu Aug 02 14:55:08 2012 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/simon/code/TextLCD/#0f6daea1c38b
+http://mbed.org/users/simon/code/TextLCD/#c1ad3961696d