界面实现,然后称重还有问题,灯改为手动控制
This commit is contained in:
3
components/scale_controller/CMakeLists.txt
Normal file
3
components/scale_controller/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "scale_controller.c"
|
||||
INCLUDE_DIRS "include"
|
||||
)
|
||||
50
components/scale_controller/include/scale_controller.h
Normal file
50
components/scale_controller/include/scale_controller.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 称重控制器配置
|
||||
*/
|
||||
typedef struct {
|
||||
float calibration_factor; // 校准系数
|
||||
int32_t tare_offset; // 初始皮重偏移
|
||||
} scale_config_t;
|
||||
|
||||
/**
|
||||
* @brief 初始化称重控制器
|
||||
* @param config 配置参数
|
||||
*/
|
||||
void scale_controller_init(const scale_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief 更新皮重偏移(去皮)
|
||||
* @param raw_avg 测量的多次原始值平均值
|
||||
*/
|
||||
void scale_controller_set_tare(int32_t raw_avg);
|
||||
|
||||
/**
|
||||
* @brief 原始值转换为重量(带简单均值滤波)
|
||||
* @param raw_val 采集到的最新 ADC 原始值
|
||||
* @return float 转换并滤波后的重量(g)
|
||||
*/
|
||||
float scale_controller_raw_to_weight(int16_t raw_val);
|
||||
|
||||
/**
|
||||
* @brief 重置滤波器缓冲区
|
||||
*/
|
||||
void scale_controller_filter_reset(void);
|
||||
|
||||
/**
|
||||
* @brief 设置校准系数
|
||||
* @param factor 校准系数
|
||||
*/
|
||||
void scale_controller_set_factor(float factor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
69
components/scale_controller/scale_controller.c
Normal file
69
components/scale_controller/scale_controller.c
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "scale_controller.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "scale_controller";
|
||||
|
||||
#define FILTER_SIZE 10 // 均值滤波窗口大小
|
||||
static int32_t s_filter_buf[FILTER_SIZE] = {0};
|
||||
static int s_filter_idx = 0;
|
||||
static bool s_buf_filled = false;
|
||||
|
||||
static int32_t s_tare_offset = 0;
|
||||
static float s_calib_factor = 1.0f;
|
||||
|
||||
// 重置滤波器缓冲区
|
||||
void scale_controller_filter_reset(void)
|
||||
{
|
||||
for (int i = 0; i < FILTER_SIZE; i++) s_filter_buf[i] = 0;
|
||||
s_filter_idx = 0;
|
||||
s_buf_filled = false;
|
||||
}
|
||||
|
||||
// 初始化函数,接受配置参数
|
||||
void scale_controller_init(const scale_config_t *config)
|
||||
{
|
||||
if (config != NULL) {
|
||||
s_tare_offset = config->tare_offset; // 设置初始皮重偏移
|
||||
s_calib_factor = config->calibration_factor; // 设置校准系数
|
||||
scale_controller_filter_reset();
|
||||
ESP_LOGI(TAG, "Initialized with offset: %ld, factor: %f", (long)s_tare_offset, s_calib_factor);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新皮重偏移(去皮)
|
||||
void scale_controller_set_tare(int32_t raw_avg)
|
||||
{
|
||||
s_tare_offset = raw_avg; // 更新皮重偏移为当前测量的平均原始值
|
||||
ESP_LOGI(TAG, "Tare updated to offset: %ld", (long)s_tare_offset);
|
||||
}
|
||||
|
||||
|
||||
// 原始值转换为重量 (带 10 点滑动均值滤波)
|
||||
float scale_controller_raw_to_weight(int16_t raw_val)
|
||||
{
|
||||
// 1. 更新滑动滤波缓冲区
|
||||
s_filter_buf[s_filter_idx] = (int32_t)raw_val;
|
||||
s_filter_idx = (s_filter_idx + 1) % FILTER_SIZE;
|
||||
if (s_filter_idx == 0) s_buf_filled = true;
|
||||
|
||||
// 2. 计算缓冲区内的平均值
|
||||
int32_t sum = 0;
|
||||
int count = s_buf_filled ? FILTER_SIZE : s_filter_idx;
|
||||
if (count == 0) return 0.0f;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
sum += s_filter_buf[i];
|
||||
}
|
||||
float avg_raw = (float)sum / count;
|
||||
|
||||
// 3. 应用去皮和校准系数
|
||||
float diff = avg_raw - (float)s_tare_offset;
|
||||
return diff * s_calib_factor;
|
||||
}
|
||||
|
||||
// 设置校准系数 (外部调用以调整称重精度)
|
||||
void scale_controller_set_factor(float factor)
|
||||
{
|
||||
s_calib_factor = factor; // 更新校准系数
|
||||
ESP_LOGI(TAG, "Calibration factor updated: %f", factor);
|
||||
}
|
||||
3
components/sgm8031_use/CMakeLists.txt
Normal file
3
components/sgm8031_use/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "sgm8031_use.c"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES esp-idf-lib__sgm58031)
|
||||
61
components/sgm8031_use/include/sgm8031_use.h
Normal file
61
components/sgm8031_use/include/sgm8031_use.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <esp_err.h>
|
||||
|
||||
/**
|
||||
* @brief 数据结构体:存放重量和电压值
|
||||
*/
|
||||
typedef struct {
|
||||
float weight; // 校准后的重量值
|
||||
} scale_data_t;
|
||||
|
||||
/**
|
||||
* @brief 初始化 SGM58031 ADC 以及 I2C 设备
|
||||
*
|
||||
* @param i2c_port I2C外设端口号(通常为 0)
|
||||
* @param sda_pin SDA 引脚号
|
||||
* @param scl_pin SCL 引脚号
|
||||
* @return esp_err_t 初始化结果
|
||||
*/
|
||||
esp_err_t sgm8031_use_init(int i2c_port, int sda_pin, int scl_pin);
|
||||
|
||||
/**
|
||||
* @brief 触发单次转换并读取此时的重量和电压值
|
||||
*
|
||||
* @param out_data 读取到的数据将会存放到这边
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t sgm8031_use_read_data(scale_data_t *out_data);
|
||||
|
||||
/**
|
||||
* @brief 去皮(空载归零)
|
||||
* 调用时保证秤面没有物品,系统会读取多次后均值认定为现在的零点基准值。
|
||||
*
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t sgm8031_use_tare(void);
|
||||
|
||||
/**
|
||||
* @brief 设置称重传感器的校准系数(即:实际重量 / ADC变化量)
|
||||
*
|
||||
* @param factor 浮点校准系数
|
||||
*/
|
||||
void sgm8031_use_set_calibration_factor(float factor);
|
||||
|
||||
|
||||
/**
|
||||
* @brief (调试用)直接读取最原始的差分 ADC 值
|
||||
*
|
||||
* @param raw_out 输出的原始ADC整数值
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t sgm8031_use_read_raw_weight(int16_t *raw_out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
85
components/sgm8031_use/sgm8031_use.c
Normal file
85
components/sgm8031_use/sgm8031_use.c
Normal file
@@ -0,0 +1,85 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "sgm8031_use.h"
|
||||
#include "sgm58031.h"
|
||||
|
||||
static const char *TAG = "sgm8031_use";
|
||||
|
||||
static i2c_dev_t s_device;
|
||||
static bool s_initialized = false;
|
||||
|
||||
esp_err_t sgm8031_use_init(int i2c_port, int sda_pin, int scl_pin)
|
||||
{
|
||||
// Initialize I2C driver if not already done. (i2cdev_init doesn't hurt to call multiple times)
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(i2cdev_init());
|
||||
|
||||
memset(&s_device, 0, sizeof(i2c_dev_t));
|
||||
|
||||
// 使用 GND 地址针脚
|
||||
esp_err_t err = sgm58031_init_desc(&s_device, SGM58031_ADDR_GND, i2c_port, sda_pin, scl_pin);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "SGM58031 init desc failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
uint8_t id, version;
|
||||
if (sgm58031_get_chip_id(&s_device, &id, &version) == ESP_OK) {
|
||||
ESP_LOGI(TAG, "SGM58031 Found! ID: %d, Version: %d", id, version);
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Failed to get SGM58031 Chip ID");
|
||||
}
|
||||
|
||||
// 设置为单次转换模式,以便我们在不同通道间切换
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(sgm58031_set_conv_mode(&s_device, SGM58031_CONV_MODE_SINGLE_SHOT));
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(sgm58031_set_data_rate(&s_device, SGM58031_DATA_RATE_100)); // 适当的速度 100SPS
|
||||
|
||||
s_initialized = true;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// 内部函数:读取指定通道和增益下的ADC值
|
||||
static esp_err_t read_channel(sgm58031_mux_t mux, sgm58031_gain_t gain, int16_t *out_val)
|
||||
{
|
||||
if (!s_initialized) return ESP_ERR_INVALID_STATE;
|
||||
|
||||
// 配置 MUX 和 增益
|
||||
esp_err_t err = sgm58031_set_input_mux(&s_device, mux);
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
err = sgm58031_set_gain(&s_device, gain);
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
// 启动单次转换
|
||||
err = sgm58031_start_conversion(&s_device);
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
// 直接延时足够的时间跳过 busy 检查 (8 SPS 时大约 125ms,100SPS只需 10ms,我们延时 50ms 保底)
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
|
||||
// 读取值
|
||||
return sgm58031_get_value(&s_device, out_val);
|
||||
}
|
||||
|
||||
esp_err_t sgm8031_use_read_data(scale_data_t *out_data)
|
||||
{
|
||||
if (out_data == NULL) return ESP_ERR_INVALID_ARG;
|
||||
int16_t weight_raw = 0;
|
||||
esp_err_t err = read_channel(SGM58031_MUX_AIN0_AIN1, SGM58031_GAIN_0V256, &weight_raw);
|
||||
if (err != ESP_OK) return err;
|
||||
out_data->weight = (float)weight_raw; // 现在直接输出原始值供外部处理
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t sgm8031_use_tare(void)
|
||||
{
|
||||
// 该函数已被外部 controller 取代,仅作为兼容占位或直接废弃
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void sgm8031_use_set_calibration_factor(float factor)
|
||||
{
|
||||
// 该函数已被外部 controller 取代
|
||||
}
|
||||
@@ -13,6 +13,10 @@
|
||||
"styles.h",
|
||||
"ui.c",
|
||||
"ui.h",
|
||||
"ui_font_chinese32.c",
|
||||
"ui_font_chinese64.c",
|
||||
"ui_font_num.c",
|
||||
"ui_font_num2.c",
|
||||
"vars.h"
|
||||
]
|
||||
}
|
||||
@@ -5,7 +5,12 @@
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern const lv_font_t ui_font_num;
|
||||
extern const lv_font_t ui_font_num2;
|
||||
extern const lv_font_t ui_font_chinese64;
|
||||
extern const lv_font_t ui_font_chinese32;
|
||||
|
||||
#ifndef EXT_FONT_DESC_T
|
||||
#define EXT_FONT_DESC_T
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
objects_t objects;
|
||||
|
||||
static const char *screen_names[] = { "Main" };
|
||||
static const char *object_names[] = { "main" };
|
||||
static const char *object_names[] = { "main", "obj0", "obj1", "obj2" };
|
||||
|
||||
//
|
||||
// Event handlers
|
||||
@@ -32,14 +32,36 @@ void create_screen_main() {
|
||||
objects.main = obj;
|
||||
lv_obj_set_pos(obj, 0, 0);
|
||||
lv_obj_set_size(obj, 240, 240);
|
||||
lv_obj_set_style_bg_color(obj, lv_color_hex(0xff075d00), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_bg_color(obj, lv_color_hex(0xff000000), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
{
|
||||
lv_obj_t *parent_obj = obj;
|
||||
{
|
||||
lv_obj_t *obj = lv_label_create(parent_obj);
|
||||
lv_obj_set_pos(obj, 75, 103);
|
||||
objects.obj0 = obj;
|
||||
lv_obj_set_pos(obj, 217, 123);
|
||||
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_label_set_text(obj, "Hello, world!");
|
||||
lv_obj_set_style_text_font(obj, &ui_font_num, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_text_color(obj, lv_color_hex(0xffffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_label_set_text(obj, "g");
|
||||
}
|
||||
{
|
||||
lv_obj_t *obj = lv_label_create(parent_obj);
|
||||
objects.obj1 = obj;
|
||||
lv_obj_set_pos(obj, 5, 94);
|
||||
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_text_font(obj, &ui_font_num2, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_text_color(obj, lv_color_hex(0xffffe503), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_text_align(obj, LV_TEXT_ALIGN_RIGHT, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_label_set_text(obj, "");
|
||||
}
|
||||
{
|
||||
lv_obj_t *obj = lv_label_create(parent_obj);
|
||||
objects.obj2 = obj;
|
||||
lv_obj_set_pos(obj, 40, 7);
|
||||
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_text_font(obj, &ui_font_chinese32, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_text_color(obj, lv_color_hex(0xffffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_label_set_text(obj, "智能电子称");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +71,15 @@ void create_screen_main() {
|
||||
void tick_screen_main() {
|
||||
void *flowState = getFlowState(0, 0);
|
||||
(void)flowState;
|
||||
{
|
||||
const char *new_val = evalTextProperty(flowState, 2, 3, "Failed to evaluate Text in Label widget");
|
||||
const char *cur_val = lv_label_get_text(objects.obj1);
|
||||
if (strcmp(new_val, cur_val) != 0) {
|
||||
tick_value_change_obj = objects.obj1;
|
||||
lv_label_set_text(objects.obj1, new_val);
|
||||
tick_value_change_obj = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (*tick_screen_func_t)();
|
||||
@@ -67,6 +98,10 @@ void tick_screen_by_id(enum ScreensEnum screenId) {
|
||||
//
|
||||
|
||||
ext_font_desc_t fonts[] = {
|
||||
{ "Num", &ui_font_num },
|
||||
{ "Num2", &ui_font_num2 },
|
||||
{ "chinese64", &ui_font_chinese64 },
|
||||
{ "chinese32", &ui_font_chinese32 },
|
||||
#if LV_FONT_MONTSERRAT_8
|
||||
{ "MONTSERRAT_8", &lv_font_montserrat_8 },
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,9 @@ enum ScreensEnum {
|
||||
|
||||
typedef struct _objects_t {
|
||||
lv_obj_t *main;
|
||||
lv_obj_t *obj0;
|
||||
lv_obj_t *obj1;
|
||||
lv_obj_t *obj2;
|
||||
} objects_t;
|
||||
|
||||
extern objects_t objects;
|
||||
|
||||
@@ -5,25 +5,33 @@
|
||||
#include "vars.h"
|
||||
|
||||
// ASSETS DEFINITION
|
||||
const uint8_t assets[332] = {
|
||||
const uint8_t assets[460] = {
|
||||
0x7E, 0x45, 0x45, 0x5A, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
|
||||
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xF0, 0x00, 0xF0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
|
||||
0x54, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||
0x24, 0x00, 0x00, 0x00, 0x30, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0x00, 0x00, 0x31, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||
0x2C, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x30, 0x75, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x31, 0x75, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x30, 0x75, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x30, 0x75, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
|
||||
0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
|
||||
0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
|
||||
0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
|
||||
0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00,
|
||||
0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00,
|
||||
0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00,
|
||||
0x00, 0xE0, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
@@ -31,6 +39,7 @@ const uint8_t assets[332] = {
|
||||
|
||||
native_var_t native_vars[] = {
|
||||
{ NATIVE_VAR_TYPE_NONE, 0, 0 },
|
||||
{ NATIVE_VAR_TYPE_FLOAT, get_var_weigt_ui, set_var_weigt_ui },
|
||||
};
|
||||
|
||||
ActionExecFunc actions[] = {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const uint8_t assets[332];
|
||||
extern const uint8_t assets[460];
|
||||
|
||||
void ui_init();
|
||||
void ui_tick();
|
||||
|
||||
5393
components/ui/ui_font_chinese32.c
Normal file
5393
components/ui/ui_font_chinese32.c
Normal file
File diff suppressed because it is too large
Load Diff
18752
components/ui/ui_font_chinese64.c
Normal file
18752
components/ui/ui_font_chinese64.c
Normal file
File diff suppressed because it is too large
Load Diff
3293
components/ui/ui_font_num.c
Normal file
3293
components/ui/ui_font_num.c
Normal file
File diff suppressed because it is too large
Load Diff
11151
components/ui/ui_font_num2.c
Normal file
11151
components/ui/ui_font_num2.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,2 +1,13 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "vars.h"
|
||||
|
||||
float weigt_ui;
|
||||
|
||||
float get_var_weigt_ui() {
|
||||
return weigt_ui;
|
||||
}
|
||||
|
||||
void set_var_weigt_ui(float value) {
|
||||
weigt_ui = value;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,10 @@ enum FlowGlobalVariables {
|
||||
FLOW_GLOBAL_VARIABLE_NONE
|
||||
};
|
||||
|
||||
// Native global variables
|
||||
// Native global variables
|
||||
|
||||
extern float get_var_weigt_ui();
|
||||
extern void set_var_weigt_ui(float value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -2,7 +2,38 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void ws2812_start_task(void);
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
// 预设颜色枚举
|
||||
typedef enum {
|
||||
WS2812_COLOR_RED = 0,
|
||||
WS2812_COLOR_GREEN,
|
||||
WS2812_COLOR_BLUE,
|
||||
WS2812_COLOR_YELLOW,
|
||||
WS2812_COLOR_CYAN,
|
||||
WS2812_COLOR_MAGENTA,
|
||||
WS2812_COLOR_WHITE,
|
||||
WS2812_COLOR_ORANGE,
|
||||
WS2812_COLOR_PURPLE,
|
||||
WS2812_COLOR_PINK,
|
||||
WS2812_COLOR_LIME,
|
||||
WS2812_COLOR_SKYBLUE,
|
||||
WS2812_COLOR_OFF,
|
||||
WS2812_COLOR_MAX
|
||||
} ws2812_color_t;
|
||||
|
||||
// 初始化 LED(调用一次)
|
||||
esp_err_t ws2812_init(void);
|
||||
|
||||
// 设置 RGB 颜色(0-255)
|
||||
esp_err_t ws2812_set_color(uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
// 使用预设颜色快速设置
|
||||
esp_err_t ws2812_set_preset_color(ws2812_color_t color);
|
||||
|
||||
// 熄灭 LED
|
||||
esp_err_t ws2812_off(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -10,6 +12,55 @@ extern "C" {
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
// 提前声明 ws2812_set_color,避免隐式声明
|
||||
esp_err_t ws2812_set_color(uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
// 预设颜色枚举
|
||||
typedef enum {
|
||||
WS2812_COLOR_RED = 0,
|
||||
WS2812_COLOR_GREEN,
|
||||
WS2812_COLOR_BLUE,
|
||||
WS2812_COLOR_YELLOW,
|
||||
WS2812_COLOR_CYAN,
|
||||
WS2812_COLOR_MAGENTA,
|
||||
WS2812_COLOR_WHITE,
|
||||
WS2812_COLOR_ORANGE,
|
||||
WS2812_COLOR_PURPLE,
|
||||
WS2812_COLOR_PINK,
|
||||
WS2812_COLOR_LIME,
|
||||
WS2812_COLOR_SKYBLUE,
|
||||
WS2812_COLOR_OFF,
|
||||
WS2812_COLOR_MAX
|
||||
} ws2812_color_t;
|
||||
|
||||
// 预设颜色表(GRB 顺序)
|
||||
static const uint8_t ws2812_color_table[WS2812_COLOR_MAX][3] = {
|
||||
{0, 50, 0}, // RED (G,R,B)
|
||||
{50, 0, 0}, // GREEN
|
||||
{0, 0, 50}, // BLUE
|
||||
{50, 50, 0}, // YELLOW
|
||||
{50, 0, 50}, // CYAN
|
||||
{0, 50, 50}, // MAGENTA
|
||||
{50, 50, 50}, // WHITE
|
||||
{25, 50, 0}, // ORANGE
|
||||
{25, 0, 50}, // PURPLE
|
||||
{0, 25, 50}, // PINK
|
||||
{50, 25, 0}, // LIME
|
||||
{50, 0, 25}, // SKYBLUE
|
||||
{0, 0, 0}, // OFF
|
||||
};
|
||||
|
||||
// 快捷设置预设颜色接口
|
||||
esp_err_t ws2812_set_preset_color(ws2812_color_t color)
|
||||
{
|
||||
if (color < 0 || color >= WS2812_COLOR_MAX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
const uint8_t *grb = ws2812_color_table[color];
|
||||
// 注意 GRB 顺序
|
||||
return ws2812_set_color(grb[1], grb[0], grb[2]);
|
||||
}
|
||||
|
||||
static const char *TAG = "led_strip";
|
||||
|
||||
// --- 针对 ESP32-C3 和单颗 LED 的配置 ---
|
||||
@@ -30,8 +81,14 @@ static const char *TAG = "led_strip";
|
||||
// 内存块大小:单颗 LED 需要的数据非常少,设为 0 让驱动自动分配最合适的内存
|
||||
#define LED_STRIP_MEMORY_BLOCK_WORDS 0
|
||||
|
||||
led_strip_handle_t configure_led(void)
|
||||
|
||||
static led_strip_handle_t s_led_strip = NULL;
|
||||
|
||||
esp_err_t ws2812_init(void)
|
||||
{
|
||||
if (s_led_strip) {
|
||||
return ESP_OK; // 已初始化
|
||||
}
|
||||
// 1. LED 灯带通用配置
|
||||
led_strip_config_t strip_config = {
|
||||
.strip_gpio_num = LED_STRIP_GPIO_PIN, // GPIO 0
|
||||
@@ -54,64 +111,45 @@ led_strip_handle_t configure_led(void)
|
||||
};
|
||||
|
||||
// 3. 创建 LED 灯带对象
|
||||
led_strip_handle_t led_strip;
|
||||
// 初始化 RMT 设备
|
||||
esp_err_t ret = led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip);
|
||||
esp_err_t ret = led_strip_new_rmt_device(&strip_config, &rmt_config, &s_led_strip);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to create LED strip object: %s", esp_err_to_name(ret));
|
||||
while (1); // 初始化失败则卡死
|
||||
s_led_strip = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Created LED strip object with RMT backend on GPIO %d", LED_STRIP_GPIO_PIN);
|
||||
return led_strip;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void ws2812_blink_task(void *pvParameters)
|
||||
esp_err_t ws2812_set_color(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
(void)pvParameters;
|
||||
|
||||
// 初始化 LED 灯带
|
||||
led_strip_handle_t led_strip = configure_led();
|
||||
uint8_t r = 0, g = 0, b = 0;
|
||||
int color_state = 0; // 0:红, 1:绿, 2:蓝
|
||||
|
||||
ESP_LOGI(TAG, "Start RGB cycling");
|
||||
|
||||
while (1) {
|
||||
// 根据状态设置颜色
|
||||
if (color_state == 0) {
|
||||
r = 50; g = 0; b = 0; // 红色
|
||||
ESP_LOGI(TAG, "Color: RED");
|
||||
} else if (color_state == 1) {
|
||||
r = 0; g = 50; b = 0; // 绿色
|
||||
ESP_LOGI(TAG, "Color: GREEN");
|
||||
} else {
|
||||
r = 0; g = 0; b = 50; // 蓝色
|
||||
ESP_LOGI(TAG, "Color: BLUE");
|
||||
}
|
||||
|
||||
// 设置像素 (索引0, R, G, B)
|
||||
ESP_ERROR_CHECK(led_strip_set_pixel(led_strip, 0, r, g, b));
|
||||
|
||||
// 刷新显示
|
||||
ESP_ERROR_CHECK(led_strip_refresh(led_strip));
|
||||
|
||||
// 更新状态,0->1->2->0...
|
||||
color_state = (color_state + 1) % 3;
|
||||
|
||||
// 延时 500ms
|
||||
vTaskDelay(pdMS_TO_TICKS(1600));
|
||||
if (!s_led_strip) {
|
||||
ESP_LOGE(TAG, "LED strip not initialized");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
esp_err_t ret = led_strip_set_pixel(s_led_strip, 0, r, g, b);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set pixel: %s", esp_err_to_name(ret));
|
||||
return ret;
|
||||
}
|
||||
ret = led_strip_refresh(s_led_strip);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to refresh strip: %s", esp_err_to_name(ret));
|
||||
return ret;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void ws2812_start_task(void)
|
||||
// 熄灭 LED(快捷接口)
|
||||
esp_err_t ws2812_off(void)
|
||||
{
|
||||
BaseType_t ret = xTaskCreate(ws2812_blink_task, "ws2812_blink_task", 4096, NULL, 5, NULL);
|
||||
if (ret != pdPASS) {
|
||||
ESP_LOGE(TAG, "Failed to create ws2812 blink task");
|
||||
}
|
||||
return ws2812_set_color(0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user