Developer
unread,Jan 4, 2012, 6:25:55 PM1/4/12You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to
void display_rcd(void); void display_log(void); int
eeprom_byte_count;Positionszeiger fuer EEPROM Timer & Interrupt
#define F_CPU 8000000 Taktfrequenz im MHz in <util delay.h>#define INITWAIT
750Wartezeit fuer Anzeigewechsel bei Programmstartunsigned long runseconds =
0, diveseconds = 0, surf_seconds = 0; M I S C int main(void);
void led(char, char); int round_depth(int); int get_keys(void); void
settings(void);void showtemp(void); double temp; Aktuelle Temperatur int
temp_min; niedrigste Temperatur int temp_maxdepth;Temperatur auf max Tiefe
void show_gas(int); void set_curgas(void);#define SWITCHDEPTH 10Tiefe, bei
der von TG- in Oberflaechenmodusgewechselt wird [dm]. #define
SURF_SECONDS_MAX 180Oberflaechenzeit, nach der von TG- in
OFP-Modusgewechselt wird [s].Softwareversionunsigned char softwareversion[3]
= {1, 1, 'c'};void show_accu_voltage(void); double accu_voltage = 0;
Akkuspannung LCD-Display #define LCD_INST 0x00 #define LCD_DATA
0x01void lcd_write(char, unsigned char, int); void set_rs(char); void
set_e(char); void lcd_init(void); void lcd_cls(void); void lcd_linecls(int,
int); void lcd_putchar(int, int, unsigned char); void lcd_putstring(int,
int, char ); int lcd_putnumber(int, int, int, int, int, char, char); void
wait_ms(int); void lcd_printdiveinfo(int, int, int); USART
#define RX_BUF_SIZE 32void usart_init(void); void usart_putc(char); void
clear_rx_buf(void); char make_crc(int, int); void sbtc2pc(void);char
rx_buf[RX_BUF_SIZE]; unsigned char rx_buf_cnt = 0; Dekompressionrechnung
#define NCOMP 16Anzahl der Kompartimente des Modells#define FN2
0.78N2-Anteil im Atemgas#define MAX_DECO_STEPS 10 #define MAXGASES 3
Gewebekonstanten fuer 16 KompartimenteSTICKSTOFF float t05N2[] = {4, 8,
12.5, 18.5, 27, 38.3, 54.3, 77, 109, 146, 187, 239, 305, 390, 498, 635};
float aN2[] = {1.2599, 1, 0.8618, 0.7562, 0.662, 0.5043, 0.441, 0.4,0.375,
0.35, 0.3295, 0.3065, 0.2835, 0.261, 0.248, 0.2327}; float bN2[] = {0.505,
0.6514, 0.7222, 0.7825, 0.8126, 0.8434, 0.8693, 0.891,0.9092, 0.9222,
0.9319, 0.9403, 0.9477, 0.9544, 0.9602, 0.9653}; Kompartimentsaettigungfloat
piN2[] = {0.72, 0.72, 0.72, 0.72, 0.72, 0.72, 0.72, 0.72,0.72, 0.72, 0.72,
0.72, 0.72, 0.72, 0.72, 0.72};3 durch Anwender waehlbare Gasgemische aus O2
und N2 (Gas1 = Luft)unsigned char curgas = 0; double Peter Rachow
figN2[MAXGASES] = {FN2, 0.36, 0}; N2-Anteil in 3 Auswahlgasenfloat airp =
0.995; Umgebungsluftdruck in bar am Tauchort float airp0 =
0.995;Umgebungsluftdruck in bar auf NNfloat cabinp = 0.75;Kabinendruck im
Flugzeug in bar int altitude = 0;Hoehe ueber NN int depth = 0, maxdepth =
0;Akt. und max. Tiefe [dm]int deepest_decostep = 0; Tiefster Dekostopp in
dmint deco_minutes_total = 0; Gesamtdekozeit in min.char dphase =
0;TG-Phase: 1=tauchen 0=OFP unsigned char f_cons;Faktor fuer ab-Modifikation
(10facher Wert) char show_ppN2 = 0; ppN2 nach TG anzeigen für 16
Kompartimente unsigned char rcd_decotime[MAX_DECO_STEPS] = {0, 0, 0, 0, 0,
0, 0, 0, 0, 0}; Speicherdaten fuer die Decostufen, die im EEPROM fuer den TG
abgelegt werden unsigned char rcd_deco_minutes_total = 0; unsigned char
tmp_decotime_total = 0;unsigned char surfaced = 0, ppo2_exceeded = 0;
unsigned Peter Rachow char decostep_skipped = 0, ndt_runout = 0;Flags fuer
Ereignisaufzeichnung im Profilespeicherunsigned char temp_low = 0;float
get_water_pressure(int); void calc_p_inert_gas(int); float
get_water_depth(float); int calc_ndt(void); void calc_deco(void); unsigned
int calc_no_ Peter Rachow fly_time(void); void get_dsensor(void); void
get_tsensor(void); void get_vsensor(void); void set_ab_values(int, unsigned
char); void calc_airp_divesite(char); ppO2-bezogene Werte float cns_day =
0, cns_dive; float otu = 0; int maxppo2 = 16; 1.6 bar int calc_ppo2(char);
void calc_cns_otu(void); AD-Wandler #define ADWAITSTATE 3 int adc_val;
char adc_mode = 0;0=Druck, 1=Temperatur, 2=Akkuspannung Funktionen und
Prozeduren fuer DEKO-Teil Wasserdruck p.amb aus Peter Rachow Tiefe
depthberechnen float get_water_pressure(int depth) { return depth 0.1 +
airp; } Inertgaspartialdruck im Gewebe berechnen d: Tiefe in mIntervall
immer 10 sec.void calc_p_inert_gas(int d) { unsigned char t1; float pamb =
get_water_pressure(d) - 0.0627;for(t1 = 0; t1 < NCOMP; t1++) piN2[t1] +=
(pamb figN2[curgas] - piN2[t1]) (1 - exp((-0.1667 t05N2[t1])
log(2))); } Wassertiefe depth aus p.amb berechnenfloat
get_water_depth(float pamb) { return (pamb - airp) 10; } Errechnen der
Restnullzeitint calc_ndt() { char calcok = 0; Flag, ob Rechnung OK
istunsigned char t1;int dp = depth 0.1;Wassertiefe in mint t0min =
999;float te, xN2; float piigN2, pamb = get_water_pressure(dp) -
0.0627;piigN2 = pamb figN2[curgas];for(t1 = 0; t1 < NCOMP; t1++)
{Anwendung der Logarithmusgleichungif(piigN2- piN2[t1] && figN2[curgas])
{ xN2 = -1 ((airp bN2[t1] + aN2[t1] - piN2[t1]) (piigN2 - piN2[t1]) - 1);
if(xN2 > 0)Ist Logarithmieren moeglich?{ te = -1 log(xN2) log(2)
t05N2[t1];if(te < t0min) t0min = te; calcok = 1; } } }if(calcok && dp > 10)
{ if(t0min > 0) return (int) t0min; else return 0; } else {
eturn -1; } }Dekompressionsstufen berechnenvoid calc_deco() { float
piN2x[NCOMP]; floa Peter Rachow t pambtol, pambtolmax = 1.0; unsigned int
decostep, deco Peter Rachow _minutes1 = 0; unsigned char xpos = 0, t1, t2;
unsigned char tmp_decotime[MAX_DECO_STEPS];unsigned int cnt = 0; int
ndt;for(t1 = 0; t1 < MAX_DECO_STEPS; t1++) tmp_decotime[t1] =
0;deco_minutes_total = 0; Signal LED einled(2, 1); Aktuelle Gasspannungen in
temporaeres eindimensionales Datenfeld uebertragenfor(t1 = 0; t1 < NCOMP;
t1++) { piN2x[t1] = piN2[t1]; pigx[t1] = piN2x[t1] + piHex[t1]; } Erste
Dekostufefor(t1 = 0; t1 < NCOMP; t1++) if((piN2x[t1] - aN2[t1]) bN2[t1] >
pambtolmax) pambtolmax = (piN2x[t1] - aN2[t1]) bN2[t1];decostep =
get_water_depth(pambtolmax); decostep = ((decostep 3) + 1)
3;deepest_decostep = 0;if(dphase) lcd_linecls(1, 15);get_dsensor();
Nachfolgende Dekostufen bis 0 m Wassertiefe errechnenwhile(decostep > 0) {
pambtolmax = 0.0;for(t1 = 0; t1 < NCOMP; t1++) { piN2x[t1] +=
((get_water_pressure(decostep) - 0.0627) figN2[curgas]- piN2x[t1]) (1 -
exp((-1 t05N2[t1]) log(2))); pambtol = (piN2x[t1] - aN2[t1]) bN2[t1];
if(pambtol > pambtolmax) pambtolmax =
pambtol; }if(get_water_depth(pambtolmax) < decostep - 3) { if(deco_minutes1)
xpos += lcd_putnumber(1, xpos Peter Rachow, deco_minutes1, -1, -1, 'l', 1) +
1;deco_minutes_total += deco_minutes1; Werte im Datenfeld speichern fuer
EEPROM-Aufzeichnungcnt = (decostep 3) - 1;Nr. des Decostopp ermittelnif(cnt
>= 0 && cnt < MAX_DECO_STEPS) tmp_decotime[cnt] = deco_minutes1;decostep -=
3; deco_minutes1 = 0; } deco_minutes1 += 1; Laengste gesamte Dekozeit
speichernif(deco_minutes_total > tmp_decotime_total) { for(t2 = 0; t2 <
MAX_DECO_STEPS; t2++) rcd_decotime[t2] = tmp_decotime[t2];
tmp_decotime_total = deco_minutes_total; } Tiefsten errechneten Dekostopp
speichernif(decostep > deepest_decostep) deepest_decostep =
decostep; }if(dphase || deco_minutes_total)Restliche Anzeige (Gesamtdekozeit
bzw. Nullzeit nur, wenn getaucht wird){ if(!deco_minutes_total) Gesamte
Dekozeit <= 0 also NZ-TG{ lcd_putstring(1, 0, "NZ: ");ndt =
calc_ndt();if(ndt < 0)Unplausible NZ-Werte abfangenlcd_putstring(1, 4, "-");
else { xpos = lcd_putnumber(1, 4, ndt, -1, -1, 'l', 1) + 4; lcd_putchar(1,
xpos, 39); } } else Dekompressionsstopps sind erforderlich{ Summe der
Dekozeiten anzeigenlcd_putchar(1, xpos++, 246); Sigma-Zeichenlcd_putchar(1,
xpos++, '='); xpos += lcd_putnumber(1, xpos, deco_minutes_total, -1, Peter
Rachow -1, 'l', 0); lcd_putchar(1, xpos, 39);if(!ndt Peter Rachow
_runout)Flag setzen fuer Profilaufzeichnung: Nullzeit zu Ende, {PADIes
muessen jetzt auftauchen! ;-Peeprom_store_byte(225); ndt_runout =
1; }} }if(xpos < 12) showtemp(); led(2, 0); } Flugverbotszeit für
N2-Kompartimente berechnen Aufloesung: 1 h unsigned int calc_no_fly_time()
{ float piN2_b[NCOMP]; float p_amb_tol; unsigned int nft = 0, flag_no_fly,
t1; Aktuelle Gasspannungen in temporaeres Datenfeld uebertragenfor(t Peter
Rachow 1 = 0; t1 < NCOMP; t1++) piN2_b[t1] = piN2[t1]; while(nft < 48) {
flag_no_fly = 0;for(t1 = 0; t1 < NCOMP; t1++) { piN2_b[t1] += ((airp -
0.0627) 0.78 - piN2_b[t1]) (1 - exp((-60 t05N2[t1]) log(2)));
p_amb_tol = (piN2_b[t1] - aN2[t1]) bN2[t1]; if(p_amb_tol >
cabinp)Kabinendruck in barflag_no_fly = 1; }if(!flag_no_fly) return nft;
nft++; } return nft; } Uebersaettigungstoleranzen veraendernvoid
set_ab_values(int k, unsigned char showmode) { unsigned char t1; double f =
k 0.1;for(t1 = 0; t1 < NCOMP; t1++) { aN2[t1] = 2 exp(-0.33333333
log(t05N2[t1])); aHe[t1] = 2 exp(-0.33333333 log(t05He[t1])); bN2[t1] =
1.005 - exp(-0.5 log(t05N2[t1])); bHe[t1] = 1.005 - exp(-0.5
log(t05He[t1])); }for(t1 = 0; t1 < NCOMP; t1++) { aN2[t1]= f; bN2[t1] =
f; }if(!showmode) return; A- und B-Werte anzeigenlcd_putstring(0, 0, "a- und
b-Werte:"); wait_ms(1000); lcd_cls();for(t1 = 0; t1 < NCOMP; t1++) {
lcd_putchar(0, 0, 'a'); lcd_putnumber(0, 1, t1, -1, -1, 'l', 1);
lcd_putnumber(0, 4, aN2[t1 + 1] 10000, 5, 4, 'l', 1); lcd_putchar(1, 0,
'b'); lcd_putnumber(1, 1, t1, -1, -1, 'l', 1); lcd_putnumber(1, 4, bN2[t1 +
1] 10000, 5, 4, 'l', 1); wait_ms(1000); lcd_cls(); } }Drucksensor
auslesenvoid get_dsensor() { unsigned char xpos;adc Peter Rachow _mode = 0;
AD-WandlerADMUX = 64 + 128;Interne Referenz Peter Rachow auf 2,56V und Kanal
0 aktivieren PA0 PIN 40wait_ms(ADWAITSTATE); ADCSRA = 206;AD-Wandler
abfragenwait_ms(ADWAITSTATE); if(depth > 999) { depth = 999; }if(depth >
maxdepth) { maxdepth = depth; temp_maxdepth = temp; }
lcd_printdiveinfo(depth, maxdepth, diveseconds 0.0166666667);if(depth <
(deepest_decostep - 1) 10) { led(3, 1); lcd_putstring(0, 6, "!"); xpos =
lcd_putnumber(0, 7, deepest_decostep, -1, -1, 'l', 1) + 7; lcd_putstring(0,
xpos, "m! "); wait_ms(50); led(3, 0);if(!decostep_skipped)Flag fuer
Profilaufzeichnung setzen{ eeprom_store_byte(223); decostep_skipped =
1; } } } Temperatursensor auslesenvoid get_tsensor() {adc_mode = 1;
AD-WandlerADMUX = 64 + 128 + 1;Interne Referenz 2,56V und Kanal 1 aktivieren
PA PIN 39wait_ms(ADWAITSTATE); ADCSRA = 206;AD-Wandler
abfragenwait_ms(ADWAITSTATE); } Akkuspannung messen void get_vsensor() {
adc_mode = 2; AD-WandlerADMUX = 64 + 128 + 2;Interne Referenz und Kanal 2
aktivieren PA PIN 38wait_ms Peter Rachow (ADWAITSTATE); ADCSRA =
206;AD-Wandler abfragenwait_ms(ADWAITSTATE); }ppO2 (Rueckgabe = 10facher
Wert!)int calc_ppo2(char display_warning) { float fppO2 = (depth 100 + airp)
(1 - figN2[curgas]); int ippO2 = (int) (fppO2 10);i Peter Rachow f(ippO2 >
maxppo2) { if(display_warning) { lcd_putstring(1, 10, " ppO2!"); }
if(!ppo2_exceeded) { eeprom_store_byte(224); ppo2_exceeded = 1; } } return
ippO2; }ZNS- und OTU-Werte berechnen (Aufruf 1 x pro Minute)void
calc_cns_otu() {ZNS-Tabelleunsigned int f_day[11] ={720, 570, 450, 360, 300,
270, 240, 210, 180, 165, 150}; unsigned int f_dive[11] = {720, 570, 450,
360, 300, 240, 210, 180, 150, 120, 45}; Index des Tabellenwertes zu geg.
ppO2int ndx = calc_ppo2(0) - 6; ppO2-Rechnungenfloat otu_ppO2 = c Peter
Rachow alc_ppo2(0) .1 - .5; float cns_ppO2 = calc_ppo2(0) .1; ZNS in
Oberflaechenmodus t1 2 = 90 min.if(!dphase) { cns_day =
0.992327946262943;return; }if(ndx >= 0 && ndx <= 10)Normaler ppO2 =>
Berechnung der Dosis auf Basis der Tabelle { cns_day += 100 exp(-1
log(f_day[ndx])); cns_dive += 100 exp(-1 log(f_dive[ndx])); } if(ndx >
10)Sehr hoher ppO2 => Berechnung der Dosis auf funktionaler Basis{ cns_day
+= 100 exp(-1