Skip to content

Commit

Permalink
improve reliablity of setting desired water temperatur
Browse files Browse the repository at this point in the history
- introduce constant PureSpaIO::BUTTON_FRAMES to make PureSpaIO::TOTAL_FRAMES depended on pool model
- introduce constant PureSpaIO::BUTTON::PRESS_SHORT_COUNT for changing the desired water temperature
- method PureSpaIO::updateButtonState() extracted from PureSpaIO::decodeButton()
- PureSpaIO::setDesiredWaterTempCelsius: calculate changeTries depeding on inital temperature delta
- PureSpaIO::changeWaterTemp: set tries and toggleTempUp/Down based on PRESS_SHORT_COUNT
- PureSpaIO::changeWaterTemp: clear toggleTempUp/Down when PRESS_SHORT_COUNT is reached
- PureSpaIO::changeWaterTemp: wait for buzzer until delta to BUTTON::PRESS_COUNT has expired
  • Loading branch information
jnsbyr committed Aug 4, 2023
1 parent eae1344 commit 389dace
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 108 deletions.
125 changes: 55 additions & 70 deletions PureSpaIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,15 +484,14 @@ void PureSpaIO::setDesiredWaterTempCelsius(int temp)
changeWaterTemp(-1);

int sleep = 100; // ms
int changeTries = WATER_TEMP::SET_MAX - WATER_TEMP::SET_MIN + 3;
int changeTries = 3;
int setTemp = UNDEF::INT;
do
{
// wait for temp readback (will take 2-3 blink durations)
int readTries = 5*BLINK::PERIOD/sleep;
int newSetTemp = UNDEF::INT;
ESP.wdtFeed();
delay(BLINK::PERIOD);
do
{
delay(sleep);
Expand All @@ -510,18 +509,22 @@ void PureSpaIO::setDesiredWaterTempCelsius(int temp)
}
else
{
// success, check direction and change
// update change tries based on inital delta
if (setTemp == UNDEF::INT)
{
changeTries += abs(newSetTemp - temp);
}

// change temperature by 1 degree
setTemp = newSetTemp;
if (temp > setTemp)
{
if (!changeWaterTemp(+1))
changeWaterTemp(+1);
changeWaterTemp(+1);
changeTries--;
}
else if (temp < setTemp)
{
if (!changeWaterTemp(-1))
changeWaterTemp(-1);
changeWaterTemp(-1);
changeTries--;
}
}
Expand Down Expand Up @@ -682,43 +685,59 @@ bool PureSpaIO::waitBuzzerOff() const
/**
* change water temperature setpoint by 1 degree and wait for confirmation (blocking)
*
* notes:
* - WiFi is temporarily put to sleep to improve receive decoding reliability
*
* @param up press up (> 0) or down (< 0) button
* @return true if beep was received, false if no beep was received until timeout
*/
bool PureSpaIO::changeWaterTemp(int up)
{
if (isPowerOn() && state.error == ERROR_NONE)
{
// perform button action
waitBuzzerOff();
//DEBUG_MSG("\nP ");

#ifndef FORCE_WIFI_SLEEP
WiFi.setSleepMode(WIFI_LIGHT_SLEEP);
#endif
int tries = BUTTON::ACK_TIMEOUT/BUTTON::ACK_CHECK_PERIOD;

// perform button action
int tries = BUTTON::PRESS_SHORT_COUNT*CYCLE::PERIOD/BUTTON::ACK_CHECK_PERIOD;
if (up > 0)
{
buttons.toggleTempUp = BUTTON::PRESS_COUNT;
buttons.toggleTempUp = BUTTON::PRESS_SHORT_COUNT;
while (buttons.toggleTempUp && tries)
{
delay(BUTTON::ACK_CHECK_PERIOD);
tries--;
}
buttons.toggleTempUp = 0;
}
else if (up < 0)
{
buttons.toggleTempDown = BUTTON::PRESS_COUNT;
buttons.toggleTempDown = BUTTON::PRESS_SHORT_COUNT;
while (buttons.toggleTempDown && tries)
{
delay(BUTTON::ACK_CHECK_PERIOD);
tries--;
}
buttons.toggleTempDown = 0;
}

// wait for buzzer
tries = (BUTTON::PRESS_COUNT - BUTTON::PRESS_SHORT_COUNT)*CYCLE::PERIOD/BUTTON::ACK_CHECK_PERIOD;
while (!state.buzzer && tries)
{
delay(BUTTON::ACK_CHECK_PERIOD);
tries--;
}

#ifndef FORCE_WIFI_SLEEP
WiFi.setSleepMode(WIFI_NONE_SLEEP);
#endif

if (tries && state.buzzer)
if (state.buzzer)
{
return true;
}
Expand Down Expand Up @@ -1117,96 +1136,62 @@ ICACHE_RAM_ATTR inline void PureSpaIO::decodeLED()
}
}

ICACHE_RAM_ATTR inline void PureSpaIO::decodeButton()
ICACHE_RAM_ATTR inline void PureSpaIO::updateButtonState(volatile unsigned int& buttonPressCount)
{
if (isrState.frameValue & FRAME_BUTTON::FILTER)
if (buttonPressCount)
{
//DEBUG_MSG("F");
if (buttons.toggleFilter)
if (state.buzzer)
{
buttonPressCount = 0;
}
else
{
isrState.reply = true;
buttons.toggleFilter--;
buttonPressCount--;
}
}
}

ICACHE_RAM_ATTR inline void PureSpaIO::decodeButton()
{
if (isrState.frameValue & FRAME_BUTTON::FILTER)
{
//DEBUG_MSG("F");
updateButtonState(buttons.toggleFilter);
}
else if (isrState.frameValue & FRAME_BUTTON::HEATER)
{
//DEBUG_MSG("H");
if (buttons.toggleHeater)
{
isrState.reply = true;
buttons.toggleHeater--;
}
updateButtonState(buttons.toggleHeater);
}
else if (isrState.frameValue & FRAME_BUTTON::BUBBLE)
{
//DEBUG_MSG("B");
if (buttons.toggleBubble)
{
isrState.reply = true;
buttons.toggleBubble--;
//if (!buttons.toggleBubble)
//{
// DEBUG_MSG("\nFBO");
//}
}
updateButtonState(buttons.toggleBubble);
}
else if (isrState.frameValue & FRAME_BUTTON::POWER)
{
//DEBUG_MSG(" P");
if (buttons.togglePower)
{
isrState.reply = true;
buttons.togglePower--;
}
updateButtonState(buttons.togglePower);
}
else if (isrState.frameValue & FRAME_BUTTON::TEMP_UP)
{
//DEBUG_MSG("U");
if (buttons.toggleTempUp)
{
if (state.buzzer)
{
buttons.toggleTempUp = 0;
}
else
{
isrState.reply = true;
buttons.toggleTempUp--;
}
}
updateButtonState(buttons.toggleTempUp);
}
else if (isrState.frameValue & FRAME_BUTTON::TEMP_DOWN)
{
//DEBUG_MSG("D");
if (buttons.toggleTempDown)
{
if (state.buzzer)
{
buttons.toggleTempDown = 0;
}
else
{
isrState.reply = true;
buttons.toggleTempDown--;
}
}
updateButtonState(buttons.toggleTempDown);
}
#ifdef MODEL_SJB_HS
else if (isrState.frameValue & FRAME_BUTTON::DISINFECTION)
{
if (buttons.toggleDisinfection)
{
isrState.reply = true;
buttons.toggleDisinfection--;
}
updateButtonState(buttons.toggleDisinfection);
}
else if (isrState.frameValue & FRAME_BUTTON::JET)
{
if (buttons.toggleJet)
{
isrState.reply = true;
buttons.toggleJet--;
}
updateButtonState(buttons.toggleJet);
}
#endif
else if (isrState.frameValue & FRAME_BUTTON::TEMP_UNIT)
Expand Down
82 changes: 45 additions & 37 deletions PureSpaIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,33 +77,34 @@
*
* telegram order:
*
* 32 frames, repeating every 21 ms (5x digit 1-4, 5x LEDs, 1x buttons 1-7)
* 25 cue frames and 32/34 data frames (5x digit 1-4, 5x LEDs, 1x buttons 1-7/9), repeating every 21 ms
*
* CD1
* CD2
* CD3
* CD4
* CL
* CD1
* CD2
* CD3
* CD4
* CL
* CD1
* CD2
* CD3
* CD4
* CL
* CD1
* CD2
* CD3
* CD4
* CL
* CD1
* CD2
* CD3
* CD4
* CBBBBBBBL
* C D1
* C D2
* C D3
* C D4
* C L
* C D1
* C D2
* C D3
* C D4
* C L
* C D1
* C D2
* C D3
* C D4
* C L
* C D1
* C D2
* C D3
* C D4
* C L
* C D1
* C D2
* C D3
* C D4
* C BBBBBBB L [SB-H20]
* C BBBBBBBBB L [SJB-HS]
*
*
* Build Notes:
Expand Down Expand Up @@ -196,40 +197,46 @@ class PureSpaIO
class CYCLE
{
public:
static const unsigned int TOTAL_FRAMES = 32; // number of frames in each cycle
static const unsigned int DISPLAY_FRAMES = 5; // number of digit frame groups in each cycle
static const unsigned int PERIOD = 21; // ms, period of frame cycle
#if defined MODEL_SB_H20
static const unsigned int BUTTON_FRAMES = 7; // number of button frames in each cycle
#elif defined MODEL_SJB_HS
static const unsigned int BUTTON_FRAMES = 9; // number of button frames in each cycle
#endif
static const unsigned int TOTAL_FRAMES = 25 + BUTTON_FRAMES; // number of frames in each cycle
static const unsigned int DISPLAY_FRAME_GROUPS = 5; // number of digit frame groups in each cycle
static const unsigned int PERIOD = 21; // ms, period of frame cycle @todo might be longer for SJB-HS
static const unsigned int RECEIVE_TIMEOUT = 50*CYCLE::PERIOD; // ms
};

class FRAME
{
public :
static const unsigned int BITS = 16;
static const unsigned int BITS = 16; // bits per frame
static const unsigned int FREQUENCY = CYCLE::TOTAL_FRAMES/CYCLE::PERIOD; // frames/ms
};

class BLINK
{
public:
static const unsigned int PERIOD = 500; // ms, temp will blink 8 times in 4000 ms
static const unsigned int TEMP_FRAMES = PERIOD/4*FRAME::FREQUENCY; // sample duration of desired temp after blank display
static const unsigned int PERIOD = 500; // ms, temp will blink 8 times in 4000 ms
static const unsigned int TEMP_FRAMES = PERIOD/4*FRAME::FREQUENCY; // sample duration of desired temp after blank display
static const unsigned int STOPPED_FRAMES = 2*PERIOD*FRAME::FREQUENCY; // must be longer than single blink duration
};

class CONFIRM_FRAMES
{
public:
static const unsigned int REGULAR = 3; // ms, for values which do not blink
static const unsigned int NOT_BLINKING = BLINK::PERIOD/2*FRAME::FREQUENCY/CYCLE::DISPLAY_FRAMES; // ms, must be high enough to tell from blinking
static const unsigned int REGULAR = 3; // frames, for values which do not blink
static const unsigned int NOT_BLINKING = BLINK::PERIOD/2*FRAME::FREQUENCY/CYCLE::DISPLAY_FRAME_GROUPS; // frames, must be high enough to tell from blinking
};

class BUTTON
{
public:
static const unsigned int PRESS_COUNT = BLINK::PERIOD/CYCLE::PERIOD - 4; // must be long enough to trigger, but short enough to avoid double trigger
static const unsigned int ACK_CHECK_PERIOD = 10; // ms
static const unsigned int ACK_TIMEOUT = 2*PRESS_COUNT*CYCLE::PERIOD; // ms
static const unsigned int PRESS_COUNT = BLINK::PERIOD/CYCLE::PERIOD; // cycles, must be long enough to activate buzzer
static const unsigned int PRESS_SHORT_COUNT = 340/CYCLE::PERIOD; // cycles, must be long enough to trigger, but short enough to avoid double trigger
static const unsigned int ACK_CHECK_PERIOD = 10; // ms
static const unsigned int ACK_TIMEOUT = 2*PRESS_COUNT*CYCLE::PERIOD; // ms
};

private:
Expand Down Expand Up @@ -302,6 +309,7 @@ class PureSpaIO
static ICACHE_RAM_ATTR inline void decodeDisplay();
static ICACHE_RAM_ATTR inline void decodeLED();
static ICACHE_RAM_ATTR inline void decodeButton();
static ICACHE_RAM_ATTR inline void updateButtonState(volatile unsigned int& buttonPressCount);

private:
// ISR variables
Expand Down
2 changes: 1 addition & 1 deletion common.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@

namespace CONFIG
{
const char WIFI_VERSION[] = "1.0.6.0"; // 23.07.2023
const char WIFI_VERSION[] = "1.0.6.1"; // 24.07.2023

// WiFi parameters
const unsigned long WIFI_MAX_DISCONNECT_DURATION = 900000; // [ms] 5 min until reboot
Expand Down

0 comments on commit 389dace

Please sign in to comment.