From 15f8d41656beb28d13ceb654dcc7a6a6085326ab Mon Sep 17 00:00:00 2001 From: Stephen Minakian Date: Wed, 9 Jul 2025 17:10:51 -0600 Subject: [PATCH] Refactored out config and macros --- main/config.h | 124 ++++++++++++++++++ main/maxxfan-controller.c | 266 ++++++++++++++++---------------------- 2 files changed, 239 insertions(+), 151 deletions(-) create mode 100644 main/config.h diff --git a/main/config.h b/main/config.h new file mode 100644 index 0000000..90fc402 --- /dev/null +++ b/main/config.h @@ -0,0 +1,124 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#include "driver/gpio.h" +#include "driver/ledc.h" + +// ================================ +// WiFi Configuration +// ================================ +#define WIFI_SSID "GL-AXT1800-0c2" +#define WIFI_PASS "CR7W25FM8S" +#define WIFI_MAXIMUM_RETRY 5 + +// WiFi event group bits +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 + +// ================================ +// GPIO Pin Definitions +// ================================ +#define LED_PIN GPIO_NUM_13 +#define MOTOR_R_EN GPIO_NUM_18 +#define MOTOR_L_EN GPIO_NUM_19 +#define PWM_R_PIN GPIO_NUM_21 +#define PWM_L_PIN GPIO_NUM_22 + +// ================================ +// PWM Configuration +// ================================ +#define PWM_FREQUENCY 20000 +#define PWM_RESOLUTION LEDC_TIMER_8_BIT +#define PWM_R_CHANNEL LEDC_CHANNEL_0 +#define PWM_L_CHANNEL LEDC_CHANNEL_1 +#define PWM_TIMER LEDC_TIMER_0 +#define PWM_SPEED_MODE LEDC_LOW_SPEED_MODE + +// ================================ +// Motor Control Configuration +// ================================ +#define RAMP_STEP_MS 150 // Time between ramp steps (milliseconds) +#define RAMP_STEP_SIZE 5 // PWM duty change per step (0-255) +#define MIN_MOTOR_SPEED 10 // Minimum speed to overcome motor inertia +#define DIRECTION_CHANGE_COOLDOWN_MS 10000 // 10 seconds cooldown for direction changes + +// ================================ +// Watchdog Configuration +// ================================ +#define WATCHDOG_TIMEOUT_S 10 // Watchdog timeout in seconds +#define WATCHDOG_FEED_INTERVAL_MS 3000 // Feed watchdog every 3 seconds + +// ================================ +// State Preservation Configuration +// ================================ +#define NVS_NAMESPACE "fan_state" +#define NVS_KEY_MODE "mode" +#define NVS_KEY_SPEED "speed" +#define NVS_KEY_LAST_ON_MODE "last_mode" +#define NVS_KEY_LAST_ON_SPEED "last_speed" +#define NVS_KEY_POWER_STATE "power_state" + +// ================================ +// HTTP Server Configuration +// ================================ +#define HTTP_SERVER_PORT 80 +#define HTTP_MAX_URI_HANDLERS 15 +#define HTTP_RECV_TIMEOUT_SEC 10 +#define HTTP_SEND_TIMEOUT_SEC 10 + +// ================================ +// Status Update Configuration +// ================================ +#define STATUS_UPDATE_INTERVAL_MS 1000 // Web interface status update interval + +// ================================ +// System Configuration +// ================================ +#define SYSTEM_TAG "HTTP_MOTOR" // Main logging tag + +// ================================ +// Safety Limits +// ================================ +#define MAX_SPEED_PERCENT 100 +#define MIN_SPEED_PERCENT 0 +#define MAX_JSON_BUFFER_SIZE 200 + +// ================================ +// Motor PWM Calculation Macros +// ================================ +#define SPEED_TO_DUTY(speed_percent) ((speed_percent * 255) / 100) +#define DUTY_TO_SPEED(duty) ((duty * 100) / 255) + +// ================================ +// Validation Macros +// ================================ +#define CLAMP_SPEED(speed) ((speed) < MIN_SPEED_PERCENT ? MIN_SPEED_PERCENT : \ + (speed) > MAX_SPEED_PERCENT ? MAX_SPEED_PERCENT : (speed)) + +// For unsigned types (uint8_t), we only need to check the upper bound since MIN_SPEED_PERCENT is 0 +#define IS_VALID_SPEED(speed) ((speed) <= MAX_SPEED_PERCENT) + +// For signed types or when MIN_SPEED_PERCENT might be > 0, use this version: +#define IS_VALID_SPEED_FULL(speed) ((speed) >= MIN_SPEED_PERCENT && (speed) <= MAX_SPEED_PERCENT) + +#define IS_DIRECTION_CHANGE(old_mode, new_mode) \ + (((old_mode) == MOTOR_EXHAUST && (new_mode) == MOTOR_INTAKE) || \ + ((old_mode) == MOTOR_INTAKE && (new_mode) == MOTOR_EXHAUST)) + +// ================================ +// Debug Configuration +// ================================ +#ifdef CONFIG_LOG_DEFAULT_LEVEL_DEBUG +#define MOTOR_DEBUG_ENABLED 1 +#else +#define MOTOR_DEBUG_ENABLED 0 +#endif + +// Debug logging macro +#if MOTOR_DEBUG_ENABLED +#define MOTOR_LOGD(tag, format, ...) ESP_LOGD(tag, format, ##__VA_ARGS__) +#else +#define MOTOR_LOGD(tag, format, ...) +#endif + +#endif // CONFIG_H \ No newline at end of file diff --git a/main/maxxfan-controller.c b/main/maxxfan-controller.c index 0af619b..ca94ed3 100755 --- a/main/maxxfan-controller.c +++ b/main/maxxfan-controller.c @@ -16,48 +16,11 @@ #include "driver/ledc.h" #include "cJSON.h" -// WiFi credentials - CHANGE THESE TO YOUR NETWORK -#define WIFI_SSID "GL-AXT1800-0c2" -#define WIFI_PASS "CR7W25FM8S" -#define WIFI_MAXIMUM_RETRY 5 - -// Pin definitions -#define LED_PIN GPIO_NUM_13 -#define MOTOR_R_EN GPIO_NUM_18 -#define MOTOR_L_EN GPIO_NUM_19 -#define PWM_R_PIN GPIO_NUM_21 -#define PWM_L_PIN GPIO_NUM_22 - -// PWM configuration -#define PWM_FREQUENCY 20000 -#define PWM_RESOLUTION LEDC_TIMER_8_BIT -#define PWM_R_CHANNEL LEDC_CHANNEL_0 -#define PWM_L_CHANNEL LEDC_CHANNEL_1 - -// Motor ramping configuration -#define RAMP_STEP_MS 150 // Time between ramp steps (milliseconds) -#define RAMP_STEP_SIZE 5 // PWM duty change per step (0-255) -#define MIN_MOTOR_SPEED 10 // Minimum speed to overcome motor inertia -#define DIRECTION_CHANGE_COOLDOWN_MS 10000 // 10 seconds cooldown for direction changes - -// Watchdog configuration -#define WATCHDOG_TIMEOUT_S 10 // Watchdog timeout in seconds - -// State preservation configuration -#define NVS_NAMESPACE "fan_state" -#define NVS_KEY_MODE "mode" -#define NVS_KEY_SPEED "speed" -#define NVS_KEY_LAST_ON_MODE "last_mode" -#define NVS_KEY_LAST_ON_SPEED "last_speed" -#define NVS_KEY_POWER_STATE "power_state" - -static const char* TAG = "HTTP_MOTOR"; +// Project configuration +#include "config.h" // WiFi event group static EventGroupHandle_t s_wifi_event_group; -#define WIFI_CONNECTED_BIT BIT0 -#define WIFI_FAIL_BIT BIT1 - static int s_retry_num = 0; // Motor control @@ -184,18 +147,18 @@ static void save_last_on_state(motor_mode_t mode, int speed); // Initialize watchdog timer void init_watchdog(void) { - ESP_LOGI(TAG, "Setting up watchdog monitoring..."); + ESP_LOGI(SYSTEM_TAG, "Setting up watchdog monitoring..."); // Get current task handle and add to watchdog main_task_handle = xTaskGetCurrentTaskHandle(); esp_err_t result = esp_task_wdt_add(main_task_handle); if (result == ESP_OK) { - ESP_LOGI(TAG, "Main task added to watchdog monitoring"); + ESP_LOGI(SYSTEM_TAG, "Main task added to watchdog monitoring"); } else if (result == ESP_ERR_INVALID_ARG) { - ESP_LOGI(TAG, "Task already monitored by watchdog"); + ESP_LOGI(SYSTEM_TAG, "Task already monitored by watchdog"); } else { - ESP_LOGW(TAG, "Watchdog not available: %s", esp_err_to_name(result)); + ESP_LOGW(SYSTEM_TAG, "Watchdog not available: %s", esp_err_to_name(result)); main_task_handle = NULL; // Disable watchdog feeding } } @@ -205,7 +168,7 @@ void feed_watchdog(void) { if (main_task_handle != NULL) { esp_err_t result = esp_task_wdt_reset(); if (result != ESP_OK) { - ESP_LOGD(TAG, "Watchdog reset failed: %s", esp_err_to_name(result)); + MOTOR_LOGD(SYSTEM_TAG, "Watchdog reset failed: %s", esp_err_to_name(result)); } } } @@ -227,12 +190,12 @@ static esp_err_t save_motor_state_to_nvs(void) { err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &nvs_handle); if (err != ESP_OK) { - ESP_LOGE(TAG, "Error opening NVS handle: %s", esp_err_to_name(err)); + ESP_LOGE(SYSTEM_TAG, "Error opening NVS handle: %s", esp_err_to_name(err)); return err; } - ESP_LOGI(TAG, "=== SAVING STATE TO NVS ==="); - ESP_LOGI(TAG, "Mode: %d, Speed: %d%%, Last ON: %d@%d%%, User OFF: %s", + ESP_LOGI(SYSTEM_TAG, "=== SAVING STATE TO NVS ==="); + ESP_LOGI(SYSTEM_TAG, "Mode: %d, Speed: %d%%, Last ON: %d@%d%%, User OFF: %s", motor_state.mode, motor_state.target_speed, motor_state.last_on_mode, motor_state.last_on_speed, motor_state.user_turned_off ? "YES" : "NO"); @@ -259,14 +222,14 @@ static esp_err_t save_motor_state_to_nvs(void) { if (err == ESP_OK) { err = nvs_commit(nvs_handle); if (err == ESP_OK) { - ESP_LOGI(TAG, "✓ Motor state successfully saved to NVS"); + ESP_LOGI(SYSTEM_TAG, "✓ Motor state successfully saved to NVS"); } else { - ESP_LOGE(TAG, "✗ NVS commit failed: %s", esp_err_to_name(err)); + ESP_LOGE(SYSTEM_TAG, "✗ NVS commit failed: %s", esp_err_to_name(err)); } } else { - ESP_LOGE(TAG, "✗ Error saving to NVS: %s", esp_err_to_name(err)); + ESP_LOGE(SYSTEM_TAG, "✗ Error saving to NVS: %s", esp_err_to_name(err)); } - ESP_LOGI(TAG, "==========================="); + ESP_LOGI(SYSTEM_TAG, "==========================="); nvs_close(nvs_handle); return err; @@ -279,7 +242,7 @@ static esp_err_t load_motor_state_from_nvs(void) { err = nvs_open(NVS_NAMESPACE, NVS_READONLY, &nvs_handle); if (err != ESP_OK) { - ESP_LOGI(TAG, "NVS not found, using default state"); + ESP_LOGI(SYSTEM_TAG, "NVS not found, using default state"); return ESP_ERR_NVS_NOT_FOUND; } @@ -297,27 +260,27 @@ static esp_err_t load_motor_state_from_nvs(void) { nvs_get_u8(nvs_handle, NVS_KEY_LAST_ON_SPEED, &stored_last_speed); nvs_get_u8(nvs_handle, NVS_KEY_POWER_STATE, &stored_power_state); - // Validate ranges + // Validate ranges using config macros if (stored_mode > MOTOR_INTAKE) stored_mode = MOTOR_OFF; - if (stored_speed > 100) stored_speed = 0; + if (!IS_VALID_SPEED(stored_speed)) stored_speed = 0; if (stored_last_mode < MOTOR_EXHAUST || stored_last_mode > MOTOR_INTAKE) stored_last_mode = MOTOR_EXHAUST; - if (stored_last_speed > 100) stored_last_speed = 50; + if (!IS_VALID_SPEED(stored_last_speed)) stored_last_speed = 50; motor_state.last_on_mode = (motor_mode_t)stored_last_mode; motor_state.last_on_speed = stored_last_speed; motor_state.user_turned_off = (stored_power_state == 1); - ESP_LOGI(TAG, "Loaded state from NVS - Mode: %d, Speed: %d%%, Last ON: %d@%d%%, User OFF: %s", + ESP_LOGI(SYSTEM_TAG, "Loaded state from NVS - Mode: %d, Speed: %d%%, Last ON: %d@%d%%, User OFF: %s", stored_mode, stored_speed, motor_state.last_on_mode, motor_state.last_on_speed, motor_state.user_turned_off ? "YES" : "NO"); - // Check reset reason to decide whether to restore state + // Check reset reason to decide whether to restore state bool was_watchdog_reset = is_watchdog_reset(); esp_reset_reason_t reset_reason = esp_reset_reason(); - ESP_LOGI(TAG, "=== RESET ANALYSIS ==="); - ESP_LOGI(TAG, "Reset reason: %d", reset_reason); - ESP_LOGI(TAG, "Reset reason name: %s", + ESP_LOGI(SYSTEM_TAG, "=== RESET ANALYSIS ==="); + ESP_LOGI(SYSTEM_TAG, "Reset reason: %d", reset_reason); + ESP_LOGI(SYSTEM_TAG, "Reset reason name: %s", reset_reason == ESP_RST_POWERON ? "POWERON" : reset_reason == ESP_RST_EXT ? "EXTERNAL" : reset_reason == ESP_RST_SW ? "SOFTWARE" : @@ -328,39 +291,39 @@ static esp_err_t load_motor_state_from_nvs(void) { reset_reason == ESP_RST_DEEPSLEEP ? "DEEPSLEEP" : reset_reason == ESP_RST_BROWNOUT ? "BROWNOUT" : reset_reason == ESP_RST_SDIO ? "SDIO" : "UNKNOWN"); - ESP_LOGI(TAG, "Watchdog reset: %s", was_watchdog_reset ? "YES" : "NO"); - ESP_LOGI(TAG, "Stored mode: %d, speed: %d", stored_mode, stored_speed); - ESP_LOGI(TAG, "User turned off: %s", motor_state.user_turned_off ? "YES" : "NO"); - ESP_LOGI(TAG, "===================="); + ESP_LOGI(SYSTEM_TAG, "Watchdog reset: %s", was_watchdog_reset ? "YES" : "NO"); + ESP_LOGI(SYSTEM_TAG, "Stored mode: %d, speed: %d", stored_mode, stored_speed); + ESP_LOGI(SYSTEM_TAG, "User turned off: %s", motor_state.user_turned_off ? "YES" : "NO"); + ESP_LOGI(SYSTEM_TAG, "===================="); if (was_watchdog_reset) { // True watchdog reset (TASK_WDT or INT_WDT) - don't restore state, start fresh - ESP_LOGI(TAG, "⚠️ TRUE watchdog reset detected - starting in OFF state for safety"); + ESP_LOGI(SYSTEM_TAG, "⚠️ TRUE watchdog reset detected - starting in OFF state for safety"); motor_state.mode = MOTOR_OFF; motor_state.target_speed = 0; motor_state.current_speed = 0; motor_state.user_turned_off = false; // Reset user off flag } else if (motor_state.user_turned_off) { // User manually turned off - stay off - ESP_LOGI(TAG, "🔒 User had turned off manually - staying OFF"); + ESP_LOGI(SYSTEM_TAG, "🔒 User had turned off manually - staying OFF"); motor_state.mode = MOTOR_OFF; motor_state.target_speed = 0; motor_state.current_speed = 0; } else if (stored_mode != MOTOR_OFF && stored_speed > 0) { // Normal power loss or general WDT (which can be power-related) - restore previous state - ESP_LOGI(TAG, "🔋 Power restored - will resume previous state: %s @ %d%%", + ESP_LOGI(SYSTEM_TAG, "🔋 Power restored - will resume previous state: %s @ %d%%", stored_mode == MOTOR_EXHAUST ? "EXHAUST" : "INTAKE", stored_speed); motor_state.mode = (motor_mode_t)stored_mode; motor_state.target_speed = stored_speed; motor_state.current_speed = 0; // Always start ramping from 0 } else { - ESP_LOGI(TAG, "❌ No valid state to restore (mode=%d, speed=%d)", stored_mode, stored_speed); + ESP_LOGI(SYSTEM_TAG, "❌ No valid state to restore (mode=%d, speed=%d)", stored_mode, stored_speed); motor_state.mode = MOTOR_OFF; motor_state.target_speed = 0; motor_state.current_speed = 0; } } else { - ESP_LOGI(TAG, "No saved state found, using defaults"); + ESP_LOGI(SYSTEM_TAG, "No saved state found, using defaults"); err = ESP_ERR_NVS_NOT_FOUND; } @@ -373,7 +336,7 @@ static void save_last_on_state(motor_mode_t mode, int speed) { if (mode != MOTOR_OFF && speed > 0) { motor_state.last_on_mode = mode; motor_state.last_on_speed = speed; - ESP_LOGI(TAG, "Last ON state updated: %s @ %d%%", + ESP_LOGI(SYSTEM_TAG, "Last ON state updated: %s @ %d%%", mode == MOTOR_EXHAUST ? "EXHAUST" : "INTAKE", speed); } } @@ -388,14 +351,14 @@ static void event_handler(void* arg, esp_event_base_t event_base, if (s_retry_num < WIFI_MAXIMUM_RETRY) { esp_wifi_connect(); s_retry_num++; - ESP_LOGI(TAG, "retry to connect to the AP"); + ESP_LOGI(SYSTEM_TAG, "retry to connect to the AP"); } else { xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); } - ESP_LOGI(TAG, "connect to the AP fail"); + ESP_LOGI(SYSTEM_TAG, "connect to the AP fail"); } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; - ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); + ESP_LOGI(SYSTEM_TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); s_retry_num = 0; xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); } @@ -403,7 +366,7 @@ static void event_handler(void* arg, esp_event_base_t event_base, void configure_gpio_pins(void) { - ESP_LOGI(TAG, "Configuring GPIO pins..."); + ESP_LOGI(SYSTEM_TAG, "Configuring GPIO pins..."); uint64_t pin_mask = (1ULL << LED_PIN) | (1ULL << MOTOR_R_EN) | @@ -423,16 +386,16 @@ void configure_gpio_pins(void) gpio_set_level(MOTOR_R_EN, 0); gpio_set_level(MOTOR_L_EN, 0); - ESP_LOGI(TAG, "GPIO pins configured"); + ESP_LOGI(SYSTEM_TAG, "GPIO pins configured"); } void configure_pwm(void) { - ESP_LOGI(TAG, "Configuring PWM..."); + ESP_LOGI(SYSTEM_TAG, "Configuring PWM..."); ledc_timer_config_t timer_conf = { - .speed_mode = LEDC_LOW_SPEED_MODE, - .timer_num = LEDC_TIMER_0, + .speed_mode = PWM_SPEED_MODE, + .timer_num = PWM_TIMER, .duty_resolution = PWM_RESOLUTION, .freq_hz = PWM_FREQUENCY, .clk_cfg = LEDC_AUTO_CLK @@ -443,9 +406,9 @@ void configure_pwm(void) .channel = PWM_R_CHANNEL, .duty = 0, .gpio_num = PWM_R_PIN, - .speed_mode = LEDC_LOW_SPEED_MODE, + .speed_mode = PWM_SPEED_MODE, .hpoint = 0, - .timer_sel = LEDC_TIMER_0 + .timer_sel = PWM_TIMER }; ledc_channel_config(&channel_conf); @@ -453,42 +416,42 @@ void configure_pwm(void) channel_conf.gpio_num = PWM_L_PIN; ledc_channel_config(&channel_conf); - ESP_LOGI(TAG, "PWM configured"); + ESP_LOGI(SYSTEM_TAG, "PWM configured"); } // Apply PWM to motor based on current mode and speed static void apply_motor_pwm(int speed_percent) { - if (speed_percent < 0) speed_percent = 0; - if (speed_percent > 100) speed_percent = 100; + // Clamp speed to valid range using config macro + speed_percent = CLAMP_SPEED(speed_percent); - uint32_t duty = (speed_percent * 255) / 100; + uint32_t duty = SPEED_TO_DUTY(speed_percent); if (motor_state.mode == MOTOR_OFF || speed_percent == 0) { gpio_set_level(LED_PIN, 0); gpio_set_level(MOTOR_R_EN, 0); gpio_set_level(MOTOR_L_EN, 0); - ledc_set_duty(LEDC_LOW_SPEED_MODE, PWM_R_CHANNEL, 0); - ledc_set_duty(LEDC_LOW_SPEED_MODE, PWM_L_CHANNEL, 0); - ledc_update_duty(LEDC_LOW_SPEED_MODE, PWM_R_CHANNEL); - ledc_update_duty(LEDC_LOW_SPEED_MODE, PWM_L_CHANNEL); + ledc_set_duty(PWM_SPEED_MODE, PWM_R_CHANNEL, 0); + ledc_set_duty(PWM_SPEED_MODE, PWM_L_CHANNEL, 0); + ledc_update_duty(PWM_SPEED_MODE, PWM_R_CHANNEL); + ledc_update_duty(PWM_SPEED_MODE, PWM_L_CHANNEL); } else if (motor_state.mode == MOTOR_EXHAUST) { gpio_set_level(LED_PIN, 1); gpio_set_level(MOTOR_R_EN, 1); gpio_set_level(MOTOR_L_EN, 1); - ledc_set_duty(LEDC_LOW_SPEED_MODE, PWM_R_CHANNEL, duty); - ledc_set_duty(LEDC_LOW_SPEED_MODE, PWM_L_CHANNEL, 0); - ledc_update_duty(LEDC_LOW_SPEED_MODE, PWM_R_CHANNEL); - ledc_update_duty(LEDC_LOW_SPEED_MODE, PWM_L_CHANNEL); + ledc_set_duty(PWM_SPEED_MODE, PWM_R_CHANNEL, duty); + ledc_set_duty(PWM_SPEED_MODE, PWM_L_CHANNEL, 0); + ledc_update_duty(PWM_SPEED_MODE, PWM_R_CHANNEL); + ledc_update_duty(PWM_SPEED_MODE, PWM_L_CHANNEL); } else if (motor_state.mode == MOTOR_INTAKE) { gpio_set_level(LED_PIN, 1); gpio_set_level(MOTOR_R_EN, 1); gpio_set_level(MOTOR_L_EN, 1); - ledc_set_duty(LEDC_LOW_SPEED_MODE, PWM_R_CHANNEL, 0); - ledc_set_duty(LEDC_LOW_SPEED_MODE, PWM_L_CHANNEL, duty); - ledc_update_duty(LEDC_LOW_SPEED_MODE, PWM_R_CHANNEL); - ledc_update_duty(LEDC_LOW_SPEED_MODE, PWM_L_CHANNEL); + ledc_set_duty(PWM_SPEED_MODE, PWM_R_CHANNEL, 0); + ledc_set_duty(PWM_SPEED_MODE, PWM_L_CHANNEL, duty); + ledc_update_duty(PWM_SPEED_MODE, PWM_R_CHANNEL); + ledc_update_duty(PWM_SPEED_MODE, PWM_L_CHANNEL); } } @@ -509,7 +472,7 @@ static void motor_ramp_timer_callback(TimerHandle_t xTimer) { // Stop the timer xTimerStop(motor_state.ramp_timer, 0); - ESP_LOGI(TAG, "Ramping complete - Final speed: %d%%", motor_state.current_speed); + ESP_LOGI(SYSTEM_TAG, "Ramping complete - Final speed: %d%%", motor_state.current_speed); } else { // Continue ramping if (speed_diff > 0) { @@ -518,7 +481,7 @@ static void motor_ramp_timer_callback(TimerHandle_t xTimer) { motor_state.current_speed -= RAMP_STEP_SIZE; } - ESP_LOGD(TAG, "Ramping: %d%% (target: %d%%)", motor_state.current_speed, motor_state.target_speed); + MOTOR_LOGD(SYSTEM_TAG, "Ramping: %d%% (target: %d%%)", motor_state.current_speed, motor_state.target_speed); } apply_motor_pwm(motor_state.current_speed); @@ -526,7 +489,7 @@ static void motor_ramp_timer_callback(TimerHandle_t xTimer) { // Motor cooldown timer callback static void motor_cooldown_timer_callback(TimerHandle_t xTimer) { - ESP_LOGI(TAG, "Cooldown complete - Starting motor in %s mode at %d%%", + ESP_LOGI(SYSTEM_TAG, "Cooldown complete - Starting motor in %s mode at %d%%", motor_state.pending_mode == MOTOR_EXHAUST ? "EXHAUST" : "INTAKE", motor_state.pending_speed); @@ -540,8 +503,8 @@ static void motor_cooldown_timer_callback(TimerHandle_t xTimer) { // Update cooldown remaining time (called periodically) static void update_cooldown_time(void) { if (motor_state.state == MOTOR_STATE_COOLDOWN && motor_state.cooldown_remaining_ms > 0) { - if (motor_state.cooldown_remaining_ms >= 1000) { - motor_state.cooldown_remaining_ms -= 1000; + if (motor_state.cooldown_remaining_ms >= STATUS_UPDATE_INTERVAL_MS) { + motor_state.cooldown_remaining_ms -= STATUS_UPDATE_INTERVAL_MS; } else { motor_state.cooldown_remaining_ms = 0; } @@ -550,6 +513,9 @@ static void update_cooldown_time(void) { // Start motor operation (internal function) static void start_motor_operation(motor_mode_t mode, int speed_percent) { + // Clamp speed using config macro + speed_percent = CLAMP_SPEED(speed_percent); + motor_state.mode = mode; motor_state.target_speed = speed_percent; motor_state.state = MOTOR_STATE_RAMPING; @@ -562,7 +528,7 @@ static void start_motor_operation(motor_mode_t mode, int speed_percent) { motor_state.state = MOTOR_STATE_IDLE; motor_state.ramping = false; apply_motor_pwm(0); - ESP_LOGI(TAG, "Motor stopped immediately"); + ESP_LOGI(SYSTEM_TAG, "Motor stopped immediately"); } else { // Save last ON state for future ON button use save_last_on_state(mode, speed_percent); @@ -572,7 +538,7 @@ static void start_motor_operation(motor_mode_t mode, int speed_percent) { int start_speed = (speed_percent < MIN_MOTOR_SPEED) ? speed_percent : MIN_MOTOR_SPEED; motor_state.current_speed = start_speed; apply_motor_pwm(start_speed); - ESP_LOGI(TAG, "Motor starting at %d%%, ramping to %d%%", start_speed, speed_percent); + ESP_LOGI(SYSTEM_TAG, "Motor starting at %d%%, ramping to %d%%", start_speed, speed_percent); } // Start ramping if needed @@ -607,18 +573,18 @@ void init_motor_ramping(void) { ); if (motor_state.ramp_timer == NULL || motor_state.cooldown_timer == NULL) { - ESP_LOGE(TAG, "Failed to create motor timers"); + ESP_LOGE(SYSTEM_TAG, "Failed to create motor timers"); } else { - ESP_LOGI(TAG, "Motor control system initialized with direction change safety"); + ESP_LOGI(SYSTEM_TAG, "Motor control system initialized with direction change safety"); } } void set_motor_speed(motor_mode_t mode, int speed_percent) { - if (speed_percent < 0) speed_percent = 0; - if (speed_percent > 100) speed_percent = 100; + // Clamp speed to valid range using config macro + speed_percent = CLAMP_SPEED(speed_percent); - ESP_LOGI(TAG, "Motor command: %s - Speed: %d%% (Current mode: %s, Current speed: %d%%, State: %d)", + ESP_LOGI(SYSTEM_TAG, "Motor command: %s - Speed: %d%% (Current mode: %s, Current speed: %d%%, State: %d)", mode == MOTOR_OFF ? "OFF" : (mode == MOTOR_EXHAUST ? "EXHAUST" : "INTAKE"), speed_percent, motor_state.mode == MOTOR_OFF ? "OFF" : (motor_state.mode == MOTOR_EXHAUST ? "EXHAUST" : "INTAKE"), @@ -628,32 +594,29 @@ void set_motor_speed(motor_mode_t mode, int speed_percent) // Track if user manually turned off if (mode == MOTOR_OFF && motor_state.mode != MOTOR_OFF) { motor_state.user_turned_off = true; - ESP_LOGI(TAG, "User manually turned OFF - will stay off after restart"); + ESP_LOGI(SYSTEM_TAG, "User manually turned OFF - will stay off after restart"); } else if (mode != MOTOR_OFF) { motor_state.user_turned_off = false; - ESP_LOGI(TAG, "Motor turned ON - will resume after power loss"); + ESP_LOGI(SYSTEM_TAG, "Motor turned ON - will resume after power loss"); } // If we're in cooldown, update the pending command if (motor_state.state == MOTOR_STATE_COOLDOWN) { motor_state.pending_mode = mode; motor_state.pending_speed = speed_percent; - ESP_LOGI(TAG, "Motor in cooldown - command queued for execution"); + ESP_LOGI(SYSTEM_TAG, "Motor in cooldown - command queued for execution"); save_motor_state_to_nvs(); // Save the pending state return; } - // Check if this is a direction change that requires cooldown + // Check if this is a direction change that requires cooldown using config macro bool requires_cooldown = false; if (motor_state.current_speed > 0 && motor_state.mode != MOTOR_OFF) { - if ((motor_state.mode == MOTOR_EXHAUST && mode == MOTOR_INTAKE) || - (motor_state.mode == MOTOR_INTAKE && mode == MOTOR_EXHAUST)) { - requires_cooldown = true; - } + requires_cooldown = IS_DIRECTION_CHANGE(motor_state.mode, mode); } if (requires_cooldown) { - ESP_LOGI(TAG, "Direction change detected - initiating safety cooldown sequence"); + ESP_LOGI(SYSTEM_TAG, "Direction change detected - initiating safety cooldown sequence"); // Stop any current ramping if (motor_state.ramping) { @@ -676,7 +639,7 @@ void set_motor_speed(motor_mode_t mode, int speed_percent) // Start cooldown timer xTimerStart(motor_state.cooldown_timer, 0); - ESP_LOGI(TAG, "Motor stopped for direction change - %d second cooldown started", + ESP_LOGI(SYSTEM_TAG, "Motor stopped for direction change - %d second cooldown started", DIRECTION_CHANGE_COOLDOWN_MS / 1000); // Save state including pending command @@ -723,7 +686,7 @@ static esp_err_t status_get_handler(httpd_req_t *req) // Update cooldown time before reporting update_cooldown_time(); - ESP_LOGI(TAG, "Status request - Mode: %d, Current: %d%%, Target: %d%%, State: %d, Ramping: %s", + ESP_LOGI(SYSTEM_TAG, "Status request - Mode: %d, Current: %d%%, Target: %d%%, State: %d, Ramping: %s", motor_state.mode, motor_state.current_speed, motor_state.target_speed, motor_state.state, motor_state.ramping ? "YES" : "NO"); @@ -782,7 +745,7 @@ static esp_err_t status_get_handler(httpd_req_t *req) // HTTP handler for fan control (POST /fan) static esp_err_t fan_post_handler(httpd_req_t *req) { - char buf[200]; + char buf[MAX_JSON_BUFFER_SIZE]; int ret, remaining = req->content_len; if (remaining >= sizeof(buf)) { @@ -799,11 +762,11 @@ static esp_err_t fan_post_handler(httpd_req_t *req) } buf[ret] = '\0'; - ESP_LOGI(TAG, "Received POST data: %s", buf); + ESP_LOGI(SYSTEM_TAG, "Received POST data: %s", buf); cJSON *json = cJSON_Parse(buf); if (json == NULL) { - ESP_LOGE(TAG, "JSON parsing failed"); + ESP_LOGE(SYSTEM_TAG, "JSON parsing failed"); httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON"); return ESP_FAIL; } @@ -812,7 +775,7 @@ static esp_err_t fan_post_handler(httpd_req_t *req) cJSON *speed_json = cJSON_GetObjectItem(json, "speed"); if (!cJSON_IsString(mode_json) || (!cJSON_IsNumber(speed_json) && !cJSON_IsString(speed_json))) { - ESP_LOGE(TAG, "JSON parsing failed - mode: %s, speed: %s", + ESP_LOGE(SYSTEM_TAG, "JSON parsing failed - mode: %s, speed: %s", mode_json ? (cJSON_IsString(mode_json) ? mode_json->valuestring : "not_string") : "null", speed_json ? (cJSON_IsNumber(speed_json) ? "number" : (cJSON_IsString(speed_json) ? speed_json->valuestring : "not_number_or_string")) : "null"); cJSON_Delete(json); @@ -838,7 +801,7 @@ static esp_err_t fan_post_handler(httpd_req_t *req) if (strcmp(mode_str, "on") == 0) { mode = motor_state.last_on_mode; speed = motor_state.last_on_speed; - ESP_LOGI(TAG, "ON button pressed - resuming %s @ %d%%", + ESP_LOGI(SYSTEM_TAG, "ON button pressed - resuming %s @ %d%%", mode == MOTOR_EXHAUST ? "EXHAUST" : "INTAKE", speed); } else if (strcmp(mode_str, "exhaust") == 0) { mode = MOTOR_EXHAUST; @@ -846,7 +809,7 @@ static esp_err_t fan_post_handler(httpd_req_t *req) mode = MOTOR_INTAKE; } - ESP_LOGI(TAG, "HTTP Request: mode=%s, speed=%d", mode_str, speed); + ESP_LOGI(SYSTEM_TAG, "HTTP Request: mode=%s, speed=%d", mode_str, speed); set_motor_speed(mode, speed); cJSON_Delete(json); @@ -868,13 +831,14 @@ static esp_err_t options_handler(httpd_req_t *req) static httpd_handle_t start_webserver(void) { httpd_config_t config = HTTPD_DEFAULT_CONFIG(); - config.max_uri_handlers = 15; - config.recv_wait_timeout = 10; - config.send_wait_timeout = 10; + config.server_port = HTTP_SERVER_PORT; + config.max_uri_handlers = HTTP_MAX_URI_HANDLERS; + config.recv_wait_timeout = HTTP_RECV_TIMEOUT_SEC; + config.send_wait_timeout = HTTP_SEND_TIMEOUT_SEC; - ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port); + ESP_LOGI(SYSTEM_TAG, "Starting server on port: '%d'", config.server_port); if (httpd_start(&server, &config) == ESP_OK) { - ESP_LOGI(TAG, "Registering URI handlers"); + ESP_LOGI(SYSTEM_TAG, "Registering URI handlers"); // Root handler httpd_uri_t root = { @@ -923,7 +887,7 @@ static httpd_handle_t start_webserver(void) return server; } - ESP_LOGI(TAG, "Error starting server!"); + ESP_LOGI(SYSTEM_TAG, "Error starting server!"); return NULL; } @@ -966,7 +930,7 @@ void wifi_init_sta(void) ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); ESP_ERROR_CHECK(esp_wifi_start()); - ESP_LOGI(TAG, "wifi_init_sta finished."); + ESP_LOGI(SYSTEM_TAG, "wifi_init_sta finished."); EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, @@ -975,17 +939,17 @@ void wifi_init_sta(void) portMAX_DELAY); if (bits & WIFI_CONNECTED_BIT) { - ESP_LOGI(TAG, "connected to ap SSID:%s", WIFI_SSID); + ESP_LOGI(SYSTEM_TAG, "connected to ap SSID:%s", WIFI_SSID); } else if (bits & WIFI_FAIL_BIT) { - ESP_LOGI(TAG, "Failed to connect to SSID:%s", WIFI_SSID); + ESP_LOGI(SYSTEM_TAG, "Failed to connect to SSID:%s", WIFI_SSID); } else { - ESP_LOGE(TAG, "UNEXPECTED EVENT"); + ESP_LOGE(SYSTEM_TAG, "UNEXPECTED EVENT"); } } void app_main(void) { - ESP_LOGI(TAG, "Starting Maxxfan HTTP Controller with State Preservation!"); + ESP_LOGI(SYSTEM_TAG, "Starting Maxxfan HTTP Controller with State Preservation!"); // Initialize NVS esp_err_t ret = nvs_flash_init(); @@ -1006,44 +970,44 @@ void app_main(void) init_motor_ramping(); // Load saved state from NVS - ESP_LOGI(TAG, "Loading saved state..."); + ESP_LOGI(SYSTEM_TAG, "Loading saved state..."); load_motor_state_from_nvs(); - ESP_LOGI(TAG, "Connecting to WiFi network: %s", WIFI_SSID); + ESP_LOGI(SYSTEM_TAG, "Connecting to WiFi network: %s", WIFI_SSID); wifi_init_sta(); // Start HTTP server start_webserver(); // Restore motor state if needed (after WiFi is connected and server is running) - ESP_LOGI(TAG, "=== MOTOR STATE RESTORATION ==="); - ESP_LOGI(TAG, "Current motor state: mode=%d, target=%d%%, current=%d%%", + ESP_LOGI(SYSTEM_TAG, "=== MOTOR STATE RESTORATION ==="); + ESP_LOGI(SYSTEM_TAG, "Current motor state: mode=%d, target=%d%%, current=%d%%", motor_state.mode, motor_state.target_speed, motor_state.current_speed); if (motor_state.mode != MOTOR_OFF && motor_state.target_speed > 0) { - ESP_LOGI(TAG, "Restoring motor state: %s @ %d%%", + ESP_LOGI(SYSTEM_TAG, "Restoring motor state: %s @ %d%%", motor_state.mode == MOTOR_EXHAUST ? "EXHAUST" : "INTAKE", motor_state.target_speed); // Start the motor with current settings motor_state.current_speed = 0; // Start from 0 and ramp up start_motor_operation(motor_state.mode, motor_state.target_speed); - ESP_LOGI(TAG, "Motor restoration initiated"); + ESP_LOGI(SYSTEM_TAG, "Motor restoration initiated"); } else { - ESP_LOGI(TAG, "No motor state to restore - staying OFF"); + ESP_LOGI(SYSTEM_TAG, "No motor state to restore - staying OFF"); } - ESP_LOGI(TAG, "==============================="); + ESP_LOGI(SYSTEM_TAG, "==============================="); - ESP_LOGI(TAG, "=== Enhanced Maxxfan Controller Ready! ==="); - ESP_LOGI(TAG, "Features: State Preservation, Direction Safety, Motor Ramping, ON Button"); - ESP_LOGI(TAG, "Safety: 10-second cooldown for direction changes"); - ESP_LOGI(TAG, "Memory: Remembers settings after power loss (except watchdog resets)"); - ESP_LOGI(TAG, "Open your browser and go to: http://[ESP32_IP_ADDRESS]"); - ESP_LOGI(TAG, "Check the monitor output above for your IP address"); + ESP_LOGI(SYSTEM_TAG, "=== Enhanced Maxxfan Controller Ready! ==="); + ESP_LOGI(SYSTEM_TAG, "Features: State Preservation, Direction Safety, Motor Ramping, ON Button"); + ESP_LOGI(SYSTEM_TAG, "Safety: 10-second cooldown for direction changes"); + ESP_LOGI(SYSTEM_TAG, "Memory: Remembers settings after power loss (except watchdog resets)"); + ESP_LOGI(SYSTEM_TAG, "Open your browser and go to: http://[ESP32_IP_ADDRESS]"); + ESP_LOGI(SYSTEM_TAG, "Check the monitor output above for your IP address"); // Main loop - reset watchdog periodically while (1) { feed_watchdog(); - vTaskDelay(pdMS_TO_TICKS(3000)); // Feed every 3 seconds (system default is usually 5s timeout) + vTaskDelay(pdMS_TO_TICKS(WATCHDOG_FEED_INTERVAL_MS)); } } \ No newline at end of file