ESP32-S3 WiFi CSI 모션 감지 펌웨어
Wikiprompt, 무료 프롬프트 백과사전에서
ESP32-S3 WiFi CSI 모션 감지 펌웨어 ESP32-S3 펌웨어를 생성하기 위한 프롬프트로, WiFi CSI를 사용하여 실내 움직임을 감지하고, 조정 가능한 임계값으로 직렬 포트를 통해 JSON 데이터를 출력합니다.
프롬프트 내용저장
🌐
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_netif.h"
#include "driver/uart.h"
#include "math.h"
#define CSI_WINDOW_SECONDS 2
#define CSI_SAMPLE_RATE_HZ 100 // CSI packets per second (adjust based on your environment)
#define MOTION_THRESHOLD 50.0f // 초기 임계값 - 이 값을 조정하여 감도 설정
#define STILL_THRESHOLD 30.0f // 초기 정지 임계값 - 히스테리시스로 오실레이션 방지
static const char *TAG = "CSI_MOTION";
static float csi_variance = 0.0f;
static bool motion_state = false;
static uint32_t csi_sample_count = 0;
static float csi_amplitude_sum = 0.0f;
static float csi_amplitude_sq_sum = 0.0f;
// CSI 데이터 콜백 - WiFi 드라이버에서 CSI 패킷 수신 시 호출됨
static void wifi_csi_cb(void *ctx, wifi_csi_info_t *info) {
if (info == NULL || info->rx_ctrl == NULL) {
return;
}
// CSI 데이터에서 진폭 계산 (실수부와 허수부의 크기)
int16_t *csi_data = (int16_t *)info->buf;
uint16_t csi_len = info->rx_ctrl->sig_len;
uint16_t csi_num = csi_len / 4; // 각 CSI 샘플은 4바이트 (2바이트 실수 + 2바이트 허수)
float amplitude_sum = 0.0f;
for (uint16_t i = 0; i < csi_num; i++) {
int16_t real = csi_data[i * 2];
int16_t imag = csi_data[i * 2 + 1];
amplitude_sum += sqrtf((float)(real * real + imag * imag));
}
float avg_amplitude = amplitude_sum / csi_num;
// 2초 윈도우 동안의 합과 제곱합을 누적
csi_amplitude_sum += avg_amplitude;
csi_amplitude_sq_sum += avg_amplitude * avg_amplitude;
csi_sample_count++;
// 윈도우가 가득 찼을 때 분산 계산
if (csi_sample_count >= CSI_WINDOW_SECONDS * CSI_SAMPLE_RATE_HZ) {
float mean = csi_amplitude_sum / csi_sample_count;
float mean_sq = csi_amplitude_sq_sum / csi_sample_count;
csi_variance = mean_sq - (mean * mean);
// 히스테리시스를 사용한 상태 판별
if (!motion_state && csi_variance > MOTION_THRESHOLD) {
motion_state = true;
} else if (motion_state && csi_variance < STILL_THRESHOLD) {
motion_state = false;
}
// JSON 형식으로 시리얼 출력
printf("{\"timestamp\":%lu,\"state\":\"%s\",\"variance\":%.2f}\n",
(unsigned long)(esp_timer_get_time() / 1000),
motion_state ? "motion detected" : "still",
csi_variance);
// 윈도우 초기화
csi_sample_count = 0;
csi_amplitude_sum = 0.0f;
csi_amplitude_sq_sum = 0.0f;
}
}
// WiFi 초기화 및 CSI 활성화
static void wifi_init(void) {
// NVS 초기화 (WiFi 설정 저장용)
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
nvs_flash_erase();
nvs_flash_init();
}
// 네트워크 인터페이스 초기화
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
// WiFi 스테이션 모드 설정
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
// CSI 콜백 등록
ESP_ERROR_CHECK(esp_wifi_set_csi_rx_cb(&wifi_csi_cb));
// CSI 활성화 - 모든 패킷에서 CSI 수집
wifi_csi_config_t csi_config = {
.lltf_en = 1, // L-LTF 활성화
.htltf_en = 1, // HT-LTF 활성화
.stbc_htltf2_en = 1, // STBC HT-LTF2 활성화
.ltf_merge_en = 1, // LTF 병합 활성화
.channel_filter_en = 0, // 채널 필터 비활성화
.manu_scale = 0 // 수동 스케일링 비활성화
};
ESP_ERROR_CHECK(esp_wifi_set_csi_config(&csi_config));
ESP_ERROR_CHECK(esp_wifi_set_csi(true));
// WiFi 시작 (연결 시도)
ESP_ERROR_CHECK(esp_wifi_start());
// 홈 WiFi에 연결 - 여기에 SSID와 비밀번호 입력
wifi_config_t wifi_config = {
.sta = {
.ssid = "YOUR_HOME_WIFI_SSID",
.password = "YOUR_WIFI_PASSWORD",
.threshold.authmode = WIFI_AUTH_WPA2_PSK
},
};
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_connect());
ESP_LOGI(TAG, "WiFi initialized and CSI enabled");
}
void app_main(void) {
// UART 초기화 (시리얼 출력용)
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
uart_param_config(UART_NUM_0, &uart_config);
uart_driver_install(UART_NUM_0, 1024 * 2, 0, 0, NULL, 0);
// WiFi 및 CSI 초기화
wifi_init();
ESP_LOGI(TAG, "CSI motion detection started");
// 메인 루프 - FreeRTOS 태스크가 콜백을 처리하므로 여기서는 대기만 함
while (1) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
전체 프롬프트를 보려면 로그인하세요
Continue with:
By logging in, you agree to our Terms of Use and Privacy Policy
사용법
이 프롬프트는 coding와 함께 사용하도록 설계되었습니다. 위의 프롬프트 내용을 복사하여 원하는 AI 도구에 붙여넣으세요.
최상의 결과를 얻으려면 자리 표시자(대괄호 또는 대문자로 표시)를 특정 요구 사항으로 사용자 지정할 수 있습니다.
토론
댓글 0개