WiFi网络
概述
YFAir8000 通过 Air8000W 模组内置 WiFi 芯片,支持 STA(客户端)、AP(热点) 两种模式。
技术栈
- 运行环境:LuatOS(合宙 Air8000W 模组)
- 核心 API:
wlan.connect()/wlan.createAP()/wlan.scan()/wlan.scanResult() - WiFi 事件:
WLAN_STA_INC/WLAN_AP_INC/WLAN_SCAN_DONE
项目结构
06 - WIFI网络/
├── wifi_sta.lua # WiFi STA 客户端模式 + HTTP 联网验证
├── wifi_ap.lua # WiFi AP 热点模式 + 4G 上游 + DNS/DHCP
├── wifi_scan.lua # WiFi 扫描功能
├── ap_config_net.lua # AP Web 配网(HTTP 服务器 + 网页配网)
├── check_wifi.lua # WiFi 固件版本检查与 FOTA 升级
├── index.html # AP 配网 Web 页面
└── main.lua # 入口,切换不同功能模块
使用方式
在 main.lua 中通过 require 切换功能模块,当前启用 require "wifi_scan",其余已注释。
模式一:WiFi 扫描 (wifi_scan.lua)
每 10 秒扫描一次周围 WiFi,打印 SSID、RSSI 和 MAC 地址。
sys.taskInit(function()
while true do
sys.wait(10000)
wlan.scan() -- 触发扫描
end
end)
-- 扫描完成事件
sys.subscribe("WLAN_SCAN_DONE", function()
local result = wlan.scanResult()
for k, v in pairs(result) do
log.info("scan", v["ssid"] or "[隐藏SSID]",
v["rssi"], v["bssid"]:toHex())
end
end)
| API | 说明 |
|---|---|
wlan.scan() | 触发 WiFi 扫描 |
wlan.scanResult() | 获取扫描结果(SSID/RSSI/BSSID) |
sys.subscribe("WLAN_SCAN_DONE") | 扫描完成事件 |
模式二:WiFi STA (wifi_sta.lua)
连接路由器 → 发起 HTTP 请求验证联网:
-- STA 事件监听
sys.subscribe("WLAN_STA_INC", function(evt, data)
log.info("STA事件", evt, data) -- evt: CONNECTED / DISCONNECTED
end)
sys.taskInit(function()
wlan.connect("YFSoft_IoT", "YFSoft1018")
-- 等待 IP 就绪
while not socket.adapter(socket.LWIP_STA) do
sys.waitUntil("IP_READY", 1000)
end
-- HTTP 联网验证
while true do
local code, headers, body = http.request("GET",
"https://httpbin.air32.cn/bytes/2048",
nil, nil, {adapter = socket.LWIP_STA, timeout = 5000}).wait()
log.info("http", code, body and #body)
sys.wait(2000)
end
end)
| API | 说明 |
|---|---|
wlan.connect(ssid, pwd) | STA 连接路由器 |
socket.adapter(LWIP_STA) | 检查 STA 是否就绪 |
sys.waitUntil("IP_READY") | 等待 DHCP 获取 IP |
http.request("GET", url) | HTTP 联网验证 |
模式三:WiFi AP 热点 (wifi_ap.lua)
创建 AP 热点,将 4G 网络共享给连接热点的设备:
sys.taskInit(function()
wlan.init()
wlan.createAP("Air8000WAP测试", "12345678")
-- 配置 AP 静态 IP
netdrv.ipv4(socket.LWIP_AP, "192.168.4.1",
"255.255.255.0", "192.168.4.1")
-- 等待 4G 网络就绪(作为上游)
while not socket.adapter(socket.LWIP_GP) do
sys.waitUntil("IP_READY", 1000)
end
-- DNS 代理:AP 客户端 DNS 请求转发到 4G
dnsproxy.setup(socket.LWIP_AP, socket.LWIP_GP)
-- DHCP 服务器:自动分配 IP
dhcpsrv.create({adapter = socket.LWIP_AP})
-- NAT:AP 内网 → 4G 外网
netdrv.napt(socket.LWIP_GP)
end)
-- AP 事件:设备连接/断开
sys.subscribe("WLAN_AP_INC", function(evt, data)
log.info("AP事件", evt, data and data:toHex())
end)
| API | 说明 |
|---|---|
wlan.createAP(ssid, pwd) | 创建 WiFi 热点 |
netdrv.ipv4(LWIP_AP, ip, mask, gw) | 配置 AP 静态 IP |
dnsproxy.setup(local, upstream) | DNS 代理 |
dhcpsrv.create({adapter = LWIP_AP}) | DHCP 服务器 |
netdrv.napt(LWIP_GP) | NAT 地址转换 |
模式四:AP Web 配网 (ap_config_net.lua)
开启 AP 热点 + HTTP 服务器,用户手机连接热点后访问 192.168.4.1 完成配网:
-- 创建 AP 热点 + HTTP 服务器
function create_ap()
wlan.createAP("test2", "HZ88888888")
netdrv.ipv4(socket.LWIP_AP, "192.168.4.1", "255.255.255.0", "192.168.4.1")
dhcpsrv.create({adapter = socket.LWIP_AP})
end
function wifi_networking()
httpsrv.start(80, handle_http_request, socket.LWIP_AP)
log.info("web", "pls open url http://192.168.4.1/")
end
-- HTTP 路由处理
function handle_http_request(fd, method, uri, headers, body)
if uri == "/scan/go" then
wlan.scan()
return 200, {}, "ok"
elseif uri == "/scan/list" then
return 200, json_header, json.encode(scan_result)
elseif uri == "/connect" and method == "POST" then
local jdata = json.decode(body)
sys.timerStart(wlan.connect, 500, jdata.ssid, jdata.passwd)
return 200, {}, "ok"
end
end
配网页面 index.html 提供完整的前端交互:WiFi 扫描、SSID 选择、密码输入、一键连接。
全部代码
main.lua
main.lua(当前启用 wifi_scan)
PROJECT = "air8000_wifi"
VERSION = "001.999.000"
log.info("main", PROJECT, VERSION)
-- 切换不同模式(取消注释即可启用)
-- require "wifi_ap"
-- require "wifi_sta"
-- require "ap_config_net"
require "wifi_scan"
-- require "check_wifi"
sys.run()
wifi_scan.lua
wifi_scan.lua
local scan_result = {}
sys.taskInit(function()
while true do
log.info("10秒后执行wifi扫描")
sys.wait(10000)
wlan.scan()
end
end)
sys.subscribe("WLAN_SCAN_DONE", function()
local result = wlan.scanResult()
for k, v in pairs(result) do
log.info("scan", (v["ssid"] and #v["ssid"] > 0) and v["ssid"] or "[隐藏SSID]",
v["rssi"], v["bssid"]:toHex())
if v["ssid"] and #v["ssid"] > 0 then
table.insert(scan_result, v["ssid"])
end
end
log.info("scan", "aplist", json.encode(scan_result))
end)
wifi_sta.lua
wifi_sta.lua
sys.subscribe("WLAN_STA_INC", function(evt, data)
log.info("收到STA事件", evt, data)
end)
sys.taskInit(function()
log.info("执行STA连接操作")
wlan.connect("YFSoft_IoT", "YFSoft1018")
while not socket.adapter(socket.LWIP_STA) do
sys.waitUntil("IP_READY", 1000)
end
while true do
local code, headers, body = http.request("GET",
"https://httpbin.air32.cn/bytes/2048",
nil, nil, {adapter = socket.LWIP_STA, timeout = 5000, debug = false}).wait()
log.info("http执行结果", code, headers, body and #body)
sys.wait(2000)
end
end)
wifi_ap.lua
wifi_ap.lua
dnsproxy = require("dnsproxy")
dhcpsrv = require("dhcpsrv")
sys.taskInit(function()
log.info("开始AP 测试...")
wlan.init()
wlan.createAP("Air8000WAP测试", "12345678")
netdrv.ipv4(socket.LWIP_AP, "192.168.4.1", "255.255.255.0", "192.168.4.1")
while not socket.adapter(socket.LWIP_GP) do
sys.waitUntil("IP_READY", 1000)
end
dnsproxy.setup(socket.LWIP_AP, socket.LWIP_GP)
dhcpsrv.create({adapter = socket.LWIP_AP})
netdrv.napt(socket.LWIP_GP)
end)
sys.subscribe("WLAN_AP_INC", function(evt, data)
log.info("收到AP事件", evt, data and data:toHex())
end)
check_wifi.lua
check_wifi.lua(WiFi 固件 FOTA 升级)
local exfotawifi = require("exfotawifi")
sys.taskInit(function()
local result = exfotawifi.request()
if result then
log.info("exfotawifi", "升级任务执行成功")
else
log.info("exfotawifi", "升级任务执行失败")
end
end)