Add motor control files

This commit is contained in:
2025-07-17 21:13:28 -06:00
parent 5fd11369cc
commit 18e4041514
8 changed files with 1598 additions and 29 deletions

267
MOTOR_CONTROL_README.md Normal file
View File

@ -0,0 +1,267 @@
# Motor Control Module
This module provides safe and reliable control of water pumps using the TB6612FNG motor driver.
## Features
- **Dual Motor Control**: Independent control of 2 DC water pumps
- **PWM Speed Control**: Variable speed from 20% to 100%
- **Safety Features**:
- Maximum runtime protection (default 30 seconds)
- Minimum interval between runs (default 5 minutes)
- Soft-start to reduce current spikes
- Emergency stop functionality
- **Runtime Statistics**: Track usage, runtime, and error counts
- **MQTT Integration**: Full remote control and monitoring
- **NVS Persistence**: Statistics survive reboots
## Hardware Connections
### ESP32-S3 to TB6612FNG Wiring
| ESP32-S3 | TB6612FNG | Function |
|----------|-----------|----------|
| GPIO4 | AIN1 | Pump 1 Direction |
| GPIO5 | AIN2 | Pump 1 Direction |
| GPIO6 | BIN1 | Pump 2 Direction |
| GPIO7 | BIN2 | Pump 2 Direction |
| GPIO8 | PWMA | Pump 1 Speed (PWM) |
| GPIO9 | PWMB | Pump 2 Speed (PWM) |
| GPIO10 | STBY | Standby (Active High) |
| GND | GND | Ground |
| 3.3V | VCC | Logic Power |
### Power Connections
- **VM** on TB6612FNG: Connect to pump power supply (12V typical)
- **Pump 1**: Connect to AOUT1 and AOUT2
- **Pump 2**: Connect to BOUT1 and BOUT2
## Usage
### Basic Control
```c
// Initialize the motor control system
motor_control_init();
// Start pump at default speed (80%)
motor_start(MOTOR_PUMP_1, MOTOR_DEFAULT_SPEED);
// Start pump at specific speed
motor_start(MOTOR_PUMP_2, 60); // 60% speed
// Stop pumps
motor_stop(MOTOR_PUMP_1);
motor_stop_all(); // Stop all pumps
// Emergency stop (immediate)
motor_emergency_stop();
```
### Timed Operations
```c
// Run pump for specific duration
motor_start_timed(MOTOR_PUMP_1, 80, 10000); // 80% speed for 10 seconds
// Pulse operation
motor_pulse(MOTOR_PUMP_1, 90, 2000, 1000, 5); // On 2s, off 1s, repeat 5x
```
### Speed Control
```c
// Change speed while running
motor_set_speed(MOTOR_PUMP_1, 50); // Change to 50%
// Set speed limits
motor_set_speed_limits(MOTOR_PUMP_1, 30, 90); // Min 30%, Max 90%
```
### Safety Configuration
```c
// Set maximum runtime (prevents pump from running too long)
motor_set_max_runtime(MOTOR_PUMP_1, 60000); // 60 seconds max
// Set minimum interval between runs (prevents frequent cycling)
motor_set_min_interval(MOTOR_PUMP_1, 300000); // 5 minutes
```
### Status and Statistics
```c
// Check if pump is running
if (motor_is_running(MOTOR_PUMP_1)) {
uint32_t runtime = motor_get_runtime_ms(MOTOR_PUMP_1);
ESP_LOGI(TAG, "Pump has been running for %d ms", runtime);
}
// Check if in cooldown
if (motor_is_cooldown(MOTOR_PUMP_1)) {
ESP_LOGI(TAG, "Pump is in cooldown period");
}
// Get statistics
motor_stats_t stats;
motor_get_stats(MOTOR_PUMP_1, &stats);
ESP_LOGI(TAG, "Total runtime: %d seconds", stats.total_runtime_ms / 1000);
ESP_LOGI(TAG, "Total runs: %d", stats.run_count);
```
## MQTT Commands
### Basic Control
- **Topic**: `plant_watering/pump/[1-2]/set`
- **Payload**:
- `on` - Start pump at default speed
- `off` - Stop pump
- `pulse` - Run pump for 5 seconds
### Speed Control
- **Topic**: `plant_watering/pump/[1-2]/speed`
- **Payload**: `0-100` (percentage)
### Test Commands
- **Topic**: `plant_watering/commands/test_pump/[1-2]`
- **Payload**: Duration in milliseconds (max 10000)
### Emergency Stop
- **Topic**: `plant_watering/commands/emergency_stop`
- **Payload**: Any value
## MQTT Status Publishing
The system publishes the following status information:
### Pump State
- **Topic**: `plant_watering/pump/[1-2]/state`
- **Values**: `on`, `off`
### Runtime (when running)
- **Topic**: `plant_watering/pump/[1-2]/runtime`
- **Value**: Current runtime in milliseconds
### Statistics (on connect and periodically)
- **Topic**: `plant_watering/pump/[1-2]/stats`
- **Format**: JSON
```json
{
"total_runtime": 123456,
"run_count": 42,
"last_duration": 5000
}
```
### Errors
- **Topic**: `plant_watering/alerts/pump_error/[1-2]`
- **Value**: Error description string
## Testing
### Hardware Test Program
A standalone test program is provided in `motor_test.c`. To use it:
1. Replace `app_main()` in your main.c with the test version
2. Build and flash
3. Monitor serial output
4. Verify each pump responds correctly
### Test Sequence
1. Individual pump ON/OFF test
2. PWM speed ramping
3. Timed operations
4. Dual pump operation
5. Safety features (cooldown, max runtime)
6. Emergency stop
7. Statistics verification
### Manual Testing via MQTT
```bash
# Start pump 1
mosquitto_pub -h <broker> -t "plant_watering/pump/1/set" -m "on"
# Change speed
mosquitto_pub -h <broker> -t "plant_watering/pump/1/speed" -m "50"
# Stop pump
mosquitto_pub -h <broker> -t "plant_watering/pump/1/set" -m "off"
# Test run for 3 seconds
mosquitto_pub -h <broker> -t "plant_watering/commands/test_pump/1" -m "3000"
# Emergency stop all
mosquitto_pub -h <broker> -t "plant_watering/commands/emergency_stop" -m "1"
```
## Troubleshooting
### Pump Not Starting
1. Check cooldown period hasn't been violated
2. Verify power connections (12V to VM)
3. Check STBY pin is HIGH
4. Verify PWM signal on oscilloscope
### Pump Runs Continuously
1. Check safety timer is working
2. Verify MQTT commands are being received
3. Check for stuck relay/MOSFET
### Low Power/Speed
1. Check power supply voltage and current capacity
2. Verify PWM duty cycle
3. Check for voltage drop in wiring
4. Ensure pumps aren't clogged
### Error Messages
- **"Cooldown period not elapsed"**: Wait for minimum interval
- **"Maximum runtime exceeded"**: Safety timer triggered
- **"Motor not initialized"**: Call `motor_control_init()` first
## Design Considerations
### Soft Start
The module implements a 500ms soft-start sequence, ramping PWM from 0 to target speed in 5% increments. This reduces current spikes and mechanical stress.
### Unidirectional Operation
While the TB6612FNG supports bidirectional control, pumps are configured for forward operation only. The direction pins are set but typically won't be changed.
### Power Management
The STBY pin is used to enable/disable the motor driver. During emergency stop, STBY is pulled low momentarily to ensure immediate motor shutdown.
### Statistics Persistence
Runtime statistics are saved to NVS every 10 pump cycles to minimize flash wear while preserving useful data across reboots.
## Integration Example
```c
// In your main application
void app_main() {
// Initialize subsystems
wifi_manager_init();
mqtt_client_init();
motor_control_init();
// Configure safety limits from Kconfig
motor_set_max_runtime(MOTOR_PUMP_1, CONFIG_WATERING_MAX_DURATION_MS);
motor_set_min_interval(MOTOR_PUMP_1, CONFIG_WATERING_MIN_INTERVAL_MS);
// Register callbacks
motor_register_state_callback(on_motor_state_change);
motor_register_error_callback(on_motor_error);
// Start your application...
}
// Automation example
void water_if_dry() {
if (soil_moisture < 30 && !motor_is_cooldown(MOTOR_PUMP_1)) {
motor_start_timed(MOTOR_PUMP_1, 70, 15000); // 15 seconds at 70%
}
}
```