Motor control implemented

This commit is contained in:
2025-07-19 22:55:58 -06:00
parent fef8da2de2
commit 5a4c91fbd3
4 changed files with 316 additions and 17 deletions

242
main/motor_test.c Normal file
View File

@ -0,0 +1,242 @@
/**
* Motor Control Hardware Test Program
*
* This is a standalone test program to verify TB6612FNG motor driver
* connections before integrating with the full system.
*
* Test sequence:
* 1. Initialize motor control
* 2. Test each pump individually
* 3. Test PWM speed control
* 4. Test safety features
* 5. Test both pumps together
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "motor_control.h"
static const char *TAG = "MOTOR_TEST";
// Test callbacks
static void test_state_callback(motor_id_t id, motor_state_t state)
{
const char *state_str[] = {"STOPPED", "RUNNING", "ERROR", "COOLDOWN"};
ESP_LOGI(TAG, "Motor %d state: %s", id, state_str[state]);
}
static void test_error_callback(motor_id_t id, const char* error)
{
ESP_LOGE(TAG, "Motor %d error: %s", id, error);
}
void app_main(void)
{
ESP_LOGI(TAG, "=== TB6612FNG Motor Driver Test Program ===");
ESP_LOGI(TAG, "GPIO Connections:");
ESP_LOGI(TAG, " AIN1 (Pump1 Dir): GPIO%d", MOTOR_AIN1_GPIO);
ESP_LOGI(TAG, " AIN2 (Pump1 Dir): GPIO%d", MOTOR_AIN2_GPIO);
ESP_LOGI(TAG, " BIN1 (Pump2 Dir): GPIO%d", MOTOR_BIN1_GPIO);
ESP_LOGI(TAG, " BIN2 (Pump2 Dir): GPIO%d", MOTOR_BIN2_GPIO);
ESP_LOGI(TAG, " PWMA (Pump1 PWM): GPIO%d", MOTOR_PWMA_GPIO);
ESP_LOGI(TAG, " PWMB (Pump2 PWM): GPIO%d", MOTOR_PWMB_GPIO);
ESP_LOGI(TAG, " STBY (Standby): GPIO%d", MOTOR_STBY_GPIO);
// Initialize motor control
ESP_LOGI(TAG, "\n--- Initializing Motor Control ---");
esp_err_t ret = motor_control_init();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialize motor control: %s", esp_err_to_name(ret));
return;
}
// Register callbacks
motor_register_state_callback(test_state_callback);
motor_register_error_callback(test_error_callback);
// Wait a bit
vTaskDelay(pdMS_TO_TICKS(2000));
// Test 1: Basic ON/OFF for Pump 1
ESP_LOGI(TAG, "\n--- Test 1: Pump 1 Basic ON/OFF ---");
ESP_LOGI(TAG, "Starting Pump 1 at default speed (%d%%)", MOTOR_DEFAULT_SPEED);
motor_start(MOTOR_PUMP_1, MOTOR_DEFAULT_SPEED);
vTaskDelay(pdMS_TO_TICKS(3000));
ESP_LOGI(TAG, "Stopping Pump 1");
motor_stop(MOTOR_PUMP_1);
vTaskDelay(pdMS_TO_TICKS(2000));
// Test 2: Basic ON/OFF for Pump 2
ESP_LOGI(TAG, "\n--- Test 2: Pump 2 Basic ON/OFF ---");
ESP_LOGI(TAG, "Starting Pump 2 at default speed (%d%%)", MOTOR_DEFAULT_SPEED);
motor_start(MOTOR_PUMP_2, MOTOR_DEFAULT_SPEED);
vTaskDelay(pdMS_TO_TICKS(3000));
ESP_LOGI(TAG, "Stopping Pump 2");
motor_stop(MOTOR_PUMP_2);
vTaskDelay(pdMS_TO_TICKS(2000));
// Test 3: PWM Speed Control
ESP_LOGI(TAG, "\n--- Test 3: PWM Speed Control (Pump 1) ---");
int speeds[] = {30, 50, 70, 90, 100};
for (int i = 0; i < sizeof(speeds)/sizeof(speeds[0]); i++) {
ESP_LOGI(TAG, "Testing speed: %d%%", speeds[i]);
motor_start(MOTOR_PUMP_1, speeds[i]);
vTaskDelay(pdMS_TO_TICKS(2000));
}
motor_stop(MOTOR_PUMP_1);
vTaskDelay(pdMS_TO_TICKS(2000));
// Test 4: Timed Run
ESP_LOGI(TAG, "\n--- Test 4: Timed Run (5 seconds) ---");
ESP_LOGI(TAG, "Starting Pump 1 for 5 seconds");
motor_start_timed(MOTOR_PUMP_1, 70, 5000);
vTaskDelay(pdMS_TO_TICKS(7000)); // Wait for completion
// Test 5: Both pumps together
ESP_LOGI(TAG, "\n--- Test 5: Both Pumps Together ---");
ESP_LOGI(TAG, "Starting both pumps");
motor_start(MOTOR_PUMP_1, 60);
motor_start(MOTOR_PUMP_2, 80);
vTaskDelay(pdMS_TO_TICKS(3000));
ESP_LOGI(TAG, "Stopping both pumps");
motor_stop_all();
vTaskDelay(pdMS_TO_TICKS(2000));
// Test 6: Safety - Cooldown Period
ESP_LOGI(TAG, "\n--- Test 6: Cooldown Period Test ---");
motor_set_min_interval(MOTOR_PUMP_1, 5000); // 5 second cooldown for test
ESP_LOGI(TAG, "Starting pump 1");
motor_start(MOTOR_PUMP_1, 50);
vTaskDelay(pdMS_TO_TICKS(2000));
motor_stop(MOTOR_PUMP_1);
ESP_LOGI(TAG, "Attempting to restart immediately (should fail)");
ret = motor_start(MOTOR_PUMP_1, 50);
if (ret != ESP_OK) {
ESP_LOGI(TAG, "Good! Cooldown protection working");
}
ESP_LOGI(TAG, "Waiting for cooldown period...");
vTaskDelay(pdMS_TO_TICKS(6000));
ESP_LOGI(TAG, "Attempting to start after cooldown");
ret = motor_start(MOTOR_PUMP_1, 50);
if (ret == ESP_OK) {
ESP_LOGI(TAG, "Good! Pump started after cooldown");
vTaskDelay(pdMS_TO_TICKS(2000));
motor_stop(MOTOR_PUMP_1);
}
// Test 7: Speed change while running
ESP_LOGI(TAG, "\n--- Test 7: Speed Change While Running ---");
ESP_LOGI(TAG, "Starting at 30%%");
motor_start(MOTOR_PUMP_1, 30);
vTaskDelay(pdMS_TO_TICKS(2000));
ESP_LOGI(TAG, "Changing to 70%%");
motor_set_speed(MOTOR_PUMP_1, 70);
vTaskDelay(pdMS_TO_TICKS(2000));
ESP_LOGI(TAG, "Changing to 100%%");
motor_set_speed(MOTOR_PUMP_1, 100);
vTaskDelay(pdMS_TO_TICKS(2000));
motor_stop(MOTOR_PUMP_1);
// Test 8: Emergency Stop
ESP_LOGI(TAG, "\n--- Test 8: Emergency Stop ---");
ESP_LOGI(TAG, "Starting both pumps");
motor_start(MOTOR_PUMP_1, 80);
motor_start(MOTOR_PUMP_2, 80);
vTaskDelay(pdMS_TO_TICKS(2000));
ESP_LOGI(TAG, "Triggering emergency stop!");
motor_emergency_stop();
ESP_LOGI(TAG, "Checking states after emergency stop");
if (!motor_is_running(MOTOR_PUMP_1) && !motor_is_running(MOTOR_PUMP_2)) {
ESP_LOGI(TAG, "Good! Both pumps stopped");
}
vTaskDelay(pdMS_TO_TICKS(2000));
// Test 9: Get Statistics
ESP_LOGI(TAG, "\n--- Test 9: Runtime Statistics ---");
motor_stats_t stats;
for (int i = 1; i <= 2; i++) {
if (motor_get_stats(i, &stats) == ESP_OK) {
ESP_LOGI(TAG, "Pump %d Statistics:", i);
ESP_LOGI(TAG, " Total runtime: %lu ms", stats.total_runtime_ms);
ESP_LOGI(TAG, " Run count: %lu", stats.run_count);
ESP_LOGI(TAG, " Last duration: %lu ms", stats.last_run_duration_ms);
ESP_LOGI(TAG, " Error count: %lu", stats.error_count);
}
}
// Test 10: Maximum runtime safety
ESP_LOGI(TAG, "\n--- Test 10: Maximum Runtime Safety ---");
motor_set_max_runtime(MOTOR_PUMP_1, 3000); // 3 second max for test
ESP_LOGI(TAG, "Starting pump 1 (should auto-stop after 3 seconds)");
motor_start(MOTOR_PUMP_1, 50);
// Wait for safety timer
vTaskDelay(pdMS_TO_TICKS(5000));
if (!motor_is_running(MOTOR_PUMP_1)) {
ESP_LOGI(TAG, "Good! Safety timer stopped the pump");
}
// Test 11: Soft Start Observation
ESP_LOGI(TAG, "\n--- Test 11: Soft Start Observation ---");
ESP_LOGI(TAG, "Watch/listen for gradual speed increase over 500ms");
motor_start(MOTOR_PUMP_1, 100);
vTaskDelay(pdMS_TO_TICKS(3000));
motor_stop(MOTOR_PUMP_1);
// Final test summary
ESP_LOGI(TAG, "\n=== All Tests Complete ===");
ESP_LOGI(TAG, "Test Summary:");
ESP_LOGI(TAG, " ✓ Basic ON/OFF control");
ESP_LOGI(TAG, " ✓ PWM speed control");
ESP_LOGI(TAG, " ✓ Timed operations");
ESP_LOGI(TAG, " ✓ Dual pump control");
ESP_LOGI(TAG, " ✓ Safety features");
ESP_LOGI(TAG, " ✓ Emergency stop");
ESP_LOGI(TAG, " ✓ Statistics tracking");
ESP_LOGI(TAG, "");
ESP_LOGI(TAG, "Monitor the pumps to ensure they responded correctly to all commands");
ESP_LOGI(TAG, "Check for any unusual noises, heating, or behavior");
// Keep running and print status periodically
ESP_LOGI(TAG, "\nEntering monitoring mode - System status every 10 seconds");
while (1) {
vTaskDelay(pdMS_TO_TICKS(10000));
ESP_LOGI(TAG, "--- System Status ---");
ESP_LOGI(TAG, "Free heap: %d bytes", esp_get_free_heap_size());
for (int i = 1; i <= 2; i++) {
motor_stats_t current_stats;
if (motor_get_stats(i, &current_stats) == ESP_OK) {
const char *state = "IDLE";
if (motor_is_running(i)) {
state = "RUNNING";
} else if (motor_is_cooldown(i)) {
state = "COOLDOWN";
}
ESP_LOGI(TAG, "Pump %d: State=%s, Total runs=%lu, Total time=%lu s",
i, state, current_stats.run_count,
current_stats.total_runtime_ms / 1000);
}
}
}
}