Skip to content

Commit 8eecdd1

Browse files
authored
'增加sp-esp32-s3-1.54-muma开发板' (#655)
1 parent 319d333 commit 8eecdd1

File tree

7 files changed

+568
-0
lines changed

7 files changed

+568
-0
lines changed

main/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ elseif(CONFIG_BOARD_TYPE_MINSI_K08_DUAL)
169169
set(BOARD_TYPE "minsi-k08-dual")
170170
elseif(CONFIG_BOARD_TYPE_ZHENGCHEN_1_54TFT_ML307)
171171
set(BOARD_TYPE "zhengchen-1.54tft-ml307")
172+
elseif(CONFIG_BOARD_TYPE_ESP32_S3_1_54_MUMA)
173+
set(BOARD_TYPE "sp-esp32-s3-1.54-muma")
172174
endif()
173175
file(GLOB BOARD_SOURCES
174176
${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD_TYPE}/*.cc

main/Kconfig.projbuild

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ choice BOARD_TYPE
162162
bool "敏思科技K08(DUAL)"
163163
config BOARD_TYPE_ZHENGCHEN_1_54TFT_ML307
164164
bool "征辰科技1.54(ML307)"
165+
config BOARD_TYPE_ESP32_S3_1_54_MUMA
166+
bool "Spotpear ESP32-S3-1.54-MUMA"
165167
endchoice
166168

167169
choice ESP_S3_LCD_EV_Board_Version_TYPE
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
【产品简介】
2+
[] ESP32 S3小木马开发板1.54寸LCD小智muma虾哥AI DeepSeek人工智能语音聊天机器人N16R8
3+
【功能】
4+
[] 可爱小木马,支持天气时钟, SD视频播放, AI智能对话所有固件源码开源,适合小孩编程学习,可开发更多功能。
5+
AI小智支持语音唤醒。触摸版本额外支持触摸唤醒和打断
6+
显示屏:1.54寸ST7789 240x240分辨率
7+
产品链接:
8+
https://spotpear.cn/shop/ESP32-S3-AI-1.54-inch-LCD-Display-TouchScreen-N16R8-muma-DeepSeek/sp-esp32-s3-1.54-muma-W-Bat.html
9+
10+
# 编译配置命令
11+
12+
**配置编译目标为 ESP32S3:**
13+
14+
```bash
15+
idf.py set-target esp32s3
16+
```
17+
18+
**打开 menuconfig:**
19+
20+
```bash
21+
idf.py menuconfig
22+
```
23+
24+
**选择板子:**
25+
26+
```
27+
Xiaozhi Assistant -> Board Type -> Spotpear ESP32-S3-LCD-1.54-MUMA
28+
```
29+
30+
**编译:**
31+
32+
```bash
33+
idf.py build
34+
```
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#ifndef _BOARD_CONFIG_H_
2+
#define _BOARD_CONFIG_H_
3+
4+
// Movecall Moji configuration
5+
6+
#include <driver/gpio.h>
7+
8+
#define AUDIO_INPUT_SAMPLE_RATE 24000
9+
#define AUDIO_OUTPUT_SAMPLE_RATE 24000
10+
11+
#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_16 //MCLK
12+
#define AUDIO_I2S_GPIO_WS GPIO_NUM_45 //LRCK
13+
#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_9 //SCLK
14+
#define AUDIO_I2S_GPIO_DIN GPIO_NUM_10 //DOUT
15+
#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_8 //DIN
16+
17+
#define AUDIO_CODEC_PA_PIN GPIO_NUM_46
18+
#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_15
19+
#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_14
20+
#define AUDIO_CODEC_ES8311_ADDR ES8311_CODEC_DEFAULT_ADDR
21+
22+
#define BUILTIN_LED_GPIO GPIO_NUM_48
23+
#define BOOT_BUTTON_GPIO GPIO_NUM_0
24+
25+
26+
#define DISPLAY_WIDTH 240
27+
#define DISPLAY_HEIGHT 240
28+
#define DISPLAY_MIRROR_X false
29+
#define DISPLAY_MIRROR_Y false
30+
#define DISPLAY_SWAP_XY false
31+
32+
#define DISPLAY_OFFSET_X 0
33+
#define DISPLAY_OFFSET_Y 0
34+
35+
36+
#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_42
37+
#define DISPLAY_BACKLIGHT_OUTPUT_INVERT true
38+
39+
#define DISPLAY_SPI_SCLK_PIN GPIO_NUM_4
40+
#define DISPLAY_SPI_MOSI_PIN GPIO_NUM_2
41+
#define DISPLAY_SPI_CS_PIN GPIO_NUM_5
42+
#define DISPLAY_SPI_DC_PIN GPIO_NUM_47
43+
#define DISPLAY_SPI_RESET_PIN GPIO_NUM_38
44+
45+
46+
#define TP_PIN_NUM_TP_SDA (GPIO_NUM_11)
47+
#define TP_PIN_NUM_TP_SCL (GPIO_NUM_7)
48+
#define TP_PIN_NUM_TP_RST (GPIO_NUM_6)
49+
#define TP_PIN_NUM_TP_INT (GPIO_NUM_12)
50+
51+
#define POWER_CHARGE_LED_PIN GPIO_NUM_3
52+
#define POWER_CHARGE_DETECT_PIN GPIO_NUM_41
53+
#define POWER_ADC_UNIT ADC_UNIT_1
54+
#define POWER_ADC_CHANNEL ADC_CHANNEL_0
55+
56+
#define DISPLAY_SPI_SCLK_HZ (40 * 1000 * 1000)
57+
58+
#endif // _BOARD_CONFIG_H_
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"target": "esp32s3",
3+
"builds": [
4+
{
5+
"name": "sp-esp32-s3-1.54-muma",
6+
"sdkconfig_append": []
7+
}
8+
]
9+
}
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#ifndef __POWER_MANAGER_H__
2+
#define __POWER_MANAGER_H__
3+
4+
#include <driver/gpio.h>
5+
#include <esp_adc/adc_oneshot.h>
6+
#include <esp_log.h>
7+
#include <esp_timer.h>
8+
9+
class PowerManager {
10+
private:
11+
// 电池电量区间-分压电阻为2个100k
12+
static constexpr struct {
13+
uint16_t adc;
14+
uint8_t level;
15+
} BATTERY_LEVELS[] = {{1980, 0}, {2519, 100}};
16+
static constexpr size_t BATTERY_LEVELS_COUNT = 2;
17+
static constexpr size_t ADC_VALUES_COUNT = 10;
18+
19+
esp_timer_handle_t timer_handle_ = nullptr;
20+
gpio_num_t charging_pin_;
21+
gpio_num_t bat_led_pin_;
22+
adc_unit_t adc_unit_;
23+
adc_channel_t adc_channel_;
24+
uint16_t adc_values_[ADC_VALUES_COUNT];
25+
size_t adc_values_index_ = 0;
26+
size_t adc_values_count_ = 0;
27+
uint8_t battery_level_ = 100;
28+
bool is_charging_ = false;
29+
30+
static constexpr uint8_t MAX_CHANGE_COUNT = 8;
31+
static constexpr uint32_t TIME_LIMIT = 2000000; // 2 seconds in microseconds
32+
33+
uint8_t change_count_ = 0; // 记录状态变化次数
34+
uint64_t last_change_time_ = 0; // 最后一次状态变化的时间戳(微秒)
35+
36+
adc_oneshot_unit_handle_t adc_handle_;
37+
38+
void CheckBatteryStatus() {
39+
uint64_t current_time = esp_timer_get_time(); // 获取当前时间(微秒)
40+
41+
// 如果时间间隔超过2秒,则重置状态变化计数
42+
if (current_time - last_change_time_ > TIME_LIMIT) {
43+
change_count_ = 0;
44+
}
45+
46+
if (change_count_ < MAX_CHANGE_COUNT) {
47+
bool new_is_charging = gpio_get_level(bat_led_pin_) != 0; // 检查LED引脚状态
48+
49+
// 判断充电引脚状态
50+
if (new_is_charging) {
51+
new_is_charging = gpio_get_level(charging_pin_) == 1;
52+
}
53+
54+
// 如果状态有变化
55+
if (new_is_charging != is_charging_) {
56+
is_charging_ = new_is_charging;
57+
change_count_++; // 增加变化次数
58+
last_change_time_ = current_time; // 更新最后变化时间
59+
}
60+
}
61+
62+
ReadBatteryAdcData();
63+
}
64+
void ReadBatteryAdcData() {
65+
int adc_value;
66+
ESP_ERROR_CHECK(adc_oneshot_read(adc_handle_, adc_channel_, &adc_value));
67+
68+
adc_values_[adc_values_index_] = adc_value;
69+
adc_values_index_ = (adc_values_index_ + 1) % ADC_VALUES_COUNT;
70+
if (adc_values_count_ < ADC_VALUES_COUNT) {
71+
adc_values_count_++;
72+
}
73+
74+
uint32_t average_adc = 0;
75+
for (size_t i = 0; i < adc_values_count_; i++) {
76+
average_adc += adc_values_[i];
77+
}
78+
average_adc /= adc_values_count_;
79+
80+
CalculateBatteryLevel(average_adc);
81+
82+
83+
// ESP_LOGI("PowerManager", "ADC值: %d 平均值: %ld 电量: %u%%", adc_value, average_adc,
84+
// battery_level_);
85+
}
86+
87+
void CalculateBatteryLevel(uint32_t average_adc) {
88+
if (average_adc <= BATTERY_LEVELS[0].adc) {
89+
battery_level_ = 0;
90+
} else if (average_adc >= BATTERY_LEVELS[BATTERY_LEVELS_COUNT - 1].adc) {
91+
battery_level_ = 100;
92+
} else {
93+
float ratio = static_cast<float>(average_adc - BATTERY_LEVELS[0].adc) /
94+
(BATTERY_LEVELS[1].adc - BATTERY_LEVELS[0].adc);
95+
battery_level_ = ratio * 100;
96+
}
97+
}
98+
99+
public:
100+
PowerManager(gpio_num_t charging_pin, gpio_num_t bat_led_pin, adc_unit_t adc_unit = ADC_UNIT_2,
101+
adc_channel_t adc_channel = ADC_CHANNEL_3)
102+
: charging_pin_(charging_pin), bat_led_pin_(bat_led_pin), adc_unit_(adc_unit), adc_channel_(adc_channel) {
103+
104+
// 配置充电引脚
105+
gpio_config_t io_conf = {};
106+
io_conf.intr_type = GPIO_INTR_DISABLE;
107+
io_conf.mode = GPIO_MODE_INPUT;
108+
io_conf.pin_bit_mask = (1ULL << charging_pin_);
109+
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
110+
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
111+
gpio_config(&io_conf);
112+
113+
// 配置状态引脚
114+
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
115+
io_conf.pin_bit_mask = (1ULL << bat_led_pin_);
116+
gpio_config(&io_conf);
117+
118+
// 定时器配置
119+
esp_timer_create_args_t timer_args = {
120+
.callback =
121+
[](void* arg) {
122+
PowerManager* self = static_cast<PowerManager*>(arg);
123+
self->CheckBatteryStatus();
124+
},
125+
.arg = this,
126+
.dispatch_method = ESP_TIMER_TASK,
127+
.name = "battery_check_timer",
128+
.skip_unhandled_events = true,
129+
};
130+
ESP_ERROR_CHECK(esp_timer_create(&timer_args, &timer_handle_));
131+
ESP_ERROR_CHECK(esp_timer_start_periodic(timer_handle_, 500000)); // 1秒
132+
133+
// 初始化ADC
134+
InitializeAdc();
135+
}
136+
137+
void InitializeAdc() {
138+
adc_oneshot_unit_init_cfg_t init_config = {
139+
.unit_id = adc_unit_,
140+
.ulp_mode = ADC_ULP_MODE_DISABLE,
141+
};
142+
ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config, &adc_handle_));
143+
144+
adc_oneshot_chan_cfg_t chan_config = {
145+
.atten = ADC_ATTEN_DB_12,
146+
.bitwidth = ADC_BITWIDTH_12,
147+
};
148+
149+
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc_handle_, adc_channel_, &chan_config));
150+
}
151+
152+
~PowerManager() {
153+
if (timer_handle_) {
154+
esp_timer_stop(timer_handle_);
155+
esp_timer_delete(timer_handle_);
156+
}
157+
if (adc_handle_) {
158+
adc_oneshot_del_unit(adc_handle_);
159+
}
160+
}
161+
162+
bool IsCharging() { return is_charging_; }
163+
164+
uint8_t GetBatteryLevel() { return battery_level_; }
165+
};
166+
#endif // __POWER_MANAGER_H__

0 commit comments

Comments
 (0)