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:
- 6:ab2d7d0a9b07
- Parent:
- 5:35417986539a
- Child:
- 7:f93b7eaab5f6
diff -r 35417986539a -r ab2d7d0a9b07 Rebmon_main.cpp --- a/Rebmon_main.cpp Tue Aug 07 11:33:03 2012 +0000 +++ b/Rebmon_main.cpp Tue Aug 07 16:25:18 2012 +0000 @@ -21,6 +21,7 @@ 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); // reed switch in display unit @@ -49,7 +50,7 @@ int year = 0; int seconds=0; // general number of seconds since 2000 etc timestamp variable -int scrubtime=0; // these are expressed in minutes +int scrubtime=0,scrubold=0;; // these are expressed in minutes int divetime=0; int flash=0; // variable used top control flashing icons @@ -63,6 +64,8 @@ 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 +FILE *lp; // file pointer for log file + //===== 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); @@ -94,6 +97,13 @@ } +// stash cal values on local drive +void store() { + FILE *fp=fopen("/local/CAL.dat","w"); + fprintf(fp,"%e\n%e\n%e\n%d",eg1cal,eg2cal,pcal,scrubtime); + fclose(fp); //NB file system locked on write so must make sure we close files in case want to reprogram etc... +} + // subroutine to calibreate o2 sesnors and store ca data in /local/CAL.dat void calibrate() { @@ -120,9 +130,10 @@ pcal=pres/20; // surface pressure.... scrubtime=0; // reset the scrubber timer to zero. // write cal data NB overwites previous - FILE *fp=fopen("/local/CAL.dat","w"); - fprintf(fp,"%e\n%e\n%e\n%d",eg1cal,eg2cal,pcal,scrubtime); - fclose(fp); //NB file system locked on write so must make sure we close files in case want to reprogram etc... + /* FILE *fp=fopen("/local/CAL.dat","w"); + fprintf(fp,"%e\n%e\n%e\n%d",eg1cal,eg2cal,pcal,scrubtime); + fclose(fp); //NB file system locked on write so must make sure we close files in case want to reprogram etc...*/ + store(); } // sub to test if a variable is an even number @@ -150,6 +161,7 @@ void warning() { if (depth>=mod && flash==1) g_lcd.character(13,0,5); + else g_lcd.character(13,0,32); // blank sapce } @@ -197,6 +209,7 @@ } if (mo==1) { // SCR mode if (ppo<0.2 && flash==1) red=1; + if(ppo2>=0.2 && ppo2 <0.26) red=1; // will give green red for low but not lethal ppo2s if (depth < 0.8*mod && ppo>0.2) green=1; if (depth< mod && depth >=0.8*mod) { green=1; @@ -204,6 +217,7 @@ } if (depth >=mod && flash==1) blue=1; } + } @@ -232,7 +246,9 @@ g_lcd.locate(0,0); g_lcd.printf("%1.2f:%.2d",ppo1,(int)fo1); g_lcd.locate(10,0); - g_lcd.printf("%.2d %.2d",(int)depth,(int)mod); + g_lcd.printf("%.2d",(int)depth); + g_lcd.locate(14,0); + g_lcd.printf("%.2d",(int)mod); //2nd line g_lcd.locate(0,1); g_lcd.printf("%1.2f:%.2d",ppo2,(int)fo2); @@ -250,8 +266,8 @@ 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 @@ -290,15 +306,15 @@ // 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-barometric)*0.1; //100kPa=10m 1kPa=0.1m - this gives depth in m for freshwater. - if(depth<0) depth=0; + if (depth<0) depth=0; 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; + + 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; @@ -307,6 +323,20 @@ mod=minimum(mod1,mod2); // pick the least value } +// get values back from cal file on local drive +void recall() { + FILE *fp=fopen("/local/CAL.dat","r"); + fscanf(fp,"%e\n%e\n%e\n%d",&eg1cal,&eg2cal,&pcal,&scrubold); + fclose(fp); //NB file system locked on write so must make sure we close files in case want to reprogram etc... +} + +// write the logfile opened and closed by start and end of dive +void store_log() { + Vb=Vbatt; + //FILE *fp=fopen("/local/divelog.dat","a"); + fprintf(lp,"%d\t%e\t%e\t%e\t%e\t%d\n",seconds,depth,ppo1,ppo2,Vb,scrubtime); + // fclose(fp); +} int main() { @@ -314,8 +344,9 @@ int startuptime=getseconds(); int startdive=0,endclock=0; // value of seconds when dive starts and counter to decide if dive complete... - int minutes=0,dt=0;; // minutes is elapsed minutes since start of prog - int i=0,j=0; // general loop counting variables + int minutes=0; // minutes is elapsed minutes since start of prog + int j=0; // general loop counting variable + set_custom_char(); // does what it says on the tin really @@ -326,6 +357,10 @@ g_lcd.printf("CAL?"); battery(); j=0; + // get cal values last used from local drive + recall(); + // display the correct scrubber time + scrubtime=scrubtime+scrubold; // hang about waiting for the cal switch to be pressed in ccase it is while (seconds-startuptime<20) { seconds=getseconds(); @@ -354,7 +389,7 @@ readsensors(); seconds=getseconds(); minutes=(int)(((float)seconds-(float)startuptime)/60); - dt=seconds-startuptime; // elapsed seconds + if (j>1) flash=1; else flash=0; @@ -364,20 +399,28 @@ // setup state variable if (minutes<1) state=0; // startup mode - do nothing just wait to allow sensor readings to settle. if (minutes>=1 && state==0) state=1; // surface mode - ok to go for a dive now - if (minutes>=1 && depth>0.5 && state==1) { + if (minutes>=1 && depth>0.8 && state==1) { state=2; // enter dive mode + lp=fopen("/local/divelog.dat","a"); if (startdive==0) startdive=seconds; // set start of divetime. don't do this twice endclock=0; // reset end of dive clock } if (state==2) { divetime=(int)(((float)seconds-(float)startdive)/60); // time since start of dive in minutes. // do deco calcs here when implemented - if (depth<0.3) { + if ((seconds-startdive) %15 ==0) store_log(); // this saves the dive profile and sensor optputs in a file called divelog.dat every 15s + if (depth<=0.3) { endclock=endclock+1; - if (endclock>150) state=1; // 30s at shallower than 0.3m and we return to surface mode. + if (endclock>150) { + state=1; // 30s at shallower than 0.3m and we return to surface mode. + FILE *fp=fopen("/local/CAL.dat","w"); + fprintf(fp,"%e\n%e\n%e\n%d",eg1cal,eg2cal,pcal,scrubtime); + fclose(fp); //NB file system locked on write so must make sure we close files in case want to reprogram etc... + fclose(lp); + } } - scrubtime=minutes; // need to add memory of prior scrub time to this once variable input fom log file is implements + scrubtime=scrubold+divetime; // }