添加农业环境模块,集成 MQTT 客户端功能,支持配置参数和数据发布
This commit is contained in:
118
main/main.cpp
118
main/main.cpp
@@ -37,6 +37,7 @@
|
||||
#include "fire_sensor.h"
|
||||
#include "hx711.hpp"
|
||||
#include "su-03t.h"
|
||||
#include "agri_env.h"
|
||||
|
||||
#define TAG "MAIN"
|
||||
#define CO2_SPOILAGE_THRESHOLD_PPM 1500.0f
|
||||
@@ -97,7 +98,8 @@ static void reconfigure_twdt(uint32_t timeout_ms, uint32_t idle_core_mask)
|
||||
};
|
||||
|
||||
esp_err_t ret = esp_task_wdt_reconfigure(&twdt_cfg);
|
||||
if (ret != ESP_OK) {
|
||||
if (ret != ESP_OK)
|
||||
{
|
||||
ESP_LOGW(TAG, "TWDT reconfigure failed: %s", esp_err_to_name(ret));
|
||||
}
|
||||
}
|
||||
@@ -227,33 +229,41 @@ static void relay_status_task(void *arg)
|
||||
{
|
||||
bool relay_on = false;
|
||||
|
||||
if (relay_ctrl_get(RELAY_CTRL_ID_1, &relay_on) == ESP_OK) {
|
||||
if (relay_ctrl_get(RELAY_CTRL_ID_1, &relay_on) == ESP_OK)
|
||||
{
|
||||
set_var_fan_status(relay_status_text(relay_on));
|
||||
if (s_env_data_lock) {
|
||||
if (s_env_data_lock)
|
||||
{
|
||||
xSemaphoreTake(s_env_data_lock, portMAX_DELAY);
|
||||
s_env_data.fan_on = relay_on;
|
||||
xSemaphoreGive(s_env_data_lock);
|
||||
}
|
||||
}
|
||||
if (relay_ctrl_get(RELAY_CTRL_ID_2, &relay_on) == ESP_OK) {
|
||||
if (relay_ctrl_get(RELAY_CTRL_ID_2, &relay_on) == ESP_OK)
|
||||
{
|
||||
set_var_light_status(relay_status_text(relay_on));
|
||||
if (s_env_data_lock) {
|
||||
if (s_env_data_lock)
|
||||
{
|
||||
xSemaphoreTake(s_env_data_lock, portMAX_DELAY);
|
||||
s_env_data.light_on = relay_on;
|
||||
xSemaphoreGive(s_env_data_lock);
|
||||
}
|
||||
}
|
||||
if (relay_ctrl_get(RELAY_CTRL_ID_3, &relay_on) == ESP_OK) {
|
||||
if (relay_ctrl_get(RELAY_CTRL_ID_3, &relay_on) == ESP_OK)
|
||||
{
|
||||
set_var_cool_status(relay_status_text(relay_on));
|
||||
if (s_env_data_lock) {
|
||||
if (s_env_data_lock)
|
||||
{
|
||||
xSemaphoreTake(s_env_data_lock, portMAX_DELAY);
|
||||
s_env_data.cool_on = relay_on;
|
||||
xSemaphoreGive(s_env_data_lock);
|
||||
}
|
||||
}
|
||||
if (relay_ctrl_get(RELAY_CTRL_ID_4, &relay_on) == ESP_OK) {
|
||||
if (relay_ctrl_get(RELAY_CTRL_ID_4, &relay_on) == ESP_OK)
|
||||
{
|
||||
set_var_hot_status(relay_status_text(relay_on));
|
||||
if (s_env_data_lock) {
|
||||
if (s_env_data_lock)
|
||||
{
|
||||
xSemaphoreTake(s_env_data_lock, portMAX_DELAY);
|
||||
s_env_data.hot_on = relay_on;
|
||||
xSemaphoreGive(s_env_data_lock);
|
||||
@@ -272,9 +282,11 @@ static void sntp_task(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
if (wait_for_wifi_connected(pdMS_TO_TICKS(15000))) {
|
||||
if (wait_for_wifi_connected(pdMS_TO_TICKS(15000)))
|
||||
{
|
||||
esp_err_t sntp_ret = sntp_timp_sync_time(10000);
|
||||
if (sntp_ret != ESP_OK) {
|
||||
if (sntp_ret != ESP_OK)
|
||||
{
|
||||
ESP_LOGW(TAG, "SNTP sync failed: %s", esp_err_to_name(sntp_ret));
|
||||
}
|
||||
}
|
||||
@@ -289,20 +301,24 @@ static void sntp_task(void *arg)
|
||||
static void su03t_rx_callback(const su03t_frame_t *frame, void *user_ctx)
|
||||
{
|
||||
(void)user_ctx;
|
||||
if (frame == NULL) {
|
||||
if (frame == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char hex_buf[256];
|
||||
size_t pos = 0;
|
||||
for (size_t i = 0; i < frame->params_len && pos + 4 < sizeof(hex_buf); ++i) {
|
||||
for (size_t i = 0; i < frame->params_len && pos + 4 < sizeof(hex_buf); ++i)
|
||||
{
|
||||
int n = snprintf(&hex_buf[pos], sizeof(hex_buf) - pos, "%02X ", frame->params[i]);
|
||||
if (n <= 0) {
|
||||
if (n <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos += (size_t)n;
|
||||
}
|
||||
if (pos == 0) {
|
||||
if (pos == 0)
|
||||
{
|
||||
snprintf(hex_buf, sizeof(hex_buf), "(no params)");
|
||||
}
|
||||
|
||||
@@ -311,7 +327,8 @@ static void su03t_rx_callback(const su03t_frame_t *frame, void *user_ctx)
|
||||
(unsigned)frame->params_len,
|
||||
hex_buf);
|
||||
|
||||
if (s_env_data_lock) {
|
||||
if (s_env_data_lock)
|
||||
{
|
||||
xSemaphoreTake(s_env_data_lock, portMAX_DELAY);
|
||||
s_env_data.su03t_last_msgno = frame->msgno;
|
||||
s_env_data.su03t_rx_count++;
|
||||
@@ -332,9 +349,11 @@ static void hx711_task(void *arg)
|
||||
int tare_ok_count = 0;
|
||||
|
||||
// 上电空载自动去皮:当前重量作为 0g 基准
|
||||
for (int i = 0; i < HX711_TARE_SAMPLES; ++i) {
|
||||
for (int i = 0; i < HX711_TARE_SAMPLES; ++i)
|
||||
{
|
||||
int32_t raw = hx711.Read(pdMS_TO_TICKS(HX711_READ_TIMEOUT_MS));
|
||||
if (raw != HX711::kUndefined) {
|
||||
if (raw != HX711::kUndefined)
|
||||
{
|
||||
tare_sum += raw;
|
||||
tare_ok_count++;
|
||||
}
|
||||
@@ -342,10 +361,13 @@ static void hx711_task(void *arg)
|
||||
}
|
||||
|
||||
int32_t tare_offset = 0;
|
||||
if (tare_ok_count > 0) {
|
||||
if (tare_ok_count > 0)
|
||||
{
|
||||
tare_offset = (int32_t)(tare_sum / tare_ok_count);
|
||||
ESP_LOGI(TAG, "HX711 tare done: raw0=%ld, samples=%d", (long)tare_offset, tare_ok_count);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGW(TAG, "HX711 tare failed, use 0 as offset");
|
||||
}
|
||||
|
||||
@@ -355,14 +377,18 @@ static void hx711_task(void *arg)
|
||||
bool display_locked = false;
|
||||
uint32_t stable_count = 0;
|
||||
uint32_t err_cnt = 0;
|
||||
for (;;) {
|
||||
for (;;)
|
||||
{
|
||||
int32_t value = hx711.Read(pdMS_TO_TICKS(HX711_READ_TIMEOUT_MS));
|
||||
if (value != HX711::kUndefined) {
|
||||
if (value != HX711::kUndefined)
|
||||
{
|
||||
float weight_g = ((float)(value - tare_offset)) / HX711_COUNTS_PER_GRAM;
|
||||
if (fabsf(weight_g) < HX711_ZERO_DEADBAND_G) {
|
||||
if (fabsf(weight_g) < HX711_ZERO_DEADBAND_G)
|
||||
{
|
||||
weight_g = 0.0f;
|
||||
}
|
||||
if (weight_g < 0.0f) {
|
||||
if (weight_g < 0.0f)
|
||||
{
|
||||
weight_g = 0.0f;
|
||||
}
|
||||
|
||||
@@ -370,7 +396,8 @@ static void hx711_task(void *arg)
|
||||
filtered_weight_g = filtered_weight_g * (1.0f - HX711_FILTER_ALPHA) + weight_g * HX711_FILTER_ALPHA;
|
||||
float rounded_weight_g = roundf(filtered_weight_g * 100.0f) / 100.0f;
|
||||
|
||||
if (!display_initialized) {
|
||||
if (!display_initialized)
|
||||
{
|
||||
display_weight_g = rounded_weight_g;
|
||||
display_initialized = true;
|
||||
}
|
||||
@@ -378,40 +405,53 @@ static void hx711_task(void *arg)
|
||||
float diff_from_display = fabsf(rounded_weight_g - display_weight_g);
|
||||
|
||||
// 稳定后锁定显示,重量明显变化时再解锁并继续更新
|
||||
if (display_locked) {
|
||||
if (diff_from_display >= HX711_UNLOCK_DELTA_G) {
|
||||
if (display_locked)
|
||||
{
|
||||
if (diff_from_display >= HX711_UNLOCK_DELTA_G)
|
||||
{
|
||||
display_locked = false;
|
||||
stable_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!display_locked) {
|
||||
if (diff_from_display <= HX711_STABLE_BAND_G) {
|
||||
if (stable_count < HX711_STABLE_SAMPLES) {
|
||||
if (!display_locked)
|
||||
{
|
||||
if (diff_from_display <= HX711_STABLE_BAND_G)
|
||||
{
|
||||
if (stable_count < HX711_STABLE_SAMPLES)
|
||||
{
|
||||
stable_count++;
|
||||
}
|
||||
if (stable_count >= HX711_STABLE_SAMPLES) {
|
||||
if (stable_count >= HX711_STABLE_SAMPLES)
|
||||
{
|
||||
display_locked = true;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
stable_count = 0;
|
||||
}
|
||||
|
||||
if (diff_from_display >= HX711_UPDATE_MIN_STEP_G) {
|
||||
if (diff_from_display >= HX711_UPDATE_MIN_STEP_G)
|
||||
{
|
||||
display_weight_g = rounded_weight_g;
|
||||
}
|
||||
}
|
||||
|
||||
set_var_ice_weight(display_weight_g);
|
||||
|
||||
if (s_env_data_lock) {
|
||||
if (s_env_data_lock)
|
||||
{
|
||||
xSemaphoreTake(s_env_data_lock, portMAX_DELAY);
|
||||
s_env_data.ice_weight = display_weight_g;
|
||||
xSemaphoreGive(s_env_data_lock);
|
||||
}
|
||||
err_cnt = 0;
|
||||
} else {
|
||||
if ((++err_cnt % 20) == 0) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((++err_cnt % 20) == 0)
|
||||
{
|
||||
ESP_LOGW(TAG, "HX711 read timeout, check DOUT/SCK wiring and power");
|
||||
}
|
||||
}
|
||||
@@ -449,6 +489,12 @@ extern "C" void app_main(void)
|
||||
if (wait_for_wifi_connected(pdMS_TO_TICKS(15000)))
|
||||
{
|
||||
set_var_system_ip(wifi_connect_get_ip());
|
||||
|
||||
esp_err_t err = agri_env_mqtt_start();
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGW(TAG, "MQTT 启动失败: %s", esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 独立 SNTP 对时任务
|
||||
|
||||
Reference in New Issue
Block a user