由 WildboarG 贡献,Ai-Thinker 进行整理
【AI-WB2应用】动态密码锁
AI-WB2-动态密码锁
说明
用AI-WB2实现一个动态密码锁。原理很简单,用随机数发生器生成一组密码,借助定时器每十分钟更新一次密码,开启一个http服务器,同步显示动态密码,借助内网穿透就可以在外面随时访问获取密码,应用在密码锁上就是一个随机动态密码锁。提供给访客临时用。
启动流程
- 启动
- 连接wifi
- 开启定时器每10分钟定时器中断一次
- 在中断回调函数中更新密码
- 开启http服务器,显示密码界面,以及一个倒计时更新进度条
- 访问静态页面获取密码,当进度条归零后,会自动更新页面保证获取密码的实时性
- 输入密码,解锁
代码示例
- 连接wifi
📜 点击展开完整代码
c
static
void
wifi_sta_connect
(
char
*ssid,
char
*password)
{
wifi_interface_t
wifi_interface;
wifi_interface = wifi_mgmr_sta_enable();
wifi_mgmr_sta_connect(wifi_interface, ssid, password,
NULL
,
NULL
,
0
,
0
);
}- 定时任务
📜 点击展开完整代码
c
void
flush_password
(
void
*arg)
{
count--;
if
(count <=
0
) {
if
(Generate_password(lockpass) != SUCCESS) {
printf
(
"[password]:error\r\n"
);
return
;
}
printf
(
"[password]:\t"
);
for
(
int
i =
0
; i <
6
; i++) {
printf
(
"%d\t"
, lockpass[i]);
}
printf
(
"\r\n"
);
count = UPDATE_CYCLE;
}
}
// 更新锁任务
void
updatelock_task
(
void
*pvParameters)
{
// 初始化锁
if
(Generate_password(lockpass) != SUCCESS) {
printf
(
"[LOCK]:init error"
);
return
;
};
timer_init(timer, flush_password);
printf
(
"[timer]:start\r\n"
);
hosal_timer_start(&timer);
while
(
1
) {
//
}
}- 生成密码
📜 点击展开完整代码
c
int
hosal_random_num_get
(
int
range_min,
int
range_max)
{
int
status;
uint32_t
buf;
// 确保是 32 位整数
status = hosal_random_num_read(&buf,
sizeof
(buf));
if
(!status) {
buf =
abs
(buf) % (range_max - range_min +
1
) + range_min;
return
buf;
}
return
-1
;
}
int
Generate_password
(
char
*passwd)
{
for
(
int
i =
0
; i <
6
; i++) {
LOCK_PASSWORD[i] = hosal_random_num_get(
0
,
9
);
// printf("LOCK_PASSWORD[%d]= %d\n", i, LOCK_PASSWORD[i]);
}
memcpy
(passwd, LOCK_PASSWORD,
6
);
return
0
;
}
LockState
Authentication
(
char
*passwd)
{
for
(
int
i =
0
; i <
6
; i++) {
if
(passwd[i] != LOCK_PASSWORD[i]) {
return
lock;
}
}
return
unlock;
}- 开启httpserver
📜 点击展开完整代码
c
static
void
web_httpserver
(
struct
netconn *conn)
{
struct
netbuf
*
inputbuf
;
char
*buf;
uint16_t
buflen;
err_t
err;
err = netconn_recv(conn, &inputbuf);
if
(err != ERR_OK) {
return
;
}
netbuf_data(inputbuf, (
void
**)&buf, &buflen);
// 处理 HTTP 请求
if
(
strstr
(buf,
"GET / "
)) {
// netconn_write(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n",
// 44, NETCONN_NOCOPY);
netconn_write(conn, html_page,
strlen
(html_page), NETCONN_NOCOPY);
}
else
if
(
strstr
(buf,
"GET /cgi-bin/get_password"
)) {
char
json_response[
128
];
snprintf
(json_response,
sizeof
(json_response),
"HTTP/1.1 200 OK\r\n"
"Content-Type: application/json\r\n"
"Connection: close\r\n"
"\r\n"
"{\"password\":\"%d%d%d%d%d%d\",\"remainingTime\":%d}"
,
lockpass[
0
], lockpass[
1
], lockpass[
2
], lockpass[
3
], lockpass[
4
],
lockpass[
5
], count);
netconn_write(conn, json_response,
strlen
(json_response), NETCONN_NOCOPY);
}
netconn_close(conn);
netbuf_delete(inputbuf);
}
void
server_task
(
void
*pvParameters)
{
struct
netconn
*
conn
, *
newconn
;
err_t
err;
conn = netconn_new(NETCONN_TCP);
netconn_bind(conn,
NULL
, SERVER_PORT);
netconn_listen(conn);
while
(
1
) {
err = netconn_accept(conn, &newconn);
if
(err != ERR_OK) {
netconn_close(conn);
netconn_delete(conn);
break
;
}
web_httpserver(newconn);
netconn_delete(newconn);
}
}演示效果
这里为了快速演示用的是每50s自动更新一次


