Add motor control files
This commit is contained in:
267
MOTOR_CONTROL_README.md
Normal file
267
MOTOR_CONTROL_README.md
Normal 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%
|
||||
}
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user