Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
esp32s3rebotcontrol
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
957dd
esp32s3rebotcontrol
Commits
8210082f
Commit
8210082f
authored
Jan 06, 2026
by
957dd
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
更新了部分代码
parent
2be6a78d
Show whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
748 additions
and
32 deletions
+748
-32
settings.json
.vscode/settings.json
+1
-1
CMakeLists.txt
main/CMakeLists.txt
+30
-3
Kconfig.projbuild
main/Kconfig.projbuild
+29
-7
application.c
main/application.c
+4
-0
application.h
main/application.h
+8
-0
betteryread.c
main/boards/gpiotrol/betteryread.c
+73
-0
betteryread.h
main/boards/gpiotrol/betteryread.h
+20
-0
gpiocontrol.c
main/boards/gpiotrol/gpiocontrol.c
+158
-0
gpiocontrol.h
main/boards/gpiotrol/gpiocontrol.h
+46
-0
serial.c
main/boards/serial/serial.c
+5
-0
serial.h
main/boards/serial/serial.h
+12
-0
gpio_led.c
main/led/gpio_led.c
+2
-0
gpio_led.h
main/led/gpio_led.h
+7
-0
main.c
main/main.c
+38
-5
mqttconf_commun.c
main/mqttconf/mqttconf_commun.c
+169
-10
mqttconf_commun.h
main/mqttconf/mqttconf_commun.h
+4
-0
ota.c
main/ota.c
+125
-2
ota.h
main/ota.h
+2
-1
wifidevnum_config.c
main/wifidevnum_config.c
+7
-0
wifidevnum_config.h
main/wifidevnum_config.h
+3
-0
partitions.csv
partitions.csv
+4
-2
index.html
www/index.html
+1
-1
No files found.
.vscode/settings.json
View file @
8210082f
...
@@ -15,6 +15,6 @@
...
@@ -15,6 +15,6 @@
"--query-driver=**"
,
"--query-driver=**"
,
"--compile-commands-dir=c:
\\
Users
\\
17122
\\
Desktop
\\
机甲大师自话
\\
H60
\\
esp32project
\\
RobotMiddle
\\
build"
"--compile-commands-dir=c:
\\
Users
\\
17122
\\
Desktop
\\
机甲大师自话
\\
H60
\\
esp32project
\\
RobotMiddle
\\
build"
],
],
"idf.portWin"
:
"COM
24
"
,
"idf.portWin"
:
"COM
6
"
,
"idf.flashType"
:
"UART"
"idf.flashType"
:
"UART"
}
}
main/CMakeLists.txt
View file @
8210082f
set
(
SOURCES
"wifidevnum_config.c"
set
(
SOURCES
"wifidevnum_config.c"
"mqttconf/mqttconf_commun.c"
"mqttconf/mqttconf_commun.c"
#"led/gpio_led.c"
#"led/gpio_led.c"
"serial/serial.c"
"boards/serial/serial.c"
"boards/gpiotrol/gpiocontrol.c"
"boards/gpiotrol/betteryread.c"
#"boards/common/board_common.c" # 统一入口文件
"ota.c"
"main.c"
)
"main.c"
)
set
(
INCLUDE_DIRS
"."
"mqttconf"
"serial"
)
set
(
INCLUDE_DIRS
"."
"mqttconf"
"boards/serial"
"boards/gpiotrol"
#"boards/common"
)
idf_component_register
(
SRCS
${
SOURCES
}
idf_component_register
(
SRCS
${
SOURCES
}
INCLUDE_DIRS
${
INCLUDE_DIRS
}
INCLUDE_DIRS
${
INCLUDE_DIRS
}
#HOLE_ARCHIVE
REQUIRES
driver
esp_https_ota
app_update
nvs_flash
esp_https_ota
esp_http_client
esp_http_server
spiffs
esp-tls
# <--- 替换掉刚才报错的 esp_crt_bundle
esp_netif
esp_event
esp_wifi
esp_adc
mqtt
json
)
)
spiffs_create_partition_image
(
storage ../www FLASH_IN_PROJECT
)
spiffs_create_partition_image
(
storage ../www FLASH_IN_PROJECT
)
main/Kconfig.projbuild
View file @
8210082f
...
@@ -6,18 +6,40 @@ config ROBIOT_WIFI_SSID
...
@@ -6,18 +6,40 @@ config ROBIOT_WIFI_SSID
help
help
Hotspot Name Settings.
Hotspot Name Settings.
config OTA_VERSION_URL
string "OTA Version URL"
default "wu"
help
The application will access this URL to check for updates.
config ROBOIOT_MQTT_URL
config ROBOIOT_MQTT_URL
string "MQTT URL"
string "MQTT URL"
default "https://fcrs-api.yd-ss.com/device/getConfig?deviceNo="
default "https://fcrs-api.yd-ss.com/device/getConfig?deviceNo="
help
help
MQTT Config URL
MQTT Config URL
config MY_APP_VERSION
string "Project Version"
default "1.0.1"
help
The version number of this firmware.
choice DEVICE_STM32_SERIAL_MODE
prompt "Does it have an STM32 serial?"
default MODE_SERIAL_WHETHER_OPEN
help
选择是否有串口心跳检测
config MODE_SERIAL_WHETHER_OPEN
bool "open stm32 serial beat"
help
打开串口心跳检测(适用于将esp32s3作为中间联网使用)
config MODE_SERIAL_WHETHER_CLOSE
bool "close stm32 serial beat"
help
关闭串口心跳检测,使用esp32引脚控制和心跳(适用于单ESP32)
config MODE_SERIAL_AND_GPIO
bool "open stm32 serial and gpio"
help
同时打开串口心跳和引脚使用()
endchoice
endmenu
endmenu
main/application.c
0 → 100644
View file @
8210082f
#include"application.h"
#include <stdio.h>
#include <string.h>
main/application.h
0 → 100644
View file @
8210082f
#ifndef APPLICATION_H
#define APPLICATION_H
#include "esp_err.h"
#endif
\ No newline at end of file
main/boards/gpiotrol/betteryread.c
0 → 100644
View file @
8210082f
#include "betteryread.h"
#include "esp_adc/adc_oneshot.h"
#include "esp_adc/adc_cali.h"
#include "esp_adc/adc_cali_scheme.h"
#include "esp_log.h"
static
const
char
*
TAG
=
"ADC_CONTROL"
;
// 全局句柄
static
adc_oneshot_unit_handle_t
adc1_handle
;
static
adc_cali_handle_t
adc_cali_handle
=
NULL
;
static
bool
do_calibration
=
false
;
// 校准初始化函数(内部使用)
static
bool
example_adc_calibration_init
(
adc_unit_t
unit
,
adc_channel_t
channel
,
adc_atten_t
atten
,
adc_cali_handle_t
*
out_handle
)
{
adc_cali_handle_t
handle
=
NULL
;
esp_err_t
ret
=
ESP_FAIL
;
bool
calibrated
=
false
;
// ESP32-S3 支持 Curve Fitting 校准方式
if
(
!
calibrated
)
{
adc_cali_curve_fitting_config_t
cali_config
=
{
.
unit_id
=
unit
,
.
chan
=
channel
,
.
atten
=
atten
,
.
bitwidth
=
ADC_BITWIDTH_DEFAULT
,
};
ret
=
adc_cali_create_scheme_curve_fitting
(
&
cali_config
,
&
handle
);
if
(
ret
==
ESP_OK
)
{
calibrated
=
true
;
}
}
*
out_handle
=
handle
;
ESP_LOGI
(
TAG
,
"ADC初始化成功"
);
return
calibrated
;
}
esp_err_t
board_adc_init
(
void
)
{
adc_oneshot_unit_init_cfg_t
init_config1
=
{
.
unit_id
=
ADC_UNIT_1
,
};
ESP_ERROR_CHECK
(
adc_oneshot_new_unit
(
&
init_config1
,
&
adc1_handle
));
adc_oneshot_chan_cfg_t
config
=
{
.
bitwidth
=
ADC_BITWIDTH_DEFAULT
,
.
atten
=
ADC_ATTEN_DB_12
,
};
ESP_ERROR_CHECK
(
adc_oneshot_config_channel
(
adc1_handle
,
ADC_CHANNEL_4
,
&
config
));
// 初始化校准
do_calibration
=
example_adc_calibration_init
(
ADC_UNIT_1
,
ADC_CHANNEL_4
,
ADC_ATTEN_DB_12
,
&
adc_cali_handle
);
return
ESP_OK
;
}
// 核心修改:返回 float
float
board_get_voltage_v
(
void
)
{
int
adc_raw
;
int
voltage_mv
;
esp_err_t
ret
=
adc_oneshot_read
(
adc1_handle
,
ADC_CHANNEL_4
,
&
adc_raw
);
if
(
ret
!=
ESP_OK
)
return
-
1
.
0
f
;
if
(
do_calibration
)
{
// 先获取校准后的毫伏值 (int)
adc_cali_raw_to_voltage
(
adc_cali_handle
,
adc_raw
,
&
voltage_mv
);
// 转换为伏特并返回小数
return
(
float
)
voltage_mv
/
1000
.
0
f
;
}
else
{
return
(
float
)(
adc_raw
*
3100
)
/
4095
.
0
f
/
1000
.
0
f
;
}
}
\ No newline at end of file
main/boards/gpiotrol/betteryread.h
0 → 100644
View file @
8210082f
#ifndef BETTERYREAD_H
#define BETTERYREAD_H
#include "esp_err.h"
#define ADC_GET_VOLTAGE_GPIO 5
/**
* @brief 初始化 ADC1 通道 4 (GPIO 5)
*/
esp_err_t
board_adc_init
(
void
);
/**
* @brief 读取当前电压值
* @return int 返回毫伏值 (mV),读取失败返回 -1
*/
float
board_get_voltage_v
(
void
);
#endif
\ No newline at end of file
main/boards/gpiotrol/gpiocontrol.c
0 → 100644
View file @
8210082f
#include "gpiocontrol.h"
#include "esp_log.h"
static
const
char
*
TAG
=
"GPIO_CONTROL"
;
// 定义 LEDC 通道结构体
static
const
ledc_channel_config_t
ledc_channels
[]
=
{
{
.
gpio_num
=
GPIO_PWM_MOTOR_6
,
.
speed_mode
=
LEDC_MODE
,
.
channel
=
LEDC_CHANNEL_0
,
.
intr_type
=
LEDC_INTR_DISABLE
,
.
timer_sel
=
LEDC_TIMER
,
.
duty
=
0
,
// 初始停止
.
hpoint
=
0
},
{
.
gpio_num
=
GPIO_PWM_MOTOR_7
,
.
speed_mode
=
LEDC_MODE
,
.
channel
=
LEDC_CHANNEL_1
,
.
intr_type
=
LEDC_INTR_DISABLE
,
.
timer_sel
=
LEDC_TIMER
,
.
duty
=
0
,
// 初始停止
.
hpoint
=
0
},
{
.
gpio_num
=
GPIO_PWM_SERVO_10
,
.
speed_mode
=
LEDC_MODE
,
.
channel
=
LEDC_CHANNEL_2
,
.
intr_type
=
LEDC_INTR_DISABLE
,
.
timer_sel
=
LEDC_TIMER
,
.
duty
=
SERVO_INIT_90_DEG
,
// 舵机初始化为 90 度
.
hpoint
=
0
},
{
.
gpio_num
=
GPIO_PWM_ESC_15
,
.
speed_mode
=
LEDC_MODE
,
.
channel
=
LEDC_CHANNEL_3
,
.
intr_type
=
LEDC_INTR_DISABLE
,
.
timer_sel
=
LEDC_TIMER
,
.
duty
=
ESC_MIN_DUTY
,
.
hpoint
=
0
},
{
.
gpio_num
=
GPIO_PWM_ESC_16
,
.
speed_mode
=
LEDC_MODE
,
.
channel
=
LEDC_CHANNEL_4
,
.
intr_type
=
LEDC_INTR_DISABLE
,
.
timer_sel
=
LEDC_TIMER
,
.
duty
=
ESC_MIN_DUTY
,
.
hpoint
=
0
}
};
esp_err_t
gpiocontrol_init
(
void
)
{
// 1. 配置定时器
ledc_timer_config_t
ledc_timer
=
{
.
speed_mode
=
LEDC_MODE
,
.
timer_num
=
LEDC_TIMER
,
.
duty_resolution
=
LEDC_DUTY_RES
,
.
freq_hz
=
FREQUENCY
,
.
clk_cfg
=
LEDC_AUTO_CLK
};
ESP_ERROR_CHECK
(
ledc_timer_config
(
&
ledc_timer
));
// 2. 配置 3 个通道
for
(
int
i
=
0
;
i
<
5
;
i
++
)
{
ESP_ERROR_CHECK
(
ledc_channel_config
(
&
ledc_channels
[
i
]));
}
ESP_LOGI
(
TAG
,
"PWM 初始化完成 (GPIO 6, 7 为电机, GPIO 10 为舵机 90度)"
);
return
ESP_OK
;
}
void
set_servo_angle
(
uint32_t
angle
)
{
if
(
angle
>
180
)
angle
=
180
;
// 将 0-180 度线性映射到 SERVO_MIN_DUTY 和 SERVO_MAX_DUTY 之间
uint32_t
duty
=
SERVO_MIN_DUTY
+
(
angle
*
(
SERVO_MAX_DUTY
-
SERVO_MIN_DUTY
)
/
180
);
ledc_set_duty
(
LEDC_MODE
,
LEDC_CHANNEL_2
,
duty
);
ledc_update_duty
(
LEDC_MODE
,
LEDC_CHANNEL_2
);
}
/**
* @brief 设置电机驱动引脚占空比 (GPIO 6, 7)
* @param gpio GPIO_PWM_MOTOR_6 或 GPIO_PWM_MOTOR_7
* @param duty_percent 0 到 100 之间的百分比
*/
void
set_motor_speed
(
int
gpio
,
uint32_t
duty_percent
)
{
if
(
duty_percent
>
100
)
duty_percent
=
100
;
// 百分比转换为 13-bit 数值 (0-8191)
uint32_t
duty
=
(
duty_percent
*
8191
)
/
100
;
ledc_channel_t
channel
=
(
gpio
==
GPIO_PWM_MOTOR_6
)
?
LEDC_CHANNEL_0
:
LEDC_CHANNEL_1
;
ledc_set_duty
(
LEDC_MODE
,
channel
,
duty
);
ledc_update_duty
(
LEDC_MODE
,
channel
);
}
void
car0102_speed_stop
(
void
)
{
// 将电机引脚占空比降为 0
ledc_set_duty
(
LEDC_MODE
,
LEDC_CHANNEL_0
,
0
);
ledc_update_duty
(
LEDC_MODE
,
LEDC_CHANNEL_0
);
ledc_set_duty
(
LEDC_MODE
,
LEDC_CHANNEL_1
,
0
);
ledc_update_duty
(
LEDC_MODE
,
LEDC_CHANNEL_1
);
ESP_LOGD
(
TAG
,
"电机已强制停止输出"
);
}
void
car0102_control_motor
(
int
mode
,
int
val
){
if
(
mode
==
1
){
if
(
val
<
50
){
set_motor_speed
(
GPIO_PWM_MOTOR_6
,
0
);
set_motor_speed
(
GPIO_PWM_MOTOR_7
,
0
);
}
else
{
set_motor_speed
(
GPIO_PWM_MOTOR_6
,
val
/
2
-
10
);
set_motor_speed
(
GPIO_PWM_MOTOR_7
,
0
);
}
}
else
if
(
mode
==
2
){
if
(
val
<
50
){
set_motor_speed
(
GPIO_PWM_MOTOR_6
,
0
);
set_motor_speed
(
GPIO_PWM_MOTOR_7
,
0
);
}
else
{
set_motor_speed
(
GPIO_PWM_MOTOR_6
,
0
);
set_motor_speed
(
GPIO_PWM_MOTOR_7
,
val
/
2
-
10
);
}
}
if
(
mode
==
3
){
if
(
val
<
45
)
set_servo_angle
(
90
);
else
if
(
val
<
70
)
set_servo_angle
(
50
+
val
+
7
);
else
if
(
val
>=
70
)
set_servo_angle
(
135
);
}
else
if
(
mode
==
4
){
if
(
val
<
45
)
set_servo_angle
(
90
);
else
if
(
val
<
70
)
set_servo_angle
(
130
-
val
-
7
);
else
if
(
val
>=
70
)
set_servo_angle
(
45
);
}
}
void
esc_set_throttle
(
uint8_t
percent
)
{
if
(
percent
>
100
)
percent
=
100
;
uint32_t
duty
=
ESC_MIN_DUTY
+
(
ESC_MAX_DUTY
-
ESC_MIN_DUTY
)
*
percent
/
100
;
ledc_set_duty
(
LEDC_LOW_SPEED_MODE
,
LEDC_CHANNEL_3
,
duty
);
ledc_update_duty
(
LEDC_LOW_SPEED_MODE
,
LEDC_CHANNEL_3
);
ledc_set_duty
(
LEDC_LOW_SPEED_MODE
,
LEDC_CHANNEL_4
,
duty
);
ledc_update_duty
(
LEDC_LOW_SPEED_MODE
,
LEDC_CHANNEL_4
);
}
\ No newline at end of file
main/boards/gpiotrol/gpiocontrol.h
0 → 100644
View file @
8210082f
#ifndef GPIOCONTROL_H
#define GPIOCONTROL_H
#include "driver/ledc.h"
#include "esp_err.h"
// 引脚定义
#define GPIO_PWM_MOTOR_6 6
#define GPIO_PWM_MOTOR_7 7
#define GPIO_PWM_SERVO_10 10
#define GPIO_PWM_ESC_15 15 // C615电调控制引脚
#define GPIO_PWM_ESC_16 16 // C615电调控制引脚
// LEDC 配置定义
#define LEDC_TIMER LEDC_TIMER_0
#define LEDC_MODE LEDC_LOW_SPEED_MODE
#define LEDC_DUTY_RES LEDC_TIMER_13_BIT // 13位分辨率 (0-8191)
#define FREQUENCY 50 // 频率 50Hz
// 舵机角度换算 (基于 50Hz, 13-bit 分辨率)
// 0.5ms (0度) -> 约 205
// 1.5ms (90度) -> 约 614
// 2.5ms (180度) -> 约 1024
#define SERVO_MIN_DUTY 205 // 0.5ms
#define SERVO_MAX_DUTY 1024 // 2.5ms
#define SERVO_INIT_90_DEG 614 // 1.5ms (90度)
// ===== ESC PWM (50Hz, 13bit) =====
#define ESC_MIN_DUTY 410 // 1.0ms
#define ESC_MID_DUTY 614 // 1.5ms
#define ESC_MAX_DUTY 819 // 2.0ms
/**
* @brief 初始化所有 PWM 引脚 (6, 7, 10)
*/
esp_err_t
gpiocontrol_init
(
void
);
void
car0102_speed_stop
(
void
);
void
car0102_control_motor
(
int
mode
,
int
val
);
void
esc_set_throttle
(
uint8_t
percent
);
#endif
\ No newline at end of file
main/serial/serial.c
→
main/
boards/
serial/serial.c
View file @
8210082f
...
@@ -101,6 +101,11 @@ void recserial_data(uint8_t *data){
...
@@ -101,6 +101,11 @@ void recserial_data(uint8_t *data){
void
serial_receive_task
(
void
*
pvParameters
)
{
void
serial_receive_task
(
void
*
pvParameters
)
{
uint8_t
data
[
128
];
uint8_t
data
[
128
];
uint8_t
frame_buf
[
8
];
uint8_t
frame_buf
[
8
];
vTaskDelay
(
pdMS_TO_TICKS
(
1000
));
esp_err_t
wifi_result
=
(
esp_err_t
)
pvParameters
;
if
(
wifi_result
!=
ESP_OK
){
vTaskDelay
(
pdMS_TO_TICKS
(
2000
));
}
serial_send_command
(
0x00
,
0x00
,
0x00
,
0x00
,
0x00
);
serial_send_command
(
0x00
,
0x00
,
0x00
,
0x00
,
0x00
);
...
...
main/serial/serial.h
→
main/
boards/
serial/serial.h
View file @
8210082f
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
#include <stdint.h>
#include <stdint.h>
#include "esp_err.h"
#include "esp_err.h"
#include <stdbool.h>
#include <stdbool.h>
#include "sdkconfig.h"
// 定义串口参数 (根据实际引脚修改)
// 定义串口参数 (根据实际引脚修改)
#define STM32_UART_PORT UART_NUM_1
#define STM32_UART_PORT UART_NUM_1
...
@@ -31,5 +32,15 @@ void serial_send_command(uint8_t mode, uint8_t value,uint8_t data3,uint8_t data4
...
@@ -31,5 +32,15 @@ void serial_send_command(uint8_t mode, uint8_t value,uint8_t data3,uint8_t data4
// 接收处理任务入口 (在 app_main 中启动)
// 接收处理任务入口 (在 app_main 中启动)
void
serial_receive_task
(
void
*
pvParameters
);
void
serial_receive_task
(
void
*
pvParameters
);
#if defined(CONFIG_ODE_SERIAL_WHETHER_OPEN)
#define DEVICE_SERIAL_BEAT 0
#elif defined(CONFIG_MODE_SERIAL_WHETHER_CLOSE)
#define DEVICE_SERIAL_BEAT 1
#elif defined(CONFIG_MODE_SERIAL_AND_GPIO)
#define DEVICE_SERIAL_BEAT 2
#else
#define DEVICE_SERIAL_BEAT 999
#endif
#endif
#endif
\ No newline at end of file
main/led/gpio_led.c
View file @
8210082f
#include "gpio_led.h"
\ No newline at end of file
main/led/gpio_led.h
View file @
8210082f
#ifndef __GPIO_LED_H__
#define __GPIO_LED_H__
#endif
\ No newline at end of file
main/main.c
View file @
8210082f
...
@@ -7,7 +7,10 @@
...
@@ -7,7 +7,10 @@
#include "esp_netif.h"
#include "esp_netif.h"
#include "wifidevnum_config.h"
#include "wifidevnum_config.h"
#include "mqttconf_commun.h"
#include "mqttconf_commun.h"
#include "betteryread.h"
#include "gpiocontrol.h"
#include "serial.h"
#include "serial.h"
#include "ota.h"
static
const
char
*
TAG
=
"MAIN"
;
static
const
char
*
TAG
=
"MAIN"
;
static
bool
init_task_triggered
=
false
;
static
bool
init_task_triggered
=
false
;
...
@@ -34,20 +37,49 @@ static void wifi_event_handler(void* arg, esp_event_base_t base, int32_t id, voi
...
@@ -34,20 +37,49 @@ static void wifi_event_handler(void* arg, esp_event_base_t base, int32_t id, voi
}
}
}
}
esp_err_t
device_type_init
(
void
){
#if DEVICE_SERIAL_BEAT ==0
ESP_ERROR_CHECK
(
serial_init
());
//初始化串口
ESP_LOGI
(
TAG
,
"使用仅串口控制模式"
);
xTaskCreate
(
serial_receive_task
,
"serial_rx"
,
4096
,
(
void
*
)
wifi_ret
,
10
,
NULL
);
#elif DEVICE_SERIAL_BEAT ==1
ESP_ERROR_CHECK
(
board_adc_init
());
ESP_ERROR_CHECK
(
gpiocontrol_init
());
ESP_LOGI
(
TAG
,
"使用自带引脚控制模式"
);
#else
ESP_ERROR_CHECK
(
board_adc_init
());
ESP_ERROR_CHECK
(
gpiocontrol_init
());
ESP_ERROR_CHECK
(
serial_init
());
//初始化串口
ESP_LOGI
(
TAG
,
"使用串口和自带引脚同时使用控制模式"
);
xTaskCreate
(
serial_receive_task
,
"serial_rx"
,
4096
,
NULL
,
10
,
NULL
);
#endif
return
ESP_OK
;
}
void
app_main
(
void
)
{
void
app_main
(
void
)
{
vTaskDelay
(
pdMS_TO_TICKS
(
10000
));
esp_err_t
ret
=
nvs_flash_init
();
esp_err_t
ret
=
nvs_flash_init
();
if
(
ret
==
ESP_ERR_NVS_NO_FREE_PAGES
||
ret
==
ESP_ERR_NVS_NEW_VERSION_FOUND
)
{
if
(
ret
==
ESP_ERR_NVS_NO_FREE_PAGES
||
ret
==
ESP_ERR_NVS_NEW_VERSION_FOUND
)
{
ESP_ERROR_CHECK
(
nvs_flash_erase
());
ESP_ERROR_CHECK
(
nvs_flash_erase
());
ret
=
nvs_flash_init
();
ret
=
nvs_flash_init
();
}
}
ESP_ERROR_CHECK
(
ret
);
ESP_ERROR_CHECK
(
ret
);
char
ssid
[
32
]
=
{
0
},
pass
[
64
]
=
{
0
};
esp_err_t
wifi_ret
=
read_from_nvs
(
"wifi_ssid"
,
ssid
,
sizeof
(
ssid
));
ESP_ERROR_CHECK
(
init_spiffs
());
// 启动 Web 前挂载 SPIFFS
ESP_ERROR_CHECK
(
init_spiffs
());
// 启动 Web 前挂载 SPIFFS
ESP_ERROR_CHECK
(
esp_netif_init
());
ESP_ERROR_CHECK
(
esp_netif_init
());
ESP_ERROR_CHECK
(
esp_event_loop_create_default
());
ESP_ERROR_CHECK
(
esp_event_loop_create_default
());
ESP_ERROR_CHECK
(
serial_init
());
//初始化串口
if
(
wifi_ret
==
ESP_OK
)
{
read_from_nvs
(
"wifi_pass"
,
pass
,
sizeof
(
pass
));
ESP_ERROR_CHECK
(
device_type_init
());
// 关键:创建 STA 模式的网络接口句柄
// 关键:创建 STA 模式的网络接口句柄
esp_netif_create_default_wifi_sta
();
esp_netif_create_default_wifi_sta
();
...
@@ -57,9 +89,6 @@ void app_main(void) {
...
@@ -57,9 +89,6 @@ void app_main(void) {
xTaskCreate
(
button_monitor_task
,
"btn_task"
,
4096
,
NULL
,
5
,
NULL
);
xTaskCreate
(
button_monitor_task
,
"btn_task"
,
4096
,
NULL
,
5
,
NULL
);
char
ssid
[
32
]
=
{
0
},
pass
[
64
]
=
{
0
};
if
(
read_from_nvs
(
"wifi_ssid"
,
ssid
,
sizeof
(
ssid
))
==
ESP_OK
)
{
read_from_nvs
(
"wifi_pass"
,
pass
,
sizeof
(
pass
));
wifi_init_config_t
cfg
=
WIFI_INIT_CONFIG_DEFAULT
();
wifi_init_config_t
cfg
=
WIFI_INIT_CONFIG_DEFAULT
();
esp_wifi_init
(
&
cfg
);
esp_wifi_init
(
&
cfg
);
...
@@ -78,6 +107,9 @@ void app_main(void) {
...
@@ -78,6 +107,9 @@ void app_main(void) {
esp_wifi_start
();
esp_wifi_start
();
esp_wifi_connect
();
esp_wifi_connect
();
xTaskCreate
(
serial_receive_task
,
"serial_rx"
,
4096
,
NULL
,
10
,
NULL
);
}
else
{
ESP_LOGI
(
TAG
,
"无保存wifi 信息,启动wifi 配置页面"
);
nowifidata_start_config_web
();
}
}
}
}
\ No newline at end of file
main/mqttconf/mqttconf_commun.c
View file @
8210082f
...
@@ -18,6 +18,12 @@
...
@@ -18,6 +18,12 @@
#include "sdkconfig.h"
#include "sdkconfig.h"
#include "esp_heap_caps.h"
#include "esp_heap_caps.h"
#include "serial.h"
#include "serial.h"
#include "esp_ota_ops.h"
#include "esp_app_format.h"
#include "gpiocontrol.h"
#include "betteryread.h"
#include "ota.h"
static
const
char
*
TAG
=
"MQTT_MGR"
;
static
const
char
*
TAG
=
"MQTT_MGR"
;
#define DEFAULT_MQTT_HOST "119.45.167.177"
#define DEFAULT_MQTT_HOST "119.45.167.177"
...
@@ -30,7 +36,7 @@ typedef struct {
...
@@ -30,7 +36,7 @@ typedef struct {
int
len
;
int
len
;
}
http_response_t
;
}
http_response_t
;
static
char
g_device_id
[
32
]
=
{
0
};
char
g_device_id
[
32
]
=
{
0
};
static
char
g_sta_ip
[
16
]
=
"0.0.0.0"
;
static
char
g_sta_ip
[
16
]
=
"0.0.0.0"
;
// 存储所有活跃的 MQTT 客户端句柄,用于心跳群发
// 存储所有活跃的 MQTT 客户端句柄,用于心跳群发
...
@@ -38,14 +44,19 @@ static esp_mqtt_client_handle_t client_list[MAX_MQTT_CLIENTS] = {NULL};
...
@@ -38,14 +44,19 @@ static esp_mqtt_client_handle_t client_list[MAX_MQTT_CLIENTS] = {NULL};
static
int
client_count
=
0
;
static
int
client_count
=
0
;
static
esp_timer_handle_t
g_hb_timer
=
NULL
;
static
esp_timer_handle_t
g_hb_timer
=
NULL
;
static
int
mqtt_send_deviceota_info
(
void
);
/**
/**
* @brief 远程控制解析
* @brief 远程控制解析
*/
*/
static
void
handle_remote_control
(
const
char
*
data
)
{
static
void
handle_remote_control
(
const
char
*
data
)
{
if
(
!
data
)
return
;
if
(
!
data
)
return
;
cJSON
*
root
=
cJSON_Parse
(
data
);
cJSON
*
root
=
cJSON_Parse
(
data
);
if
(
!
root
)
return
;
cJSON
*
head
=
cJSON_GetObjectItem
(
root
,
"head"
);
cJSON
*
head
=
cJSON_GetObjectItem
(
root
,
"head"
);
if
(
head
==
NULL
)
ota_update_recmqtt
(
data
);
if
(
head
&&
cJSON_IsObject
(
head
))
{
if
(
head
&&
cJSON_IsObject
(
head
))
{
cJSON
*
m_type
=
cJSON_GetObjectItem
(
head
,
"message_type"
);
cJSON
*
m_type
=
cJSON_GetObjectItem
(
head
,
"message_type"
);
cJSON
*
body
=
cJSON_GetObjectItem
(
root
,
"body"
);
cJSON
*
body
=
cJSON_GetObjectItem
(
root
,
"body"
);
...
@@ -54,9 +65,12 @@ static void handle_remote_control(const char *data) {
...
@@ -54,9 +65,12 @@ static void handle_remote_control(const char *data) {
if
(
pin_ctrl
)
{
if
(
pin_ctrl
)
{
int
pin
=
cJSON_GetObjectItem
(
pin_ctrl
,
"pin"
)
->
valueint
;
int
pin
=
cJSON_GetObjectItem
(
pin_ctrl
,
"pin"
)
->
valueint
;
int
val
=
cJSON_GetObjectItem
(
pin_ctrl
,
"val"
)
->
valueint
;
int
val
=
cJSON_GetObjectItem
(
pin_ctrl
,
"val"
)
->
valueint
;
gpio_reset_pin
(
pin
);
if
(
pin
==
27
&&
val
==
1
)
esc_set_throttle
(
25
);
gpio_set_direction
(
pin
,
GPIO_MODE_OUTPUT
);
if
(
pin
==
27
&&
val
==
0
)
esc_set_throttle
(
0
);
gpio_set_level
(
pin
,
val
);
if
(
pin
==
5
&&
val
==
1
)
esc_set_throttle
(
100
);
if
(
pin
==
7
&&
val
==
1
)
esc_set_throttle
(
0
);
ESP_LOGW
(
TAG
,
"GPIO控制: Pin %d -> %d"
,
pin
,
val
);
ESP_LOGW
(
TAG
,
"GPIO控制: Pin %d -> %d"
,
pin
,
val
);
}
}
}
else
if
(
m_type
&&
m_type
->
valueint
==
3
&&
body
)
{
}
else
if
(
m_type
&&
m_type
->
valueint
==
3
&&
body
)
{
...
@@ -66,36 +80,58 @@ static void handle_remote_control(const char *data) {
...
@@ -66,36 +80,58 @@ static void handle_remote_control(const char *data) {
int
type
=
cJSON_GetObjectItem
(
pwm_ctrl
,
"type"
)
->
valueint
;
int
type
=
cJSON_GetObjectItem
(
pwm_ctrl
,
"type"
)
->
valueint
;
int
val
=
cJSON_GetObjectItem
(
pwm_ctrl
,
"val"
)
->
valueint
;
int
val
=
cJSON_GetObjectItem
(
pwm_ctrl
,
"val"
)
->
valueint
;
ESP_LOGW
(
TAG
,
"PWM指令: m:%d t:%d v:%d"
,
mode
,
type
,
val
);
ESP_LOGW
(
TAG
,
"PWM指令: m:%d t:%d v:%d"
,
mode
,
type
,
val
);
#if DEVICE_SERIAL_BEAT ==0
serial_send_command
(
mode
,
val
,
0
,
0
,
0
);
// 串口下发给STM32
serial_send_command
(
mode
,
val
,
0
,
0
,
0
);
// 串口下发给STM32
#elif DEVICE_SERIAL_BEAT ==1
car0102_control_motor
(
mode
,
val
);
#else
ESP_LOGW
(
TAG
,
"看情况"
);
#endif
}
}
}
}
}
}
cJSON_Delete
(
root
);
cJSON_Delete
(
root
);
}
}
/**
/**
* @brief 构造心跳包内容
* @brief 构造心跳包内容
*/
*/
static
char
*
generate_hb_payload
()
{
static
char
*
generate_hb_payload
()
{
cJSON
*
root
=
cJSON_CreateObject
();
cJSON
*
root
=
cJSON_CreateObject
();
cJSON
*
body
=
cJSON_CreateObject
();
cJSON
*
body
=
cJSON_CreateObject
();
cJSON_AddStringToObject
(
body
,
"ip"
,
g_sta_ip
);
cJSON_AddStringToObject
(
body
,
"ip"
,
g_sta_ip
);
char
id_full
[
64
],
volat
[
16
]
,
tempvalue
[
16
]
;
char
id_full
[
64
],
volat
[
16
];
snprintf
(
id_full
,
sizeof
(
id_full
),
"app2dev/%s"
,
g_device_id
);
snprintf
(
id_full
,
sizeof
(
id_full
),
"app2dev/%s"
,
g_device_id
);
#if DEVICE_SERIAL_BEAT ==0
char
tempvalue
[
16
];
snprintf
(
volat
,
sizeof
(
volat
),
"%.2f"
,
get_stm32_battery_voltage
());
snprintf
(
volat
,
sizeof
(
volat
),
"%.2f"
,
get_stm32_battery_voltage
());
snprintf
(
tempvalue
,
sizeof
(
tempvalue
),
"%.2f"
,
get_stm32_battery_tempvalue
());
snprintf
(
tempvalue
,
sizeof
(
tempvalue
),
"%.2f"
,
get_stm32_battery_tempvalue
());
cJSON_AddStringToObject
(
body
,
"tempvalue"
,
tempvalue
);
cJSON_AddStringToObject
(
body
,
"device_ID"
,
id_full
);
cJSON_AddStringToObject
(
body
,
"voltage"
,
volat
);
cJSON_AddStringToObject
(
body
,
"voltage"
,
volat
);
#elif DEVICE_SERIAL_BEAT ==1
snprintf
(
volat
,
sizeof
(
volat
),
"%.2f"
,
board_get_voltage_v
());
cJSON_AddStringToObject
(
body
,
"voltage"
,
volat
);
#else
char
volat_stm32
[
16
],
tempvalue
[
16
];
snprintf
(
volat_stm32
,
sizeof
(
volat_stm32
),
"%.2f"
,
get_stm32_battery_voltage
());
snprintf
(
tempvalue
,
sizeof
(
tempvalue
),
"%.2f"
,
get_stm32_battery_tempvalue
());
cJSON_AddStringToObject
(
body
,
"tempvalue"
,
tempvalue
);
cJSON_AddStringToObject
(
body
,
"tempvalue"
,
tempvalue
);
cJSON_AddStringToObject
(
body
,
"version"
,
"1.1.0"
);
cJSON_AddStringToObject
(
body
,
"stm32_voltage"
,
volat_stm32
);
snprintf
(
volat
,
sizeof
(
volat
),
"%.2f"
,
board_get_voltage_v
());
cJSON_AddStringToObject
(
body
,
"esp32_voltage"
,
volat
);
#endif
cJSON_AddStringToObject
(
body
,
"device_ID"
,
id_full
);
cJSON_AddStringToObject
(
body
,
"version"
,
CONFIG_MY_APP_VERSION
);
cJSON_AddItemToObject
(
root
,
"body"
,
body
);
cJSON_AddItemToObject
(
root
,
"body"
,
body
);
cJSON
*
head
=
cJSON_CreateObject
();
cJSON
*
head
=
cJSON_CreateObject
();
cJSON_AddNumberToObject
(
head
,
"message_type"
,
1
);
cJSON_AddNumberToObject
(
head
,
"message_type"
,
1
);
cJSON_AddItemToObject
(
root
,
"head"
,
head
);
cJSON_AddItemToObject
(
root
,
"head"
,
head
);
char
*
out
=
cJSON_PrintUnformatted
(
root
);
char
*
out
=
cJSON_PrintUnformatted
(
root
);
cJSON_Delete
(
root
);
cJSON_Delete
(
root
);
return
out
;
return
out
;
...
@@ -130,6 +166,46 @@ static void mqtt_heartbeat_timer_cb(void *arg) {
...
@@ -130,6 +166,46 @@ static void mqtt_heartbeat_timer_cb(void *arg) {
free
(
json
);
free
(
json
);
}
}
// 定时器句柄
TimerHandle_t
ota_msg_timer
;
// 定时器触发后的回调函数
void
ota_msg_send_task
(
void
*
pvParameters
)
{
// 将传入的参数转回延迟秒数
int
delay_seconds
=
(
int
)
pvParameters
;
// 在任务内部进行延迟,不阻塞其他程序
vTaskDelay
(
pdMS_TO_TICKS
(
delay_seconds
*
1000
));
ESP_LOGI
(
"OTA_TASK"
,
"延迟结束,正在发送 MQTT OTA 信息..."
);
// 执行你的 MQTT 发送逻辑
mqtt_send_deviceota_info
();
// 2. 关键:发送完毕后,任务自行销毁,实现“自动取消”和内存释放
ESP_LOGI
(
"OTA_TASK"
,
"发送完成,任务已自动退出并销毁"
);
vTaskDelete
(
NULL
);
}
/**
* @brief 启动延迟发送
* @param delay_seconds 延迟几秒发送
*/
void
start_ota_report_timer
(
int
delay_seconds
)
{
ESP_LOGI
(
"OTA_TASK"
,
"创建一次性任务,将在 %d 秒后执行"
,
delay_seconds
);
// 创建一个独立任务
// 栈大小设置为 4096,足以应对 MQTT 和 JSON 操作,防止溢出
xTaskCreate
(
ota_msg_send_task
,
// 任务函数
"ota_msg_task"
,
// 任务名称
4096
,
// 栈深度 (Stack Size)
(
void
*
)
delay_seconds
,
// 传递延迟时间作为参数
5
,
// 优先级 (根据需要调整)
NULL
// 不需要保存任务句柄
);
}
/**
/**
* @brief MQTT 事件回调
* @brief MQTT 事件回调
*/
*/
...
@@ -140,6 +216,9 @@ static void common_mqtt_event_handler(void *handler_args, esp_event_base_t base,
...
@@ -140,6 +216,9 @@ static void common_mqtt_event_handler(void *handler_args, esp_event_base_t base,
switch
(
event
->
event_id
)
{
switch
(
event
->
event_id
)
{
case
MQTT_EVENT_CONNECTED
:
case
MQTT_EVENT_CONNECTED
:
ESP_LOGI
(
TAG
,
"[%s] 已连接"
,
ip
);
ESP_LOGI
(
TAG
,
"[%s] 已连接"
,
ip
);
if
(
strcmp
(
ip
,
DEFAULT_MQTT_HOST
)
==
0
){
start_ota_report_timer
(
5
);
}
char
s1
[
64
],
s2
[
64
];
char
s1
[
64
],
s2
[
64
];
snprintf
(
s1
,
sizeof
(
s1
),
"app2dev/%s"
,
g_device_id
);
snprintf
(
s1
,
sizeof
(
s1
),
"app2dev/%s"
,
g_device_id
);
snprintf
(
s2
,
sizeof
(
s2
),
"ser2dev/%s"
,
g_device_id
);
snprintf
(
s2
,
sizeof
(
s2
),
"ser2dev/%s"
,
g_device_id
);
...
@@ -154,6 +233,7 @@ static void common_mqtt_event_handler(void *handler_args, esp_event_base_t base,
...
@@ -154,6 +233,7 @@ static void common_mqtt_event_handler(void *handler_args, esp_event_base_t base,
memcpy
(
tmp
,
event
->
data
,
event
->
data_len
);
memcpy
(
tmp
,
event
->
data
,
event
->
data_len
);
tmp
[
event
->
data_len
]
=
'\0'
;
tmp
[
event
->
data_len
]
=
'\0'
;
handle_remote_control
(
tmp
);
handle_remote_control
(
tmp
);
free
(
tmp
);
free
(
tmp
);
}
}
}
}
...
@@ -314,3 +394,81 @@ void mqtt_manager_stop(void) {
...
@@ -314,3 +394,81 @@ void mqtt_manager_stop(void) {
ESP_LOGI
(
TAG
,
"MQTT 服务已完全停止"
);
ESP_LOGI
(
TAG
,
"MQTT 服务已完全停止"
);
}
}
/**
* @brief 发送设备信息到 MQTT(JSON 格式)
* @return 0 成功,-1 失败
*/
int
mqtt_send_deviceota_info
(
void
)
{
cJSON
*
root
=
NULL
;
char
*
json_str
=
NULL
;
int
ret
=
-
1
;
/* 1. 创建 JSON 对象 */
root
=
cJSON_CreateObject
();
if
(
!
root
)
{
return
-
1
;
}
/* 2. 添加字段(直接读取全局变量) */
cJSON_AddStringToObject
(
root
,
"device_id"
,
g_device_id
);
const
esp_app_desc_t
*
app_desc
=
esp_app_get_description
();
const
char
*
running_version
=
app_desc
->
version
;
cJSON_AddStringToObject
(
root
,
"version"
,
running_version
);
/* 3. JSON 转字符串(紧凑格式,适合 MQTT) */
json_str
=
cJSON_PrintUnformatted
(
root
);
if
(
!
json_str
)
{
goto
exit
;
}
/* 4. MQTT 发送 */
esp_mqtt_client_publish
(
client_list
[
0
],
"esp32updata"
,
json_str
,
0
,
1
,
0
);
exit:
if
(
json_str
)
{
free
(
json_str
);
}
if
(
root
)
{
cJSON_Delete
(
root
);
}
return
ret
;
}
// #if defined(CONFIG_ODE_SERIAL_WHETHER_OPEN)
// void mqtt_abnormal_exittask(void *pvParameters)
// {
// ESP_LOGI(TAG, "MQTT异常任务启动");
// while(1){
// if(client_list[0] == NULL) {
// vTaskDelay(pdMS_TO_TICKS(1000));
// continue;
// }
// }
// }
// #elif defined(CONFIG_MODE_SERIAL_WHETHER_CLOSE)
// void mqtt_abnormal_exittask(void *pvParameters)
// {
// ESP_LOGI(TAG, "MQTT异常任务启动");
// while(1){
// if(client_list[0] == NULL) {
// vTaskDelay(pdMS_TO_TICKS(1000));
// continue;
// }
// }
// }
//#elif defined(CONFIG_MODE_SERIAL_AND_GPIO)
// #endif
\ No newline at end of file
main/mqttconf/mqttconf_commun.h
View file @
8210082f
...
@@ -8,4 +8,7 @@
...
@@ -8,4 +8,7 @@
// 启动所有 MQTT 相关逻辑
// 启动所有 MQTT 相关逻辑
void
mqtt_manager_init_sequence
(
void
);
void
mqtt_manager_init_sequence
(
void
);
void
mqtt_manager_stop
(
void
);
void
mqtt_manager_stop
(
void
);
#endif
#endif
\ No newline at end of file
main/ota.c
View file @
8210082f
#include "OTA.h"
#include "ota.h"
\ No newline at end of file
#include "esp_log.h"
#include "esp_ota_ops.h"
#include "esp_app_format.h"
#include "esp_http_client.h"
#include "esp_https_ota.h"
#include "esp_crt_bundle.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "wifidevnum_config.h" // 假设你有封装好的 read_from_nvs 和 save_to_nvs
#include "esp_spiffs.h"
#include <cJSON.h>
#include <string.h>
static
const
char
*
TAG
=
"OTA_UPDATE"
;
/**
* @brief HTTP 事件处理
*/
esp_err_t
_ota_http_event_handler
(
esp_http_client_event_t
*
evt
)
{
switch
(
evt
->
event_id
)
{
case
HTTP_EVENT_ERROR
:
ESP_LOGE
(
TAG
,
"HTTP_EVENT_ERROR"
);
break
;
case
HTTP_EVENT_ON_CONNECTED
:
ESP_LOGI
(
TAG
,
"已连接到服务器"
);
break
;
case
HTTP_EVENT_ON_FINISH
:
ESP_LOGI
(
TAG
,
"数据传输完成"
);
break
;
default:
break
;
}
return
ESP_OK
;
}
/**
* @brief 启动 OTA
*/
void
start_ota_update
(
const
char
*
url
)
{
ESP_LOGI
(
TAG
,
"正在从 URL 启动 OTA: %s"
,
url
);
esp_http_client_config_t
config
=
{
.
url
=
url
,
.
crt_bundle_attach
=
esp_crt_bundle_attach
,
.
event_handler
=
_ota_http_event_handler
,
.
keep_alive_enable
=
true
,
.
timeout_ms
=
10000
,
};
esp_https_ota_config_t
ota_config
=
{
.
http_config
=
&
config
,
};
ESP_LOGI
(
TAG
,
"正在下载并写入固件... 请勿断电"
);
esp_err_t
ret
=
esp_https_ota
(
&
ota_config
);
// 在这里获取更新后的分区指针
const
esp_partition_t
*
updated_partition
=
esp_ota_get_next_update_partition
(
NULL
);
if
(
ret
==
ESP_OK
)
{
ESP_LOGI
(
TAG
,
"OTA 升级成功!即将重启..."
);
ESP_LOGI
(
TAG
,
"找到更新分区: %s (偏移: 0x%08x)"
,
updated_partition
->
label
,
updated_partition
->
address
);
esp_err_t
set_err
=
esp_ota_set_boot_partition
(
updated_partition
);
if
(
set_err
==
ESP_OK
)
{
ESP_LOGI
(
TAG
,
"启动分区设置成功!"
);
// 验证设置结果
const
esp_partition_t
*
boot_partition
=
esp_ota_get_boot_partition
();
const
esp_partition_t
*
running_partition
=
esp_ota_get_running_partition
();
ESP_LOGI
(
TAG
,
"当前运行分区: %s (0x%08x)"
,
running_partition
->
label
,
running_partition
->
address
);
ESP_LOGI
(
TAG
,
"下次启动分区: %s (0x%08x)"
,
boot_partition
->
label
,
boot_partition
->
address
);
// 等待设置完成
vTaskDelay
(
2000
/
portTICK_PERIOD_MS
);
esp_restart
();
}
else
{
ESP_LOGE
(
TAG
,
"设置启动分区失败: %s"
,
esp_err_to_name
(
set_err
));
}
}
else
{
ESP_LOGE
(
TAG
,
"OTA 升级失败: %s"
,
esp_err_to_name
(
ret
));
}
}
/**
* @brief MQTT 消息处理函数:解析 JSON 并判断是否需要更新
*/
int
ota_update_recmqtt
(
const
char
*
json_data
)
{
if
(
json_data
==
NULL
)
return
-
1
;
cJSON
*
root
=
cJSON_Parse
(
json_data
);
if
(
root
==
NULL
)
return
-
1
;
ESP_LOGI
(
TAG
,
"当前固件运行版本: %s"
,
CONFIG_MY_APP_VERSION
);
// 2. 解析云端发来的新版本号
cJSON
*
new_version_obj
=
cJSON_GetObjectItem
(
root
,
"new_version"
);
if
(
!
cJSON_IsString
(
new_version_obj
)
||
(
new_version_obj
->
valuestring
==
NULL
))
{
cJSON_Delete
(
root
);
return
-
1
;
}
const
char
*
cloud_version
=
new_version_obj
->
valuestring
;
// 3. 版本对比
if
(
strcmp
(
CONFIG_MY_APP_VERSION
,
cloud_version
)
==
0
)
{
ESP_LOGI
(
TAG
,
"当前已是最新版本 (%s),跳过更新。"
,
CONFIG_MY_APP_VERSION
);
cJSON_Delete
(
root
);
return
0
;
}
ESP_LOGI
(
TAG
,
"检测到新版本: %s -> %s"
,
CONFIG_MY_APP_VERSION
,
cloud_version
);
// 5. 解析下载地址并启动更新
cJSON
*
esp32_url
=
cJSON_GetObjectItem
(
root
,
"esp32_url"
);
if
(
cJSON_IsString
(
esp32_url
)
&&
(
esp32_url
->
valuestring
!=
NULL
))
{
start_ota_update
(
esp32_url
->
valuestring
);
}
else
{
ESP_LOGE
(
TAG
,
"JSON 中未找到有效的 esp32_url"
);
}
cJSON_Delete
(
root
);
return
0
;
}
main/ota.h
View file @
8210082f
...
@@ -3,6 +3,6 @@
...
@@ -3,6 +3,6 @@
#include "esp_err.h"
#include "esp_err.h"
int
ota_update_recmqtt
(
const
char
*
json_data
);
#endif
#endif
\ No newline at end of file
main/wifidevnum_config.c
View file @
8210082f
...
@@ -188,7 +188,14 @@ void start_config_web() {
...
@@ -188,7 +188,14 @@ void start_config_web() {
}
}
}
}
void
nowifidata_start_config_web
(
void
)
{
wifi_editable
=
true
;
devid_editable
=
true
;
start_config_web
();
}
void
button_monitor_task
(
void
*
arg
)
{
void
button_monitor_task
(
void
*
arg
)
{
gpio_config_t
io_conf
=
{
gpio_config_t
io_conf
=
{
.
pin_bit_mask
=
(
1ULL
<<
BTN_WIFI_IO
)
|
(
1ULL
<<
BTN_DEVID_IO
),
.
pin_bit_mask
=
(
1ULL
<<
BTN_WIFI_IO
)
|
(
1ULL
<<
BTN_DEVID_IO
),
.
mode
=
GPIO_MODE_INPUT
,
.
pull_up_en
=
1
.
mode
=
GPIO_MODE_INPUT
,
.
pull_up_en
=
1
...
...
main/wifidevnum_config.h
View file @
8210082f
...
@@ -14,4 +14,6 @@ void button_monitor_task(void* arg);
...
@@ -14,4 +14,6 @@ void button_monitor_task(void* arg);
void
start_config_web
(
void
);
void
start_config_web
(
void
);
esp_err_t
init_spiffs
(
void
);
esp_err_t
init_spiffs
(
void
);
void
nowifidata_start_config_web
(
void
);
#endif
#endif
\ No newline at end of file
partitions.csv
View file @
8210082f
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
nvs, data, nvs, , 0x6000,
nvs, data, nvs, , 0x6000,
otadata, data, ota, , 0x2000,
otadata, data, ota, , 0x2000,
phy_init, data, phy, , 0x1000,
phy_init, data, phy, , 0x1000,
ota_0, app, ota_0, , 0x
4
00000,
ota_0, app, ota_0, , 0x
6
00000,
ota_1, app, ota_1, , 0x
4
00000,
ota_1, app, ota_1, , 0x
6
00000,
storage, data, spiffs, , 0x50000,
storage, data, spiffs, , 0x50000,
stm32otadata, data, stm32, , 0x100000
\ No newline at end of file
www/index.html
View file @
8210082f
...
@@ -13,7 +13,7 @@
...
@@ -13,7 +13,7 @@
</head>
</head>
<body>
<body>
<div
class=
"card"
>
<div
class=
"card"
>
<h1>
🦉 设备配置中心
</h1>
<h1>
🦉
飞驰
设备配置中心
</h1>
<form
action=
'/save'
method=
'POST'
>
<form
action=
'/save'
method=
'POST'
>
<b>
WiFi 配置 %s
</b>
<b>
WiFi 配置 %s
</b>
<input
name=
'ssid'
placeholder=
'WiFi名称'
%
s
>
<input
name=
'ssid'
placeholder=
'WiFi名称'
%
s
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment