ESP32 Arduino教程:基于soft AP(热点)实现Websocket server
本帖最后由 dfrobot 于 2019-5-24 22:36 编辑本ESP32教程的测试是使用集成在FireBeetle ESP32 开发板中的DFRobot的ESP-WROOM-32设备运行的。
简介本文主要介绍如何在运行于soft AP模式的ESP32上设置Websocket server(服务器)。使用的软件架构是ESP32的Arduino内核。设置Websocket server(服务器)所需要的代码在此前的这篇帖子:ESP32 Arduino教程:Websocket server(服务器)中已经详细说明。本文直接使用相同的代码,详情不再赘述。本教程中用于测试的Python客户端也在上一篇帖子里进行了分析。设置ESP32作为soft AP运行的相关代码,其详细说明也可以参考上一篇帖子:ESP32 Arduino教程:Websocket server(服务器)。
在本教程中,ESP32仅作为一台回发Websocket server(服务器)使用,它会将接受到的内容原封不动地回发给客户端。因为ESP32作为soft AP运行,所以就不需要通过路由器提供外部WiFi以建立客户端与服务器之间的连接。因此,运行Python代码的电脑就需要连接到ESP32提供的WiFi网络,以在两者之间透明地发送和接收数据。
Python代码简介部分说过,我们将重用上一篇帖子:ESP32 Arduino教程:Websocket server(服务器) 介绍的Python websocket客户端代码。那篇帖子还提供了安装websocket-client模块的相关说明。
首先需要在代码中导入websocket和time模块。然后,建立一个WebSocket类的对象实例,通过调用该对象的connect方法将其连接到我们的ESP32 websocket server(服务器)。请注意,为了成功连接到服务器,我们需要使用ESP32的正确IP地址。在本教程中,由于ESP32作为soft AP运行,所以我们需要使用它自己的IP地址,我们将在Arduino代码中将这个地址打印到串行控制台上。
import websocket
import time
ws = websocket.WebSocket()
ws.connect("ws://192.168.4.1/")
建立好连接之后,我们将通过循环将数据发送到服务器,然后获取服务器回发过来的响应。完成与服务器的交互之后,通过调用WebSocket对象的close方法以断开服务器连接。
Python websocket客户端的完整源代码如下所示。
import websocket
import time
ws = websocket.WebSocket()
ws.connect("ws://192.168.4.1/")
i = 0
nrOfMessages = 30
while i<nrOfMessages:
ws.send("Soft AP mode: message nr " + str(i))
result = ws.recv()
print(result)
i=i+1
time.sleep(1)
ws.close()
Arduino代码Arduino代码也和上一篇帖子里的代码非常相似:ESP32 Arduino教程:Websocket server(服务器)。首先,将WiFi.h和WebSocketServer.h库包含进来,前者主要用于设置我们的soft AP,后者则负责处理与Websocket相关的功能。
我们需要一个WiFiServer类的对象,以创建能够接收客户端连接的TCP服务器。这个类的构造函数有一个可选的端口输入参数,用于指定服务器将要监听的端口号。我们使用端口80。
然后,在我们的TCP服务器上新建一个Websocket server(服务器)。为了使用与Websocket相关的功能,我们需要一个WebSocketServer类的对象。封装函数(wrapper)将负责处理具体的Websocket协议,我们只需要考虑与客户端之间的数据交换即可。
在Arduino的setup函数中,首先打开一个串行连接,以便将接收自客户端的数据打印出来。
#include <WiFi.h>
#include <WebSocketServer.h>
WiFiServer server(80);
WebSocketServer webSocketServer;
const char *ssid = "MyESP32AP";
const char *password = "testpassword";
还有两点需要考虑,那就是所创建网络的名称(ssid)以及访问密码。
然后,调用WiFi外部变量(通过WiFi.h库包含进来)的softAP方法以对soft AP进行设置。在连接到路由器提供的WiFi网络时,我们使用的也是这个外部变量。
接下来,要打印ESP32的IP地址,我们需要调用同一个WiFi变量的softAPIP方法。有关在ESP32上设置soft AP的更多详情,请参阅此前的这篇帖子:ESP32 Arduino教程:通过软接入点(soft AP)实现HTTP服务器。
Serial.begin(115200);
delay(4000);
WiFi.softAP(ssid, password);
Serial.println(WiFi.softAPIP());
在setup函数最后,我们需要对TCP服务器进行初始化。只需在先前声明的全局WiFiServer对象上调用begin方法即可。
server.begin();
在主函数中,我们将调用WiFiServer对象的available方法,以确认客户端是否已成功连接。
调用该方法将会返回一个WiFiClient类型的对象。为确认客户端是否连接成功,我们会调用该对象的connected方法。如果客户端成功连接,则该方法会返回true,否则将返回false。
客户端已连接成功的话,我们需要执行Websocket协议握手。只需在我们先前声明的全局WebSocketServer对象上调用handshake方法即可。
该方法的输入参数是我们所获得的WiFiClient对象,如果握手成功则该方法的返回值为true。
if (client.connected() && webSocketServer.handshake(client)) {
// Exchanging data with the client
}
在条件判断代码部分,我们会声明一个变量,用作接收自客户端的数据缓冲区。只要客户端已连接,我们就循环接收数据、打印到串行控制台并将数据回发给客户端。
通过调用WebSocketServer对象的getData方法,即可从WebSocket获取数据。该方法不需要输入参数,其返回值是一个字符串(其中包含了所接收到的数据)。
为将数据回发给客户端,只需调用sendData方法并把数据作为其输入字符串传给它即可。在本例中,因为服务器就是一台回发服务器,所以要发送的数据就是先前接收的数据。
最终的源代码如下所示,其中包括了与客户端之间的数据交换。请注意,当前文提到的循环结束时,就意味着客户端已经断开,所以我们会把相关信息也打印到串行控制台。
#include <WiFi.h>
#include <WebSocketServer.h>
WiFiServer server(80);
WebSocketServer webSocketServer;
const char *ssid = "MyESP32AP";
const char *password = "testpassword";
void setup() {
Serial.begin(115200);
delay(4000);
WiFi.softAP(ssid, password);
Serial.println(WiFi.softAPIP());
server.begin();
delay(100);
}
void loop() {
WiFiClient client = server.available();
if (client.connected() && webSocketServer.handshake(client)) {
String data;
while (client.connected()) {
data = webSocketServer.getData();
if (data.length() > 0) {
Serial.println(data);
webSocketServer.sendData(data);
}
delay(10); // Delay needed for receiving the data correctly
}
Serial.println("The client disconnected");
delay(100);
}
delay(100);
}
测试代码使用Arduino IDE对代码进行编译并上传到您的ESP32开发板,即可对代码进行测试。然后,打开IDE serial monitor并复制打印出来的IP地址。在您Python程序的connect方法中,应该使用此处所输出的IP地址。
一旦您的电脑检测到ESP32 WiFi网络,请直接连接即可。在Windows 8上的视图如下所示。
http://mc.dfrobot.com.cn/data/attachment/forum/201904/08/174456c9zkr86hnvvn69nr.png图1 - Windows 8检测到ESP32 WiFi网络的视图(菜单语言为葡萄牙语)。
然后,运行Python代码。控制台上显示的输出结果如图2所示。和我们所预期的一样,发送到服务器的消息都被回发给了客户端。
http://mc.dfrobot.com.cn/data/attachment/forum/201904/08/174505sjg5dr9303rj9gjm.png图2 - Python程序的输出结果。
在Arduino IDE serial monitor上,程序的输出结果如图3所示。客户端所发送的消息都被接收并打印到了串行控制台上。
http://mc.dfrobot.com.cn/data/attachment/forum/201904/08/174541dxpmlz0u7ur1auzd.png图3 - 串行控制台打印的数据(接收自客户端)。
注:本文作者是Nuno Santos,他是一位和蔼可亲的电子和计算机工程师,住在葡萄牙里斯本 (Lisbon)。他写了200多篇有关ESP32、ESP8266的有用的教程和项目。
查看更多ESP32/ESP8266教程和项目,请点击 : ESP32教程汇总贴英文版教程 : ESP32 tutorial
页:
[1]