[MCU] ESP32通过蓝牙配置WIFI

littleshrimp   2021-5-22 11:05 楼主

以下内容通过软件自动翻译,源文为:https://robotzero.one/esp32-wi-fi-connection-bluetooth/

 

使用蓝牙串行,首选项库和枚举状态机的Wi-Fi连接管理器。

有时您需要通过Wi-Fi远程连接到ESP32,但您不知道IP地址,或者ESP32每次都用新的IP地址重新连接。

查找无法访问的板的IP地址的最简单方法是通过蓝牙串行将其传输到手机。但是蓝牙和Wi-Fi在ESP32上并不能很好地共存,因为它们共享同一无线电系统。一旦开始将Wi-Fi连接用于数据,就需要关闭蓝牙连接。

在本教程和示例代码中,您可以看到如何使用Bluetooth串行读取IP地址,然后关闭连接,以便只有Wi-Fi使用无线电。

该演示应用程序使用基于ESP32的摄像头板,但可适用于需要通过Wi-Fi访问ESP32的其他项目。

本教程分为三个部分-上传草图,将手机与ESP32配对以及使用串行蓝牙应用程序进行连接。

将草图上传到ESP32

从此处将代码复制到https://github.com/robotzero1/esp32-bluewifi到新的Sketch中,并将其上传到您的ESP32开发板。如果您使用的是ESP32-CAM,请记住断开引脚0的连接,然后按Reset键。

打开串行监视器,以便您可以检查以下步骤的进度。

将手机连接到ESP32

我有Android 9,但其他手机应该非常相似。

转到设置,然后选择已连接的设备:
Android-Bluetooth-Settings-Link.jpg

选择配对新设备:
Pair-New-Device.jpg

从可用设备列表中选择robot01:
Available-Devices.jpg

确认配对:
Pair-Confirm.jpg

您应该在“当前已连接”中看到该设备:
Bluetooth-Device-Connected.jpg

使用串行终端

从Play商店安装串行蓝牙终端应用程序– https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal&hl=zh-CN

打开串行蓝牙终端,然后从菜单中选择“设备”:
Serial-Bluetooth-Terminal-Devices.jpg

从列表中选择robot01以启动串行终端连接:
Choose-Bluetooth-Device.jpg

如果这是ESP32首次连接到该Wi-Fi网络或密码已更改,则您将看到以下输出。

串口连接到ESP32:
Bluetooth-Serial-Terminal-Connection.jpg

ESP32扫描Wi-Fi网络:
Bluetooth-Serial-Terminal-WiFi-Scan.jpg

选择您的网络SSID的号码:
Bluetooth-Serial-Terminal-SSID.jpg

输入此网络的密码:
Bluetooth-Serial-Terminal-Pass.jpg

ESP32连接到Wi-Fi网络时,将显示ESP32 IP地址且蓝牙已断开连接:
Bluetooth-Serial-Terminal-Wi-Fi-IP-address.jpg

如果ESP32已经具有正确的连接凭证,则仅显示ESP32的IP地址:
Bluetooth-Serial-Show-IP-Address.jpg

这是如何运作的?

下面解释了代码的一些重要部分:

该代码使用“枚举状态机”。可以将枚举视为具有固定数量的值的变量,例如SCAN_START,SCAN_COMPLETE,SSID_ENTERED,PASS_ENTERED,LOGIN_FAILED

这些值在主循环的switch语句中使用。根据当前枚举值设置函数运行或变量值:

case SCAN_START:
  SerialBT.println("Scanning Wi-Fi networks");
  Serial.println("Scanning Wi-Fi networks");
  scan_wifi_networks();
  SerialBT.println("Please enter the number for your Wi-Fi");
  wifi_stage = SCAN_COMPLETE;
  break;
 
case SSID_ENTERED:
  SerialBT.println("Please enter your Wi-Fi password");
  Serial.println("Please enter your Wi-Fi password");
  wifi_stage = WAIT_PASS;
  break;
 
