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
Diff: Rebmon_main.cpp
- Revision:
- 5:35417986539a
- Parent:
- 4:74df6d31ee0a
- Child:
- 6:ab2d7d0a9b07
--- a/Rebmon_main.cpp Fri Aug 03 14:19:44 2012 +0000 +++ b/Rebmon_main.cpp Tue Aug 07 11:33:03 2012 +0000 @@ -1,7 +1,7 @@ //lpc1124lcddemo #include "ds1307.h" #include "mbed.h" -#include "TextLCD.h" +#include "TextOLED.h" #define METRE 0.02 // change in DEPin for 1m depth @@ -23,7 +23,9 @@ // switches and buttons - these are pulled up by resistors so are active low DigitalIn CAL(p36); -DigitalIn SW1(p35); +DigitalIn SW1(p35); // reed switch in display unit +DigitalIn SW2(p10); // reed switch in dispaly unit +DigitalIn MODE(p11);// a switchn on the mbed pcb to select between SCR and CCR modes for the LEDs // log data storage LocalFileSystem local("local"); @@ -81,7 +83,7 @@ 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,17,17,0,17,14,0 // happy symbol 7 + 2,6,2,2,2,2,23 // defined to handle dec point in depth 7 }; int i=0; // do stuff here to set cstom chars @@ -126,7 +128,7 @@ // sub to test if a variable is an even number int iseven(int g) { int test=0; - if(g%2 ==0) test=1; + if (g%2 ==0) test=1; return(test); } @@ -135,6 +137,8 @@ if (state==0) { g_lcd.character(9,0,5); // warning icon until 1 min up g_lcd.character(8,0,6); // surface icon + } else { + g_lcd.character(9,0,32); } if (state==1) g_lcd.character(8,0,6); // surface icon if (state==2 && iseven(seconds)==1) g_lcd.character(8,0,4); // diving icon @@ -169,18 +173,37 @@ void leds() { // first turn everything off -red=0; -green=0; -blue=0; -float ppo; -ppo=maximum(ppo1,ppo2); // use max value to compute leds... -if(ppo<0.2 && flash==1) red=1; // flashing red means very bad things - getting low on oxygen!!! -if(ppo>0.2 && ppo < 1) red=1; // non-flashing red -if(ppo>=1.0 && ppo <1.2) {red=1;green=1;} // red-green -if(ppo<1.3 && ppo >=1.2) green=1; // green - optimal range in ccr mode -if(ppo<1.4 && ppo >=1.3){green=1;blue=1;} // green-blue - high ppo2 be careful of spiking -if(ppo2<1.6 && ppo2>=1.4) blue=1; // DANGE ble high ppo2 -if(ppo2>=1.6 && flash==1) blue=1; + red=0; + green=0; + blue=0; + float ppo; + int mo=0; + mo=MODE; + ppo=maximum(ppo1,ppo2); // use max value to compute leds... + if (mo==0) { // CCR mode + if (ppo<0.2 && flash==1) red=1; // flashing red means very bad things - getting low on oxygen!!! + if (ppo>0.2 && ppo < 1) red=1; // non-flashing red + if (ppo>=1.0 && ppo <1.2) { + red=1; // red-green + green=1; + } + if (ppo<1.3 && ppo >=1.2) green=1; // green - optimal range in ccr mode + if (ppo<1.4 && ppo >=1.3) { + green=1; // green-blue - high ppo2 be careful of spiking + blue=1; + } + if (ppo2<1.6 && ppo2>=1.4) blue=1; // DANGE ble high ppo2 + if (ppo2>=1.6 && flash==1) blue=1; + } + if (mo==1) { // SCR mode + if (ppo<0.2 && flash==1) red=1; + if (depth < 0.8*mod && ppo>0.2) green=1; + if (depth< mod && depth >=0.8*mod) { + green=1; + blue=1; + } + if (depth >=mod && flash==1) blue=1; + } } @@ -203,18 +226,55 @@ //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() { + int mo=0; + mo=MODE; //1st line g_lcd.locate(0,0); - g_lcd.printf("%1.2f:%.2d %.2d %.2d",ppo1,(int)fo1,(int)depth,(int)mod); + g_lcd.printf("%1.2f:%.2d",ppo1,(int)fo1); + g_lcd.locate(10,0); + g_lcd.printf("%.2d %.2d",(int)depth,(int)mod); //2nd line g_lcd.locate(0,1); - g_lcd.printf("%1.2f:%.2d %.2d %.3d",ppo2,(int)fo2,divetime,scrubtime); + g_lcd.printf("%1.2f:%.2d",ppo2,(int)fo2); + g_lcd.locate(10,1); + g_lcd.printf("%.2d %.3d",divetime % 100 ,scrubtime % 1000); // modulo to avoid digits conflict - means divetime is always less than 100 // bung in battery icon battery(); - status(); // this will set the diviong / suface mode icon + status(); // this will set the diving / suface mode icon warning(); // this will set the warning icon assuming that max ppo2 is exceeded leds(); // this sets the leds according to the various warning conditions + if (mo==0) { + g_lcd.character(7,1,99); //'c' = ccr + } else { + g_lcd.character(7,1,115); //'s' = scr + } + // custom character setting to sort out dp in depths + + + char cgchar[80]={ + 7,5,5,5,23,0,0,0, // .0 + 2,2,2,2,18,0,0,0, // .1 + 7,1,7,4,23,0,0,0, // 0.2 + 7,1,3,1,23,0,0,0, // 0.3 + 5,5,7,1,17,0,0,0, //0.4 + 7,4,7,1,23,0,0,0, //0.5 + 7,4,7,5,23,0,0,0, //0.6 + 7,1,2,2,18,0,0,0, //.7 + 7,5,7,5,23,0,0,0, //.8 + 7,5,7,1,17,0,0,0 //.9 + + }; + + int i=0,d=0; + d=(int)((depth-(int)depth)*10); // should be size of the 1st decimal place +// do stuff here to set cstom chars + g_lcd.writeCommand(120); // set start address for CGRAM + for (i=0; i<8; i++) { + g_lcd.writeData(cgchar[i+d*8]); + } + + g_lcd.character(12,0,7); // put in appropriate custom character } @@ -227,20 +287,24 @@ float barometric=0,mod1,mod2; ppo1=EG1*0.21/eg1cal; // eg1cal is 0.21bar ppO2 ppo2=EG2*0.21/eg2cal; // second oxygen cell ppO2 + // NB this assumes that the calibration is done at exactly 1 bar.... - not always the case but ok for sea level diving pressure=(PRESin*3.3-0.024)/(0.0038574); // pressure in kPa assuming standard cal for mpx5700 sensor SUSPECT - // barometric=(pcal*3.3-0.024)/(0.0038574); // sealevel in kPa assuming standard cal for mpx5700 sensor - depth=(pressure-101.325)*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 + 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. + if(depth<0) depth=0; - fo1=100*ppo1/(pressure/100); // pressure in bar = pressure /100 and want a % so multiply by 100 as well - fo2=100*ppo2/(pressure/100); + fo1=100*ppo1/((pressure-barometric)/100+1); // pressure in bar = pressure /100 and want a % so multiply by 100 as well + fo2=100*ppo2/((pressure-barometric)/100+1); + + if(fo1<0) fo2=0; + if(fo2<0) fo1=0; - + //with two sensors will calculate mod from the largest ppo2 reading mod1=(1.4/(fo1/100)-1)*10; mod2=(1.4/(fo2/100)-1)*10; mod=minimum(mod1,mod2); // pick the least value - //DEBUG } @@ -280,7 +344,7 @@ j=(j+1) % 4; } 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