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...

Committer:
pegcjs
Date:
Tue Aug 07 11:33:03 2012 +0000
Revision:
5:35417986539a
Parent:
4:74df6d31ee0a
Child:
6:ab2d7d0a9b07
basic function done - still no recovery of values fro cal file...

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pegcjs 1:9cff4feccbce 1 //lpc1124lcddemo
pegcjs 1:9cff4feccbce 2 #include "ds1307.h"
pegcjs 1:9cff4feccbce 3 #include "mbed.h"
pegcjs 5:35417986539a 4 #include "TextOLED.h"
pegcjs 1:9cff4feccbce 5
pegcjs 1:9cff4feccbce 6
pegcjs 1:9cff4feccbce 7 #define METRE 0.02 // change in DEPin for 1m depth
pegcjs 1:9cff4feccbce 8
pegcjs 1:9cff4feccbce 9 //pin assignments and declarations
pegcjs 1:9cff4feccbce 10 // LCD display
pegcjs 1:9cff4feccbce 11 TextLCD g_lcd(p26, p25, p24, p23, p22, p21); // RS, E, DB4, DB5, DB6, DB7
pegcjs 1:9cff4feccbce 12 //backlight
pegcjs 1:9cff4feccbce 13 DigitalOut backlight(p29);
pegcjs 1:9cff4feccbce 14
pegcjs 1:9cff4feccbce 15 //onboard leds
pegcjs 1:9cff4feccbce 16 DigitalOut led1(LED1);
pegcjs 1:9cff4feccbce 17 DigitalOut led2(LED2);
pegcjs 1:9cff4feccbce 18
pegcjs 1:9cff4feccbce 19 // warning leds
pegcjs 1:9cff4feccbce 20 DigitalOut red(p34);
pegcjs 1:9cff4feccbce 21 DigitalOut green(p33);
pegcjs 1:9cff4feccbce 22 DigitalOut blue(p30);
pegcjs 1:9cff4feccbce 23
pegcjs 1:9cff4feccbce 24 // switches and buttons - these are pulled up by resistors so are active low
pegcjs 1:9cff4feccbce 25 DigitalIn CAL(p36);
pegcjs 5:35417986539a 26 DigitalIn SW1(p35); // reed switch in display unit
pegcjs 5:35417986539a 27 DigitalIn SW2(p10); // reed switch in dispaly unit
pegcjs 5:35417986539a 28 DigitalIn MODE(p11);// a switchn on the mbed pcb to select between SCR and CCR modes for the LEDs
pegcjs 1:9cff4feccbce 29
pegcjs 1:9cff4feccbce 30 // log data storage
pegcjs 1:9cff4feccbce 31 LocalFileSystem local("local");
pegcjs 1:9cff4feccbce 32
pegcjs 1:9cff4feccbce 33 // adc inputs for sensors
pegcjs 1:9cff4feccbce 34 AnalogIn PRESin(p20);
pegcjs 1:9cff4feccbce 35 AnalogIn EG1(p19);
pegcjs 1:9cff4feccbce 36 AnalogIn EG2(p18);
pegcjs 1:9cff4feccbce 37 AnalogIn Vbatt(p17);
pegcjs 1:9cff4feccbce 38
pegcjs 1:9cff4feccbce 39 // realtime clock
pegcjs 1:9cff4feccbce 40 DS1307 my1307(p28,p27); // start DS1307 class and give it pins for connections of the DS1307 device
pegcjs 1:9cff4feccbce 41
pegcjs 1:9cff4feccbce 42 // variables for realtime clock
pegcjs 1:9cff4feccbce 43 int sec = 0;
pegcjs 1:9cff4feccbce 44 int min = 0;
pegcjs 1:9cff4feccbce 45 int hours = 0;
pegcjs 1:9cff4feccbce 46 int day = 0;
pegcjs 1:9cff4feccbce 47 int date = 0;
pegcjs 1:9cff4feccbce 48 int month = 0;
pegcjs 1:9cff4feccbce 49 int year = 0;
pegcjs 4:74df6d31ee0a 50 int seconds=0; // general number of seconds since 2000 etc timestamp variable
pegcjs 1:9cff4feccbce 51
pegcjs 1:9cff4feccbce 52 int scrubtime=0; // these are expressed in minutes
pegcjs 1:9cff4feccbce 53 int divetime=0;
pegcjs 1:9cff4feccbce 54
pegcjs 3:0d94a277aa8c 55 int flash=0; // variable used top control flashing icons
pegcjs 2:a1c26faa9103 56 int state=0; // IMPORTANT - VARIABLE THAT DRIVES HNTE STATE MACHINE STATE=0 = STARTUP, STATE=1=SURFACE STATE=2= DIVING
pegcjs 2:a1c26faa9103 57
pegcjs 1:9cff4feccbce 58 // variables for the eg cells and pressure sensor eg1calamd eg2cal ar reading when the sensor is in 0.21bar O2 and
pegcjs 1:9cff4feccbce 59 //dcal is the reading whe the pressure sensor is at the surface
pegcjs 1:9cff4feccbce 60 float eg1cal=0.09,eg2cal=0.09,pcal=0.1136;
pegcjs 1:9cff4feccbce 61 // NB these are updated from /local/cal.dat so values not so important.... eventually
pegcjs 1:9cff4feccbce 62
pegcjs 1:9cff4feccbce 63 float depth=0,ppo1=0,ppo2=0, Vb=0,pressure=0; // depth, 1st o2 sensor second o2 sensor battery voltage,,Pressure
pegcjs 1:9cff4feccbce 64 float fo1=0,fo2=0,mod=55; //%f values,mod
pegcjs 3:0d94a277aa8c 65
pegcjs 1:9cff4feccbce 66 //===== sub to get time from ds1307 and create the 'seconds' which is a version of timestamp....
pegcjs 1:9cff4feccbce 67 int getseconds() {
pegcjs 1:9cff4feccbce 68 my1307.gettime( &sec, &min, &hours, &day, &date, &month, &year);
pegcjs 1:9cff4feccbce 69 //simple timestamp = # seconds since midnight jan 1st 2000 if all months were 30 days.
pegcjs 4:74df6d31ee0a 70 int secondst=year*365*24*60*60+month*30*24*60*60+day*24*60*60+hours*60*60+min*60+sec;
pegcjs 1:9cff4feccbce 71 //simple timestamp = # seconds since midnight jan 1st 2000 if all months were 30 days....
pegcjs 1:9cff4feccbce 72 // ie wrong but simpler than the real thing
pegcjs 4:74df6d31ee0a 73 return(secondst);
pegcjs 1:9cff4feccbce 74 }
pegcjs 1:9cff4feccbce 75
pegcjs 1:9cff4feccbce 76
pegcjs 1:9cff4feccbce 77 void set_custom_char() {
pegcjs 1:9cff4feccbce 78 char cgchar[64]={
pegcjs 1:9cff4feccbce 79 6,9,9,9,9,9,9,15, // battery empty symbol 0
pegcjs 1:9cff4feccbce 80 6,9,9,9,9,15,15,15, // battery 50% symbol 1
pegcjs 1:9cff4feccbce 81 6,9,9,15,15,15,15,15, // battery 75% symbol 2
pegcjs 1:9cff4feccbce 82 6,15,15,15,15,15,15,15, // battery 100% symbol 3
pegcjs 1:9cff4feccbce 83 31,19,21,21,21,21,19,31, // diving symbol 4 inverse D
pegcjs 1:9cff4feccbce 84 6,6,6,6,6,0,0,6, // warning symbol 5
pegcjs 1:9cff4feccbce 85 31,17,23,17,29,17,31,0, // surface symbol 6 inverse S
pegcjs 5:35417986539a 86 2,6,2,2,2,2,23 // defined to handle dec point in depth 7
pegcjs 1:9cff4feccbce 87 };
pegcjs 1:9cff4feccbce 88 int i=0;
pegcjs 1:9cff4feccbce 89 // do stuff here to set cstom chars
pegcjs 1:9cff4feccbce 90 g_lcd.writeCommand(0x40); // set start address for CGRAM
pegcjs 1:9cff4feccbce 91 for (i=0; i<64; i++) {
pegcjs 1:9cff4feccbce 92 g_lcd.writeData(cgchar[i]);
pegcjs 1:9cff4feccbce 93 }
pegcjs 1:9cff4feccbce 94
pegcjs 1:9cff4feccbce 95 }
pegcjs 1:9cff4feccbce 96
pegcjs 1:9cff4feccbce 97
pegcjs 1:9cff4feccbce 98 // subroutine to calibreate o2 sesnors and store ca data in /local/CAL.dat
pegcjs 1:9cff4feccbce 99 void calibrate() {
pegcjs 1:9cff4feccbce 100 int count=1;
pegcjs 1:9cff4feccbce 101 float ppo1=0,ppo2=0,pres=0;
pegcjs 1:9cff4feccbce 102 // average 20 readings for noise reduction
pegcjs 1:9cff4feccbce 103 g_lcd.cls();
pegcjs 1:9cff4feccbce 104 for (count=20; count>0; count--) {
pegcjs 1:9cff4feccbce 105 g_lcd.locate(0,0);
pegcjs 4:74df6d31ee0a 106 g_lcd.printf("Calibrate 21%% %.2d",count);
pegcjs 1:9cff4feccbce 107 ppo1=ppo1+EG1;
pegcjs 1:9cff4feccbce 108 ppo2=ppo2+EG2;
pegcjs 1:9cff4feccbce 109 pres=pres+PRESin;
pegcjs 1:9cff4feccbce 110 g_lcd.locate(0,1);
pegcjs 1:9cff4feccbce 111 g_lcd.printf("%1.2f: %1.2f: %1.2f",ppo1/(20-count+1),ppo2/(20-count+1),pres/(20-count+1));
pegcjs 1:9cff4feccbce 112 wait(1);
pegcjs 1:9cff4feccbce 113 }
pegcjs 1:9cff4feccbce 114 //average
pegcjs 1:9cff4feccbce 115 ppo1=ppo1/20;
pegcjs 1:9cff4feccbce 116 ppo2=ppo2/20;
pegcjs 1:9cff4feccbce 117 // set calibration variables
pegcjs 1:9cff4feccbce 118 eg1cal=ppo1;
pegcjs 1:9cff4feccbce 119 eg2cal=ppo2;
pegcjs 1:9cff4feccbce 120 pcal=pres/20; // surface pressure....
pegcjs 1:9cff4feccbce 121 scrubtime=0; // reset the scrubber timer to zero.
pegcjs 2:a1c26faa9103 122 // write cal data NB overwites previous
pegcjs 2:a1c26faa9103 123 FILE *fp=fopen("/local/CAL.dat","w");
pegcjs 2:a1c26faa9103 124 fprintf(fp,"%e\n%e\n%e\n%d",eg1cal,eg2cal,pcal,scrubtime);
pegcjs 2:a1c26faa9103 125 fclose(fp); //NB file system locked on write so must make sure we close files in case want to reprogram etc...
pegcjs 1:9cff4feccbce 126 }
pegcjs 1:9cff4feccbce 127
pegcjs 4:74df6d31ee0a 128 // sub to test if a variable is an even number
pegcjs 4:74df6d31ee0a 129 int iseven(int g) {
pegcjs 4:74df6d31ee0a 130 int test=0;
pegcjs 5:35417986539a 131 if (g%2 ==0) test=1;
pegcjs 4:74df6d31ee0a 132 return(test);
pegcjs 4:74df6d31ee0a 133 }
pegcjs 4:74df6d31ee0a 134
pegcjs 1:9cff4feccbce 135
pegcjs 2:a1c26faa9103 136 void status() {
pegcjs 3:0d94a277aa8c 137 if (state==0) {
pegcjs 3:0d94a277aa8c 138 g_lcd.character(9,0,5); // warning icon until 1 min up
pegcjs 3:0d94a277aa8c 139 g_lcd.character(8,0,6); // surface icon
pegcjs 5:35417986539a 140 } else {
pegcjs 5:35417986539a 141 g_lcd.character(9,0,32);
pegcjs 3:0d94a277aa8c 142 }
pegcjs 2:a1c26faa9103 143 if (state==1) g_lcd.character(8,0,6); // surface icon
pegcjs 4:74df6d31ee0a 144 if (state==2 && iseven(seconds)==1) g_lcd.character(8,0,4); // diving icon
pegcjs 4:74df6d31ee0a 145 if (state==2 && iseven(seconds)==0) g_lcd.character(8,0,68); // diving icon
pegcjs 4:74df6d31ee0a 146
pegcjs 4:74df6d31ee0a 147 }
pegcjs 3:0d94a277aa8c 148
pegcjs 3:0d94a277aa8c 149 // warning and LED conditions
pegcjs 2:a1c26faa9103 150
pegcjs 2:a1c26faa9103 151 void warning() {
pegcjs 3:0d94a277aa8c 152 if (depth>=mod && flash==1) g_lcd.character(13,0,5);
pegcjs 2:a1c26faa9103 153
pegcjs 2:a1c26faa9103 154 }
pegcjs 2:a1c26faa9103 155
pegcjs 4:74df6d31ee0a 156 // pick maximum of two values
pegcjs 4:74df6d31ee0a 157 float maximum(float a,float b) {
pegcjs 4:74df6d31ee0a 158 float maximum;
pegcjs 4:74df6d31ee0a 159 if (a>b) maximum=a;
pegcjs 4:74df6d31ee0a 160 else maximum=b;
pegcjs 4:74df6d31ee0a 161 return(maximum);
pegcjs 4:74df6d31ee0a 162 }
pegcjs 4:74df6d31ee0a 163
pegcjs 4:74df6d31ee0a 164 // pick minimum of two values
pegcjs 4:74df6d31ee0a 165 float minimum(float a,float b) {
pegcjs 4:74df6d31ee0a 166 float minim;
pegcjs 4:74df6d31ee0a 167 if (a<b) minim=a;
pegcjs 4:74df6d31ee0a 168 else minim=b;
pegcjs 4:74df6d31ee0a 169 return(minim);
pegcjs 4:74df6d31ee0a 170 }
pegcjs 4:74df6d31ee0a 171
pegcjs 4:74df6d31ee0a 172
pegcjs 4:74df6d31ee0a 173
pegcjs 2:a1c26faa9103 174 void leds() {
pegcjs 4:74df6d31ee0a 175 // first turn everything off
pegcjs 5:35417986539a 176 red=0;
pegcjs 5:35417986539a 177 green=0;
pegcjs 5:35417986539a 178 blue=0;
pegcjs 5:35417986539a 179 float ppo;
pegcjs 5:35417986539a 180 int mo=0;
pegcjs 5:35417986539a 181 mo=MODE;
pegcjs 5:35417986539a 182 ppo=maximum(ppo1,ppo2); // use max value to compute leds...
pegcjs 5:35417986539a 183 if (mo==0) { // CCR mode
pegcjs 5:35417986539a 184 if (ppo<0.2 && flash==1) red=1; // flashing red means very bad things - getting low on oxygen!!!
pegcjs 5:35417986539a 185 if (ppo>0.2 && ppo < 1) red=1; // non-flashing red
pegcjs 5:35417986539a 186 if (ppo>=1.0 && ppo <1.2) {
pegcjs 5:35417986539a 187 red=1; // red-green
pegcjs 5:35417986539a 188 green=1;
pegcjs 5:35417986539a 189 }
pegcjs 5:35417986539a 190 if (ppo<1.3 && ppo >=1.2) green=1; // green - optimal range in ccr mode
pegcjs 5:35417986539a 191 if (ppo<1.4 && ppo >=1.3) {
pegcjs 5:35417986539a 192 green=1; // green-blue - high ppo2 be careful of spiking
pegcjs 5:35417986539a 193 blue=1;
pegcjs 5:35417986539a 194 }
pegcjs 5:35417986539a 195 if (ppo2<1.6 && ppo2>=1.4) blue=1; // DANGE ble high ppo2
pegcjs 5:35417986539a 196 if (ppo2>=1.6 && flash==1) blue=1;
pegcjs 5:35417986539a 197 }
pegcjs 5:35417986539a 198 if (mo==1) { // SCR mode
pegcjs 5:35417986539a 199 if (ppo<0.2 && flash==1) red=1;
pegcjs 5:35417986539a 200 if (depth < 0.8*mod && ppo>0.2) green=1;
pegcjs 5:35417986539a 201 if (depth< mod && depth >=0.8*mod) {
pegcjs 5:35417986539a 202 green=1;
pegcjs 5:35417986539a 203 blue=1;
pegcjs 5:35417986539a 204 }
pegcjs 5:35417986539a 205 if (depth >=mod && flash==1) blue=1;
pegcjs 5:35417986539a 206 }
pegcjs 1:9cff4feccbce 207 }
pegcjs 1:9cff4feccbce 208
pegcjs 4:74df6d31ee0a 209
pegcjs 4:74df6d31ee0a 210
pegcjs 1:9cff4feccbce 211 //read battery state and insert the battery symbol
pegcjs 1:9cff4feccbce 212 void battery() {
pegcjs 1:9cff4feccbce 213 int batsym=0;
pegcjs 1:9cff4feccbce 214 Vb=Vbatt; // read adc connected to battery via a 1/3 potential divider
pegcjs 1:9cff4feccbce 215 if (Vb>0.606) batsym=1;
pegcjs 1:9cff4feccbce 216 if (Vb>0.707) batsym=2;
pegcjs 1:9cff4feccbce 217 if (Vb>0.808) batsym=3;
pegcjs 3:0d94a277aa8c 218 if (batsym >0) g_lcd.character(8,1,batsym);
pegcjs 3:0d94a277aa8c 219 if (batsym ==0 && flash==1) g_lcd.character(8,1,batsym);
pegcjs 3:0d94a277aa8c 220 if (batsym ==0 && flash==0) g_lcd.character(8,1,32);
pegcjs 1:9cff4feccbce 221 }
pegcjs 1:9cff4feccbce 222
pegcjs 2:a1c26faa9103 223 // subroutine to write the main display data
pegcjs 2:a1c26faa9103 224 //0123456789abcdef
pegcjs 2:a1c26faa9103 225
pegcjs 2:a1c26faa9103 226 //x.xx:xx D XX xx
pegcjs 2:a1c26faa9103 227 //x.xx:xx B XX xxx NB the warning, staus and battery icons are driven by separate subroutines.
pegcjs 2:a1c26faa9103 228 void display() {
pegcjs 5:35417986539a 229 int mo=0;
pegcjs 5:35417986539a 230 mo=MODE;
pegcjs 2:a1c26faa9103 231 //1st line
pegcjs 2:a1c26faa9103 232 g_lcd.locate(0,0);
pegcjs 5:35417986539a 233 g_lcd.printf("%1.2f:%.2d",ppo1,(int)fo1);
pegcjs 5:35417986539a 234 g_lcd.locate(10,0);
pegcjs 5:35417986539a 235 g_lcd.printf("%.2d %.2d",(int)depth,(int)mod);
pegcjs 2:a1c26faa9103 236 //2nd line
pegcjs 2:a1c26faa9103 237 g_lcd.locate(0,1);
pegcjs 5:35417986539a 238 g_lcd.printf("%1.2f:%.2d",ppo2,(int)fo2);
pegcjs 5:35417986539a 239 g_lcd.locate(10,1);
pegcjs 5:35417986539a 240 g_lcd.printf("%.2d %.3d",divetime % 100 ,scrubtime % 1000); // modulo to avoid digits conflict - means divetime is always less than 100
pegcjs 2:a1c26faa9103 241 // bung in battery icon
pegcjs 2:a1c26faa9103 242 battery();
pegcjs 5:35417986539a 243 status(); // this will set the diving / suface mode icon
pegcjs 2:a1c26faa9103 244 warning(); // this will set the warning icon assuming that max ppo2 is exceeded
pegcjs 2:a1c26faa9103 245
pegcjs 2:a1c26faa9103 246 leds(); // this sets the leds according to the various warning conditions
pegcjs 5:35417986539a 247 if (mo==0) {
pegcjs 5:35417986539a 248 g_lcd.character(7,1,99); //'c' = ccr
pegcjs 5:35417986539a 249 } else {
pegcjs 5:35417986539a 250 g_lcd.character(7,1,115); //'s' = scr
pegcjs 5:35417986539a 251 }
pegcjs 5:35417986539a 252 // custom character setting to sort out dp in depths
pegcjs 5:35417986539a 253
pegcjs 5:35417986539a 254
pegcjs 5:35417986539a 255 char cgchar[80]={
pegcjs 5:35417986539a 256 7,5,5,5,23,0,0,0, // .0
pegcjs 5:35417986539a 257 2,2,2,2,18,0,0,0, // .1
pegcjs 5:35417986539a 258 7,1,7,4,23,0,0,0, // 0.2
pegcjs 5:35417986539a 259 7,1,3,1,23,0,0,0, // 0.3
pegcjs 5:35417986539a 260 5,5,7,1,17,0,0,0, //0.4
pegcjs 5:35417986539a 261 7,4,7,1,23,0,0,0, //0.5
pegcjs 5:35417986539a 262 7,4,7,5,23,0,0,0, //0.6
pegcjs 5:35417986539a 263 7,1,2,2,18,0,0,0, //.7
pegcjs 5:35417986539a 264 7,5,7,5,23,0,0,0, //.8
pegcjs 5:35417986539a 265 7,5,7,1,17,0,0,0 //.9
pegcjs 5:35417986539a 266
pegcjs 5:35417986539a 267 };
pegcjs 5:35417986539a 268
pegcjs 5:35417986539a 269 int i=0,d=0;
pegcjs 5:35417986539a 270 d=(int)((depth-(int)depth)*10); // should be size of the 1st decimal place
pegcjs 5:35417986539a 271 // do stuff here to set cstom chars
pegcjs 5:35417986539a 272 g_lcd.writeCommand(120); // set start address for CGRAM
pegcjs 5:35417986539a 273 for (i=0; i<8; i++) {
pegcjs 5:35417986539a 274 g_lcd.writeData(cgchar[i+d*8]);
pegcjs 5:35417986539a 275 }
pegcjs 5:35417986539a 276
pegcjs 5:35417986539a 277 g_lcd.character(12,0,7); // put in appropriate custom character
pegcjs 2:a1c26faa9103 278
pegcjs 2:a1c26faa9103 279 }
pegcjs 2:a1c26faa9103 280
pegcjs 2:a1c26faa9103 281
pegcjs 2:a1c26faa9103 282
pegcjs 1:9cff4feccbce 283
pegcjs 2:a1c26faa9103 284
pegcjs 2:a1c26faa9103 285 // read sensors and generate calibrated outputs NB battery is read elsewhere
pegcjs 1:9cff4feccbce 286 void readsensors() {
pegcjs 1:9cff4feccbce 287 float barometric=0,mod1,mod2;
pegcjs 1:9cff4feccbce 288 ppo1=EG1*0.21/eg1cal; // eg1cal is 0.21bar ppO2
pegcjs 1:9cff4feccbce 289 ppo2=EG2*0.21/eg2cal; // second oxygen cell ppO2
pegcjs 5:35417986539a 290 // NB this assumes that the calibration is done at exactly 1 bar.... - not always the case but ok for sea level diving
pegcjs 2:a1c26faa9103 291 pressure=(PRESin*3.3-0.024)/(0.0038574); // pressure in kPa assuming standard cal for mpx5700 sensor SUSPECT
pegcjs 5:35417986539a 292 barometric=(pcal*3.3-0.024)/(0.0038574); // sealevel in kPa assuming standard cal for mpx5700 sensor
pegcjs 5:35417986539a 293
pegcjs 5:35417986539a 294 depth=(pressure-barometric)*0.1; //100kPa=10m 1kPa=0.1m - this gives depth in m for freshwater.
pegcjs 5:35417986539a 295 if(depth<0) depth=0;
pegcjs 2:a1c26faa9103 296
pegcjs 5:35417986539a 297 fo1=100*ppo1/((pressure-barometric)/100+1); // pressure in bar = pressure /100 and want a % so multiply by 100 as well
pegcjs 5:35417986539a 298 fo2=100*ppo2/((pressure-barometric)/100+1);
pegcjs 5:35417986539a 299
pegcjs 5:35417986539a 300 if(fo1<0) fo2=0;
pegcjs 5:35417986539a 301 if(fo2<0) fo1=0;
pegcjs 3:0d94a277aa8c 302
pegcjs 5:35417986539a 303 //with two sensors will calculate mod from the largest ppo2 reading
pegcjs 2:a1c26faa9103 304 mod1=(1.4/(fo1/100)-1)*10;
pegcjs 2:a1c26faa9103 305 mod2=(1.4/(fo2/100)-1)*10;
pegcjs 3:0d94a277aa8c 306
pegcjs 2:a1c26faa9103 307 mod=minimum(mod1,mod2); // pick the least value
pegcjs 3:0d94a277aa8c 308
pegcjs 1:9cff4feccbce 309 }
pegcjs 4:74df6d31ee0a 310
pegcjs 1:9cff4feccbce 311
pegcjs 1:9cff4feccbce 312 int main() {
pegcjs 2:a1c26faa9103 313 // first some local variables
pegcjs 2:a1c26faa9103 314 int startuptime=getseconds();
pegcjs 4:74df6d31ee0a 315 int startdive=0,endclock=0; // value of seconds when dive starts and counter to decide if dive complete...
pegcjs 1:9cff4feccbce 316
pegcjs 4:74df6d31ee0a 317 int minutes=0,dt=0;; // minutes is elapsed minutes since start of prog
pegcjs 1:9cff4feccbce 318 int i=0,j=0; // general loop counting variables
pegcjs 1:9cff4feccbce 319
pegcjs 1:9cff4feccbce 320
pegcjs 1:9cff4feccbce 321 set_custom_char(); // does what it says on the tin really
pegcjs 1:9cff4feccbce 322 g_lcd.cls();
pegcjs 1:9cff4feccbce 323 g_lcd.locate(0, 0);
pegcjs 1:9cff4feccbce 324 g_lcd.printf( "RebMon");
pegcjs 1:9cff4feccbce 325 g_lcd.locate(0,1);
pegcjs 1:9cff4feccbce 326 g_lcd.printf("CAL?");
pegcjs 1:9cff4feccbce 327 battery();
pegcjs 4:74df6d31ee0a 328 j=0;
pegcjs 1:9cff4feccbce 329 // hang about waiting for the cal switch to be pressed in ccase it is
pegcjs 1:9cff4feccbce 330 while (seconds-startuptime<20) {
pegcjs 1:9cff4feccbce 331 seconds=getseconds();
pegcjs 1:9cff4feccbce 332 g_lcd.locate(5,1);
pegcjs 1:9cff4feccbce 333 g_lcd.printf("%.2d",21-(seconds-startuptime));
pegcjs 4:74df6d31ee0a 334 if (j>1) flash=1;
pegcjs 3:0d94a277aa8c 335 else flash=0;
pegcjs 1:9cff4feccbce 336 battery(); // bung in battery symbol.
pegcjs 1:9cff4feccbce 337 g_lcd.locate(7,0);
pegcjs 1:9cff4feccbce 338 g_lcd.printf( "%.2d:%.2d:%.2d", hours,min,sec);
pegcjs 1:9cff4feccbce 339 if (CAL==0) {
pegcjs 1:9cff4feccbce 340 calibrate();
pegcjs 1:9cff4feccbce 341
pegcjs 1:9cff4feccbce 342 }
pegcjs 3:0d94a277aa8c 343 wait(0.2);
pegcjs 3:0d94a277aa8c 344 j=(j+1) % 4;
pegcjs 1:9cff4feccbce 345 }
pegcjs 1:9cff4feccbce 346 g_lcd.cls();
pegcjs 5:35417986539a 347
pegcjs 1:9cff4feccbce 348
pegcjs 1:9cff4feccbce 349 // ok there are three states in this system
pegcjs 1:9cff4feccbce 350 //MAIN LOOP ONCE STARTUP PROTOCOLS ARE COMPLETED
pegcjs 3:0d94a277aa8c 351 j=0;
pegcjs 1:9cff4feccbce 352 while (1) {
pegcjs 2:a1c26faa9103 353 wait(0.2); //stop screen flicker
pegcjs 1:9cff4feccbce 354 readsensors();
pegcjs 2:a1c26faa9103 355 seconds=getseconds();
pegcjs 4:74df6d31ee0a 356 minutes=(int)(((float)seconds-(float)startuptime)/60);
pegcjs 3:0d94a277aa8c 357 dt=seconds-startuptime; // elapsed seconds
pegcjs 3:0d94a277aa8c 358
pegcjs 3:0d94a277aa8c 359 if (j>1) flash=1;
pegcjs 3:0d94a277aa8c 360 else flash=0;
pegcjs 3:0d94a277aa8c 361
pegcjs 3:0d94a277aa8c 362 display(); // write the display
pegcjs 3:0d94a277aa8c 363
pegcjs 3:0d94a277aa8c 364 // setup state variable
pegcjs 3:0d94a277aa8c 365 if (minutes<1) state=0; // startup mode - do nothing just wait to allow sensor readings to settle.
pegcjs 4:74df6d31ee0a 366 if (minutes>=1 && state==0) state=1; // surface mode - ok to go for a dive now
pegcjs 4:74df6d31ee0a 367 if (minutes>=1 && depth>0.5 && state==1) {
pegcjs 3:0d94a277aa8c 368 state=2; // enter dive mode
pegcjs 4:74df6d31ee0a 369 if (startdive==0) startdive=seconds; // set start of divetime. don't do this twice
pegcjs 3:0d94a277aa8c 370 endclock=0; // reset end of dive clock
pegcjs 3:0d94a277aa8c 371 }
pegcjs 3:0d94a277aa8c 372 if (state==2) {
pegcjs 4:74df6d31ee0a 373 divetime=(int)(((float)seconds-(float)startdive)/60); // time since start of dive in minutes.
pegcjs 3:0d94a277aa8c 374 // do deco calcs here when implemented
pegcjs 3:0d94a277aa8c 375 if (depth<0.3) {
pegcjs 4:74df6d31ee0a 376 endclock=endclock+1;
pegcjs 4:74df6d31ee0a 377
pegcjs 4:74df6d31ee0a 378 if (endclock>150) state=1; // 30s at shallower than 0.3m and we return to surface mode.
pegcjs 3:0d94a277aa8c 379 }
pegcjs 4:74df6d31ee0a 380 scrubtime=minutes; // need to add memory of prior scrub time to this once variable input fom log file is implements
pegcjs 3:0d94a277aa8c 381 }
pegcjs 1:9cff4feccbce 382
pegcjs 1:9cff4feccbce 383
pegcjs 3:0d94a277aa8c 384 j=(j+1) %4; // flash control variable = used to make the warnings flash for 0.4s duty cycle
pegcjs 1:9cff4feccbce 385 } // end while
pegcjs 1:9cff4feccbce 386 } //end main
pegcjs 1:9cff4feccbce 387
pegcjs 1:9cff4feccbce 388
pegcjs 1:9cff4feccbce 389
pegcjs 1:9cff4feccbce 390