diff --git a/Software/src/extensions/u8g2Extensions.h b/Software/src/extensions/u8g2Extensions.h index dbb3d8c0..cb1f7d3d 100644 --- a/Software/src/extensions/u8g2Extensions.h +++ b/Software/src/extensions/u8g2Extensions.h @@ -199,7 +199,7 @@ namespace drawShape { }; // Function to draw a setting bar with label and percentage - static void settingBar(const String &name, float value, int x = 0, + static void settingBar(const String &name, float value, float target, int x = 0, int y = 0, Alignment alignment = LEFT_ALIGNED, int textPadding = 0, float minValue = 0, float maxValue = 100) { @@ -213,6 +213,9 @@ namespace drawShape { float scaledValue = constrain(value, minValue, maxValue) / maxValue * 100; int boxHeight = ceil(h * scaledValue / 100); + float scaledTarget = + constrain(target, minValue, maxValue) / maxValue * 100; + int targetHeight = ceil(h * scaledTarget / 100); // Position calculations based on alignment int barStartX = (alignment == LEFT_ALIGNED) ? x : x - w; @@ -222,7 +225,8 @@ namespace drawShape { padding - w - textPadding; // Draw the bar and its frame - display.drawBox(barStartX, h - boxHeight, w, boxHeight); + display.drawBox(barStartX, h - boxHeight, w - 2, boxHeight); + display.drawVLine(barStartX + w - 2, h - targetHeight, targetHeight); display.drawFrame(barStartX, 0, w, h); // Set font for label and draw it @@ -258,7 +262,7 @@ namespace drawShape { display.setDrawColor(1); } - static void settingBarSmall(float value, int x = 0, int y = 0, + static void settingBarSmall(float value, float target, int x = 0, int y = 0, float minValue = 0, float maxValue = 100) { int w = 3; int mid = (w - 1) / 2; @@ -268,12 +272,16 @@ namespace drawShape { float scaledValue = constrain(value, minValue, maxValue) / maxValue * 100; int boxHeight = ceil(h * scaledValue / 100); + float scaledTarget = + constrain(target, minValue, maxValue) / maxValue * 100; + int targetHeight = ceil(h * scaledTarget / 100); // draw a single pixel line int lineH = boxHeight > 0 ? constrain(64 - boxHeight - 2, 0, 64) : 64; display.drawVLine(x + mid, y, lineH); + display.drawVLine(x + w - 1, h - targetHeight, targetHeight); // draw a box 3px wide - display.drawBox(x, 64 - boxHeight, w, boxHeight); + display.drawBox(x, 64 - boxHeight, w - 1, boxHeight); } // Function to draw lines between a variadic number of points diff --git a/Software/src/ossm/OSSM.PlayControls.cpp b/Software/src/ossm/OSSM.PlayControls.cpp index ece90b6d..4128ea63 100644 --- a/Software/src/ossm/OSSM.PlayControls.cpp +++ b/Software/src/ossm/OSSM.PlayControls.cpp @@ -25,7 +25,12 @@ void OSSM::drawPlayControlsTask(void *pvParameters) { auto menuString = menuStrings[ossm->menuOption]; - SettingPercents next = {0, 0, 0, 0}; + SettingPercents next; + next.speed = ossm->setting.speed; + next.stroke = ossm->setting.stroke; + next.depth = ossm->setting.depth; + next.sensation = ossm->setting.sensation; + unsigned long displayLastUpdated = 0; /** @@ -53,52 +58,71 @@ void OSSM::drawPlayControlsTask(void *pvParameters) { bool isStrokeEngine = ossm->sm->is("strokeEngine"_s) || ossm->sm->is("strokeEngine.idle"_s); - bool shouldUpdateDisplay = false; - // This small break gives the encoder a minute to settle. vTaskDelay(100); - while (isInCorrectState(ossm)) { // Always assume the display should not update. - shouldUpdateDisplay = false; - - next.speedKnob = - getAnalogAveragePercent(SampleOnPin{Pins::Remote::speedPotPin, 50}); - ossm->setting.speedKnob = next.speedKnob; - encoder = ossm->encoder.readEncoder(); - - next.speed = next.speedKnob; + bool shouldUpdateDisplay = false; - if (next.speed != ossm->setting.speed) { - shouldUpdateDisplay = true; - ossm->setting.speed = next.speed; - } + /** + * //////////////////////////////////////////// + * /////////// Manage analog //////////// + * //////////////////////////////////////////// + */ + next.speed = round(getAnalogAveragePercent(SampleOnPin{Pins::Remote::speedPotPin, 50})); + /** + * ///////////////////////////////////////////// + * /////////// Manage encoder //////////// + * ///////////////////////////////////////////// + */ + encoder = ossm->encoder.readEncoder(); switch (ossm->playControl) { + // STROKE used for SinglePenetration and StrokeEngine case PlayControls::STROKE: next.stroke = encoder; - shouldUpdateDisplay = shouldUpdateDisplay || - next.stroke - ossm->setting.stroke >= 1; - ossm->setting.stroke = next.stroke; break; + // SENSATION used for StrokeEngine case PlayControls::SENSATION: next.sensation = encoder; - shouldUpdateDisplay = - shouldUpdateDisplay || - next.sensation - ossm->setting.sensation >= 1; - ossm->setting.sensation = next.sensation; break; + // DEPTH used for StrokeEngine case PlayControls::DEPTH: next.depth = encoder; - shouldUpdateDisplay = shouldUpdateDisplay || - next.depth - ossm->setting.depth >= 1; - ossm->setting.depth = next.depth; break; } - shouldUpdateDisplay = - shouldUpdateDisplay || millis() - displayLastUpdated > 1000; + /** + * ////////////////////////////////////////////// + * /////////// Inputs update display //////////// + * ////////////////////////////////////////////// + */ + shouldUpdateDisplay = shouldUpdateDisplay || next.speed != ossm->setting.speed; + shouldUpdateDisplay = shouldUpdateDisplay || next.stroke != ossm->setting.stroke; + shouldUpdateDisplay = shouldUpdateDisplay || next.sensation != ossm->setting.sensation; + shouldUpdateDisplay = shouldUpdateDisplay || next.depth != ossm->setting.depth; + + shouldUpdateDisplay = shouldUpdateDisplay || millis() - displayLastUpdated > 1000; + /** + * ///////////////////////////////////////////// + * /////////// Apply input ramp //////////// + * ///////////////////////////////////////////// + */ + ossm->setting.speed = applyRamp(ossm->setting.speed, next.speed, + Config::Remote::speedUpPercentPerCycle, + Config::Remote::speedDownPercentPerCycle); + ossm->setting.stroke = applyRamp(ossm->setting.stroke, next.stroke, + Config::Remote::strokeUpPercentPerCycle, + Config::Remote::strokeDownPercentPerCycle); + ossm->setting.sensation = applyRamp(ossm->setting.sensation, next.sensation, + Config::Remote::sensationUpPercentPerCycle, + Config::Remote::sensationDownPercentPerCycle); + ossm->setting.depth = applyRamp(ossm->setting.depth, next.depth, + Config::Remote::depthUpPercentPerCycle, + Config::Remote::depthDownPercentPerCycle); + + // Waiting and continue if display not updated if (!shouldUpdateDisplay) { vTaskDelay(100); continue; @@ -113,33 +137,33 @@ void OSSM::drawPlayControlsTask(void *pvParameters) { ossm->display.clearBuffer(); ossm->display.setFont(Config::Font::base); - drawShape::settingBar(UserConfig::language.Speed, next.speedKnob); + drawShape::settingBar(UserConfig::language.Speed, next.speed, ossm->setting.speed); if (isStrokeEngine) { switch (ossm->playControl) { case PlayControls::STROKE: - drawShape::settingBarSmall(ossm->setting.sensation, 125); - drawShape::settingBarSmall(ossm->setting.depth, 120); - drawShape::settingBar(strokeString, ossm->setting.stroke, + drawShape::settingBarSmall(next.sensation, ossm->setting.sensation, 125); + drawShape::settingBarSmall(next.depth, ossm->setting.depth, 120); + drawShape::settingBar(strokeString, next.stroke, ossm->setting.stroke, 118, 0, RIGHT_ALIGNED); break; case PlayControls::SENSATION: - drawShape::settingBar("Sensation", ossm->setting.sensation, + drawShape::settingBar("Sensation", next.sensation, ossm->setting.sensation, 128, 0, RIGHT_ALIGNED, 10); - drawShape::settingBarSmall(ossm->setting.depth, 113); - drawShape::settingBarSmall(ossm->setting.stroke, 108); + drawShape::settingBarSmall(next.depth, ossm->setting.depth, 113); + drawShape::settingBarSmall(next.stroke, ossm->setting.stroke, 108); break; case PlayControls::DEPTH: - drawShape::settingBarSmall(ossm->setting.sensation, 125); - drawShape::settingBar("Depth", ossm->setting.depth, 123, 0, - RIGHT_ALIGNED, 5); - drawShape::settingBarSmall(ossm->setting.stroke, 108); + drawShape::settingBarSmall(next.sensation, ossm->setting.sensation, 125); + drawShape::settingBar("Depth", next.depth, ossm->setting.depth, + 123, 0, RIGHT_ALIGNED, 5); + drawShape::settingBarSmall(next.stroke, ossm->setting.stroke, 108); break; } } else { - drawShape::settingBar(strokeString, ossm->encoder.readEncoder(), + drawShape::settingBar(strokeString, next.stroke, ossm->setting.stroke, 118, 0, RIGHT_ALIGNED); } @@ -187,4 +211,14 @@ void OSSM::drawPlayControls() { int stackSize = 3 * configMINIMAL_STACK_SIZE; xTaskCreate(drawPlayControlsTask, "drawPlayControlsTask", stackSize, this, 1, &drawPlayControlsTaskH); -} \ No newline at end of file +} + +// Apply ramp in current value to move to target value +float OSSM::applyRamp(float current, float target, + float increaseValue, float decreaseValue) { + if (target > current) + current = constrain(current + increaseValue, current, target); + else + current = constrain(current - decreaseValue, target, current); + return current; +} diff --git a/Software/src/ossm/OSSM.SimplePenetration.cpp b/Software/src/ossm/OSSM.SimplePenetration.cpp index 0b18073b..73bfdbf6 100644 --- a/Software/src/ossm/OSSM.SimplePenetration.cpp +++ b/Software/src/ossm/OSSM.SimplePenetration.cpp @@ -25,7 +25,7 @@ void OSSM::startSimplePenetrationTask(void *pvParameters) { ossm->setting.speed * ossm->setting.speed / Config::Advanced::accelerationScaling; - bool isSpeedZero = ossm->setting.speedKnob < + bool isSpeedZero = ossm->setting.speed < Config::Advanced::commandDeadZonePercentage; bool isSpeedChanged = !isSpeedZero && abs(speed - lastSpeed) > @@ -102,4 +102,4 @@ void OSSM::startSimplePenetration() { "startSimplePenetrationTask", stackSize, this, configMAX_PRIORITIES - 1, &runSimplePenetrationTaskH, operationTaskCore); -} \ No newline at end of file +} diff --git a/Software/src/ossm/OSSM.h b/Software/src/ossm/OSSM.h index 18989216..eca9a323 100644 --- a/Software/src/ossm/OSSM.h +++ b/Software/src/ossm/OSSM.h @@ -313,6 +313,7 @@ class OSSM { static void drawMenuTask(void *pvParameters); static void drawPlayControlsTask(void *pvParameters); + static float applyRamp(float current, float target, float increaseValue, float decreaseValue); static void drawPatternControlsTask(void *pvParameters); void drawUpdate(); diff --git a/Software/src/structs/SettingPercents.h b/Software/src/structs/SettingPercents.h index 204290f4..8647c720 100644 --- a/Software/src/structs/SettingPercents.h +++ b/Software/src/structs/SettingPercents.h @@ -17,7 +17,6 @@ struct SettingPercents { float sensation; float depth; StrokePatterns pattern; - float speedKnob; }; #endif // SOFTWARE_SETTINGPERCENTS_H