这篇帖子,分享了使用FireBeetle 2 ESP32-C5制作一个简易网络速度测试器的过程,并帮助大家了解ESP32-C5在Arduino,快速使用上5GHz WiFi网络的方法。
一、硬件了解这次的FireBeetle 2 ESP32-C5,搭载ESP32-C5-WROOM-1-N4模组。
ESP32-C5是乐鑫首款支持5G网络的芯片,可以说,乐鑫对它寄予了厚望。

另外,DF还配置了专用扩展板:

这块扩展板上引出的引脚非常的丰富,供电也很方便。
上图中,扩展板正面的右下角是并排的三个I2C接口,在分享中,会用于连接I2C的OLED显示屏。
二、WiFi库了解
如果用过Arduino-ESP32的WiFi库,会知道这是相当的方便,使用下面的两行代码,就能连接到WiFi热点了:
- WiFi.mode(WIFI_STA);
- WiFi.begin(ssid, password);
复制代码
如果你还关注 Arduino-ESP32 的进展的话,那么会注意到今年3月11日的一个pull/11045:

正是在这个pull中,提供了对2.4GHz和5GHz WiFi的切换,并提供了三个方法:
- setBandMode:设置Band模式
- getBandMode:获取Band设置模式
- getBand:获取当前实际生效的Band模式
可供设置的Band模式一共有三种:
- WIFI_BAND_MODE_2G_ONLY:仅使用2.4GHz网络
- WIFI_BAND_MODE_5G_ONLY:仅使用5GHz网络
- WIFI_BAND_MODE_AUTO:自动切换
注意getBandMode和getBand,差异在于使用setBandMode设置WIFI_BAND_MODE_AUTO的时候,getBandMode会返回WIFI_BAND_MODE_AUTO,而getBand返回的则是实际连接的网络所使用的Band。
三、设计思路
网络测试要做的复杂的话,可以参考esp-idf的iperf组件,能够测试WiFi的吞吐量。
但这里要做一个简易网络速度测试器,那就用简单一点的方法好了。
访问一个网址10次,然后根据获取的数据大小,以及获取所花费的时间,来计算这10次的平均网络速度。
在测试过程中,交替连接2.4GHz和5GHz网络,进行测试。
就是这么简易。
我准备了不同大小的文件,方便测试: 测试文件.zip,其中包含:

注意,最后一个显示的是10.5MB,实际是1024*1024字节,但显示出来是:10485760 / 1000 / 1000 = 10.48576 ~= 10.5
另外,除了串口输出数据,我还是用了一块128x64的OLED,来显示当前连接的网络以及测试的速度。
驱动OLED,我使用的是最最最强大的U8g2,通过库管理直接安装最新版即可:

