AP手机连接热地点神烦。记得乐鑫有smartconfig,可以用微信配网优先选择这个,在使用过程中遇到一些坑,记录下来:
实现的步骤:
1)编译带smartconfig的固件:
参考三十大叔的文章:伟大的micropython smartconfig 配网它来了!!!_esp32 micropython 智能配网_三十岁开始学编程的大叔的博客-CSDN博客
有2个要注意的点
a) 配网代码没有重置状态,会导致如果密码出错,除了reset没其他办法,其实修改一下启动命令就好,把状态清理一下就可以重复配网了
STATIC mp_obj_t smartconfig_start(void)
{
found_ssid_and_password = false; // 标记为未获取
ESP_ERROR_CHECK(esp_smartconfig_stop()); // 先停止
initialise_wifi();
return mp_const_none;
}
b) 固件编译适用于micropython 1.20及以下的版本,以上的版本Makefile位置不对了,要改一下,另外1.20以上是使用idf5.0.2以上版本,目前稳定性还不确定
2)micropython配网部分:
micropython配网可以直接参考大叔的文章,但是有几个要注意的点:
a) 如果采用协程开发,部分代码要修改,主要是sleep部分的
b) 要获取wifi状态时,必须先disconnect()断开才能获取到正确的状态,注意disconnect是一个过程,需要监测状态,提供一个状态监测代码(协程版)
async def wait_for(func: func_type, *, timeout_ms=10000, sleep_ms=100) -> bool:
"""
一般性检查状态超时,使用方法例如:
await wait_for(lambda: station.isconnected())
:param func: 执行表达式,返回True终止检测,返回False继续检测
:param sleep_ms: 检测间隔
:param timeout_ms: 总超时毫秒
:return: False为超时,True为func成功
"""
start = utime.ticks_ms()
while not func():
if utime.ticks_diff(utime.ticks_ms(), start) > timeout_ms:
return False
await asyncio.sleep_ms(sleep_ms)
return True
连接的过程:
is_success = await wait_for(lambda: station.isconnected() and self.stop_falg == NO_STOP, sleep_ms=500)
if not is_success:
station.disconnect() # 没连上,断开,断开
await wait_for(lambda: not station.isconnected()) # 等断开
if self.stop_falg == USER_STOP: # 被点停止按钮终止的
self.log_it('用户停止配网')
elif station.status() == network.STAT_WRONG_PASSWORD: # 这个状态没法收到
self.log_it('密码错误')
self.stop_falg = ERROR_STOP
elif station.status() == network.STAT_NO_AP_FOUND:
self.log_it(f'没找到 {ssid}')
self.stop_falg = ERROR_STOP
elif station.status() == network.STAT_HANDSHAKE_TIMEOUT:
self.log_it(f'握手超时')
self.stop_falg = ERROR_STOP
elif station.status() == network.STAT_BEACON_TIMEOUT:
self.log_it(f'连接超时')
self.stop_falg = ERROR_STOP
elif station.status() in (8, 15):
self.log_it(f'密码鉴权失败')
self.stop_falg = ERROR_STOP
elif station.status() == network.STAT_ASSOC_FAIL:
self.log_it(f'未知错误')
self.stop_falg = ERROR_STOP
else:
self.log_it(f'连接失败 {station.status()}') # 例如密码长度不够
self.log_it(f'连接已终止')
self.wifi_stat_img.set_file(f'/icons/cancel.bmp', True)
# 连接成功后的动作
在最新的固件测试时,发现鉴权错并没有返回官方的STAT_WRONG_PASSWORD,而是返回的8或15,不知道为什么,所以就有上面的代码