Motor control implemented
This commit is contained in:
40
main/main.c
40
main/main.c
@ -12,6 +12,9 @@
|
|||||||
#include "motor_control.h"
|
#include "motor_control.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
// Uncomment this line to enable motor test mode with shorter intervals
|
||||||
|
// #define MOTOR_TEST_MODE
|
||||||
|
|
||||||
static const char *TAG = "MAIN";
|
static const char *TAG = "MAIN";
|
||||||
|
|
||||||
// Application version
|
// Application version
|
||||||
@ -76,6 +79,7 @@ static void mqtt_connected_callback(void)
|
|||||||
"plant_watering/pump/+/speed",
|
"plant_watering/pump/+/speed",
|
||||||
"plant_watering/commands/test_pump/+",
|
"plant_watering/commands/test_pump/+",
|
||||||
"plant_watering/commands/emergency_stop",
|
"plant_watering/commands/emergency_stop",
|
||||||
|
"plant_watering/commands/test_mode",
|
||||||
"plant_watering/settings/+/+",
|
"plant_watering/settings/+/+",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
@ -161,17 +165,37 @@ static void mqtt_data_callback(const char* topic, const char* data, int data_len
|
|||||||
// Parse JSON configuration here
|
// Parse JSON configuration here
|
||||||
} else if (strcmp(topic, "plant_watering/commands/test_pump/1") == 0) {
|
} else if (strcmp(topic, "plant_watering/commands/test_pump/1") == 0) {
|
||||||
uint32_t duration = atoi(data);
|
uint32_t duration = atoi(data);
|
||||||
if (duration > 0 && duration <= 10000) { // Max 10 seconds for test
|
if (duration > 0 && duration <= 30000) { // Max 30 seconds for test
|
||||||
|
ESP_LOGI(TAG, "Test pump 1 for %lu ms", duration);
|
||||||
motor_test_run(MOTOR_PUMP_1, duration);
|
motor_test_run(MOTOR_PUMP_1, duration);
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "Invalid test duration: %lu (max 30000ms)", duration);
|
||||||
}
|
}
|
||||||
} else if (strcmp(topic, "plant_watering/commands/test_pump/2") == 0) {
|
} else if (strcmp(topic, "plant_watering/commands/test_pump/2") == 0) {
|
||||||
uint32_t duration = atoi(data);
|
uint32_t duration = atoi(data);
|
||||||
if (duration > 0 && duration <= 10000) { // Max 10 seconds for test
|
if (duration > 0 && duration <= 30000) { // Max 30 seconds for test
|
||||||
|
ESP_LOGI(TAG, "Test pump 2 for %lu ms", duration);
|
||||||
motor_test_run(MOTOR_PUMP_2, duration);
|
motor_test_run(MOTOR_PUMP_2, duration);
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "Invalid test duration: %lu (max 30000ms)", duration);
|
||||||
}
|
}
|
||||||
} else if (strcmp(topic, "plant_watering/commands/emergency_stop") == 0) {
|
} else if (strcmp(topic, "plant_watering/commands/emergency_stop") == 0) {
|
||||||
ESP_LOGW(TAG, "Emergency stop command received!");
|
ESP_LOGW(TAG, "Emergency stop command received!");
|
||||||
motor_emergency_stop();
|
motor_emergency_stop();
|
||||||
|
} else if (strcmp(topic, "plant_watering/commands/test_mode") == 0) {
|
||||||
|
if (strncmp(data, "on", data_len) == 0) {
|
||||||
|
ESP_LOGW(TAG, "Enabling test mode - short intervals");
|
||||||
|
motor_set_min_interval(MOTOR_PUMP_1, 5000); // 5 seconds
|
||||||
|
motor_set_min_interval(MOTOR_PUMP_2, 5000);
|
||||||
|
motor_set_max_runtime(MOTOR_PUMP_1, 30000); // 30 seconds
|
||||||
|
motor_set_max_runtime(MOTOR_PUMP_2, 30000);
|
||||||
|
} else if (strncmp(data, "off", data_len) == 0) {
|
||||||
|
ESP_LOGI(TAG, "Disabling test mode - normal intervals");
|
||||||
|
motor_set_min_interval(MOTOR_PUMP_1, CONFIG_WATERING_MIN_INTERVAL_MS);
|
||||||
|
motor_set_min_interval(MOTOR_PUMP_2, CONFIG_WATERING_MIN_INTERVAL_MS);
|
||||||
|
motor_set_max_runtime(MOTOR_PUMP_1, CONFIG_WATERING_MAX_DURATION_MS);
|
||||||
|
motor_set_max_runtime(MOTOR_PUMP_2, CONFIG_WATERING_MAX_DURATION_MS);
|
||||||
|
}
|
||||||
} else if (strncmp(topic, "plant_watering/settings/pump/", 29) == 0) {
|
} else if (strncmp(topic, "plant_watering/settings/pump/", 29) == 0) {
|
||||||
// Parse settings commands like:
|
// Parse settings commands like:
|
||||||
// plant_watering/settings/pump/1/max_runtime
|
// plant_watering/settings/pump/1/max_runtime
|
||||||
@ -373,11 +397,21 @@ void app_main(void)
|
|||||||
motor_register_state_callback(motor_state_change_callback);
|
motor_register_state_callback(motor_state_change_callback);
|
||||||
motor_register_error_callback(motor_error_callback);
|
motor_register_error_callback(motor_error_callback);
|
||||||
|
|
||||||
// Configure motor safety limits from Kconfig
|
// Configure motor safety limits
|
||||||
|
#ifdef MOTOR_TEST_MODE
|
||||||
|
// Use shorter limits for testing
|
||||||
|
ESP_LOGI(TAG, "MOTOR TEST MODE - Using short intervals for testing");
|
||||||
|
motor_set_max_runtime(MOTOR_PUMP_1, 30000); // 30 seconds max
|
||||||
|
motor_set_max_runtime(MOTOR_PUMP_2, 30000);
|
||||||
|
motor_set_min_interval(MOTOR_PUMP_1, 5000); // 5 seconds for testing
|
||||||
|
motor_set_min_interval(MOTOR_PUMP_2, 5000);
|
||||||
|
#else
|
||||||
|
// Use production values from Kconfig
|
||||||
motor_set_max_runtime(MOTOR_PUMP_1, CONFIG_WATERING_MAX_DURATION_MS);
|
motor_set_max_runtime(MOTOR_PUMP_1, CONFIG_WATERING_MAX_DURATION_MS);
|
||||||
motor_set_max_runtime(MOTOR_PUMP_2, CONFIG_WATERING_MAX_DURATION_MS);
|
motor_set_max_runtime(MOTOR_PUMP_2, CONFIG_WATERING_MAX_DURATION_MS);
|
||||||
motor_set_min_interval(MOTOR_PUMP_1, CONFIG_WATERING_MIN_INTERVAL_MS);
|
motor_set_min_interval(MOTOR_PUMP_1, CONFIG_WATERING_MIN_INTERVAL_MS);
|
||||||
motor_set_min_interval(MOTOR_PUMP_2, CONFIG_WATERING_MIN_INTERVAL_MS);
|
motor_set_min_interval(MOTOR_PUMP_2, CONFIG_WATERING_MIN_INTERVAL_MS);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Start WiFi connection
|
// Start WiFi connection
|
||||||
esp_err_t ret = wifi_manager_start();
|
esp_err_t ret = wifi_manager_start();
|
||||||
|
|||||||
@ -182,7 +182,10 @@ esp_err_t motor_control_init(void)
|
|||||||
|
|
||||||
// Create safety timers
|
// Create safety timers
|
||||||
for (int i = 0; i < MOTOR_PUMP_MAX - 1; i++) {
|
for (int i = 0; i < MOTOR_PUMP_MAX - 1; i++) {
|
||||||
s_motors[i].safety_timer = xTimerCreate("motor_safety",
|
char timer_name[32];
|
||||||
|
snprintf(timer_name, sizeof(timer_name), "motor_safety_%d", i + 1);
|
||||||
|
|
||||||
|
s_motors[i].safety_timer = xTimerCreate(timer_name,
|
||||||
pdMS_TO_TICKS(1000),
|
pdMS_TO_TICKS(1000),
|
||||||
pdFALSE,
|
pdFALSE,
|
||||||
(void*)(i + 1),
|
(void*)(i + 1),
|
||||||
@ -193,7 +196,8 @@ esp_err_t motor_control_init(void)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_motors[i].soft_start_timer = xTimerCreate("motor_soft_start",
|
snprintf(timer_name, sizeof(timer_name), "motor_soft_%d", i + 1);
|
||||||
|
s_motors[i].soft_start_timer = xTimerCreate(timer_name,
|
||||||
pdMS_TO_TICKS(50),
|
pdMS_TO_TICKS(50),
|
||||||
pdTRUE,
|
pdTRUE,
|
||||||
(void*)(i + 1),
|
(void*)(i + 1),
|
||||||
@ -627,13 +631,22 @@ esp_err_t motor_test_run(motor_id_t id, uint32_t duration_ms)
|
|||||||
static void motor_safety_timer_callback(TimerHandle_t xTimer)
|
static void motor_safety_timer_callback(TimerHandle_t xTimer)
|
||||||
{
|
{
|
||||||
motor_id_t id = (motor_id_t)(intptr_t)pvTimerGetTimerID(xTimer);
|
motor_id_t id = (motor_id_t)(intptr_t)pvTimerGetTimerID(xTimer);
|
||||||
|
motor_t *motor = &s_motors[id - 1];
|
||||||
|
|
||||||
ESP_LOGW(TAG, "Safety timer expired for motor %d", id);
|
ESP_LOGW(TAG, "Safety timer expired for motor %d", id);
|
||||||
motor_stop(id);
|
|
||||||
|
|
||||||
if (s_error_callback) {
|
// Do minimal work in timer callback to avoid stack overflow
|
||||||
s_error_callback(id, "Maximum runtime exceeded");
|
// Just stop the PWM and update state
|
||||||
}
|
ledc_set_duty(LEDC_LOW_SPEED_MODE, motor->pwm_channel, 0);
|
||||||
|
ledc_update_duty(LEDC_LOW_SPEED_MODE, motor->pwm_channel);
|
||||||
|
|
||||||
|
// Update basic state
|
||||||
|
motor->speed_percent = 0;
|
||||||
|
motor->state = MOTOR_STATE_STOPPED;
|
||||||
|
|
||||||
|
// Stats update can be deferred or done in main context
|
||||||
|
// For now, just record the stop time
|
||||||
|
motor->last_stop_time = get_time_ms();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void motor_soft_start_timer_callback(TimerHandle_t xTimer)
|
static void motor_soft_start_timer_callback(TimerHandle_t xTimer)
|
||||||
@ -661,7 +674,10 @@ static void motor_soft_start_timer_callback(TimerHandle_t xTimer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t duty = (motor->speed_percent * MOTOR_PWM_MAX_DUTY) / 100;
|
uint8_t duty = (motor->speed_percent * MOTOR_PWM_MAX_DUTY) / 100;
|
||||||
motor_update_pwm(id, duty);
|
|
||||||
|
// Update PWM directly without taking mutex (atomic operation)
|
||||||
|
ledc_set_duty(LEDC_LOW_SPEED_MODE, motor->pwm_channel, duty);
|
||||||
|
ledc_update_duty(LEDC_LOW_SPEED_MODE, motor->pwm_channel);
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Soft start motor %d: %d%% (target: %d%%)",
|
ESP_LOGD(TAG, "Soft start motor %d: %d%% (target: %d%%)",
|
||||||
id, motor->speed_percent, motor->target_speed);
|
id, motor->speed_percent, motor->target_speed);
|
||||||
|
|||||||
@ -21,9 +21,16 @@
|
|||||||
// Safety Configuration
|
// Safety Configuration
|
||||||
#define MOTOR_DEFAULT_SPEED 80 // Default pump speed (%)
|
#define MOTOR_DEFAULT_SPEED 80 // Default pump speed (%)
|
||||||
#define MOTOR_MIN_SPEED 20 // Minimum pump speed (%)
|
#define MOTOR_MIN_SPEED 20 // Minimum pump speed (%)
|
||||||
#define MOTOR_MAX_RUNTIME_MS 30000 // Maximum runtime (30 seconds)
|
|
||||||
#define MOTOR_MIN_INTERVAL_MS 300000 // Minimum interval between runs (5 minutes)
|
// Default safety limits (can be overridden at runtime)
|
||||||
#define MOTOR_SOFT_START_TIME_MS 1000 // Soft start ramp time
|
#define MOTOR_MAX_RUNTIME_MS 30000 // Default maximum runtime (30 seconds)
|
||||||
|
#define MOTOR_MIN_INTERVAL_MS 300000 // Default minimum interval between runs (5 minutes)
|
||||||
|
|
||||||
|
// Test mode limits (shorter for testing)
|
||||||
|
#define MOTOR_TEST_MAX_RUNTIME_MS 30000 // Test mode max runtime (30 seconds)
|
||||||
|
#define MOTOR_TEST_MIN_INTERVAL_MS 5000 // Test mode min interval (5 seconds)
|
||||||
|
|
||||||
|
#define MOTOR_SOFT_START_TIME_MS 500 // Soft start ramp time
|
||||||
|
|
||||||
// Motor IDs
|
// Motor IDs
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
242
main/motor_test.c
Normal file
242
main/motor_test.c
Normal 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, ¤t_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user