四、代码编写
做好了各项准备工作,就可以编写实际的代码了。
首先是头文件包含:
- #include <WiFi.h>
- #include <WiFiClientSecure.h>
- #include <Arduino.h>
- #include <U8g2lib.h>
复制代码
其中包括Arduin的头文件、WiFi和WiFiClient的头文件,以及U8g2的头文件。
然后定义要连接的2.4GHz网络和5GHz网络:
- const char* ssid = "OpenBSD";
- const char* ssid_5g = "OpenBSD_5G";
- const char* password = "********";
复制代码
再定义要用于测试的服务端:
- const char* testHost = "192.168.1.15"; // 测试服务器
- const int testPort = 8088; // 测试服务端口
- const int numRequests = 10; // 请求次数
- const char* testFile = "/10k.dat"; // 测试文件
复制代码
我这里测试用的是本地的其他电脑,使用下面的python命令,来提供网络服务:
- cd 10k.dat文件所在的目录
- python -m http.server 8088 -d .
复制代码
执行成功后,会输出:Serving HTTP on :: port 8088 (http://[::]:8088/) ...
再定义下面的变量:
- bool is5G = false; // 当前连接热点类型
- WiFiClient client;
复制代码
is5G表示当前要测试的是5GHz还是2.4GHz网络。
client则表示WiFi网络请求连接client
最后,定义显示模块:
- String text = ""; // 显示文本
- U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 10, /* data=*/ 9);
复制代码
U8g2支持IIC和SPI的OLED,可以根据实际需要,很方便的进行设置。
再往后,就是setup()和loop()了。
setup()的代码如下:
- void setup() {
- Serial.begin(115200);
- WiFi.mode(WIFI_STA); //配置WIFI为Station模式
-
- u8g2.begin();
- u8g2.clearBuffer();
-
- u8g2.setFontDirection(0);
- u8g2.setFont(u8g2_font_ncenB08_tr);
-
- u8g2.drawStr( 0, 12, "SSID: ");
- u8g2.drawStr( 40, 12, is5G ? ssid_5g : ssid);
- u8g2.drawStr( 0, 30, "Speed: ");
- u8g2.drawStr( 40, 55, "testing...");
- u8g2.sendBuffer();
- }
复制代码
其中包含了串口初始化、WiFi初始化,以及显示屏的初始化。
关于U8g2的具体使用,这里就不展开详细说了,可以找到的资料也蛮多的。
这里主要是清空,然后设置字体方向、字体,以及在指定的(x,y)坐标处,使用drawStr写上文字,最后发送缓冲区的内容以便显示出来。
loop()的代码如下:
- void loop() {
- Serial.println("Testing network speed...");
-
- // 断开WiFi连接
- while (WiFi.status() == WL_CONNECTED) {
- WiFi.disconnect();
- }
-
- // 设置WiFi连接模式
- WiFi.setBandMode(is5G ? WIFI_BAND_MODE_5G_ONLY : WIFI_BAND_MODE_2G_ONLY);
- WiFi.begin(is5G ? ssid_5g : ssid, password);
-
- Serial.print("Connecting to WiFi: ");
- Serial.print(is5G ? ssid_5g : ssid);
- while (WiFi.status() != WL_CONNECTED) {
- delay(1000);
- Serial.print(".");
- }
- Serial.println("\nConnected to WiFi!");
-
- // 下载测试
- long startTime = millis();
-
- for (int i = 0; i < numRequests; i++) {
- if (client.connect(testHost, testPort)) {
- client.print(String("GET " + String(testFile) + " HTTP/1.1\r\n") +
- "Host: " + testHost + "\r\n" +
- "Connection: close\r\n\r\n");
-
- while (!client.available()) {
- delay(10);
- }
-
- while (client.available()) {
- client.read();
- }
- client.stop();
- } else {
- Serial.println("Connection failed!");
- }
- }
-
- // 计算和输出速度
- long elapsedTime = millis() - startTime;
- float speedReqSec = (float)numRequests / (elapsedTime / 1000.0); // 请求速率
- float speedMbps = (numRequests * 0.2 * 8) / (elapsedTime / 1000.0); // 下载速度
-
- Serial.print("Network speed: ");
- Serial.print(speedReqSec);
- Serial.println(" requests per second");
-
- Serial.print("Download speed: ");
- Serial.print(speedMbps);
- Serial.println(" Mbps");
-
- text = String(speedMbps) + "Mbps";
- u8g2.clearBuffer();
-
- u8g2.setFontDirection(0);
- u8g2.setFont(u8g2_font_ncenB08_tr);
-
- u8g2.drawStr( 0, 12, "WiFi: ");
- u8g2.drawStr( 40, 12, is5G ? ssid_5g : ssid);
- u8g2.drawStr( 0, 30, "Speed: ");
-
- u8g2.setFont(u8g2_font_ncenB12_tr);
- u8g2.drawStr( 35, 50, text.c_str());
- u8g2.sendBuffer();
-
- // 断开WiFi连接
- while (WiFi.status() == WL_CONNECTED) {
- WiFi.disconnect();
- }
-
- is5G = !is5G;
-
- delay(1000);
- }
复制代码
其中的基本逻辑就是:断开WiFi连接(如果有),连接当前要测试的WiFi网络,发起网络请求下载数据10次(根据numRequests指定次数),然后根据获取的数据和实际是时间,计算平均访问速度,最后就是串口输出和显示屏输出了。
五、编译运行
在运行之前,首先要确保测试资源可以被正确访问。
我使用了本地的其他电脑提供测试资源,那么在执行 python -m http.server 8088 -d . (请查看代码编写部分关于测试服务器的设置)以后,我会通过网址 http://192.168.1.15:8088/10k.dat 来测试文件是否可被成功下载。

然后,把FireBeetle 2 ESP32-C5连接到电脑,并使用下面的参数编译和下载:

烧录前,先打开串口监听,然后下载,直到最终输出如下的结果:

如果没有成功连接到WiFi,请仔细检查WiFi的配置。
另外,我的本地电脑,也会输出如下的信息,表示正在被请求测试:

五、实际效果
运行后,实际效果如下:
 
动图效果:

六、总结
在实际测试中,发现5GHz网络比2.4GHz网络,略微有一点点优势,但不想电脑或者手机那样有重大优势,毕竟ESP32-C5还是小身板,能力有限。
但是今后在实际应用中,能够方便的使用5GHz和2.4Ghz网络,不用在怕选错了网络不能连接,这一点,就比之前的只能用2.4GHz网络有了巨大的优势。
|