# HG changeset patch # User heinrichsweikamp # Date 1682063303 -7200 # Node ID 29d9b5bc79464348660298d90cbeab288f613e84 # Parent 8deb28b2d4da12672c9854da56391c3b327bb81e Revised automatic setpoint change. The proposed approach is essentially the approach used by most controllers of eCCR ('upshift' on descent, 'downshift' on ascent), so that the OSTC4 when used as a backup computer for eCCR will make the changes at the same time as the eCCR itself. diff -r 8deb28b2d4da -r 29d9b5bc7946 Common/Inc/data_central.h --- a/Common/Inc/data_central.h Fri Apr 21 09:47:44 2023 +0200 +++ b/Common/Inc/data_central.h Fri Apr 21 09:48:23 2023 +0200 @@ -210,8 +210,9 @@ * includes setpoint information */ SGas actualGas; + uint8_t lastDiluent_GasIdInSettings; - uint8_t gas_temp2; + float lastSetpointChangeDepthM; /* calculated by DataEX_copy_to_LifeData() bottle_bar array size is made like this to have multiples of 32bit diff -r 8deb28b2d4da -r 29d9b5bc7946 Discovery/Src/check_warning.c --- a/Discovery/Src/check_warning.c Fri Apr 21 09:47:44 2023 +0200 +++ b/Discovery/Src/check_warning.c Fri Apr 21 09:48:23 2023 +0200 @@ -32,6 +32,8 @@ /* Includes ------------------------------------------------------------------*/ +#include + #include "data_exchange.h" #include "check_warning.h" #include "settings.h" @@ -44,7 +46,7 @@ /* Private variables with access ----------------------------------------------*/ static uint8_t betterGasId = 0; -static uint8_t betterSetpointId = 0; +static uint8_t betterSetpointId = 1; static int8_t fallback = 0; static uint16_t debounceFallbackTimeMS = 0; @@ -286,40 +288,82 @@ return pDiveState->warnings.betterGas; } -/* check for better travel!!! setpoint hw 151210 - */ -static int8_t check_BetterSetpoint(SDiveState * pDiveState) + +uint8_t getSetpointLowId(void) { - pDiveState->warnings.betterSetpoint = 0; - betterSetpointId = 0; - uint8_t bestSetpointDepth = 0; // travel the deeper, the better - uint8_t betterSetpointIdLocal = 0; // nothing better + uint8_t setpointLowId = 0; + uint8_t setpointLowDepthM = UINT8_MAX; + for (unsigned i = 1; i <= NUM_GASES; i++) { + if (stateUsed->diveSettings.setpoint[i].depth_meter && stateUsed->diveSettings.setpoint[i].depth_meter < setpointLowDepthM) { + setpointLowId = i; + setpointLowDepthM = stateUsed->diveSettings.setpoint[i].depth_meter; + } + } + + return setpointLowId; +} + + +uint8_t getSetpointHighId(void) +{ + uint8_t setpointHighId = 0; + uint8_t setpointHighDepthM = 0; + for (unsigned i = 1; i <= NUM_GASES; i++) { + if (stateUsed->diveSettings.setpoint[i].depth_meter && stateUsed->diveSettings.setpoint[i].depth_meter >= setpointHighDepthM) { + setpointHighId = i; + setpointHighDepthM = stateUsed->diveSettings.setpoint[i].depth_meter; + } + } + + return setpointHighId; +} - if((stateUsed->mode == MODE_DIVE) && (pDiveState->diveSettings.diveMode == DIVEMODE_CCR)) - { - if(!actualLeftMaxDepth(pDiveState)) /* travel gases */ - { - for(int i=1; i<=NUM_GASES; i++) - { - if( (pDiveState->diveSettings.setpoint[i].note.ub.active) - && (pDiveState->diveSettings.setpoint[i].depth_meter) - && (pDiveState->diveSettings.setpoint[i].depth_meter <= ( pDiveState->lifeData.depth_meter + 0.01f )) - && (pDiveState->diveSettings.setpoint[i].depth_meter >= bestSetpointDepth) - ) - { - betterSetpointIdLocal = i; - bestSetpointDepth = pDiveState->diveSettings.setpoint[i].depth_meter; - } - } - if((betterSetpointIdLocal) && (pDiveState->diveSettings.setpoint[betterSetpointIdLocal].setpoint_cbar != pDiveState->lifeData.actualGas.setPoint_cbar)) - { - betterSetpointId = betterSetpointIdLocal; - pDiveState->warnings.betterSetpoint = 1; - } - } - } - return pDiveState->warnings.betterSetpoint; +/* check for better travel!!! setpoint hw 151210 + */ +static int8_t check_BetterSetpoint(SDiveState *diveState) +{ + diveState->warnings.betterSetpoint = 0; + + if (stateUsed->mode != MODE_DIVE) { + betterSetpointId = 1; + + return 0; + } + + SSettings *settings = settingsGetPointer(); + + float currentDepthM = diveState->lifeData.depth_meter; + if (settings->dive_mode == DIVEMODE_CCR && diveState->lifeData.lastSetpointChangeDepthM != currentDepthM) { + float lastChangeDepthM = diveState->lifeData.lastSetpointChangeDepthM; + bool descending = currentDepthM > lastChangeDepthM; + uint8_t setpointLowId = getSetpointLowId(); + uint8_t setpointHighId = getSetpointHighId(); + uint8_t betterSetpointIdLocal = 0; + uint8_t betterSetpointSwitchDepthM = descending ? 0 : UINT8_MAX; + + for (unsigned i = 1; i <= NUM_GASES; i++) { + uint8_t switchDepthM = diveState->diveSettings.setpoint[i].depth_meter; + if (!switchDepthM || (descending && i == setpointLowId) || (!descending && i == setpointHighId)) { + continue; + } + + if ((descending && lastChangeDepthM < switchDepthM && switchDepthM < currentDepthM && switchDepthM > betterSetpointSwitchDepthM) + || (!descending && lastChangeDepthM > switchDepthM && switchDepthM > currentDepthM && switchDepthM <= betterSetpointSwitchDepthM)) { + betterSetpointIdLocal = i; + betterSetpointSwitchDepthM = switchDepthM; + } + } + + if (betterSetpointIdLocal) { + betterSetpointId = betterSetpointIdLocal; + if (diveState->diveSettings.diveMode == DIVEMODE_CCR && diveState->diveSettings.setpoint[betterSetpointIdLocal].setpoint_cbar != diveState->lifeData.actualGas.setPoint_cbar) { + diveState->warnings.betterSetpoint = 1; + } + } + } + + return diveState->warnings.betterSetpoint; } diff -r 8deb28b2d4da -r 29d9b5bc7946 Discovery/Src/data_central.c --- a/Discovery/Src/data_central.c Fri Apr 21 09:47:44 2023 +0200 +++ b/Discovery/Src/data_central.c Fri Apr 21 09:48:23 2023 +0200 @@ -501,8 +501,10 @@ lifeData->actualGas.change_during_ascent_depth_meter_otherwise_zero = 0; lifeData->actualGas.AppliedDiveMode = stateUsed->diveSettings.diveMode; lifeData->actualGas.pscr_factor = 1.0 / pSettings->pscr_lung_ratio * pSettings->pscr_o2_drop; - if(isLoopMode(pSettings->dive_mode) && (gasId > NUM_OFFSET_DILUENT)) + if (isLoopMode(pSettings->dive_mode) && gasId > NUM_OFFSET_DILUENT) { lifeData->lastDiluent_GasIdInSettings = gasId; + lifeData->lastSetpointChangeDepthM = lifeData->depth_meter; + } }