From Newsgroup: alt.bbs.doors
Hi John,
I recently found that code on the website of Peter Rachow (
http://www.peter-rachow.de) who developes his own diving computers. Here is
a code snippet that he developed to calculate inert gas saturation within tissues and that might serve your business.
I think Peter Rachow agrees publishing, because his code is in the public domain.
see ya
/* Dekompressionsstufen berechnen */
void calc_deco()
{
float piN2x[NCOMP], piHex[NCOMP], pigx[NCOMP];
float a[NCOMP], b[NCOMP];
float pambtol, pambtolmax = 1.0;
unsigned int decostep, deco_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 ein */
led(2, 1);
/* Aktuelle Gasspannungen in temporaeres eindimensionales Datenfeld uebertragen */
for(t1 = 0; t1 < NCOMP; t1++)
{
piN2x[t1] = piN2[t1];
piHex[t1] = piHe[t1];
pigx[t1] = piN2x[t1] + piHex[t1];
}
/* Erste Dekostufe */
for(t1 = 0; t1 < NCOMP; t1++)
if((pigx[t1] - aN2[t1]) * bN2[t1] > pambtolmax)
pambtolmax = (pigx[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();
/* a- und b-Konstanten errechnen, Gewichtung entsprechend dem Inertgaspartial- */
/* druck im Gewebe
*/
for(t1 = 0; t1 < NCOMP; t1++)
{
if(piHex[t1] > 0.1)
{
a[t1] = (aN2[t1] * piN2x[t1] + aHe[t1] * piHex[t1]) / (piN2x[t1]
+ piHex[t1]);
b[t1] = (bN2[t1] * piN2x[t1] + bHe[t1] * piHex[t1]) / (piN2x[t1] + piHex[t1]);
}
else
{
a[t1] = aN2[t1];
b[t1] = bN2[t1];
}
}
/* Nachfolgende Dekostufen bis 0 m Wassertiefe errechnen */
while(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)));
piHex[t1] += ((get_water_pressure(decostep) - 0.0627) * figHe[curgas] - piHex[t1]) * (1 - exp((-1 / t05He[t1]) * log(2)));
pigx[t1] = piN2x[t1] + piHex[t1];
pambtol = (pigx[t1] - a[t1]) * b[t1];
if(pambtol > pambtolmax)
pambtolmax = pambtol;
}
if(get_water_depth(pambtolmax) < decostep - 3)
{
if(deco_minutes1)
xpos += lcd_putnumber(1, xpos, deco_minutes1, -1, -1, 'l') +
1;
deco_minutes_total += deco_minutes1;
/* Werte im Datenfeld speichern fuer EEPROM-Aufzeichnung
*/
cnt = (decostep / 3) - 1; /* Nr. des Decostopp ermitteln */
if(cnt >= 0 && cnt < MAX_DECO_STEPS)
tmp_decotime[cnt] = deco_minutes1;
decostep -= 3;
deco_minutes1 = 0;
}
deco_minutes1 += 1;
/* Laengste gesamte Dekozeit speichern */
if(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 speichern */
if(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 abfangen */
lcd_putstring(1, 4, "-");
else
{
xpos = lcd_putnumber(1, 4, ndt, -1, -1, 'l') + 4;
lcd_putchar(1, xpos, 39);
}
}
else /* Dekompressionsstopps sind erforderlich */
{
/* Summe der Dekozeiten anzeigen */
lcd_putchar(1, xpos++, 246); /* Sigma-Zeichen */
lcd_putchar(1, xpos++, '=');
xpos += lcd_putnumber(1, xpos, deco_minutes_total, -1, -1, 'l');
lcd_putchar(1, xpos, 39);
if(!ndt_runout) /* Flag setzen fuer Profilaufzeichnung: Nullzeit
zu Ende, */
{ /* PADIes muessen jetzt auftauchen! ;-P
*/
eeprom_store_byte(225);
ndt_runout = 1;
}
}
}
if(xpos < 12)
showtemp();
led(2, 0);
// Copyright by Peter Rachow - Germany
}
--- Synchronet 3.17a-Linux NewsLink 1.108