case PASS_ENTERED:
  SerialBT.println("Please wait for Wi-Fi connection...");
  Serial.println("Please wait for Wi_Fi connection...");
  wifi_stage = WAIT_CONNECT;
  preferences.putString("pref_ssid", client_wifi_ssid);
  preferences.putString("pref_pass", client_wifi_password);
  if (init_wifi()) { // Connected to WiFi
    connected_string = "ESP32 IP: ";
    connected_string = connected_string + WiFi.localIP().toString();
    SerialBT.println(connected_string);
    Serial.println(connected_string);
    bluetooth_disconnect = true;
  } else { // try again
    wifi_stage = LOGIN_FAILED;
  }
  break;
 
case LOGIN_FAILED:
  SerialBT.println("Wi-Fi connection failed");
  Serial.println("Wi-Fi connection failed");
  delay(2000);
  wifi_stage = SCAN_START;
  break;

 

根据Wi-Fi是否已连接,Sketch使用两个蓝牙回调:

if (!init_wifi()) { // Connect to Wi-Fi fails
  SerialBT.register_callback(callback);
} else {
  SerialBT.register_callback(callback_show_ip);
}

 

如果ESP32无法连接到Wi-Fi,则初始化第一个回调。这侦听发送到ESP32的蓝牙数据。根据数据类型和枚举的当前值,设置各种变量并运行函数:

void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
  if (event == ESP_SPP_SRV_OPEN_EVT) {
    wifi_stage = SCAN_START;
  }
 
  if (event == ESP_SPP_DATA_IND_EVT && wifi_stage == SCAN_COMPLETE) { // data from phone is SSID
    int client_wifi_ssid_id = SerialBT.readString().toInt();
    client_wifi_ssid = ssids_array[client_wifi_ssid_id];
    wifi_stage = SSID_ENTERED;
  }
 
  if (event == ESP_SPP_DATA_IND_EVT && wifi_stage == WAIT_PASS) { // data from phone is password
    client_wifi_password = SerialBT.readString();
    client_wifi_password.trim();
    wifi_stage = PASS_ENTERED;
  }
 
}

 

或者,如果ESP32已成功连接到Wi-Fi,则初始化第二个回调并等待来自蓝牙连接的输入:

void callback_show_ip(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
  if (event == ESP_SPP_SRV_OPEN_EVT) {
    SerialBT.print("ESP32 IP: ");
    SerialBT.println(WiFi.localIP());
    bluetooth_disconnect = true;
  }
}

 

代码中要注意的最后重要一点是,一旦用户知道了Wi-Fi IP地址,则应该关闭蓝牙。当IP地址已显示在手机上或用户在浏览器中连接到IP时,就会发生这种情况。上面的代码中显示了一个示例。通过网络套接字连接摄像机时,下面显示了另一个:

if (socket_server.poll()) {
  disconnect_bluetooth();
  ...
}

视频示范

下面显示了通过蓝牙连接和设置Wi-Fi访问详细信息的演示。

 

虾扯蛋,蛋扯虾,虾扯蛋扯虾

回复评论 (5)

多谢分享

文中的几个图应该是看不到

点赞  2021-5-22 21:04
引用: Jacktang 发表于 2021-5-22 21:04 多谢分享 文中的几个图应该是看不到

应该是图片的服务器被屏蔽了,正常网络原帖也无法查看,我编辑了一下,下载到本地了。

虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2021-5-22 22:20

这是github上的源码

esp32-bluewifi-master.zip (4.53 KB)
(下载次数: 2, 2021-5-22 22:23 上传)

虾扯蛋,蛋扯虾,虾扯蛋扯虾
点赞  2021-5-22 22:23

在“ESP32开发板IOT蓝牙WIFI米思齐”上做一个小项目:用这个开发板截获原设备控制板的输入信号,同时将输入信号转发至原控制板输入端和通过wif转发至手机APP端程序(这样通过手机可以获知原设备的输入);同时,手机APP可以直接发送控制信号到原设备的信号输入端,实现设备控制。可以做的话请联系!

点赞  2022-1-5 12:06

谢谢分享!

点赞  2022-1-5 15:15
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复