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@7:f93b7eaab5f6, 2013-01-14 (annotated)
- Committer:
- pegcjs
- Date:
- Mon Jan 14 12:52:45 2013 +0000
- Revision:
- 7:f93b7eaab5f6
- Parent:
- 6:ab2d7d0a9b07
- Child:
- 8:f45e654b47d0
Fixed bug in setswitch prevennting switch back to lowsetpoint on ascent; added hud flashes 4 flashes = going to high sp , 2 flashes = going to low sp.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
pegcjs | 1:9cff4feccbce | 1 | //lpc1124lcddemo |
pegcjs | 7:f93b7eaab5f6 | 2 | // driver for mbed based ppo2 monitoring system for closed circuit rebreather |
pegcjs | 7:f93b7eaab5f6 | 3 | // reading 3 electrogalvanic oxygen sensors and one pressure sensor |
pegcjs | 1:9cff4feccbce | 4 | #include "ds1307.h" |
pegcjs | 1:9cff4feccbce | 5 | #include "mbed.h" |
pegcjs | 5:35417986539a | 6 | #include "TextOLED.h" |
pegcjs | 1:9cff4feccbce | 7 | |
pegcjs | 7:f93b7eaab5f6 | 8 | //TODO - MAKE A VERSION THAT DRIVES THE HUD, CHECKS THE 5V SUPPLY AND COMPENSATES THE READINGS IF ITS VARYING (LINEARLY) |
pegcjs | 7:f93b7eaab5f6 | 9 | // AND PREVENT A HANG IF THE DS1307 FAILS TO RESPOND. |
pegcjs | 1:9cff4feccbce | 10 | |
pegcjs | 7:f93b7eaab5f6 | 11 | #define DRATIO 0.6420066 // ratio of voltage at pin20 to voltage actually generated by the sensor |
pegcjs | 7:f93b7eaab5f6 | 12 | |
pegcjs | 7:f93b7eaab5f6 | 13 | //hud LINES |
pegcjs | 7:f93b7eaab5f6 | 14 | DigitalOut AB(p7); //pins AB for data bits |
pegcjs | 7:f93b7eaab5f6 | 15 | DigitalOut CP(p5); // clock to shift reg |
pegcjs | 7:f93b7eaab5f6 | 16 | //DigitalOut MR(p8); // reset to shift reg (low for clear)# |
pegcjs | 7:f93b7eaab5f6 | 17 | DigitalOut btest(p6); // pin to drive lastblue led |
pegcjs | 7:f93b7eaab5f6 | 18 | |
pegcjs | 7:f93b7eaab5f6 | 19 | // offsets for lm324 amp in terms of reading values on adc |
pegcjs | 7:f93b7eaab5f6 | 20 | #define coff1 -0.013375 |
pegcjs | 7:f93b7eaab5f6 | 21 | #define coff2 -0.00936 |
pegcjs | 7:f93b7eaab5f6 | 22 | #define coff3 -0.0212136 |
pegcjs | 7:f93b7eaab5f6 | 23 | |
pegcjs | 7:f93b7eaab5f6 | 24 | |
pegcjs | 7:f93b7eaab5f6 | 25 | |
pegcjs | 7:f93b7eaab5f6 | 26 | Serial pc(USBTX, USBRX); // tx, rx for debug and usb pc comunications |
pegcjs | 7:f93b7eaab5f6 | 27 | |
pegcjs | 1:9cff4feccbce | 28 | |
pegcjs | 1:9cff4feccbce | 29 | //pin assignments and declarations |
pegcjs | 1:9cff4feccbce | 30 | // LCD display |
pegcjs | 1:9cff4feccbce | 31 | TextLCD g_lcd(p26, p25, p24, p23, p22, p21); // RS, E, DB4, DB5, DB6, DB7 |
pegcjs | 1:9cff4feccbce | 32 | //backlight |
pegcjs | 1:9cff4feccbce | 33 | DigitalOut backlight(p29); |
pegcjs | 1:9cff4feccbce | 34 | |
pegcjs | 1:9cff4feccbce | 35 | //onboard leds |
pegcjs | 1:9cff4feccbce | 36 | DigitalOut led1(LED1); |
pegcjs | 1:9cff4feccbce | 37 | DigitalOut led2(LED2); |
pegcjs | 1:9cff4feccbce | 38 | |
pegcjs | 1:9cff4feccbce | 39 | // warning leds |
pegcjs | 1:9cff4feccbce | 40 | DigitalOut red(p34); |
pegcjs | 1:9cff4feccbce | 41 | DigitalOut green(p33); |
pegcjs | 1:9cff4feccbce | 42 | DigitalOut blue(p30); |
pegcjs | 1:9cff4feccbce | 43 | |
pegcjs | 6:ab2d7d0a9b07 | 44 | |
pegcjs | 1:9cff4feccbce | 45 | // switches and buttons - these are pulled up by resistors so are active low |
pegcjs | 1:9cff4feccbce | 46 | DigitalIn CAL(p36); |
pegcjs | 5:35417986539a | 47 | DigitalIn SW1(p35); // reed switch in display unit |
pegcjs | 7:f93b7eaab5f6 | 48 | DigitalIn SW2(p10); // reed switch in dispaly unit - NONE FUNCIONAL IN CURRENT HEAD - SWITCH FAILED DURING POTTING |
pegcjs | 7:f93b7eaab5f6 | 49 | //DigitalIn MODE(p11);// a switchn on the mbed pcb to select between SCR and CCR modes for the LEDs NOT USED ANYMORE |
pegcjs | 1:9cff4feccbce | 50 | |
pegcjs | 1:9cff4feccbce | 51 | // log data storage |
pegcjs | 1:9cff4feccbce | 52 | LocalFileSystem local("local"); |
pegcjs | 1:9cff4feccbce | 53 | |
pegcjs | 1:9cff4feccbce | 54 | // adc inputs for sensors |
pegcjs | 1:9cff4feccbce | 55 | AnalogIn PRESin(p20); |
pegcjs | 1:9cff4feccbce | 56 | AnalogIn EG1(p19); |
pegcjs | 1:9cff4feccbce | 57 | AnalogIn EG2(p18); |
pegcjs | 7:f93b7eaab5f6 | 58 | AnalogIn EG3(p16); |
pegcjs | 7:f93b7eaab5f6 | 59 | AnalogIn Vbatt(p17); // battery voltage divided down by 3 |
pegcjs | 7:f93b7eaab5f6 | 60 | AnalogIn V5V(p15); // sense the '5V' output from the max1724 unit - divided down by 2. Nominally 2.5V===0.757575757' in 3.3V ADC |
pegcjs | 7:f93b7eaab5f6 | 61 | |
pegcjs | 7:f93b7eaab5f6 | 62 | |
pegcjs | 1:9cff4feccbce | 63 | |
pegcjs | 1:9cff4feccbce | 64 | // realtime clock |
pegcjs | 1:9cff4feccbce | 65 | DS1307 my1307(p28,p27); // start DS1307 class and give it pins for connections of the DS1307 device |
pegcjs | 1:9cff4feccbce | 66 | |
pegcjs | 1:9cff4feccbce | 67 | // variables for realtime clock |
pegcjs | 1:9cff4feccbce | 68 | int sec = 0; |
pegcjs | 1:9cff4feccbce | 69 | int min = 0; |
pegcjs | 1:9cff4feccbce | 70 | int hours = 0; |
pegcjs | 1:9cff4feccbce | 71 | int day = 0; |
pegcjs | 1:9cff4feccbce | 72 | int date = 0; |
pegcjs | 1:9cff4feccbce | 73 | int month = 0; |
pegcjs | 1:9cff4feccbce | 74 | int year = 0; |
pegcjs | 4:74df6d31ee0a | 75 | int seconds=0; // general number of seconds since 2000 etc timestamp variable |
pegcjs | 1:9cff4feccbce | 76 | |
pegcjs | 7:f93b7eaab5f6 | 77 | int scrubtime=0,scrubold=0; // these are expressed in minutes |
pegcjs | 1:9cff4feccbce | 78 | int divetime=0; |
pegcjs | 1:9cff4feccbce | 79 | |
pegcjs | 3:0d94a277aa8c | 80 | int flash=0; // variable used top control flashing icons |
pegcjs | 2:a1c26faa9103 | 81 | int state=0; // IMPORTANT - VARIABLE THAT DRIVES HNTE STATE MACHINE STATE=0 = STARTUP, STATE=1=SURFACE STATE=2= DIVING |
pegcjs | 7:f93b7eaab5f6 | 82 | float lowsetpoint=0.7,highsetpoint=1.2,switchdepth=10; // variables to determine HUD led states |
pegcjs | 7:f93b7eaab5f6 | 83 | //switchdepth is centre of switch region 1m deep if switchdepth=10 then will go to high as descebnd |
pegcjs | 7:f93b7eaab5f6 | 84 | //through 10.5 and go back to low when ascending through 9.5 |
pegcjs | 7:f93b7eaab5f6 | 85 | int setpoint=0; // 0=low 1 = high |
pegcjs | 2:a1c26faa9103 | 86 | |
pegcjs | 1:9cff4feccbce | 87 | // variables for the eg cells and pressure sensor eg1calamd eg2cal ar reading when the sensor is in 0.21bar O2 and |
pegcjs | 1:9cff4feccbce | 88 | //dcal is the reading whe the pressure sensor is at the surface |
pegcjs | 7:f93b7eaab5f6 | 89 | float eg1cal=0.09,eg2cal=0.09,eg3cal=0.09,pcal=0.1136; |
pegcjs | 1:9cff4feccbce | 90 | // NB these are updated from /local/cal.dat so values not so important.... eventually |
pegcjs | 1:9cff4feccbce | 91 | |
pegcjs | 7:f93b7eaab5f6 | 92 | float depth=0,ppo1=0,ppo2=0,ppo3=0 ,Vb=0,pressure=0; // depth, 1st o2 sensor second o2 sensor battery voltage,,Pressure |
pegcjs | 7:f93b7eaab5f6 | 93 | float fo1=0,fo2=0,fo3=0,mod=55; //%f values,mod |
pegcjs | 3:0d94a277aa8c | 94 | |
pegcjs | 6:ab2d7d0a9b07 | 95 | FILE *lp; // file pointer for log file |
pegcjs | 6:ab2d7d0a9b07 | 96 | |
pegcjs | 7:f93b7eaab5f6 | 97 | bool nostop=1, deco=0; // variables to define state for deco |
pegcjs | 7:f93b7eaab5f6 | 98 | |
pegcjs | 7:f93b7eaab5f6 | 99 | |
pegcjs | 7:f93b7eaab5f6 | 100 | |
pegcjs | 7:f93b7eaab5f6 | 101 | //HUD codes |
pegcjs | 7:f93b7eaab5f6 | 102 | // make a HUD clock pulse |
pegcjs | 7:f93b7eaab5f6 | 103 | int clk() |
pegcjs | 7:f93b7eaab5f6 | 104 | { |
pegcjs | 7:f93b7eaab5f6 | 105 | wait_us(1); |
pegcjs | 7:f93b7eaab5f6 | 106 | CP=0; |
pegcjs | 7:f93b7eaab5f6 | 107 | wait_us(1); |
pegcjs | 7:f93b7eaab5f6 | 108 | CP=1; |
pegcjs | 7:f93b7eaab5f6 | 109 | return(0); |
pegcjs | 7:f93b7eaab5f6 | 110 | } |
pegcjs | 7:f93b7eaab5f6 | 111 | |
pegcjs | 7:f93b7eaab5f6 | 112 | // write 8 bits to the HUD shift register |
pegcjs | 7:f93b7eaab5f6 | 113 | int HUD_write(char d) |
pegcjs | 7:f93b7eaab5f6 | 114 | { |
pegcjs | 7:f93b7eaab5f6 | 115 | int i=0; |
pegcjs | 7:f93b7eaab5f6 | 116 | for(i=7; i>=0; i--) { |
pegcjs | 7:f93b7eaab5f6 | 117 | AB=d & (1 << i); |
pegcjs | 7:f93b7eaab5f6 | 118 | AB=!AB; |
pegcjs | 7:f93b7eaab5f6 | 119 | clk(); |
pegcjs | 7:f93b7eaab5f6 | 120 | } |
pegcjs | 7:f93b7eaab5f6 | 121 | return(0); |
pegcjs | 7:f93b7eaab5f6 | 122 | } |
pegcjs | 7:f93b7eaab5f6 | 123 | |
pegcjs | 7:f93b7eaab5f6 | 124 | // make all HUD leds white - useful for warnings etc |
pegcjs | 7:f93b7eaab5f6 | 125 | int HUD_white() |
pegcjs | 7:f93b7eaab5f6 | 126 | { |
pegcjs | 7:f93b7eaab5f6 | 127 | // set all white; |
pegcjs | 7:f93b7eaab5f6 | 128 | HUD_write(255); |
pegcjs | 7:f93b7eaab5f6 | 129 | btest=0; |
pegcjs | 7:f93b7eaab5f6 | 130 | |
pegcjs | 7:f93b7eaab5f6 | 131 | return(0); |
pegcjs | 7:f93b7eaab5f6 | 132 | } |
pegcjs | 7:f93b7eaab5f6 | 133 | // clear the HUD - make al black |
pegcjs | 7:f93b7eaab5f6 | 134 | int HUD_clr() |
pegcjs | 7:f93b7eaab5f6 | 135 | { |
pegcjs | 7:f93b7eaab5f6 | 136 | HUD_write(0); |
pegcjs | 7:f93b7eaab5f6 | 137 | btest=1; |
pegcjs | 7:f93b7eaab5f6 | 138 | return(0); |
pegcjs | 7:f93b7eaab5f6 | 139 | } |
pegcjs | 7:f93b7eaab5f6 | 140 | |
pegcjs | 7:f93b7eaab5f6 | 141 | |
pegcjs | 7:f93b7eaab5f6 | 142 | |
pegcjs | 7:f93b7eaab5f6 | 143 | // code to detect leap years |
pegcjs | 7:f93b7eaab5f6 | 144 | int LeapYear(int year) { |
pegcjs | 7:f93b7eaab5f6 | 145 | int leap=0; |
pegcjs | 7:f93b7eaab5f6 | 146 | |
pegcjs | 7:f93b7eaab5f6 | 147 | if (year % 400==0) leap=1; |
pegcjs | 7:f93b7eaab5f6 | 148 | else if (year %100 ==0) leap=0; |
pegcjs | 7:f93b7eaab5f6 | 149 | else if (year % 4 ==0) leap=1; |
pegcjs | 7:f93b7eaab5f6 | 150 | else leap=0; |
pegcjs | 7:f93b7eaab5f6 | 151 | return(leap); |
pegcjs | 7:f93b7eaab5f6 | 152 | } |
pegcjs | 7:f93b7eaab5f6 | 153 | |
pegcjs | 7:f93b7eaab5f6 | 154 | |
pegcjs | 1:9cff4feccbce | 155 | //===== sub to get time from ds1307 and create the 'seconds' which is a version of timestamp.... |
pegcjs | 1:9cff4feccbce | 156 | int getseconds() { |
pegcjs | 7:f93b7eaab5f6 | 157 | int leap=0,dayofyear=0,timestamp=0; |
pegcjs | 7:f93b7eaab5f6 | 158 | int y=0,byear=0; |
pegcjs | 7:f93b7eaab5f6 | 159 | int days[12]={0,31,59,90,120,151,181,212,243,273,304,334}; |
pegcjs | 1:9cff4feccbce | 160 | my1307.gettime( &sec, &min, &hours, &day, &date, &month, &year); |
pegcjs | 1:9cff4feccbce | 161 | //simple timestamp = # seconds since midnight jan 1st 2000 if all months were 30 days. |
pegcjs | 7:f93b7eaab5f6 | 162 | //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 | 163 | //simple timestamp = # seconds since midnight jan 1st 2000 if all months were 30 days.... |
pegcjs | 1:9cff4feccbce | 164 | // ie wrong but simpler than the real thing |
pegcjs | 7:f93b7eaab5f6 | 165 | |
pegcjs | 7:f93b7eaab5f6 | 166 | |
pegcjs | 7:f93b7eaab5f6 | 167 | // sort out ds1307 definiteion of year |
pegcjs | 7:f93b7eaab5f6 | 168 | year=year+2000; |
pegcjs | 7:f93b7eaab5f6 | 169 | leap=LeapYear(year); |
pegcjs | 7:f93b7eaab5f6 | 170 | |
pegcjs | 7:f93b7eaab5f6 | 171 | // now decide dayofyear |
pegcjs | 7:f93b7eaab5f6 | 172 | dayofyear=days[month-1]+date-1; |
pegcjs | 7:f93b7eaab5f6 | 173 | if (leap==1 && month >2) dayofyear++; // deal with extra february day in leap year |
pegcjs | 7:f93b7eaab5f6 | 174 | |
pegcjs | 7:f93b7eaab5f6 | 175 | // now find number of days since 1970 |
pegcjs | 7:f93b7eaab5f6 | 176 | for (y=1970; y<year; y++) { |
pegcjs | 7:f93b7eaab5f6 | 177 | if (LeapYear(y) == 1) { |
pegcjs | 7:f93b7eaab5f6 | 178 | byear += 366*24*60*60; |
pegcjs | 7:f93b7eaab5f6 | 179 | } else { |
pegcjs | 7:f93b7eaab5f6 | 180 | byear += 365*24*60*60; |
pegcjs | 7:f93b7eaab5f6 | 181 | } |
pegcjs | 7:f93b7eaab5f6 | 182 | } |
pegcjs | 7:f93b7eaab5f6 | 183 | |
pegcjs | 7:f93b7eaab5f6 | 184 | // finally get the seconds right and construct timestamp in seconds since beginning of 1970 |
pegcjs | 7:f93b7eaab5f6 | 185 | timestamp=(byear)+dayofyear*24*3600+hours*3600+min*60+sec; |
pegcjs | 7:f93b7eaab5f6 | 186 | |
pegcjs | 7:f93b7eaab5f6 | 187 | //DEBUG==================================== |
pegcjs | 7:f93b7eaab5f6 | 188 | // printf("secondst = %d\t timestamp = %d\t%.2d : %.2d : %d - %.2d:%.2d:%.2d\r",secondst,timestamp,date,month,year,hours,min,sec); |
pegcjs | 7:f93b7eaab5f6 | 189 | |
pegcjs | 7:f93b7eaab5f6 | 190 | return(timestamp); |
pegcjs | 7:f93b7eaab5f6 | 191 | |
pegcjs | 1:9cff4feccbce | 192 | } |
pegcjs | 1:9cff4feccbce | 193 | |
pegcjs | 1:9cff4feccbce | 194 | |
pegcjs | 1:9cff4feccbce | 195 | void set_custom_char() { |
pegcjs | 1:9cff4feccbce | 196 | char cgchar[64]={ |
pegcjs | 7:f93b7eaab5f6 | 197 | 6,9,9,9,9,9,9,15, // battery symbol 0 address 64 = 0x40 |
pegcjs | 7:f93b7eaab5f6 | 198 | 28,20,20,20,20,20,29,0, // 0. symbol for ppo2 1 address 72 = 0x48 |
pegcjs | 7:f93b7eaab5f6 | 199 | 8,24,8,8,8,8,29,0, // 1. symbol for ppo2 2 address 80 =0x50 |
pegcjs | 7:f93b7eaab5f6 | 200 | 6,15,15,15,15,15,15,15, // unused 3 address 88 = 0x58 |
pegcjs | 7:f93b7eaab5f6 | 201 | 31,19,21,21,21,21,19,31, // unused 4 address 96 = 0x60 |
pegcjs | 7:f93b7eaab5f6 | 202 | 6,6,6,6,6,0,0,6, // top char Vmessg 5 address 104 =0x68 - used for Vmessage |
pegcjs | 7:f93b7eaab5f6 | 203 | 31,17,23,17,29,17,31,0, // bottom char Vmessg 6 address 112 =0x70 -used for Vmessg |
pegcjs | 7:f93b7eaab5f6 | 204 | 2,6,2,2,2,2,23 // for dec point in depth 7 address 120 =0x78 |
pegcjs | 1:9cff4feccbce | 205 | }; |
pegcjs | 1:9cff4feccbce | 206 | int i=0; |
pegcjs | 1:9cff4feccbce | 207 | // do stuff here to set cstom chars |
pegcjs | 1:9cff4feccbce | 208 | g_lcd.writeCommand(0x40); // set start address for CGRAM |
pegcjs | 1:9cff4feccbce | 209 | for (i=0; i<64; i++) { |
pegcjs | 1:9cff4feccbce | 210 | g_lcd.writeData(cgchar[i]); |
pegcjs | 1:9cff4feccbce | 211 | } |
pegcjs | 1:9cff4feccbce | 212 | |
pegcjs | 1:9cff4feccbce | 213 | } |
pegcjs | 1:9cff4feccbce | 214 | |
pegcjs | 6:ab2d7d0a9b07 | 215 | // stash cal values on local drive |
pegcjs | 6:ab2d7d0a9b07 | 216 | void store() { |
pegcjs | 7:f93b7eaab5f6 | 217 | int timestamp=0; |
pegcjs | 7:f93b7eaab5f6 | 218 | timestamp=getseconds(); |
pegcjs | 7:f93b7eaab5f6 | 219 | wait(0.1); |
pegcjs | 6:ab2d7d0a9b07 | 220 | FILE *fp=fopen("/local/CAL.dat","w"); |
pegcjs | 7:f93b7eaab5f6 | 221 | fprintf(fp,"%e\n%e\n%e\n%e\n%d\n%d\n",eg1cal,eg2cal,eg3cal,pcal,scrubtime,timestamp); |
pegcjs | 7:f93b7eaab5f6 | 222 | |
pegcjs | 6:ab2d7d0a9b07 | 223 | fclose(fp); //NB file system locked on write so must make sure we close files in case want to reprogram etc... |
pegcjs | 7:f93b7eaab5f6 | 224 | wait(0.1); |
pegcjs | 6:ab2d7d0a9b07 | 225 | } |
pegcjs | 6:ab2d7d0a9b07 | 226 | |
pegcjs | 1:9cff4feccbce | 227 | |
pegcjs | 1:9cff4feccbce | 228 | // subroutine to calibreate o2 sesnors and store ca data in /local/CAL.dat |
pegcjs | 1:9cff4feccbce | 229 | void calibrate() { |
pegcjs | 1:9cff4feccbce | 230 | int count=1; |
pegcjs | 7:f93b7eaab5f6 | 231 | float s1=0,s2=0,s3=0,pres=0; |
pegcjs | 1:9cff4feccbce | 232 | // average 20 readings for noise reduction |
pegcjs | 1:9cff4feccbce | 233 | g_lcd.cls(); |
pegcjs | 1:9cff4feccbce | 234 | for (count=20; count>0; count--) { |
pegcjs | 1:9cff4feccbce | 235 | g_lcd.locate(0,0); |
pegcjs | 4:74df6d31ee0a | 236 | g_lcd.printf("Calibrate 21%% %.2d",count); |
pegcjs | 7:f93b7eaab5f6 | 237 | s1=s1+EG1; |
pegcjs | 7:f93b7eaab5f6 | 238 | s2=s2+EG2; |
pegcjs | 7:f93b7eaab5f6 | 239 | s3=s3+EG3; |
pegcjs | 1:9cff4feccbce | 240 | pres=pres+PRESin; |
pegcjs | 1:9cff4feccbce | 241 | g_lcd.locate(0,1); |
pegcjs | 7:f93b7eaab5f6 | 242 | g_lcd.printf("%1.2f: %1.2f: %1.2f",s1/(20-count+1),s2/(20-count+1),s3/(20-count+1)); |
pegcjs | 1:9cff4feccbce | 243 | wait(1); |
pegcjs | 1:9cff4feccbce | 244 | } |
pegcjs | 1:9cff4feccbce | 245 | //average |
pegcjs | 7:f93b7eaab5f6 | 246 | s1=s1/20-coff1; |
pegcjs | 7:f93b7eaab5f6 | 247 | s2=s2/20-coff2; |
pegcjs | 7:f93b7eaab5f6 | 248 | s3=s3/20-coff3; |
pegcjs | 1:9cff4feccbce | 249 | // set calibration variables |
pegcjs | 7:f93b7eaab5f6 | 250 | eg1cal=s1; |
pegcjs | 7:f93b7eaab5f6 | 251 | eg2cal=s2; |
pegcjs | 7:f93b7eaab5f6 | 252 | eg3cal=s3; |
pegcjs | 7:f93b7eaab5f6 | 253 | pcal=pres/20/DRATIO; // surface pressure output voltage from sensor |
pegcjs | 1:9cff4feccbce | 254 | scrubtime=0; // reset the scrubber timer to zero. |
pegcjs | 7:f93b7eaab5f6 | 255 | scrubold=0; // set stored scrub time to zero too. |
pegcjs | 2:a1c26faa9103 | 256 | // write cal data NB overwites previous |
pegcjs | 6:ab2d7d0a9b07 | 257 | /* FILE *fp=fopen("/local/CAL.dat","w"); |
pegcjs | 6:ab2d7d0a9b07 | 258 | fprintf(fp,"%e\n%e\n%e\n%d",eg1cal,eg2cal,pcal,scrubtime); |
pegcjs | 6:ab2d7d0a9b07 | 259 | fclose(fp); //NB file system locked on write so must make sure we close files in case want to reprogram etc...*/ |
pegcjs | 6:ab2d7d0a9b07 | 260 | store(); |
pegcjs | 1:9cff4feccbce | 261 | } |
pegcjs | 1:9cff4feccbce | 262 | |
pegcjs | 4:74df6d31ee0a | 263 | // sub to test if a variable is an even number |
pegcjs | 4:74df6d31ee0a | 264 | int iseven(int g) { |
pegcjs | 4:74df6d31ee0a | 265 | int test=0; |
pegcjs | 5:35417986539a | 266 | if (g%2 ==0) test=1; |
pegcjs | 4:74df6d31ee0a | 267 | return(test); |
pegcjs | 4:74df6d31ee0a | 268 | } |
pegcjs | 4:74df6d31ee0a | 269 | |
pegcjs | 1:9cff4feccbce | 270 | |
pegcjs | 2:a1c26faa9103 | 271 | void status() { |
pegcjs | 7:f93b7eaab5f6 | 272 | /* if (state==0) { |
pegcjs | 7:f93b7eaab5f6 | 273 | g_lcd.character(7,0,33); // warning icon until 1 min up |
pegcjs | 7:f93b7eaab5f6 | 274 | g_lcd.character(8,0,83); // surface icon - letter S |
pegcjs | 5:35417986539a | 275 | } else { |
pegcjs | 7:f93b7eaab5f6 | 276 | g_lcd.character(7,0,32); |
pegcjs | 3:0d94a277aa8c | 277 | } |
pegcjs | 7:f93b7eaab5f6 | 278 | if (state==1) g_lcd.character(8,0,83); // surface icon |
pegcjs | 7:f93b7eaab5f6 | 279 | if (state==2 && iseven(seconds)==1) g_lcd.character(8,0,4); // diving icon - inverse D |
pegcjs | 7:f93b7eaab5f6 | 280 | if (state==2 && iseven(seconds)==0) g_lcd.character(8,0,68); // diving icon - normal D |
pegcjs | 7:f93b7eaab5f6 | 281 | */ |
pegcjs | 7:f93b7eaab5f6 | 282 | // yes - this does nothing as all this is now done by vmessage |
pegcjs | 4:74df6d31ee0a | 283 | } |
pegcjs | 3:0d94a277aa8c | 284 | |
pegcjs | 3:0d94a277aa8c | 285 | // warning and LED conditions |
pegcjs | 2:a1c26faa9103 | 286 | |
pegcjs | 2:a1c26faa9103 | 287 | void warning() { |
pegcjs | 7:f93b7eaab5f6 | 288 | if (depth>=mod && flash==1) g_lcd.character(11,0,33); |
pegcjs | 7:f93b7eaab5f6 | 289 | else g_lcd.character(11,0,32); // blank sapce |
pegcjs | 2:a1c26faa9103 | 290 | |
pegcjs | 2:a1c26faa9103 | 291 | } |
pegcjs | 2:a1c26faa9103 | 292 | |
pegcjs | 4:74df6d31ee0a | 293 | // pick maximum of two values |
pegcjs | 7:f93b7eaab5f6 | 294 | float maximum(float a,float b,float c) { |
pegcjs | 4:74df6d31ee0a | 295 | float maximum; |
pegcjs | 7:f93b7eaab5f6 | 296 | if(a>b && a>c) maximum=a; |
pegcjs | 7:f93b7eaab5f6 | 297 | if(b>a && b>c) maximum=b; |
pegcjs | 7:f93b7eaab5f6 | 298 | if(c>a && c>b) maximum=c; |
pegcjs | 4:74df6d31ee0a | 299 | return(maximum); |
pegcjs | 4:74df6d31ee0a | 300 | } |
pegcjs | 4:74df6d31ee0a | 301 | |
pegcjs | 7:f93b7eaab5f6 | 302 | // pick minimum of three values |
pegcjs | 7:f93b7eaab5f6 | 303 | float minimum(float a,float b,float c) { |
pegcjs | 4:74df6d31ee0a | 304 | float minim; |
pegcjs | 7:f93b7eaab5f6 | 305 | if (a<b && a < c) minim=a; |
pegcjs | 7:f93b7eaab5f6 | 306 | if(b<a && b<c) minim=b; |
pegcjs | 7:f93b7eaab5f6 | 307 | if(c<a && c <b) minim=c; |
pegcjs | 7:f93b7eaab5f6 | 308 | |
pegcjs | 4:74df6d31ee0a | 309 | return(minim); |
pegcjs | 4:74df6d31ee0a | 310 | } |
pegcjs | 4:74df6d31ee0a | 311 | |
pegcjs | 4:74df6d31ee0a | 312 | |
pegcjs | 7:f93b7eaab5f6 | 313 | // handset led control |
pegcjs | 2:a1c26faa9103 | 314 | void leds() { |
pegcjs | 4:74df6d31ee0a | 315 | // first turn everything off |
pegcjs | 5:35417986539a | 316 | red=0; |
pegcjs | 5:35417986539a | 317 | green=0; |
pegcjs | 5:35417986539a | 318 | blue=0; |
pegcjs | 7:f93b7eaab5f6 | 319 | float ppox,ppom,sp; |
pegcjs | 5:35417986539a | 320 | int mo=0; |
pegcjs | 7:f93b7eaab5f6 | 321 | //mo=MODE; |
pegcjs | 7:f93b7eaab5f6 | 322 | if(setpoint==0) sp=lowsetpoint; |
pegcjs | 7:f93b7eaab5f6 | 323 | else sp=highsetpoint; |
pegcjs | 7:f93b7eaab5f6 | 324 | ppox=maximum(ppo1,ppo2,ppo3); // use max value to compute leds... |
pegcjs | 7:f93b7eaab5f6 | 325 | ppom=minimum(ppo1,ppo2,ppo3); // unless we want minimum |
pegcjs | 5:35417986539a | 326 | if (mo==0) { // CCR mode |
pegcjs | 7:f93b7eaab5f6 | 327 | if (ppom<0.2 && flash==1) {red=1;} // flashing red means very bad things - getting very --low on oxygen!!! |
pegcjs | 7:f93b7eaab5f6 | 328 | if (ppom>0.2 && ppox < (sp-0.15)) red=1; // non-flashing red |
pegcjs | 7:f93b7eaab5f6 | 329 | if (ppox>=(sp-0.15) && ppox <(sp-0.5)) { |
pegcjs | 5:35417986539a | 330 | red=1; // red-green |
pegcjs | 5:35417986539a | 331 | green=1; |
pegcjs | 5:35417986539a | 332 | } |
pegcjs | 7:f93b7eaab5f6 | 333 | if (ppox<(sp+0.05) && ppox >=(sp-0.05)) green=1; // green - optimal range in ccr mode |
pegcjs | 7:f93b7eaab5f6 | 334 | if (ppox<(sp+0.15) && ppox >=(sp+0.05)) { |
pegcjs | 5:35417986539a | 335 | green=1; // green-blue - high ppo2 be careful of spiking |
pegcjs | 5:35417986539a | 336 | blue=1; |
pegcjs | 5:35417986539a | 337 | } |
pegcjs | 7:f93b7eaab5f6 | 338 | if (ppox<1.6 && ppox>=(sp+0.15)) blue=1; // DANGER blue high ppo2 |
pegcjs | 7:f93b7eaab5f6 | 339 | if (ppox>=1.6 && flash==1) blue=1; |
pegcjs | 5:35417986539a | 340 | } |
pegcjs | 7:f93b7eaab5f6 | 341 | /*if (mo==1) { // SCR mode |
pegcjs | 7:f93b7eaab5f6 | 342 | if (ppom<0.2 && flash==1) red=1; |
pegcjs | 7:f93b7eaab5f6 | 343 | if (ppom>=0.2 && ppox <0.26) red=1; // will give green red for low but not lethal ppo2s |
pegcjs | 7:f93b7eaab5f6 | 344 | if (depth < 0.8*mod && ppom>0.2) green=1; |
pegcjs | 5:35417986539a | 345 | if (depth< mod && depth >=0.8*mod) { |
pegcjs | 5:35417986539a | 346 | green=1; |
pegcjs | 5:35417986539a | 347 | blue=1; |
pegcjs | 5:35417986539a | 348 | } |
pegcjs | 5:35417986539a | 349 | if (depth >=mod && flash==1) blue=1; |
pegcjs | 7:f93b7eaab5f6 | 350 | }*/ |
pegcjs | 6:ab2d7d0a9b07 | 351 | |
pegcjs | 1:9cff4feccbce | 352 | } |
pegcjs | 1:9cff4feccbce | 353 | |
pegcjs | 4:74df6d31ee0a | 354 | |
pegcjs | 4:74df6d31ee0a | 355 | |
pegcjs | 1:9cff4feccbce | 356 | //read battery state and insert the battery symbol |
pegcjs | 1:9cff4feccbce | 357 | void battery() { |
pegcjs | 7:f93b7eaab5f6 | 358 | char cgchar[32]={ |
pegcjs | 7:f93b7eaab5f6 | 359 | 6,9,9,9,9,9,9,15, // battery empty symbol |
pegcjs | 7:f93b7eaab5f6 | 360 | 6,9,9,9,9,15,15,15, // battery 50% symbol |
pegcjs | 7:f93b7eaab5f6 | 361 | 6,9,9,15,15,15,15,15, // battery 75% symbol |
pegcjs | 7:f93b7eaab5f6 | 362 | 6,15,15,15,15,15,15,15, // battery 100% symbol |
pegcjs | 7:f93b7eaab5f6 | 363 | }; |
pegcjs | 7:f93b7eaab5f6 | 364 | |
pegcjs | 7:f93b7eaab5f6 | 365 | |
pegcjs | 7:f93b7eaab5f6 | 366 | int batsym=0,i=0; // battery < 3.85V |
pegcjs | 7:f93b7eaab5f6 | 367 | |
pegcjs | 7:f93b7eaab5f6 | 368 | |
pegcjs | 7:f93b7eaab5f6 | 369 | // idea to build in 6 levels of battery indicator by on the fly reprogramming character 2 as required. |
pegcjs | 7:f93b7eaab5f6 | 370 | Vb=0; |
pegcjs | 7:f93b7eaab5f6 | 371 | for (i=0; i<4; i++) { |
pegcjs | 7:f93b7eaab5f6 | 372 | Vb=Vb+Vbatt; // read adc connected to battery via a 1/3 potential divider |
pegcjs | 7:f93b7eaab5f6 | 373 | wait(0.05); |
pegcjs | 7:f93b7eaab5f6 | 374 | } |
pegcjs | 7:f93b7eaab5f6 | 375 | Vb=Vb/4; // average 4 readings to reduce noise |
pegcjs | 7:f93b7eaab5f6 | 376 | |
pegcjs | 7:f93b7eaab5f6 | 377 | if (Vb>0.388) batsym=8; //3.85-3.92V |
pegcjs | 7:f93b7eaab5f6 | 378 | if (Vb>0.395) batsym=16; // battery 3.92-4V |
pegcjs | 7:f93b7eaab5f6 | 379 | if (Vb>0.404) batsym=24; // battery . >4V |
pegcjs | 7:f93b7eaab5f6 | 380 | |
pegcjs | 7:f93b7eaab5f6 | 381 | |
pegcjs | 7:f93b7eaab5f6 | 382 | // write the appropriate battery symbol into the first custom character |
pegcjs | 7:f93b7eaab5f6 | 383 | g_lcd.writeCommand(0x40); // set start address for CGRAM |
pegcjs | 7:f93b7eaab5f6 | 384 | for (i=0; i<8; i++) { |
pegcjs | 7:f93b7eaab5f6 | 385 | g_lcd.writeData(cgchar[i+batsym]); |
pegcjs | 7:f93b7eaab5f6 | 386 | } |
pegcjs | 7:f93b7eaab5f6 | 387 | |
pegcjs | 7:f93b7eaab5f6 | 388 | g_lcd.character(11,1,0); // battery symbol |
pegcjs | 7:f93b7eaab5f6 | 389 | if (batsym ==0 && flash==0) g_lcd.character(11,1,32); // bung in space if flashing |
pegcjs | 7:f93b7eaab5f6 | 390 | |
pegcjs | 7:f93b7eaab5f6 | 391 | |
pegcjs | 1:9cff4feccbce | 392 | } |
pegcjs | 1:9cff4feccbce | 393 | |
pegcjs | 7:f93b7eaab5f6 | 394 | // sub to make the nice stop or no stop message work in locations 9,0 and 9,1 |
pegcjs | 7:f93b7eaab5f6 | 395 | void vmessage() { |
pegcjs | 7:f93b7eaab5f6 | 396 | int i,d,cpos=0; |
pegcjs | 7:f93b7eaab5f6 | 397 | // "INITSURFDIVE" in vertical chas - 1 custom char per two symbols |
pegcjs | 7:f93b7eaab5f6 | 398 | char mesg[48]={ 17,31,17,0,31,6,12,31, 0,17,31,17,0,1,31,1, 19,21,25,0,31,16,31,0, 31,13,23,0,31,5,1,0, 31,17,14,0,17,31,17,0, 15,16,15,0,31,21,17,0}; |
pegcjs | 7:f93b7eaab5f6 | 399 | |
pegcjs | 7:f93b7eaab5f6 | 400 | |
pegcjs | 7:f93b7eaab5f6 | 401 | |
pegcjs | 7:f93b7eaab5f6 | 402 | g_lcd.writeCommand(104); // set start address for CGRAM characrter #6 out of 8 |
pegcjs | 7:f93b7eaab5f6 | 403 | |
pegcjs | 7:f93b7eaab5f6 | 404 | for (i=0; i<16; i++) { // write 2 chars worth into this segment NO DECO |
pegcjs | 7:f93b7eaab5f6 | 405 | |
pegcjs | 7:f93b7eaab5f6 | 406 | |
pegcjs | 7:f93b7eaab5f6 | 407 | g_lcd.writeData(mesg[i+state*16]); |
pegcjs | 7:f93b7eaab5f6 | 408 | } // endfor |
pegcjs | 7:f93b7eaab5f6 | 409 | |
pegcjs | 7:f93b7eaab5f6 | 410 | |
pegcjs | 7:f93b7eaab5f6 | 411 | |
pegcjs | 7:f93b7eaab5f6 | 412 | g_lcd.character(12,0,5); // custom char 5 |
pegcjs | 7:f93b7eaab5f6 | 413 | |
pegcjs | 7:f93b7eaab5f6 | 414 | g_lcd.character(12,1,6); // custom char 6 |
pegcjs | 7:f93b7eaab5f6 | 415 | |
pegcjs | 7:f93b7eaab5f6 | 416 | } |
pegcjs | 7:f93b7eaab5f6 | 417 | |
pegcjs | 7:f93b7eaab5f6 | 418 | |
pegcjs | 2:a1c26faa9103 | 419 | // subroutine to write the main display data |
pegcjs | 2:a1c26faa9103 | 420 | //0123456789abcdef |
pegcjs | 2:a1c26faa9103 | 421 | |
pegcjs | 2:a1c26faa9103 | 422 | //x.xx:xx D XX xx |
pegcjs | 2:a1c26faa9103 | 423 | //x.xx:xx B XX xxx NB the warning, staus and battery icons are driven by separate subroutines. |
pegcjs | 2:a1c26faa9103 | 424 | void display() { |
pegcjs | 7:f93b7eaab5f6 | 425 | int mo=0,tmp=0; |
pegcjs | 7:f93b7eaab5f6 | 426 | //mo=MODE; |
pegcjs | 7:f93b7eaab5f6 | 427 | g_lcd.character(3,1,32); |
pegcjs | 2:a1c26faa9103 | 428 | //1st line |
pegcjs | 7:f93b7eaab5f6 | 429 | |
pegcjs | 7:f93b7eaab5f6 | 430 | //ppo1 |
pegcjs | 7:f93b7eaab5f6 | 431 | if(ppo1<1) tmp=(int)(ppo1*100); else tmp=(int)(ppo1*100-100); |
pegcjs | 7:f93b7eaab5f6 | 432 | g_lcd.locate(1,0); |
pegcjs | 7:f93b7eaab5f6 | 433 | g_lcd.printf("%02d ",tmp); |
pegcjs | 7:f93b7eaab5f6 | 434 | if(ppo1>=1) g_lcd.character(0,0,2); |
pegcjs | 7:f93b7eaab5f6 | 435 | if(ppo1<1) g_lcd.character(0,0,1); |
pegcjs | 7:f93b7eaab5f6 | 436 | |
pegcjs | 7:f93b7eaab5f6 | 437 | if(ppo2<1) tmp=(int)(ppo2*100); else tmp=(int)(ppo2*100-100); |
pegcjs | 7:f93b7eaab5f6 | 438 | g_lcd.locate(5,0); |
pegcjs | 7:f93b7eaab5f6 | 439 | g_lcd.printf("%02d ",tmp); |
pegcjs | 7:f93b7eaab5f6 | 440 | if(ppo2>=1) g_lcd.character(4,0,2); |
pegcjs | 7:f93b7eaab5f6 | 441 | if(ppo2<1) g_lcd.character(4,0,1); |
pegcjs | 7:f93b7eaab5f6 | 442 | |
pegcjs | 7:f93b7eaab5f6 | 443 | if(ppo3<1) tmp=(int)(ppo3*100); else tmp=(int)(ppo3*100-100); |
pegcjs | 7:f93b7eaab5f6 | 444 | g_lcd.locate(9,0); |
pegcjs | 7:f93b7eaab5f6 | 445 | g_lcd.printf("%02d ",tmp); |
pegcjs | 7:f93b7eaab5f6 | 446 | if(ppo3>=1) g_lcd.character(8,0,2); |
pegcjs | 7:f93b7eaab5f6 | 447 | if(ppo3<1) g_lcd.character(8,0,1); |
pegcjs | 7:f93b7eaab5f6 | 448 | |
pegcjs | 7:f93b7eaab5f6 | 449 | g_lcd.locate(13,0); |
pegcjs | 7:f93b7eaab5f6 | 450 | g_lcd.printf("%.2d",(int)depth); // depth |
pegcjs | 7:f93b7eaab5f6 | 451 | g_lcd.locate(4,1); |
pegcjs | 7:f93b7eaab5f6 | 452 | g_lcd.printf("%2dm",(int)mod); // mod |
pegcjs | 2:a1c26faa9103 | 453 | //2nd line |
pegcjs | 2:a1c26faa9103 | 454 | g_lcd.locate(0,1); |
pegcjs | 7:f93b7eaab5f6 | 455 | tmp=minimum((float)fo1,(float)fo2,(float)fo3); // get min fraction of oxygen to display lowest for deco use |
pegcjs | 7:f93b7eaab5f6 | 456 | g_lcd.printf("%2d%%",tmp); |
pegcjs | 7:f93b7eaab5f6 | 457 | g_lcd.locate(13,1); |
pegcjs | 7:f93b7eaab5f6 | 458 | g_lcd.printf("%03d",scrubtime % 1000); // modulo to avoid digits conflict - means divetime is always less than 100 |
pegcjs | 7:f93b7eaab5f6 | 459 | g_lcd.locate(8,1); |
pegcjs | 7:f93b7eaab5f6 | 460 | g_lcd.printf("%2d",(int)(divetime/60) % 100 ); // rolls back to zero if go over 99 |
pegcjs | 2:a1c26faa9103 | 461 | // bung in battery icon |
pegcjs | 2:a1c26faa9103 | 462 | battery(); |
pegcjs | 5:35417986539a | 463 | status(); // this will set the diving / suface mode icon |
pegcjs | 7:f93b7eaab5f6 | 464 | // warning(); // this will set the warning ic on assuming that max ppo2 is exceeded |
pegcjs | 7:f93b7eaab5f6 | 465 | g_lcd.character(7,1,32); // space to cover any write error on top line |
pegcjs | 2:a1c26faa9103 | 466 | leds(); // this sets the leds according to the various warning conditions |
pegcjs | 7:f93b7eaab5f6 | 467 | /* if (mo==0) { |
pegcjs | 5:35417986539a | 468 | g_lcd.character(7,1,99); //'c' = ccr |
pegcjs | 5:35417986539a | 469 | } else { |
pegcjs | 5:35417986539a | 470 | g_lcd.character(7,1,115); //'s' = scr |
pegcjs | 7:f93b7eaab5f6 | 471 | }*/ |
pegcjs | 5:35417986539a | 472 | // custom character setting to sort out dp in depths |
pegcjs | 6:ab2d7d0a9b07 | 473 | |
pegcjs | 6:ab2d7d0a9b07 | 474 | |
pegcjs | 5:35417986539a | 475 | char cgchar[80]={ |
pegcjs | 5:35417986539a | 476 | 7,5,5,5,23,0,0,0, // .0 |
pegcjs | 5:35417986539a | 477 | 2,2,2,2,18,0,0,0, // .1 |
pegcjs | 7:f93b7eaab5f6 | 478 | 7,1,7,4,23,0,0,0, // .2 |
pegcjs | 7:f93b7eaab5f6 | 479 | 7,1,3,1,23,0,0,0, // .3 |
pegcjs | 7:f93b7eaab5f6 | 480 | 5,5,7,1,17,0,0,0, //.4 |
pegcjs | 7:f93b7eaab5f6 | 481 | 7,4,7,1,23,0,0,0, //.5 |
pegcjs | 7:f93b7eaab5f6 | 482 | 7,4,7,5,23,0,0,0, //.6 |
pegcjs | 5:35417986539a | 483 | 7,1,2,2,18,0,0,0, //.7 |
pegcjs | 5:35417986539a | 484 | 7,5,7,5,23,0,0,0, //.8 |
pegcjs | 5:35417986539a | 485 | 7,5,7,1,17,0,0,0 //.9 |
pegcjs | 5:35417986539a | 486 | |
pegcjs | 5:35417986539a | 487 | }; |
pegcjs | 7:f93b7eaab5f6 | 488 | // special dp digit for depth |
pegcjs | 5:35417986539a | 489 | int i=0,d=0; |
pegcjs | 5:35417986539a | 490 | d=(int)((depth-(int)depth)*10); // should be size of the 1st decimal place |
pegcjs | 5:35417986539a | 491 | // do stuff here to set cstom chars |
pegcjs | 5:35417986539a | 492 | g_lcd.writeCommand(120); // set start address for CGRAM |
pegcjs | 5:35417986539a | 493 | for (i=0; i<8; i++) { |
pegcjs | 5:35417986539a | 494 | g_lcd.writeData(cgchar[i+d*8]); |
pegcjs | 5:35417986539a | 495 | } |
pegcjs | 5:35417986539a | 496 | |
pegcjs | 7:f93b7eaab5f6 | 497 | g_lcd.character(15,0,7); // put in appropriate custom character |
pegcjs | 7:f93b7eaab5f6 | 498 | |
pegcjs | 7:f93b7eaab5f6 | 499 | // display the current setpoint information |
pegcjs | 7:f93b7eaab5f6 | 500 | if(setpoint==0) g_lcd.character(7,1,218); // letter down arrow for low setpoint |
pegcjs | 7:f93b7eaab5f6 | 501 | if(setpoint==1) g_lcd.character(7,1,217); // Letter 'H' |
pegcjs | 7:f93b7eaab5f6 | 502 | if(flash==1) g_lcd.character(7,1,115); // Letter ':' |
pegcjs | 2:a1c26faa9103 | 503 | |
pegcjs | 2:a1c26faa9103 | 504 | } |
pegcjs | 2:a1c26faa9103 | 505 | |
pegcjs | 2:a1c26faa9103 | 506 | |
pegcjs | 2:a1c26faa9103 | 507 | |
pegcjs | 1:9cff4feccbce | 508 | |
pegcjs | 7:f93b7eaab5f6 | 509 | // read sensors and generate calibrated outputs NB battery is read elsewhere |
pegcjs | 2:a1c26faa9103 | 510 | |
pegcjs | 1:9cff4feccbce | 511 | void readsensors() { |
pegcjs | 7:f93b7eaab5f6 | 512 | float barometric=0,mod1,mod2,mod3,temp,Vdepth=0,s1,s2,s3,MPXref=0; |
pegcjs | 7:f93b7eaab5f6 | 513 | int tc=0; |
pegcjs | 7:f93b7eaab5f6 | 514 | // ppo1=EG1*0.21/eg1cal; // eg1cal is 0.21bar ppO2 |
pegcjs | 7:f93b7eaab5f6 | 515 | // ppo2=EG2*0.21/eg2cal; // second oxygen cell ppO2 |
pegcjs | 7:f93b7eaab5f6 | 516 | // ppo3=EG3*0.21/eg3cal; |
pegcjs | 7:f93b7eaab5f6 | 517 | |
pegcjs | 7:f93b7eaab5f6 | 518 | s1=0; |
pegcjs | 7:f93b7eaab5f6 | 519 | s2=0; |
pegcjs | 7:f93b7eaab5f6 | 520 | s3=0; |
pegcjs | 7:f93b7eaab5f6 | 521 | for(tc=0;tc<20;tc++) // noise on Vdepth so average readings to compensate |
pegcjs | 7:f93b7eaab5f6 | 522 | { |
pegcjs | 7:f93b7eaab5f6 | 523 | Vdepth=Vdepth+(PRESin/DRATIO); // read the depth sensor and calculate the real value rather using the dividing ratio |
pegcjs | 7:f93b7eaab5f6 | 524 | wait_ms(10); // slows stuff down a bit but not a big problem |
pegcjs | 7:f93b7eaab5f6 | 525 | s1=s1+EG1; // read o2 sensors |
pegcjs | 7:f93b7eaab5f6 | 526 | s2=s2+EG2; |
pegcjs | 7:f93b7eaab5f6 | 527 | s3=s3+EG3; |
pegcjs | 7:f93b7eaab5f6 | 528 | MPXref=MPXref+V5V; // read 5V |
pegcjs | 7:f93b7eaab5f6 | 529 | wait_ms(10); // slows stuff down a bit but not a big problem |
pegcjs | 7:f93b7eaab5f6 | 530 | } |
pegcjs | 7:f93b7eaab5f6 | 531 | Vdepth=Vdepth/20; // now have the average |
pegcjs | 7:f93b7eaab5f6 | 532 | s1=s1/20-coff1; |
pegcjs | 7:f93b7eaab5f6 | 533 | s2=s2/20-coff2; |
pegcjs | 7:f93b7eaab5f6 | 534 | s3=s3/20-coff3; |
pegcjs | 7:f93b7eaab5f6 | 535 | MPXref=MPXref/20*3.3*2; // should be 5V |
pegcjs | 6:ab2d7d0a9b07 | 536 | |
pegcjs | 7:f93b7eaab5f6 | 537 | |
pegcjs | 7:f93b7eaab5f6 | 538 | // compute ppO2s |
pegcjs | 7:f93b7eaab5f6 | 539 | ppo1=s1*0.21/eg1cal; |
pegcjs | 7:f93b7eaab5f6 | 540 | ppo2=s2*0.21/eg2cal; |
pegcjs | 7:f93b7eaab5f6 | 541 | ppo3=s3*0.21/eg3cal; |
pegcjs | 7:f93b7eaab5f6 | 542 | |
pegcjs | 7:f93b7eaab5f6 | 543 | pc.printf("EG1=%f\tEG2=%f\tEG3=%f \tMPXref=%f \r",s1,s2,s3,MPXref); |
pegcjs | 7:f93b7eaab5f6 | 544 | pressure=(Vdepth*3.3/MPXref-0.04)/0.0012858; // pressure in kpa NB - assums that the 5V is correct |
pegcjs | 7:f93b7eaab5f6 | 545 | //pressure=(PRESin*3.3/0.65006-0.04)/(0.0012858); // pressure in kPa assuming standard cal for mpx5700 sensor SUSPECT |
pegcjs | 7:f93b7eaab5f6 | 546 | // NB the mpx5700 runs off 5v so would be better to divide its output down by 3/5 to get full range measurement |
pegcjs | 7:f93b7eaab5f6 | 547 | //outputs. with no division the max mbed adc of 3.3V coresponds to 480kpa or about 38m depth..... |
pegcjs | 7:f93b7eaab5f6 | 548 | // standard spec on mpx5700 should be 5V*(P*0.0012858+0.04) |
pegcjs | 7:f93b7eaab5f6 | 549 | // new sensor has 3/5 divider built into sensor wiring. |
pegcjs | 7:f93b7eaab5f6 | 550 | //barometric=(pcal*3.3/0.65006-0.004)/(0.0012858); // sealevel in kPa assuming standard cal for mpx5700 sensor |
pegcjs | 7:f93b7eaab5f6 | 551 | barometric=(pcal*3.3/MPXref-0.04)/0.0012858; // barometric pressure (kpa) evaluated from calibration which we assume is baseline |
pegcjs | 5:35417986539a | 552 | depth=(pressure-barometric)*0.1; //100kPa=10m 1kPa=0.1m - this gives depth in m for freshwater. |
pegcjs | 7:f93b7eaab5f6 | 553 | |
pegcjs | 7:f93b7eaab5f6 | 554 | if (depth<0) depth=0; // deals wtih noise that may lead to small variation in values |
pegcjs | 2:a1c26faa9103 | 555 | |
pegcjs | 7:f93b7eaab5f6 | 556 | // THESE SHOULD BE JUST 100*ppox/(pressure/100); |
pegcjs | 5:35417986539a | 557 | fo1=100*ppo1/((pressure-barometric)/100+1); // pressure in bar = pressure /100 and want a % so multiply by 100 as well |
pegcjs | 5:35417986539a | 558 | fo2=100*ppo2/((pressure-barometric)/100+1); |
pegcjs | 7:f93b7eaab5f6 | 559 | fo3=100*ppo3/((pressure-barometric)/100+1); // maybe these should be ppox/(depth/10+1)*100....? |
pegcjs | 6:ab2d7d0a9b07 | 560 | |
pegcjs | 7:f93b7eaab5f6 | 561 | /*if (fo1<0) fo2=0; |
pegcjs | 6:ab2d7d0a9b07 | 562 | if (fo2<0) fo1=0; |
pegcjs | 7:f93b7eaab5f6 | 563 | */ |
pegcjs | 7:f93b7eaab5f6 | 564 | //with three sensors will calculate mod from the largest ppo2 reading |
pegcjs | 2:a1c26faa9103 | 565 | mod1=(1.4/(fo1/100)-1)*10; |
pegcjs | 2:a1c26faa9103 | 566 | mod2=(1.4/(fo2/100)-1)*10; |
pegcjs | 7:f93b7eaab5f6 | 567 | mod3=(1.4/(fo3/100)-1)*10; |
pegcjs | 3:0d94a277aa8c | 568 | |
pegcjs | 7:f93b7eaab5f6 | 569 | mod=minimum(mod1,mod2,mod3); // pick the least value |
pegcjs | 7:f93b7eaab5f6 | 570 | |
pegcjs | 7:f93b7eaab5f6 | 571 | // output for debugging to pc via usb line. |
pegcjs | 7:f93b7eaab5f6 | 572 | // pc.printf("VDepth %f\tPressure %f\tbarometric %f\tdepth %f\t \n\r",Vdepth,pressure,barometric,depth); |
pegcjs | 7:f93b7eaab5f6 | 573 | //NB - problem - we really need to monitor the 5V power line to ensure that it's driving the depth sensor ok. |
pegcjs | 7:f93b7eaab5f6 | 574 | // it may need thicker cables as it currently only manages 4.8V on the board when everything is running. |
pegcjs | 3:0d94a277aa8c | 575 | |
pegcjs | 1:9cff4feccbce | 576 | } |
pegcjs | 6:ab2d7d0a9b07 | 577 | // get values back from cal file on local drive |
pegcjs | 6:ab2d7d0a9b07 | 578 | void recall() { |
pegcjs | 6:ab2d7d0a9b07 | 579 | FILE *fp=fopen("/local/CAL.dat","r"); |
pegcjs | 7:f93b7eaab5f6 | 580 | fscanf(fp,"%e\n%e\n%e\n%e\n%d",&eg1cal,&eg2cal,&eg3cal,&pcal,&scrubold); |
pegcjs | 6:ab2d7d0a9b07 | 581 | fclose(fp); //NB file system locked on write so must make sure we close files in case want to reprogram etc... |
pegcjs | 6:ab2d7d0a9b07 | 582 | } |
pegcjs | 6:ab2d7d0a9b07 | 583 | |
pegcjs | 6:ab2d7d0a9b07 | 584 | // write the logfile opened and closed by start and end of dive |
pegcjs | 6:ab2d7d0a9b07 | 585 | void store_log() { |
pegcjs | 7:f93b7eaab5f6 | 586 | |
pegcjs | 6:ab2d7d0a9b07 | 587 | //FILE *fp=fopen("/local/divelog.dat","a"); |
pegcjs | 7:f93b7eaab5f6 | 588 | float v5=0; |
pegcjs | 7:f93b7eaab5f6 | 589 | v5=V5V; |
pegcjs | 7:f93b7eaab5f6 | 590 | fprintf(lp,"%d\t%e\t%e\t%e\t%e\t%e\t%e\t%d\n",seconds,depth,ppo1,ppo2,ppo3,Vb,v5,scrubtime); |
pegcjs | 7:f93b7eaab5f6 | 591 | |
pegcjs | 7:f93b7eaab5f6 | 592 | if (divetime % 60==0) fflush(lp); |
pegcjs | 7:f93b7eaab5f6 | 593 | // fclose(fp); |
pegcjs | 7:f93b7eaab5f6 | 594 | } |
pegcjs | 7:f93b7eaab5f6 | 595 | |
pegcjs | 7:f93b7eaab5f6 | 596 | // read switches and report state |
pegcjs | 7:f93b7eaab5f6 | 597 | int switches() { |
pegcjs | 7:f93b7eaab5f6 | 598 | int ss=0; |
pegcjs | 7:f93b7eaab5f6 | 599 | if (SW1==1 && SW2==1) ss=3; |
pegcjs | 7:f93b7eaab5f6 | 600 | if (SW2==1 && SW1==0) ss=2; |
pegcjs | 7:f93b7eaab5f6 | 601 | if (SW1==1 && SW2==0) ss=1; |
pegcjs | 7:f93b7eaab5f6 | 602 | return(ss); |
pegcjs | 6:ab2d7d0a9b07 | 603 | } |
pegcjs | 4:74df6d31ee0a | 604 | |
pegcjs | 7:f93b7eaab5f6 | 605 | // interpret the ppo2 data into a simple set of hud codes. |
pegcjs | 7:f93b7eaab5f6 | 606 | int HUD_display() |
pegcjs | 7:f93b7eaab5f6 | 607 | { |
pegcjs | 7:f93b7eaab5f6 | 608 | int i,j3,h1,h2,h3; |
pegcjs | 7:f93b7eaab5f6 | 609 | float cset=0; |
pegcjs | 7:f93b7eaab5f6 | 610 | char gcode[6]={0,1,3,2,6,4}; // grey code for HUD reading 'red,amber,green,cyan,blue' |
pegcjs | 7:f93b7eaab5f6 | 611 | |
pegcjs | 7:f93b7eaab5f6 | 612 | HUD_clr(); // clear the HUID ready for write |
pegcjs | 7:f93b7eaab5f6 | 613 | |
pegcjs | 7:f93b7eaab5f6 | 614 | |
pegcjs | 7:f93b7eaab5f6 | 615 | if(setpoint==0) // low setpoint |
pegcjs | 7:f93b7eaab5f6 | 616 | { |
pegcjs | 7:f93b7eaab5f6 | 617 | cset=lowsetpoint; |
pegcjs | 7:f93b7eaab5f6 | 618 | } |
pegcjs | 7:f93b7eaab5f6 | 619 | |
pegcjs | 7:f93b7eaab5f6 | 620 | if(setpoint==1) // hgh setpoint |
pegcjs | 7:f93b7eaab5f6 | 621 | { |
pegcjs | 7:f93b7eaab5f6 | 622 | cset=highsetpoint; |
pegcjs | 7:f93b7eaab5f6 | 623 | } |
pegcjs | 7:f93b7eaab5f6 | 624 | |
pegcjs | 7:f93b7eaab5f6 | 625 | h1=(int)((ppo1-cset)/0.1+3.5); |
pegcjs | 7:f93b7eaab5f6 | 626 | if(h1<1) h1=1; |
pegcjs | 7:f93b7eaab5f6 | 627 | if(h1>5) h1=5; |
pegcjs | 7:f93b7eaab5f6 | 628 | h2=(int)((ppo2-cset)/0.1+3.5); |
pegcjs | 7:f93b7eaab5f6 | 629 | if(h2<1) h2=1; |
pegcjs | 7:f93b7eaab5f6 | 630 | if(h2>5) h2=5; |
pegcjs | 7:f93b7eaab5f6 | 631 | h3=(int)((ppo3-cset)/0.1+3.5); |
pegcjs | 7:f93b7eaab5f6 | 632 | if(h3<1) h3=1; |
pegcjs | 7:f93b7eaab5f6 | 633 | if(h3>5) h3=5; |
pegcjs | 7:f93b7eaab5f6 | 634 | |
pegcjs | 7:f93b7eaab5f6 | 635 | if(h3>3) btest=0; // handle extra blue connected to btest setting btest low lights blue led |
pegcjs | 7:f93b7eaab5f6 | 636 | |
pegcjs | 7:f93b7eaab5f6 | 637 | |
pegcjs | 7:f93b7eaab5f6 | 638 | i=gcode[h1]+8*gcode[h2]+64*gcode[h3]; // this is possible bigger than a char so have to typeconvert |
pegcjs | 7:f93b7eaab5f6 | 639 | HUD_write(i); |
pegcjs | 7:f93b7eaab5f6 | 640 | |
pegcjs | 7:f93b7eaab5f6 | 641 | } |
pegcjs | 7:f93b7eaab5f6 | 642 | |
pegcjs | 7:f93b7eaab5f6 | 643 | // sub to flash HUD n times as a warning of setpoint shift |
pegcjs | 7:f93b7eaab5f6 | 644 | int HUD_flash(int n) |
pegcjs | 7:f93b7eaab5f6 | 645 | { |
pegcjs | 7:f93b7eaab5f6 | 646 | int i; |
pegcjs | 7:f93b7eaab5f6 | 647 | for(i=0;i<n;i++) |
pegcjs | 7:f93b7eaab5f6 | 648 | { |
pegcjs | 7:f93b7eaab5f6 | 649 | HUD_clr(); |
pegcjs | 7:f93b7eaab5f6 | 650 | wait(0.2); |
pegcjs | 7:f93b7eaab5f6 | 651 | HUD_white(); |
pegcjs | 7:f93b7eaab5f6 | 652 | wait(0.05); |
pegcjs | 7:f93b7eaab5f6 | 653 | } |
pegcjs | 7:f93b7eaab5f6 | 654 | } |
pegcjs | 7:f93b7eaab5f6 | 655 | |
pegcjs | 7:f93b7eaab5f6 | 656 | int setswitch() |
pegcjs | 7:f93b7eaab5f6 | 657 | { |
pegcjs | 7:f93b7eaab5f6 | 658 | if(setpoint==0 && depth >(switchdepth+0.5)) |
pegcjs | 7:f93b7eaab5f6 | 659 | { |
pegcjs | 7:f93b7eaab5f6 | 660 | setpoint=1; // handle switch from low to high |
pegcjs | 7:f93b7eaab5f6 | 661 | HUD_flash(4); |
pegcjs | 7:f93b7eaab5f6 | 662 | // flash the hud here |
pegcjs | 7:f93b7eaab5f6 | 663 | } |
pegcjs | 7:f93b7eaab5f6 | 664 | |
pegcjs | 7:f93b7eaab5f6 | 665 | if(setpoint==1 && depth < (switchdepth -0.5)) |
pegcjs | 7:f93b7eaab5f6 | 666 | { |
pegcjs | 7:f93b7eaab5f6 | 667 | setpoint=0; // swtich to low setpoint |
pegcjs | 7:f93b7eaab5f6 | 668 | HUD_flash(2); |
pegcjs | 7:f93b7eaab5f6 | 669 | // flash the HUD here |
pegcjs | 7:f93b7eaab5f6 | 670 | } |
pegcjs | 7:f93b7eaab5f6 | 671 | } |
pegcjs | 1:9cff4feccbce | 672 | |
pegcjs | 1:9cff4feccbce | 673 | int main() { |
pegcjs | 2:a1c26faa9103 | 674 | // first some local variables |
pegcjs | 2:a1c26faa9103 | 675 | int startuptime=getseconds(); |
pegcjs | 4:74df6d31ee0a | 676 | int startdive=0,endclock=0; // value of seconds when dive starts and counter to decide if dive complete... |
pegcjs | 1:9cff4feccbce | 677 | |
pegcjs | 6:ab2d7d0a9b07 | 678 | int minutes=0; // minutes is elapsed minutes since start of prog |
pegcjs | 7:f93b7eaab5f6 | 679 | int j=0,scount=1;; // general loop counting variable |
pegcjs | 7:f93b7eaab5f6 | 680 | int sw=0; // status of the switches in the handset |
pegcjs | 7:f93b7eaab5f6 | 681 | char schars[4]={32,0xd9,0xda,0xfb}; // up arrow, down arrow and both arrows; |
pegcjs | 6:ab2d7d0a9b07 | 682 | |
pegcjs | 7:f93b7eaab5f6 | 683 | bool mdir=0; |
pegcjs | 1:9cff4feccbce | 684 | |
pegcjs | 1:9cff4feccbce | 685 | set_custom_char(); // does what it says on the tin really |
pegcjs | 1:9cff4feccbce | 686 | g_lcd.cls(); |
pegcjs | 1:9cff4feccbce | 687 | g_lcd.locate(0, 0); |
pegcjs | 1:9cff4feccbce | 688 | g_lcd.printf( "RebMon"); |
pegcjs | 1:9cff4feccbce | 689 | g_lcd.locate(0,1); |
pegcjs | 1:9cff4feccbce | 690 | g_lcd.printf("CAL?"); |
pegcjs | 1:9cff4feccbce | 691 | battery(); |
pegcjs | 4:74df6d31ee0a | 692 | j=0; |
pegcjs | 7:f93b7eaab5f6 | 693 | wait(0.2); |
pegcjs | 7:f93b7eaab5f6 | 694 | |
pegcjs | 6:ab2d7d0a9b07 | 695 | // get cal values last used from local drive |
pegcjs | 6:ab2d7d0a9b07 | 696 | recall(); |
pegcjs | 6:ab2d7d0a9b07 | 697 | // display the correct scrubber time |
pegcjs | 7:f93b7eaab5f6 | 698 | scrubtime=scrubold; |
pegcjs | 1:9cff4feccbce | 699 | // hang about waiting for the cal switch to be pressed in ccase it is |
pegcjs | 7:f93b7eaab5f6 | 700 | while (scount<30) { |
pegcjs | 7:f93b7eaab5f6 | 701 | seconds=getseconds(); // NB if this hangs then nothing works :( - usually means 5V is dodgy |
pegcjs | 7:f93b7eaab5f6 | 702 | red=1; |
pegcjs | 7:f93b7eaab5f6 | 703 | green=1; |
pegcjs | 7:f93b7eaab5f6 | 704 | blue=1; // light all leds |
pegcjs | 7:f93b7eaab5f6 | 705 | |
pegcjs | 1:9cff4feccbce | 706 | g_lcd.locate(5,1); |
pegcjs | 7:f93b7eaab5f6 | 707 | g_lcd.printf("%.2d ",30-scount); |
pegcjs | 4:74df6d31ee0a | 708 | if (j>1) flash=1; |
pegcjs | 3:0d94a277aa8c | 709 | else flash=0; |
pegcjs | 1:9cff4feccbce | 710 | battery(); // bung in battery symbol. |
pegcjs | 1:9cff4feccbce | 711 | g_lcd.locate(7,0); |
pegcjs | 1:9cff4feccbce | 712 | g_lcd.printf( "%.2d:%.2d:%.2d", hours,min,sec); |
pegcjs | 7:f93b7eaab5f6 | 713 | // if (CAL==0) { |
pegcjs | 7:f93b7eaab5f6 | 714 | if(SW1==0) { |
pegcjs | 1:9cff4feccbce | 715 | calibrate(); |
pegcjs | 7:f93b7eaab5f6 | 716 | scount=31; // make sure it goes to next frame ok |
pegcjs | 1:9cff4feccbce | 717 | } |
pegcjs | 7:f93b7eaab5f6 | 718 | wait(0.05); |
pegcjs | 7:f93b7eaab5f6 | 719 | |
pegcjs | 7:f93b7eaab5f6 | 720 | |
pegcjs | 3:0d94a277aa8c | 721 | j=(j+1) % 4; |
pegcjs | 7:f93b7eaab5f6 | 722 | if(flash==0) HUD_white(); |
pegcjs | 7:f93b7eaab5f6 | 723 | else HUD_clr(); |
pegcjs | 7:f93b7eaab5f6 | 724 | scount++; |
pegcjs | 7:f93b7eaab5f6 | 725 | } |
pegcjs | 1:9cff4feccbce | 726 | g_lcd.cls(); |
pegcjs | 5:35417986539a | 727 | |
pegcjs | 1:9cff4feccbce | 728 | |
pegcjs | 1:9cff4feccbce | 729 | // ok there are three states in this system |
pegcjs | 1:9cff4feccbce | 730 | //MAIN LOOP ONCE STARTUP PROTOCOLS ARE COMPLETED |
pegcjs | 3:0d94a277aa8c | 731 | j=0; |
pegcjs | 7:f93b7eaab5f6 | 732 | g_lcd.cls(); |
pegcjs | 1:9cff4feccbce | 733 | while (1) { |
pegcjs | 7:f93b7eaab5f6 | 734 | wait(0.1); //stop screen flicker |
pegcjs | 1:9cff4feccbce | 735 | readsensors(); |
pegcjs | 7:f93b7eaab5f6 | 736 | setswitch(); // check the setpoint and adjust if crossing the swtich depth |
pegcjs | 7:f93b7eaab5f6 | 737 | HUD_display(); // write the HUD codes |
pegcjs | 2:a1c26faa9103 | 738 | seconds=getseconds(); |
pegcjs | 4:74df6d31ee0a | 739 | minutes=(int)(((float)seconds-(float)startuptime)/60); |
pegcjs | 7:f93b7eaab5f6 | 740 | led1=seconds % 2; // flash the onboard led to make it clear stuff is running |
pegcjs | 3:0d94a277aa8c | 741 | |
pegcjs | 3:0d94a277aa8c | 742 | if (j>1) flash=1; |
pegcjs | 3:0d94a277aa8c | 743 | else flash=0; |
pegcjs | 3:0d94a277aa8c | 744 | |
pegcjs | 3:0d94a277aa8c | 745 | display(); // write the display |
pegcjs | 7:f93b7eaab5f6 | 746 | HUD_display(); // write the HUD |
pegcjs | 7:f93b7eaab5f6 | 747 | // sw=switches(); // read the switches and report their state |
pegcjs | 7:f93b7eaab5f6 | 748 | // if(SW1==0) g_lcd.character(11,0,0xEF); else g_lcd.character(11,0,32); // NB here is possible alternate display underwater switching point |
pegcjs | 7:f93b7eaab5f6 | 749 | // HERE do deco calcs - update tissues and compute desat , nostop or ascent times as required. |
pegcjs | 3:0d94a277aa8c | 750 | |
pegcjs | 3:0d94a277aa8c | 751 | // setup state variable |
pegcjs | 7:f93b7eaab5f6 | 752 | if (minutes<1) state=0; // startup mode - do nothing just wait to allow sensor readings to settle. |
pegcjs | 4:74df6d31ee0a | 753 | if (minutes>=1 && state==0) state=1; // surface mode - ok to go for a dive now |
pegcjs | 6:ab2d7d0a9b07 | 754 | if (minutes>=1 && depth>0.8 && state==1) { |
pegcjs | 3:0d94a277aa8c | 755 | state=2; // enter dive mode |
pegcjs | 6:ab2d7d0a9b07 | 756 | lp=fopen("/local/divelog.dat","a"); |
pegcjs | 7:f93b7eaab5f6 | 757 | fprintf(lp,"#startdive = %d\n#seconds\tdepth\tppo1\tppo2\tppo3\tVb\t\tV5V\tscrubtime\n",seconds); // bung in a header here in case one needs it |
pegcjs | 4:74df6d31ee0a | 758 | if (startdive==0) startdive=seconds; // set start of divetime. don't do this twice |
pegcjs | 3:0d94a277aa8c | 759 | endclock=0; // reset end of dive clock |
pegcjs | 3:0d94a277aa8c | 760 | } |
pegcjs | 7:f93b7eaab5f6 | 761 | // in dive mode - things to do, 1 update divetime and scrubber time, 2 write log data 3 check for end of dive... |
pegcjs | 7:f93b7eaab5f6 | 762 | if (state==2) { |
pegcjs | 7:f93b7eaab5f6 | 763 | // divetime=(int)(((float)seconds-(float)startdive)/60.0); // time since start of dive in minutes. |
pegcjs | 7:f93b7eaab5f6 | 764 | divetime=(seconds-startdive); // divetime no recorded in seconds since start of dive |
pegcjs | 7:f93b7eaab5f6 | 765 | |
pegcjs | 3:0d94a277aa8c | 766 | // do deco calcs here when implemented |
pegcjs | 7:f93b7eaab5f6 | 767 | if (divetime %15 ==0) store_log(); // this saves the dive profile and sensor optputs in a file called divelog.dat every 15s |
pegcjs | 7:f93b7eaab5f6 | 768 | if (depth<=0.5) { |
pegcjs | 4:74df6d31ee0a | 769 | endclock=endclock+1; |
pegcjs | 4:74df6d31ee0a | 770 | |
pegcjs | 6:ab2d7d0a9b07 | 771 | if (endclock>150) { |
pegcjs | 7:f93b7eaab5f6 | 772 | state=1; // 30s at shallower than 0.3m and we return to surface mode. */ |
pegcjs | 6:ab2d7d0a9b07 | 773 | FILE *fp=fopen("/local/CAL.dat","w"); |
pegcjs | 6:ab2d7d0a9b07 | 774 | fprintf(fp,"%e\n%e\n%e\n%d",eg1cal,eg2cal,pcal,scrubtime); |
pegcjs | 6:ab2d7d0a9b07 | 775 | fclose(fp); //NB file system locked on write so must make sure we close files in case want to reprogram etc... |
pegcjs | 7:f93b7eaab5f6 | 776 | |
pegcjs | 7:f93b7eaab5f6 | 777 | store(); |
pegcjs | 6:ab2d7d0a9b07 | 778 | fclose(lp); |
pegcjs | 7:f93b7eaab5f6 | 779 | } // endif endclock |
pegcjs | 7:f93b7eaab5f6 | 780 | |
pegcjs | 7:f93b7eaab5f6 | 781 | } // end if depth |
pegcjs | 7:f93b7eaab5f6 | 782 | scrubtime=scrubold+(divetime/60); // |
pegcjs | 7:f93b7eaab5f6 | 783 | } // end state 2 |
pegcjs | 1:9cff4feccbce | 784 | |
pegcjs | 1:9cff4feccbce | 785 | |
pegcjs | 3:0d94a277aa8c | 786 | j=(j+1) %4; // flash control variable = used to make the warnings flash for 0.4s duty cycle |
pegcjs | 7:f93b7eaab5f6 | 787 | |
pegcjs | 7:f93b7eaab5f6 | 788 | |
pegcjs | 7:f93b7eaab5f6 | 789 | vmessage(); // call to generate status message in vertical segment |
pegcjs | 1:9cff4feccbce | 790 | } // end while |
pegcjs | 1:9cff4feccbce | 791 | } //end main |
pegcjs | 1:9cff4feccbce | 792 | |
pegcjs | 1:9cff4feccbce | 793 | |
pegcjs | 1:9cff4feccbce | 794 | |
pegcjs | 1:9cff4feccbce | 795 |