• Peter Rachow's source code for homemade diving computer

    From Lesser Ressel@p1968@gmx.de to alt.bbs.doors on Sun Jan 30 11:22:00 2011
    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