这个项目源于我在智能家居开发中遇到的一个实际问题:如何在不破坏装修的情况下,可视化房屋内的WiFi信号分布。传统方案要么需要专业设备,要么只能获得抽象的信号强度数值。于是我用ESP32开发板和Qt Creator搭建了一套低成本的空间信号可视化系统,能够实时显示三维空间中的WiFi信号热力图。
整套方案硬件成本控制在200元以内,软件完全开源。特别适合以下场景:
选用ESP32-WROOM-32D模组的核心考量:
关键硬件配置要点:
cpp复制// ESP32 WiFi扫描配置
wifi_country_t country = {
.cc = "CN",
.schan = 1,
.nchan = 13,
.max_tx_power = 80,
.policy = WIFI_COUNTRY_POLICY_AUTO
};
ESP_ERROR_CHECK(esp_wifi_set_country(&country));
为实现空间定位,系统采用多基站架构:
基站部署建议:
信号采集核心逻辑:
关键代码片段:
cpp复制void wifi_scan_handler(void *pvParameters) {
while(1) {
wifi_scan_config_t scanConf = {
.ssid = NULL,
.bssid = NULL,
.channel = 0,
.show_hidden = true
};
ESP_ERROR_CHECK(esp_wifi_scan_start(&scanConf, true));
uint16_t apCount = 0;
esp_wifi_scan_get_ap_num(&apCount);
wifi_ap_record_t *apList = malloc(apCount * sizeof(wifi_ap_record_t));
ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&apCount, apList));
// 数据处理和传输
process_scan_results(apList, apCount);
free(apList);
vTaskDelay(pdMS_TO_TICKS(SCAN_INTERVAL));
}
}
使用Qt3D模块创建可视化环境:
核心类结构:
cpp复制class SignalMap : public Qt3DCore::QEntity {
Q_OBJECT
public:
explicit SignalMap(Qt3DCore::QNode *parent = nullptr);
void updateHeatMap(const QVector<SignalPoint> &points);
private:
Qt3DRender::QMesh *m_roomMesh;
QVector<Qt3DExtras::QSphereMesh*> m_signalPoints;
Qt3DExtras::QDiffuseSpecularMaterial *m_material;
};
采用改进的Kriging插值算法:
颜色映射实现:
cpp复制QColor SignalVisualizer::getColorForStrength(float dbm) {
// dBm范围通常在-30到-90之间
float normalized = (dbm + 30) / (-90 + 30);
normalized = qBound(0.0f, normalized, 1.0f);
if(normalized < 0.25) {
return QColor::fromRgbF(0, 0, 1 - normalized*4);
} else if(normalized < 0.5) {
return QColor::fromRgbF(0, (normalized-0.25)*4, 1);
} else if(normalized < 0.75) {
return QColor::fromRgbF((normalized-0.5)*4, 1, 1 - (normalized-0.5)*4);
} else {
return QColor::fromRgbF(1, 1 - (normalized-0.75)*4, 0);
}
}
推荐配置清单:
| 组件 | 型号 | 数量 | 备注 |
|---|---|---|---|
| 主控板 | ESP32-DevKitC | 1 | 带USB接口 |
| 信标节点 | ESP32-WROOM | 3 | 最低配置 |
| 电源 | 18650电池 | 4 | 带充电模块 |
| 外壳 | 3D打印盒 | 4 | 防干扰设计 |
组装注意事项:
三阶段校准法:
位置校准
方向校准
环境校准
校准数据存储格式示例:
json复制{
"calibration_points": [
{
"x": 1.0,
"y": 2.0,
"z": 0.5,
"readings": [
{"beacon": "B1", "rssi": -65},
{"beacon": "B2", "rssi": -72},
{"beacon": "B3", "rssi": -68}
]
}
],
"environment_factors": {
"wall_attenuation": 8.5,
"floor_attenuation": 12.2
}
}
在80平米公寓中的测试结果:
| 位置 | 信号强度(dBm) | 实测网速(Mbps) | 预测网速(Mbps) |
|---|---|---|---|
| 客厅 | -52 | 72 | 68 |
| 卧室 | -68 | 48 | 45 |
| 厨房 | -75 | 32 | 28 |
| 阳台 | -81 | 18 | 15 |
问题1:定位漂移严重
问题2:热力图刷新卡顿
问题3:信号强度突变
当前版本仅支持2.4GHz频段,可通过以下方式扩展:
cpp复制wifi_bandwidth_t bw = WIFI_BW_HT40;
esp_wifi_set_bandwidth(WIFI_IF_STA, bw);
收集大量数据后可以:
训练数据示例结构:
python复制# 输入特征
features = [
'distance_to_router',
'wall_count',
'material_type',
'height_difference'
]
# 目标值
target = 'signal_strength'
这个项目最让我惊喜的是ESP32的WiFi扫描性能完全能满足专业级需求。在实际测试中,将扫描间隔设置为500ms时,系统可以稳定运行8小时以上。一个特别实用的技巧是:在Qt程序中添加一个"信号轨迹记录"功能,拿着设备在房间走动后,可以生成最优路由器位置建议。