feat: add dual BTS7960 motor driver support
- Refactor MotorController to parameterized class with MotorPins struct - Add motor1 and motor2 instances with shared enable pins (GPIO 14, 27) - Motor 2 uses GPIO 32/33 for PWM, GPIO 36/39 for current sense - Update web UI with side-by-side dual motor control panels - Add per-motor API endpoints (/motor1/*, /motor2/*) - Add emergency stop button for both motors - Legacy endpoints map to motor1 for backwards compatibility - Update readme and AGENTS.md documentation
This commit is contained in:
@@ -11,22 +11,51 @@
|
||||
#define SUBNET IPAddress(255, 255, 255, 0)
|
||||
#define DNS IPAddress(10, 81, 2, 1)
|
||||
|
||||
// BTS7960 Pin Definitions
|
||||
#define L_EN_PIN 14 // Left Enable
|
||||
#define LPWM_PIN 26 // Left PWM (Reverse)
|
||||
#define L_IS_PIN 35 // Left Current Sense (ADC input only)
|
||||
// Shared Enable Pins (both drivers share these)
|
||||
#define R_EN_PIN 27 // Right Enable (shared)
|
||||
#define L_EN_PIN 14 // Left Enable (shared)
|
||||
|
||||
#define R_EN_PIN 27 // Right Enable
|
||||
#define RPWM_PIN 25 // Right PWM (Forward)
|
||||
#define R_IS_PIN 34 // Right Current Sense (ADC input only)
|
||||
// Motor 1 BTS7960 Pin Definitions
|
||||
#define RPWM1_PIN 25 // Right PWM Motor 1 (Forward)
|
||||
#define LPWM1_PIN 26 // Left PWM Motor 1 (Reverse)
|
||||
#define R_IS1_PIN 34 // Right Current Sense Motor 1 (ADC input only)
|
||||
#define L_IS1_PIN 35 // Left Current Sense Motor 1 (ADC input only)
|
||||
|
||||
// Motor 2 BTS7960 Pin Definitions
|
||||
#define RPWM2_PIN 32 // Right PWM Motor 2 (Forward)
|
||||
#define LPWM2_PIN 33 // Left PWM Motor 2 (Reverse)
|
||||
#define R_IS2_PIN 36 // Right Current Sense Motor 2 (ADC input only - VP)
|
||||
#define L_IS2_PIN 39 // Left Current Sense Motor 2 (ADC input only - VN)
|
||||
|
||||
// PWM Configuration
|
||||
#define PWM_FREQ 20000 // 20kHz - reduces motor noise
|
||||
#define PWM_RESOLUTION 8 // 8-bit resolution (0-255)
|
||||
#define PWM_CHANNEL_R 0 // LEDC channel for RPWM
|
||||
#define PWM_CHANNEL_L 1 // LEDC channel for LPWM
|
||||
#define PWM_CHANNEL_R1 0 // LEDC channel for Motor 1 RPWM
|
||||
#define PWM_CHANNEL_L1 1 // LEDC channel for Motor 1 LPWM
|
||||
#define PWM_CHANNEL_R2 2 // LEDC channel for Motor 2 RPWM
|
||||
#define PWM_CHANNEL_L2 3 // LEDC channel for Motor 2 LPWM
|
||||
#define MIN_PWM_PERCENT 20 // Minimum PWM when motor is running (%)
|
||||
|
||||
// Motor pin configuration structure
|
||||
struct MotorPins {
|
||||
uint8_t rpwm; // Right PWM pin (forward)
|
||||
uint8_t lpwm; // Left PWM pin (reverse)
|
||||
uint8_t r_is; // Right current sense pin
|
||||
uint8_t l_is; // Left current sense pin
|
||||
uint8_t pwm_channel_r; // LEDC PWM channel for right
|
||||
uint8_t pwm_channel_l; // LEDC PWM channel for left
|
||||
};
|
||||
|
||||
// Motor 1 pin configuration
|
||||
const MotorPins MOTOR1_PINS = {
|
||||
RPWM1_PIN, LPWM1_PIN, R_IS1_PIN, L_IS1_PIN, PWM_CHANNEL_R1, PWM_CHANNEL_L1
|
||||
};
|
||||
|
||||
// Motor 2 pin configuration
|
||||
const MotorPins MOTOR2_PINS = {
|
||||
RPWM2_PIN, LPWM2_PIN, R_IS2_PIN, L_IS2_PIN, PWM_CHANNEL_R2, PWM_CHANNEL_L2
|
||||
};
|
||||
|
||||
// Current Sense Configuration
|
||||
// BTS7960 current sense ratio: 8500:1 (kilo-amps)
|
||||
// With 1kΩ resistor on IS pin: V = I_motor / 8500
|
||||
|
||||
@@ -9,6 +9,9 @@ typedef void (*StallCallback)();
|
||||
|
||||
class MotorController {
|
||||
public:
|
||||
// Constructor with pin configuration and motor name
|
||||
MotorController(const MotorPins& pins, const char* name);
|
||||
|
||||
void begin();
|
||||
void setSpeed(int speed); // 0-100 percentage
|
||||
void setDirection(int dir); // -1=reverse, 0=stop, 1=forward
|
||||
@@ -20,6 +23,7 @@ public:
|
||||
float getCurrentRight(); // Current in amps (forward direction)
|
||||
float getCurrentLeft(); // Current in amps (reverse direction)
|
||||
float getCurrentActive(); // Current from active direction
|
||||
const char* getName(); // Get motor name for logging
|
||||
|
||||
// Stall detection
|
||||
bool isStalled();
|
||||
@@ -27,6 +31,9 @@ public:
|
||||
void resetStallDetection();
|
||||
|
||||
private:
|
||||
MotorPins _pins;
|
||||
const char* _name;
|
||||
|
||||
int _speed = 0;
|
||||
int _direction = 0;
|
||||
float _currentRight = 0;
|
||||
@@ -42,12 +49,20 @@ private:
|
||||
StallCallback _stallCallback = nullptr;
|
||||
unsigned long _lastDirectionChangeTime = 0;
|
||||
|
||||
// Static flag to track if enable pins are already configured
|
||||
static bool _enablePinsConfigured;
|
||||
|
||||
void applyMotorState();
|
||||
float readCurrentSense(int pin);
|
||||
void calibrateCurrentOffset();
|
||||
void checkStall();
|
||||
};
|
||||
|
||||
extern MotorController motor;
|
||||
// Two motor controller instances
|
||||
extern MotorController motor1;
|
||||
extern MotorController motor2;
|
||||
|
||||
// Legacy alias for backwards compatibility
|
||||
#define motor motor1
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user