HonestQiao 发表于 2025-9-23 01:20:40

FireBeetle 2 ESP32-C5 简易网络速度测试器

这篇帖子,分享了使用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网络,进行测试。
就是这么简易。

我准备了不同大小的文件,方便测试:,其中包含:

注意,最后一个显示的是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网络有了巨大的优势。
页: [1]
查看完整版本: FireBeetle 2 ESP32-C5 简易网络速度测试器