Rdzleo 93f0e19d1d 初始化项目:精灵吊坠 RTC 语音助手 + VEML7700 石头同频匹配
ESP32-S3 吊坠设备固件,集成火山引擎 RTC 语音助手、蓝牙配网、
VEML7700 环境光传感器驱动及石头同频匹配交友功能。

VEML7700 驱动:
- 基于 ESP-IDF i2c_master API 实现,复用项目 I2cDevice 基类
- 支持 ALS + White 双通道、自动量程、Vishay 非线性校正
- 3 次采样取中位数过滤偶发异常

石头同频匹配算法(双维度):
- 维度1:光谱比值 ALS/White(石头固有光学特征,不随光照强度变化)
- 维度2:亮度等级(5级对数划分,排除极端环境差异)
- 比值阈值 15%,实测同石头姿势变化波动 1.6%~9.6%,安全余量充足

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 11:43:57 +08:00

143 lines
4.7 KiB
C

/* http client request example code
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include "freertos/idf_additions.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_wifi.h"
#include "audio_sys.h"
#include "audio_thread.h"
#include "esp_peripherals.h"
#include "periph_wifi.h"
#include "periph_sdcard.h"
#include "audio_mem.h"
#include "board.h"
#include "es8311.h"
#include "es7210.h"
#include "audio_processor.h"
#include "coze_chat.h"
static char *TAG = "main";
struct coze_ws_s {
coze_chat_handle_t chat;
audio_recorder_handle_t recorder;
audio_player_handle_t player;
char *recorder_buffer;
#define DEFAULT_RAW_OPUS_BUFFER_SIZE (1024)
char *opus_raw_buffer;
int opus_raw_buffer_len;
enum {
PLAYBACK_STATE_IDLE,
PLAYBACK_STATE_PLAYING,
} player_state;
};
static struct coze_ws_s s_coze_ws;
static void audio_event_callback(coze_chat_event_t event, void *ctx)
{
if (event == COZE_CHAT_EVENT_CHAT_SPEECH_STARTED) {
ESP_LOGI(TAG, "chat start");
s_coze_ws.player_state = PLAYBACK_STATE_IDLE;
} else if (event == COZE_CHAT_EVENT_CHAT_SPEECH_STOPED) {
ESP_LOGI(TAG, "chat stop");
s_coze_ws.player_state = PLAYBACK_STATE_PLAYING;
}
}
static void audio_data_callback(char *data, int len, void *ctx)
{
#define frame_length_prefix (2)
if (len > s_coze_ws.opus_raw_buffer_len) {
s_coze_ws.opus_raw_buffer_len = len + frame_length_prefix;
s_coze_ws.opus_raw_buffer = audio_realloc(s_coze_ws.opus_raw_buffer, s_coze_ws.opus_raw_buffer_len);
}
ESP_LOGD(TAG, "data: %p, len: %d", data, len);
s_coze_ws.opus_raw_buffer[0] = (len >> 8) & 0xFF;
s_coze_ws.opus_raw_buffer[1] = len & 0xFF;
memcpy(s_coze_ws.opus_raw_buffer + frame_length_prefix, data, len);
len += frame_length_prefix;
player_pipeline_write(s_coze_ws.player, s_coze_ws.opus_raw_buffer, len);
}
static void audio_if_open()
{
s_coze_ws.recorder = recorder_pipeline_open();
s_coze_ws.player = player_pipeline_open();
recorder_pipeline_run(s_coze_ws.recorder);
player_pipeline_run(s_coze_ws.player);
}
static void audio_data_read_task(void *pv)
{
#define recorder_buffer_size (640)
s_coze_ws.recorder_buffer = malloc(recorder_buffer_size);
while (1) {
int r_len = recorder_pipeline_read(s_coze_ws.recorder, s_coze_ws.recorder_buffer, recorder_buffer_size);
ESP_LOGD(TAG, "read len: %d", r_len);
if (r_len > 0) {
coze_chat_send_audio_data(s_coze_ws.chat, s_coze_ws.recorder_buffer, r_len);
}
}
vTaskDelete(NULL);
}
void app_main(void)
{
AUDIO_MEM_SHOW(TAG);
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_LOGI(TAG, "Initialize board peripherals");
esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG();
esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg);
audio_board_handle_t board_handle = audio_board_init();
audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_BOTH, AUDIO_HAL_CTRL_START);
#if CONFIG_ESP32_S3_SPOT_BOARD
audio_hal_set_volume(board_handle->audio_hal, 90);
es8311_set_mic_gain(ES8311_MIC_GAIN_0DB);
#endif
s_coze_ws.opus_raw_buffer_len = DEFAULT_RAW_OPUS_BUFFER_SIZE;
s_coze_ws.opus_raw_buffer = audio_malloc(s_coze_ws.opus_raw_buffer_len);
// Initialize SD Card peripheral
// audio_board_sdcard_init(set, SD_MODE_1_LINE);
periph_wifi_cfg_t wifi_cfg = {
.wifi_config.sta.ssid = CONFIG_ESP_WIFI_SSID,
.wifi_config.sta.password = CONFIG_ESP_WIFI_PASSWORD,
};
esp_periph_handle_t wifi_handle = periph_wifi_init(&wifi_cfg);
esp_periph_start(set, wifi_handle);
periph_wifi_wait_for_connected(wifi_handle, portMAX_DELAY);
coze_chat_config_t chat_config = COZE_CHAT_DEFAULT_CONFIG();
chat_config.bot_id = CONFIG_BOT_ID;
chat_config.access_token = CONFIG_ACCESS_TOKEN;
chat_config.audio_callback = audio_data_callback;
chat_config.event_callback = audio_event_callback;
s_coze_ws.chat = coze_chat_init(&chat_config);
coze_chat_start(s_coze_ws.chat);
audio_if_open();
audio_thread_create(NULL, "audio_data_read_task", audio_data_read_task, (void *)NULL, 1024 * 4, 12, true, 1);
AUDIO_MEM_SHOW(TAG);
}