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:
- 1:9cff4feccbce
- Parent:
- 0:52d05d950581
- Child:
- 2:a1c26faa9103
diff -r 52d05d950581 -r 9cff4feccbce Rebmon_main.cpp --- 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 + + + +