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
Rebmon_main.cpp@5:35417986539a, 2012-08-07 (annotated)
- 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?
User | Revision | Line number | New 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 |