Add pingpong mode with speed, time, and randomness settings
- Add pingpong oscillation mode that alternates motor direction - Settings: base speed (10-100%), time before return (0.5-10s) - Randomness controls for both speed (0-50%) and time (0-50%) - Web UI with sliders and start/stop buttons - API endpoints: /pingpong/start and /pingpong/stop - Real-time status polling shows pingpong active state
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user