通过前面的介绍,我们已经学会了如何使用 .NET nanoFramework 为 ESP32 设备连接 Wi-Fi 网络。然而,在实际的物联网环境中,我们往往需要使用更便捷的式来满足配网需求。这篇文章将带你了解一些常见的配网方案,并以 ESP32 为例,介绍如何使用 .NET nanoFramework 实现为 ESP32 蓝牙配网。
经过前面的介绍,我们已经学会了如何 为 ESP32 设备连接 Wi-Fi 网络,然后这种代码中硬编码的方式,虽然简单,但在实际的物联网环境中,我们往往需要使用更便捷的方式来满足配网需求。而且,也不适合于产品化的物联网设备。今天,我们就来看看如何使用 .NET nanoFramework 实现为 ESP32 蓝牙配网。
为了能让我们的物联网设备连接到网络,配网的方式也有很多种,每种方式都有其特定的应用场景和优缺点。在这里我们不再详细的描述其原理,只是带大家做一个简单的了解,如果你感兴趣,可以自行搜索。下面是一些常见的配网方式的总结:
softAP:在这种模式下,待配网设备会创建一个热点,用户可以通过手机或其他设备连接到这个热点,然后通过特定的接口设置网络信息。这种方式的优点是兼容性较好,不需要额外的硬件支持,但缺点是但手机端需要做两次 Wi-Fi 连接设置的切换,步骤较复杂,用户体验较差。
Sniffer模式:Sniffer模式也被称为混杂模式,待配网设备在这种模式下可以接收所有的数据包,不进行过滤。例如,SmartConfig、AirKiss、simpleConfig 等这些协议就是使用这种方式,通过监听特定的数据包来获取网络信息。这种方式的优点是不需要用户进行复杂的操作,但一般为各厂商采用私有协议,兼容性和互操作性较差。
蓝牙配网:待配网设备在这种模式下会开启蓝牙接口,用户可以通过手机或其他设备的蓝牙连接到待配网设备,然后通过蓝牙传输网络信息。这种方式的优点是操作简单,用户体验好,但缺点是需要蓝牙硬件支持。
二维码配网:如果待配网设备有摄像头,可以通过扫描二维码来获取网络信息。这种方式的优点是操作简单,用户体验好,但缺点也是非常明显,需要摄像头硬件支持,而且摄像头聚焦,用户二维码放置的远近都需要提示好用户,影响用户体验。
声波配网:如果待配网设备有麦克风,可以通过声音编码来获取网络信息。这种方式的优点是不需要额外的硬件支持,但缺点是可能会受到环境噪音的干扰,影响配网的成功率。
虽然方案有很多,但是针对这一款 ESP32-S3-Zero 开发板,其拥有蓝牙模块,刷写 ESP32_S3_BLE
固件后,我们可以使用蓝牙配网的方式来为其配网。
使用蓝牙配网我们处理可以自己定义进行私有的实现外,也可以使用开源的协议快速完成开发。除了不用自己造轮子外,配网的工具也不需要自己设计了。Improv 是一个免费且开放的标准,它允许设备通过蓝牙进行安全的 Wi-Fi 配网,这个过程可以通过以下步骤完成:
Improv协议可以通过蓝牙低功耗(Bluetooth Low Energy)或通过串行端口使用。这两种协议都可以从浏览器中使用。不过,串口就需要连线了,我们这里使用的是蓝牙低功耗的方式。
关于 Improv 协议的详细信息,可以参考其官方文档。
首先我们需要安装以下三个包:
nanoFramework.System.Device.Wifi
:用于连接 Wi-Fi 网络nanoFramework.Device.Bluetooth
:用于实现蓝牙配网nanoFramework.System.Net.Http
:用于演示联网后的网络服务对于 Improv 协议的实现,没有依赖包,但是在官方的 Samples 仓库中有一个ImprovWifi示例,我们可以参考其实现,直接使用其 Improv.cs
,然后 using ImprovWifi;
即可。
ImprovWifi
已经实现了 Improv 协议,我们只需要在 Program.cs
中实现一些简单的代码。
这里我们在完成配网后,启动一个简易的网络服务,用于演示配网成功后的网络服务。这里我们使用 HttpListener
来实现一个简易的网络服务,当然你也可以使用其他的方式,比如 WebServer
等等。
static Improv _imp;
public static void Main()
{
Console.WriteLine("蓝牙配网 Improv 协议示例");
_imp = new Improv();
// 配网完成后的回调
_imp.OnProvisioningComplete += Imp_OnProvisioningComplete;
// 开始配网服务,设备名称这里可以自定义,中文也是支持的,在搜索设备时会显示该名称
_imp.Start("ESP32 桑榆肖物");
// 纯演示,这里直接授权
_imp.Authorise(true);
Console.WriteLine("等待设备配网...");
while (_imp.CurrentState != Improv.ImprovState.provisioned)
{
Thread.Sleep(500);
}
Console.WriteLine("设备配网完成,IP地址:" + _imp.GetCurrentIPAddress());
// 停止配网服务
_imp.Stop();
_imp = null;
Console.WriteLine("启动一个简易的网络服务,用于演示配网成功后的网络服务");
SimpleWebListener();
Thread.Sleep(Timeout.Infinite);
}
private static void Imp_OnProvisioningComplete(object sender, EventArgs e)
{
SetProvisioningURL();
}
private static void SetProvisioningURL()
{
_imp.RedirectUrl = "http://" + _imp.GetCurrentIPAddress() + "/start.htm";
}
private static void SimpleWebListener()
{
string responseString =
"<html><head><meta charset='utf-8'>" +
"<title>Hello from ESP32</title></head>" +
"<body><h2>Hello from ESP32</h2>" +
"<p>It works!</p>" +
"<p>这里可以根据需求继续进行更多的设备配置信息</p>" +
"</body></html>";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
HttpListener listener = new("http", 80);
listener.Start();
while (true)
{
try
{
HttpListenerContext context = listener.GetContext();
Console.WriteLine("Request received");
HttpListenerResponse response = context.Response;
response.ContentLength64 = buffer.Length;
response.OutputStream.Write(buffer, 0, buffer.Length);
context.Response.Close();
Console.WriteLine("Response sent");
context.Close();
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message + "\nSack = " + ex.StackTrace);
}
}
}
注意:以上代码只是功能的演示,在实际项目中,需要根据自己的需求进行修改,比如我们需要在验证连接后下次也自动完成连接,再者为了安全性,我们还需要进行验证等等。后面我会有一个实际的开源项目演示,介绍如何使用近期介绍的相关功能,敬请关注。
编译并刷写完成后,通过调试的数据输出,我们可以看设备成功进入等待配网状态。这时我们通过网页打开 Improv 的 web 配网客户端,也就是之前的 Improv 官方介绍站点。当然,站点和协议都是开源的,你可以自己搭建一个。
这里我们直接使用官方的进行测试使用即可,不过,需要注意的是,因为使用了蓝牙配网,所以这里需要你的电脑也支持蓝牙,否则无法搜索到设备。如果你的电脑没有蓝牙,也可以使用手机的 Chrome 或 Egde 浏览器打开该网页进行配网。
这里可以看到,设备列表中已经搜索到了我们的设备,点击配对即可。配对成功后,我们可以会弹出下面的对话框,这里我们可以设置 Wi-Fi 的 SSID 和密码,然后点击 Connect
按钮即可。
连接成功后,我们可以看到设备的状态已经变成了 Provisioned
,这时我们就可以访问到设备启动的网络服务了。
通过这篇文章,我们学习了如何使用 .NET nanoFramework 为 ESP32 设备进行蓝牙配网。虽然这里我们使用的是 Improv 协议,但是其实现原理都是类似的,只是协议不同而已。在实际的项目中,我们可以根据自己的需求,选择合适的配网方式,或者自己实现一个配网协议,这里就不再赘述了。
对于 Improv 协议的配网客户端,我们也可以通过微信小程序来实现,或者通过微信的 JSSDK 来在微信中方便的实现配网,有兴趣的同学可以自行了解实现。