主流程
This commit is contained in:
1 parent
f96e72dbb8
commit
0045c0c390
10 files changed
+216
-74
No files matched your search
@@ -4,3 +4,6 @@ cmake_minimum_required(VERSION 3.22)
|
|||||||
|
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
project(edc-mcu)
|
project(edc-mcu)
|
||||||
|
|
||||||
|
# 调试开关: 注释掉以下行以禁用 WiFi / Web 服务器
|
||||||
|
add_compile_definitions(EDC_DEBUG_WEB)
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
idf_component_register(SRCS "actuator.c"
|
idf_component_register(SRCS "actuator.c"
|
||||||
INCLUDE_DIRS "."
|
INCLUDE_DIRS "."
|
||||||
REQUIRES emm_v5 servo protocol driver freertos)
|
REQUIRES emm_v5 servo magnet rgb protocol driver freertos)
|
||||||
+138
-28
@@ -6,6 +6,8 @@
|
|||||||
#include "actuator.h"
|
#include "actuator.h"
|
||||||
#include "emm_v5.h"
|
#include "emm_v5.h"
|
||||||
#include "servo.h"
|
#include "servo.h"
|
||||||
|
#include "magnet.h"
|
||||||
|
#include "rgb.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
@@ -36,6 +38,19 @@ static inline void _frame_gap(void)
|
|||||||
vTaskDelay(pdMS_TO_TICKS(ACTUATOR_FRAME_GAP_MS));
|
vTaskDelay(pdMS_TO_TICKS(ACTUATOR_FRAME_GAP_MS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 内部: 带 RGB 闪烁的延时 (周期 ms, 亮灭各半) */
|
||||||
|
static void _wait_flash(uint32_t ms, uint8_t r, uint8_t g, uint8_t b, uint32_t period_ms)
|
||||||
|
{
|
||||||
|
uint32_t half = pdMS_TO_TICKS(period_ms / 2);
|
||||||
|
int cycles = (int)(ms / period_ms);
|
||||||
|
for (int i = 0; i < cycles; i++) {
|
||||||
|
rgb_set(r, g, b);
|
||||||
|
vTaskDelay(half);
|
||||||
|
rgb_off();
|
||||||
|
vTaskDelay(half);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
* 初始化
|
* 初始化
|
||||||
* ================================================================ */
|
* ================================================================ */
|
||||||
@@ -49,7 +64,7 @@ void actuator_init(void)
|
|||||||
servo_init(ACTUATOR_SERVO_GPIO);
|
servo_init(ACTUATOR_SERVO_GPIO);
|
||||||
|
|
||||||
/* 配置舵机限位: 抬起=80°, 放下=160° */
|
/* 配置舵机限位: 抬起=80°, 放下=160° */
|
||||||
servo_set_limits(80.0f, 160.0f);
|
servo_set_limits(0.0f, 95.0f);
|
||||||
|
|
||||||
/* 上电默认归位到抬起状态 */
|
/* 上电默认归位到抬起状态 */
|
||||||
servo_set_up();
|
servo_set_up();
|
||||||
@@ -105,11 +120,8 @@ static void _actuator_move_abs(uint8_t addr, uint8_t dir, uint32_t pulses,
|
|||||||
* 内部: Y 轴双电机同步运动
|
* 内部: Y 轴双电机同步运动
|
||||||
* ================================================================ */
|
* ================================================================ */
|
||||||
|
|
||||||
static void _actuator_move_y_sync(uint32_t pulses_y)
|
static void _actuator_move_y_sync(uint32_t pulses_y, uint16_t vel, uint8_t acc)
|
||||||
{
|
{
|
||||||
uint16_t vel = ACTUATOR_DEFAULT_VEL;
|
|
||||||
uint8_t acc = ACTUATOR_DEFAULT_ACC;
|
|
||||||
|
|
||||||
/* Y 轴正向 = CCW (dir=1), 双电机同步 */
|
/* Y 轴正向 = CCW (dir=1), 双电机同步 */
|
||||||
_actuator_move_abs(ACTUATOR_ADDR_Y1, ACTUATOR_DIR_Y, pulses_y, vel, acc, true);
|
_actuator_move_abs(ACTUATOR_ADDR_Y1, ACTUATOR_DIR_Y, pulses_y, vel, acc, true);
|
||||||
_frame_gap();
|
_frame_gap();
|
||||||
@@ -119,9 +131,9 @@ static void _actuator_move_y_sync(uint32_t pulses_y)
|
|||||||
/* 广播地址触发一次, 两台电机同时开始运动 */
|
/* 广播地址触发一次, 两台电机同时开始运动 */
|
||||||
Emm_V5_Synchronous_motion(0);
|
Emm_V5_Synchronous_motion(0);
|
||||||
|
|
||||||
ESP_LOGD(TAG, "Y 同步(CCW): addr%d+%d -> %lu pulses (%.2fmm)",
|
ESP_LOGD(TAG, "Y 同步(CCW): addr%d+%d -> %lu pulses (%.2fmm) vel=%d acc=%d",
|
||||||
ACTUATOR_ADDR_Y1, ACTUATOR_ADDR_Y2, pulses_y,
|
ACTUATOR_ADDR_Y1, ACTUATOR_ADDR_Y2, pulses_y,
|
||||||
(double)pulses_y / (double)ACTUATOR_SCALE_Y);
|
(double)pulses_y / (double)ACTUATOR_SCALE_Y, vel, acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
@@ -130,28 +142,83 @@ static void _actuator_move_y_sync(uint32_t pulses_y)
|
|||||||
|
|
||||||
static void _actuator_move_fragment(const edc_fragment_t *frag)
|
static void _actuator_move_fragment(const edc_fragment_t *frag)
|
||||||
{
|
{
|
||||||
uint16_t vel = ACTUATOR_DEFAULT_VEL;
|
/* 固定速度/加速度 */
|
||||||
uint8_t acc = ACTUATOR_DEFAULT_ACC;
|
uint16_t vel_xy = 1500;
|
||||||
|
uint8_t acc_xy = 200;
|
||||||
|
uint16_t vel_angle = 50;
|
||||||
|
uint8_t acc_angle = 100;
|
||||||
|
|
||||||
|
/* source 坐标 → 脉冲数 */
|
||||||
|
uint32_t src_pulses_x = (uint32_t)(frag->source.x * s_scale_x);
|
||||||
|
uint32_t src_pulses_y = (uint32_t)(frag->source.y * s_scale_y);
|
||||||
|
uint32_t src_pulses_angle = (uint32_t)(frag->source.angle_x10 * s_scale_angle);
|
||||||
|
|
||||||
/* target 坐标 → 脉冲数 */
|
/* target 坐标 → 脉冲数 */
|
||||||
uint32_t pulses_x = (uint32_t)(frag->target.x * s_scale_x);
|
uint32_t dst_pulses_x = (uint32_t)(frag->target.x * s_scale_x);
|
||||||
uint32_t pulses_y = (uint32_t)(frag->target.y * s_scale_y);
|
uint32_t dst_pulses_y = (uint32_t)(frag->target.y * s_scale_y);
|
||||||
uint32_t pulses_angle = (uint32_t)(frag->target.angle_x10 * s_scale_angle);
|
uint32_t dst_pulses_angle = (uint32_t)(frag->target.angle_x10 * s_scale_angle);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Fragment: X=%lu Y=%lu Angle=%lu (raw x=%u y=%u a=%u)",
|
ESP_LOGI(TAG, "Fragment: SRC(X=%lu Y=%lu A=%lu) → DST(X=%lu Y=%lu A=%lu)",
|
||||||
pulses_x, pulses_y, pulses_angle,
|
src_pulses_x, src_pulses_y, src_pulses_angle,
|
||||||
frag->target.x, frag->target.y, frag->target.angle_x10);
|
dst_pulses_x, dst_pulses_y, dst_pulses_angle);
|
||||||
|
|
||||||
/* Angle / Z 旋转轴 (独立, CW) */
|
/* ---- 1. 磁铁掉电 ---- */
|
||||||
_actuator_move_abs(ACTUATOR_ADDR_ANGLE, ACTUATOR_DIR_ANGLE, pulses_angle, vel, acc, false);
|
magnet_set(false);
|
||||||
|
|
||||||
|
/* ---- 2. 运动到 source 位置 ---- */
|
||||||
|
/* Angle / Z 旋转轴 */
|
||||||
|
_actuator_move_abs(ACTUATOR_ADDR_ANGLE, ACTUATOR_DIR_ANGLE,
|
||||||
|
src_pulses_angle, vel_angle, acc_angle, false);
|
||||||
_frame_gap();
|
_frame_gap();
|
||||||
|
|
||||||
/* X 轴 (独立, CW) */
|
/* X 轴 */
|
||||||
_actuator_move_abs(ACTUATOR_ADDR_X, ACTUATOR_DIR_X, pulses_x, vel, acc, false);
|
_actuator_move_abs(ACTUATOR_ADDR_X, ACTUATOR_DIR_X,
|
||||||
|
src_pulses_x, vel_xy, acc_xy, false);
|
||||||
_frame_gap();
|
_frame_gap();
|
||||||
|
|
||||||
/* Y 轴 (双电机同步) */
|
/* Y 轴 (双电机同步) */
|
||||||
_actuator_move_y_sync(pulses_y);
|
_actuator_move_y_sync(src_pulses_y, vel_xy, acc_xy);
|
||||||
|
|
||||||
|
/* ---- 3. 等待 2s 运动到位 (红灯快闪) ---- */
|
||||||
|
_wait_flash(2000, 128, 0, 0, 200);
|
||||||
|
|
||||||
|
/* ---- 4. 舵机放下 ---- */
|
||||||
|
servo_set_down();
|
||||||
|
_wait_flash(500, 128, 0, 0, 200);
|
||||||
|
|
||||||
|
/* ---- 5. 磁铁吸合 ---- */
|
||||||
|
magnet_set(true);
|
||||||
|
_wait_flash(500, 128, 0, 0, 200);
|
||||||
|
|
||||||
|
/* ---- 6. 舵机抬起 ---- */
|
||||||
|
servo_set_up();
|
||||||
|
_wait_flash(500, 128, 0, 0, 200);
|
||||||
|
|
||||||
|
/* ---- 7. 运动到 target 位置 ---- */
|
||||||
|
_actuator_move_abs(ACTUATOR_ADDR_ANGLE, ACTUATOR_DIR_ANGLE,
|
||||||
|
dst_pulses_angle, vel_angle, acc_angle, false);
|
||||||
|
_frame_gap();
|
||||||
|
|
||||||
|
_actuator_move_abs(ACTUATOR_ADDR_X, ACTUATOR_DIR_X,
|
||||||
|
dst_pulses_x, vel_xy, acc_xy, false);
|
||||||
|
_frame_gap();
|
||||||
|
|
||||||
|
_actuator_move_y_sync(dst_pulses_y, vel_xy, acc_xy);
|
||||||
|
|
||||||
|
/* ---- 8. 等待 2s 运动到位 (红灯快闪) ---- */
|
||||||
|
_wait_flash(2000, 128, 0, 0, 200);
|
||||||
|
|
||||||
|
/* ---- 9. 舵机放下 ---- */
|
||||||
|
servo_set_down();
|
||||||
|
_wait_flash(500, 128, 0, 0, 200);
|
||||||
|
|
||||||
|
/* ---- 10. 磁铁掉电 ---- */
|
||||||
|
magnet_set(false);
|
||||||
|
_wait_flash(500, 128, 0, 0, 200);
|
||||||
|
|
||||||
|
/* ---- 11. 舵机抬起 ---- */
|
||||||
|
servo_set_up();
|
||||||
|
_wait_flash(500, 128, 0, 0, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
@@ -180,16 +247,8 @@ int actuator_execute_cycle(const edc_cycle_t *cycle)
|
|||||||
for (int i = 0; i < cycle->frag_count; i++) {
|
for (int i = 0; i < cycle->frag_count; i++) {
|
||||||
ESP_LOGI(TAG, "-- Fragment %d/%d --", i + 1, cycle->frag_count);
|
ESP_LOGI(TAG, "-- Fragment %d/%d --", i + 1, cycle->frag_count);
|
||||||
_actuator_move_fragment(&cycle->fragments[i]);
|
_actuator_move_fragment(&cycle->fragments[i]);
|
||||||
|
|
||||||
/* 等待当前片段运动完成 (TODO: 改为轮询到位标志) */
|
|
||||||
if (i < cycle->frag_count - 1) {
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(ACTUATOR_FRAG_DELAY_MS));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 最后一个 fragment 也等待 */
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(ACTUATOR_FRAG_DELAY_MS));
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "=== Cycle #%u 完成 ===", cycle->cycle_id);
|
ESP_LOGI(TAG, "=== Cycle #%u 完成 ===", cycle->cycle_id);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -368,3 +427,54 @@ void actuator_motor_stop(uint8_t addr)
|
|||||||
ESP_LOGD(TAG, "Y 同步: 电机%d 同停", peer);
|
ESP_LOGD(TAG, "Y 同步: 电机%d 同停", peer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ================================================================
|
||||||
|
* 协议回调: 收到 Cycle → 执行 → DONE
|
||||||
|
* ================================================================ */
|
||||||
|
|
||||||
|
static edc_cycle_t s_last_cycle;
|
||||||
|
static bool s_last_cycle_valid;
|
||||||
|
static portMUX_TYPE s_cycle_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||||
|
|
||||||
|
const edc_cycle_t *actuator_get_last_cycle(void)
|
||||||
|
{
|
||||||
|
return s_last_cycle_valid ? &s_last_cycle : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool actuator_is_last_cycle_valid(void)
|
||||||
|
{
|
||||||
|
return s_last_cycle_valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void edc_proto_on_cycle(const edc_cycle_t *cycle, edc_channel_t ch)
|
||||||
|
{
|
||||||
|
static uint16_t s_last_exec_id = 0xFFFF;
|
||||||
|
|
||||||
|
/* 保存快照 */
|
||||||
|
portENTER_CRITICAL(&s_cycle_lock);
|
||||||
|
memcpy(&s_last_cycle, cycle, sizeof(edc_cycle_t));
|
||||||
|
s_last_cycle_valid = true;
|
||||||
|
portEXIT_CRITICAL(&s_cycle_lock);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Cycle #%u via %s, %u frags",
|
||||||
|
cycle->cycle_id, ch == EDC_CH_I2C ? "I2C" : "UART",
|
||||||
|
cycle->frag_count);
|
||||||
|
|
||||||
|
/* I2C / UART 冗余下发, 同一 cycle_id 只执行一次 */
|
||||||
|
if (cycle->cycle_id == s_last_exec_id) {
|
||||||
|
ESP_LOGD(TAG, "Cycle #%u 重复, 跳过执行", cycle->cycle_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
s_last_exec_id = cycle->cycle_id;
|
||||||
|
|
||||||
|
/* 执行电机运动 (阻塞, 含拾放全流程) */
|
||||||
|
ESP_LOGI(TAG, "开始执行 Cycle #%u ...", cycle->cycle_id);
|
||||||
|
actuator_execute_cycle(cycle);
|
||||||
|
|
||||||
|
/* 全部 Fragment 执行完成后回复 DONE */
|
||||||
|
edc_proto_send_done(cycle->cycle_id);
|
||||||
|
ESP_LOGI(TAG, "Cycle #%u 执行完毕, DONE 已发送", cycle->cycle_id);
|
||||||
|
|
||||||
|
/* 设置 RGB 状态为 DONE, 主循环将持续绿灯慢闪 */
|
||||||
|
rgb_set_state(RGB_STATE_DONE);
|
||||||
|
}
|
||||||
@@ -231,7 +231,16 @@ void actuator_motor_mm(uint8_t addr, float distance_mm, uint16_t vel,
|
|||||||
* @param addr 电机地址 (1~4)
|
* @param addr 电机地址 (1~4)
|
||||||
*/
|
*/
|
||||||
void actuator_motor_stop(uint8_t addr);
|
void actuator_motor_stop(uint8_t addr);
|
||||||
|
/**
|
||||||
|
* @brief 获取最近一次执行的 Cycle 快照 (供外部读取, 如 Web 面板)
|
||||||
|
* @return 有效时返回指针, 否则 NULL
|
||||||
|
*/
|
||||||
|
const edc_cycle_t *actuator_get_last_cycle(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 最近 Cycle 是否有效
|
||||||
|
*/
|
||||||
|
bool actuator_is_last_cycle_valid(void);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -221,3 +221,17 @@ void rgb_off(void)
|
|||||||
{
|
{
|
||||||
rgb_transmit(0, 0, 0);
|
rgb_transmit(0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── 系统状态 ── */
|
||||||
|
|
||||||
|
static rgb_state_t s_rgb_state = RGB_STATE_IDLE;
|
||||||
|
|
||||||
|
void rgb_set_state(rgb_state_t state)
|
||||||
|
{
|
||||||
|
s_rgb_state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
rgb_state_t rgb_get_state(void)
|
||||||
|
{
|
||||||
|
return s_rgb_state;
|
||||||
|
}
|
||||||
@@ -42,6 +42,25 @@ void rgb_set_hsv(uint16_t h, uint8_t s, uint8_t v);
|
|||||||
*/
|
*/
|
||||||
void rgb_off(void);
|
void rgb_off(void);
|
||||||
|
|
||||||
|
/* ================================================================
|
||||||
|
* 系统状态指示 (供 main 循环读取)
|
||||||
|
* ================================================================ */
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
RGB_STATE_IDLE = 0, /* 待机: 黄灯慢闪 */
|
||||||
|
RGB_STATE_DONE = 1, /* 完成: 绿灯慢闪 */
|
||||||
|
} rgb_state_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 设置系统指示状态
|
||||||
|
*/
|
||||||
|
void rgb_set_state(rgb_state_t state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取当前系统指示状态
|
||||||
|
*/
|
||||||
|
rgb_state_t rgb_get_state(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
idf_component_register(SRCS "web_ctrl.c"
|
idf_component_register(SRCS "web_ctrl.c"
|
||||||
INCLUDE_DIRS "."
|
INCLUDE_DIRS "."
|
||||||
REQUIRES emm_v5 magnet servo esp_http_server esp_wifi nvs_flash protocol actuator)
|
REQUIRES emm_v5 magnet servo rgb esp_http_server esp_wifi nvs_flash protocol actuator)
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "servo.h"
|
#include "servo.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "actuator.h"
|
#include "actuator.h"
|
||||||
|
#include "rgb.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -22,6 +23,8 @@
|
|||||||
#include "esp_netif.h"
|
#include "esp_netif.h"
|
||||||
#include "nvs_flash.h"
|
#include "nvs_flash.h"
|
||||||
|
|
||||||
|
#ifdef EDC_DEBUG_WEB
|
||||||
|
|
||||||
static const char *TAG = "WEB_CTRL";
|
static const char *TAG = "WEB_CTRL";
|
||||||
|
|
||||||
/* ---- WiFi 配置 ---- */
|
/* ---- WiFi 配置 ---- */
|
||||||
@@ -791,37 +794,9 @@ static esp_err_t favicon_handler(httpd_req_t *req)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================
|
/* ============================================================
|
||||||
* 协议状态 API
|
* 协议状态 API (从 actuator 读取最近 Cycle 快照)
|
||||||
* ============================================================ */
|
* ============================================================ */
|
||||||
|
|
||||||
/* 最近收到的 Cycle 快照 (由 edc_proto_on_cycle 更新, web 读取) */
|
|
||||||
static edc_cycle_t s_web_cycle;
|
|
||||||
static volatile bool s_web_cycle_valid;
|
|
||||||
static portMUX_TYPE s_web_lock = portMUX_INITIALIZER_UNLOCKED;
|
|
||||||
|
|
||||||
void edc_proto_on_cycle(const edc_cycle_t *cycle, edc_channel_t ch)
|
|
||||||
{
|
|
||||||
static uint16_t s_last_done_id = 0xFFFF;
|
|
||||||
|
|
||||||
portENTER_CRITICAL(&s_web_lock);
|
|
||||||
memcpy(&s_web_cycle, cycle, sizeof(edc_cycle_t));
|
|
||||||
s_web_cycle_valid = true;
|
|
||||||
portEXIT_CRITICAL(&s_web_lock);
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Cycle #%u via %s, %u frags",
|
|
||||||
cycle->cycle_id, ch == EDC_CH_I2C ? "I2C" : "UART",
|
|
||||||
cycle->frag_count);
|
|
||||||
|
|
||||||
/* I2C / UART 冗余下发, 同一 cycle_id 只回一次 DONE */
|
|
||||||
if (cycle->cycle_id == s_last_done_id) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
s_last_done_id = cycle->cycle_id;
|
|
||||||
|
|
||||||
/* 回复 MPU: Cycle 已收到 (后续实际执行电机后应移到执行完毕处) */
|
|
||||||
edc_proto_send_done(cycle->cycle_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static esp_err_t api_proto_status_handler(httpd_req_t *req)
|
static esp_err_t api_proto_status_handler(httpd_req_t *req)
|
||||||
{
|
{
|
||||||
edc_proto_stat_t stat;
|
edc_proto_stat_t stat;
|
||||||
@@ -837,18 +812,13 @@ static esp_err_t api_proto_status_handler(httpd_req_t *req)
|
|||||||
(stat.last_channel == EDC_CH_UART) ? "UART" : "none",
|
(stat.last_channel == EDC_CH_UART) ? "UART" : "none",
|
||||||
stat.done_sent, stat.request_sent);
|
stat.done_sent, stat.request_sent);
|
||||||
|
|
||||||
portENTER_CRITICAL(&s_web_lock);
|
const edc_cycle_t *cycle = actuator_get_last_cycle();
|
||||||
bool valid = s_web_cycle_valid;
|
if (cycle) {
|
||||||
edc_cycle_t cycle;
|
|
||||||
if (valid) memcpy(&cycle, &s_web_cycle, sizeof(edc_cycle_t));
|
|
||||||
portEXIT_CRITICAL(&s_web_lock);
|
|
||||||
|
|
||||||
if (valid) {
|
|
||||||
off += snprintf(json + off, sizeof(json) - off,
|
off += snprintf(json + off, sizeof(json) - off,
|
||||||
",\"cycle\":{\"id\":%u,\"frags\":%u,\"data\":[",
|
",\"cycle\":{\"id\":%u,\"frags\":%u,\"data\":[",
|
||||||
cycle.cycle_id, cycle.frag_count);
|
cycle->cycle_id, cycle->frag_count);
|
||||||
for (int i = 0; i < cycle.frag_count; i++) {
|
for (int i = 0; i < cycle->frag_count; i++) {
|
||||||
edc_fragment_t *f = &cycle.fragments[i];
|
const edc_fragment_t *f = &cycle->fragments[i];
|
||||||
off += snprintf(json + off, sizeof(json) - off,
|
off += snprintf(json + off, sizeof(json) - off,
|
||||||
"%s{\"sx\":%u,\"sy\":%u,\"sa\":%.1f,\"tx\":%u,\"ty\":%u,\"ta\":%.1f}",
|
"%s{\"sx\":%u,\"sy\":%u,\"sa\":%.1f,\"tx\":%u,\"ty\":%u,\"ta\":%.1f}",
|
||||||
(i > 0) ? "," : "",
|
(i > 0) ? "," : "",
|
||||||
@@ -874,7 +844,6 @@ static esp_err_t api_proto_request_handler(httpd_req_t *req)
|
|||||||
|
|
||||||
static esp_err_t api_proto_done_handler(httpd_req_t *req)
|
static esp_err_t api_proto_done_handler(httpd_req_t *req)
|
||||||
{
|
{
|
||||||
edc_cycle_t cycle;
|
|
||||||
edc_proto_stat_t stat;
|
edc_proto_stat_t stat;
|
||||||
edc_proto_get_stats(&stat);
|
edc_proto_get_stats(&stat);
|
||||||
/* 对最近收到的 cycle 发送 DONE */
|
/* 对最近收到的 cycle 发送 DONE */
|
||||||
@@ -1084,3 +1053,5 @@ void web_ctrl_init(void)
|
|||||||
wifi_init_sta();
|
wifi_init_sta();
|
||||||
http_server_init();
|
http_server_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* EDC_DEBUG_WEB */
|
||||||
@@ -13,12 +13,20 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef EDC_DEBUG_WEB
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 初始化 WiFi (STA 模式) 并启动 HTTP 服务器
|
* @brief 初始化 WiFi (STA 模式) 并启动 HTTP 服务器
|
||||||
* @note 阻塞直到 WiFi 连接成功, 然后启动 HTTP 服务器
|
* @note 阻塞直到 WiFi 连接成功, 然后启动 HTTP 服务器
|
||||||
*/
|
*/
|
||||||
void web_ctrl_init(void);
|
void web_ctrl_init(void);
|
||||||
|
|
||||||
|
#else /* !EDC_DEBUG_WEB */
|
||||||
|
|
||||||
|
#define web_ctrl_init() ((void)0)
|
||||||
|
|
||||||
|
#endif /* EDC_DEBUG_WEB */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+12
-4
@@ -58,13 +58,21 @@ void app_main(void)
|
|||||||
/* 启动 WiFi + HTTP 网页控制服务器 */
|
/* 启动 WiFi + HTTP 网页控制服务器 */
|
||||||
web_ctrl_init();
|
web_ctrl_init();
|
||||||
|
|
||||||
/* 系统就绪: 绿灯 (低亮) */
|
/* 系统就绪: 黄灯 (低亮) */
|
||||||
rgb_set(0, 32, 0);
|
rgb_set(32, 32, 0);
|
||||||
|
rgb_set_state(RGB_STATE_IDLE);
|
||||||
ESP_LOGI(TAG, "系统就绪, 等待网页指令...");
|
ESP_LOGI(TAG, "系统就绪, 等待网页指令...");
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
/* 心跳指示: 绿灯慢闪 (低亮) */
|
/* 根据系统状态选择闪烁颜色 */
|
||||||
rgb_set(0, 32, 0);
|
rgb_state_t st = rgb_get_state();
|
||||||
|
if (st == RGB_STATE_DONE) {
|
||||||
|
/* 绿灯慢闪: Cycle 执行完毕 */
|
||||||
|
rgb_set(0, 32, 0);
|
||||||
|
} else {
|
||||||
|
/* 黄灯慢闪: 待机 */
|
||||||
|
rgb_set(32, 32, 0);
|
||||||
|
}
|
||||||
vTaskDelay(pdMS_TO_TICKS(500));
|
vTaskDelay(pdMS_TO_TICKS(500));
|
||||||
rgb_off();
|
rgb_off();
|
||||||
vTaskDelay(pdMS_TO_TICKS(500));
|
vTaskDelay(pdMS_TO_TICKS(500));
|
||||||
|
|||||||
Reference in new issue
Block a user