diff --git a/include/motor.h b/include/motor.h index a77d821..ba1d434 100644 --- a/include/motor.h +++ b/include/motor.h @@ -21,6 +21,15 @@ public: // Callback for stall events void setStallCallback(void (*callback)(float current)); + + // Pingpong mode + void startPingpong(int speed, int timeMs, int speedRandomPercent, int timeRandomPercent); + void stopPingpong(); + bool isPingpongActive(); + int getPingpongSpeed(); + int getPingpongTime(); + int getPingpongSpeedRandom(); + int getPingpongTimeRandom(); private: int _speed = 0; @@ -31,9 +40,22 @@ private: unsigned long _stallStartTime = 0; void (*_stallCallback)(float current) = nullptr; + // Pingpong state + bool _pingpongActive = false; + int _pingpongBaseSpeed = 50; + int _pingpongBaseTime = 2000; + int _pingpongSpeedRandomPercent = 0; + int _pingpongTimeRandomPercent = 0; + int _pingpongCurrentSpeed = 50; + int _pingpongCurrentTime = 2000; + unsigned long _pingpongLastSwitch = 0; + int _pingpongDirection = 1; + void applyMotorState(); float readCurrentSense(int pin); void checkStall(); + void updatePingpong(); + int applyRandomness(int baseValue, int randomPercent); }; extern MotorController motor; diff --git a/src/motor.cpp b/src/motor.cpp index 5269a86..fa00f2e 100644 --- a/src/motor.cpp +++ b/src/motor.cpp @@ -78,6 +78,9 @@ void MotorController::update() { // Check for stall condition checkStall(); #endif + + // Update pingpong mode + updatePingpong(); } int MotorController::getSpeed() { @@ -154,6 +157,89 @@ float MotorController::readCurrentSense(int pin) { #endif } +// Pingpong mode implementation +void MotorController::startPingpong(int speed, int timeMs, int speedRandomPercent, int timeRandomPercent) { + _pingpongBaseSpeed = constrain(speed, 0, 100); + _pingpongBaseTime = constrain(timeMs, 100, 30000); + _pingpongSpeedRandomPercent = constrain(speedRandomPercent, 0, 100); + _pingpongTimeRandomPercent = constrain(timeRandomPercent, 0, 100); + + _pingpongDirection = 1; + _pingpongCurrentSpeed = applyRandomness(_pingpongBaseSpeed, _pingpongSpeedRandomPercent); + _pingpongCurrentTime = applyRandomness(_pingpongBaseTime, _pingpongTimeRandomPercent); + _pingpongLastSwitch = millis(); + _pingpongActive = true; + + // Apply initial state + _speed = _pingpongCurrentSpeed; + _direction = _pingpongDirection; + applyMotorState(); + + Serial.printf("Pingpong started: speed=%d%% (base=%d, rand=%d%%), time=%dms (base=%d, rand=%d%%)\n", + _pingpongCurrentSpeed, _pingpongBaseSpeed, _pingpongSpeedRandomPercent, + _pingpongCurrentTime, _pingpongBaseTime, _pingpongTimeRandomPercent); +} + +void MotorController::stopPingpong() { + _pingpongActive = false; + stop(); + Serial.println("Pingpong stopped"); +} + +bool MotorController::isPingpongActive() { + return _pingpongActive; +} + +int MotorController::getPingpongSpeed() { + return _pingpongBaseSpeed; +} + +int MotorController::getPingpongTime() { + return _pingpongBaseTime; +} + +int MotorController::getPingpongSpeedRandom() { + return _pingpongSpeedRandomPercent; +} + +int MotorController::getPingpongTimeRandom() { + return _pingpongTimeRandomPercent; +} + +void MotorController::updatePingpong() { + if (!_pingpongActive) return; + + unsigned long now = millis(); + if ((now - _pingpongLastSwitch) >= (unsigned long)_pingpongCurrentTime) { + // Time to switch direction + _pingpongDirection = -_pingpongDirection; + + // Apply randomness for next cycle + _pingpongCurrentSpeed = applyRandomness(_pingpongBaseSpeed, _pingpongSpeedRandomPercent); + _pingpongCurrentTime = applyRandomness(_pingpongBaseTime, _pingpongTimeRandomPercent); + _pingpongLastSwitch = now; + + // Apply new state + _speed = _pingpongCurrentSpeed; + _direction = _pingpongDirection; + applyMotorState(); + + Serial.printf("Pingpong switch: dir=%d, speed=%d%%, next_time=%dms\n", + _pingpongDirection, _pingpongCurrentSpeed, _pingpongCurrentTime); + } +} + +int MotorController::applyRandomness(int baseValue, int randomPercent) { + if (randomPercent == 0) return baseValue; + + int maxVariation = (baseValue * randomPercent) / 100; + int variation = random(-maxVariation, maxVariation + 1); + int result = baseValue + variation; + + // Ensure result stays positive and reasonable + return max(1, result); +} + void MotorController::checkStall() { #if CURRENT_SENSING_ENABLED // Only check stall when motor should be running diff --git a/src/webserver.cpp b/src/webserver.cpp index b795db2..c044c2c 100644 --- a/src/webserver.cpp +++ b/src/webserver.cpp @@ -14,20 +14,21 @@ const char index_html[] PROGMEM = R"rawliteral(