【ESP32】制作跨境电商网络质量检测器

简介

我有很多个WiFi节点,自然有很多台手机,很个账号。如果给每个手机配一个这个WiFi质量检测器,TK主播在直播的时候,就可以很直观的观察自己的网络情况,信号强度如何,延迟是否过高。

ESP-32

相关下载

下载链接:https://pan.quark.cn/s/51fd68b6100a

  • esp32wifi.zip(项目代码)
  • CH341SER.EXE (esp32驱动)

设备型号

ESP-32 CP2102 TYPE-C USB接口 WIFI 蓝牙 无线模块 (屏幕 OLED 单色屏)

ESP32屏幕链接方式

OLED(屏幕)ESP32引脚
VCC3v3
GNDGND
SDAD21
SCLD22

教程

1、vscode Ctrl + Shift + X 添加插件:Plaftormio IDE

2、导入项目代码

3、把esp32用数据线连接到电脑,并在设备管理器中查看连接到了第几个COM

4、把项目文件中的plaftormio.ini 中的upload_port参数改为对应的com

5、在vscode底部栏: Plaftormio Build ,Plaftormio Upload

核心代码展示

#include <Arduino.h>
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ESP32Ping.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>


#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
 
const char* ssid = "TK01";
const char* password = "Abcd1234";
  
String publicIP = "N/A";
String country = "N/A";
  
// ====================== 获取公网IP + 国家 ======================
void updateIPInfo() {
  HTTPClient http;

  http.begin("http://ip-api.com/json/?fields=status,countryCode,query");

  int httpCode = http.GET();

  if (httpCode > 0) {
    String payload = http.getString();

    Serial.println(payload); // 调试用(建议保留)

    StaticJsonDocument<512> doc;
    DeserializationError error = deserializeJson(doc, payload);

    if (!error) {
      String status = doc["status"].as<String>();

      if (status == "success") {
        publicIP = doc["query"].as<String>();
        country = doc["countryCode"].as<String>();
      } else {
        publicIP = "FAIL";
        country = "N/A";
      }
    } else {
      publicIP = "JSON ERR";
      country = "ERR";
    }
  } else {
    publicIP = "HTTP ERR";
    country = "ERR";
  }

  http.end();
}

// ====================== 初始化 ======================
void setup() {
  Serial.begin(115200);

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("OLED初始化失败");
    while (true);
  }

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);

  display.setCursor(0, 0);
  display.println("Connecting WiFi...");
  display.display();

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }

  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("WiFi Connected!");
  display.display();

  delay(1000);

  // 获取一次公网信息
  updateIPInfo();
}


// ====================== 主循环 ======================
void loop() {
  display.clearDisplay();

  int rssi = WiFi.RSSI();
  String wifiName = WiFi.SSID();

  // ===== SSID =====
  display.setCursor(0, 0);
  display.setTextColor(WHITE);
  display.print("SSID: ");
  display.println(wifiName);

  // ===== IP + 国家 =====
  display.setCursor(0, 12);
  display.print("IP: ");
  display.print(publicIP);
  display.print("(");
  display.print(country);
  display.println(")");

  // ===== WiFi信号 =====
  display.setCursor(0, 24);
  display.print("WiFi: ");
  display.print(rssi);
  display.println(" dBm");

  // ===== TikTok检测 =====
  HTTPClient http;

  unsigned long start = millis();
  http.begin("https://www.tiktok.com");
  int httpCode = http.GET();
  unsigned long duration = millis() - start;

  // ===== TikTok延迟 =====
  display.setCursor(0, 36);

  if (httpCode > 0) {
    display.print("TK: ");
    display.print(duration);
    display.println(" ms");
  } else {
    display.println("TK: FAIL");
  }

  // ===== LIVE状态 =====
  display.setCursor(0, 52);

  if (httpCode <= 0) {
    display.println("LIVE: BLOCKED");
  }
  else if (duration < 100 && rssi > -60) {
    display.println("LIVE: PERFECT");
  }
  else if (duration < 200 && rssi > -70) {
    display.println("LIVE: GOOD");
  }
  else if (duration < 400) {
    display.println("LIVE: OK");
  }
  else {
    display.println("LIVE: BAD");
  }

  http.end();

  display.display();

  // 每30秒更新一次IP信息(避免频繁请求)
  static unsigned long lastUpdate = 0;
  if (millis() - lastUpdate > 30000) {
    updateIPInfo();
    lastUpdate = millis();
  }

  delay(5000);
}