• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

【你购物我买单】SenseCAP Indicator连接wifi并获取天气信息

最近折腾 ESP32S3 的时候,基于基础的 WiFi 连接代码,扩展了调用心知天气 API 获取实时天气的功能,整个过程踩了一些小坑,整理成完整教程分享给大家,新手也能轻松上手~

本代码实现核心功能:

ESP32S3 稳定连接指定 WiFi(含自动重连、超时机制); 调用心知天气免费 API 获取指定城市的实时温度、天气状况、湿度等数据; 串口打印清晰的日志和解析后的天气数据,方便调试和查看; 避免频繁请求 API,保证程序稳定性。

前期准备

1. 硬件

ESP32S3 Dev Module 开发板(带 / 不带 PSRAM 版本均可); USB 数据线(建议原装,避免供电 / 通信问题)。

2. 软件 & 依赖

VSCode + Arduino 插件(已配置 ESP32 开发板支持); 安装 ArduinoJson 库:在 VSCode 中打开「库管理器」(Ctrl+Shift+P → Arduino: Library Manager),搜索「ArduinoJson」,安装 6.x 版本(兼容性更好); 心知天气 API 密钥:前往心知天气官网注册账号,免费获取 API 密钥(个人免费版足够日常使用)。

关键代码说明

WiFi 连接模块:加入了超时机制(15 秒)和自动重连,避免程序卡死在连接环节,新手也能快速定位 WiFi 连接问题;

API 请求优化: 改用http协议而非https:ESP32S3 默认缺少 HTTPS 证书,新手无需额外配置即可请求成功; 设置 5 秒请求超时,避免等待过久;

JSON 解析:使用 ArduinoJson 6.x 版本,静态缓冲区StaticJsonDocument<512>足够存储天气数据,解析效率更高; 防频繁请求:通过UPDATE_INTERVAL设置 60 秒更新间隔,符合心知天气免费版 API 的调用限制。

// 引入核心库
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>  // 需安装ArduinoJson库(推荐6.x版本)

// ===================== 需修改的配置项 =====================
const char* WIFI_SSID = "CMCC-eP9M";        // 你的WiFi名称(区分大小写)
const char* WIFI_PASSWORD = "y634ybku";    // 你的WiFi密码
const char* SENIVERSE_KEY = "你的api key"; // 你的心知天气API密钥
const char* CITY_ID       = "beijing";            // 要查询的城市(如beijing/shanghai/shenzhen)
// ==========================================================
const uint32_t UPDATE_INTERVAL = 60000;           // 天气更新间隔(60秒,避免频繁请求API)

WiFiClient wifiClient;             // WiFi客户端对象
void getSeniverseWeather();        // 获取心知天气数据
void printWeatherData(const char* city, float temp, const char* desc, float humidity); // 打印天气数据

// WiFi连接超时时间(毫秒),避免无限等待
const uint32_t WIFI_CONNECT_TIMEOUT = 15000;

void setup() {
  // 初始化串口,波特率115200(用于打印日志)
  Serial.begin(115200);
  delay(1000); // 等待串口监视器连接

  Serial.println("\n===== ESP32S3 WiFi连接程序 =====");
  
  // 配置WiFi为站点模式(连接路由器)
  WiFi.mode(WIFI_STA);
  WiFi.disconnect(); // 断开旧连接
  delay(500);

  // 开始连接WiFi
  Serial.printf("正在连接WiFi: %s\n", WIFI_SSID);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  // 等待连接完成或超时
  uint32_t start_time = millis();
  while (WiFi.status() != WL_CONNECTED && millis() - start_time < WIFI_CONNECT_TIMEOUT) {
    delay(500);
    Serial.print(".");
  }

  // 连接结果反馈
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("\n✅ WiFi连接成功!");
    Serial.print("📶 IP地址: ");
    Serial.println(WiFi.localIP());
    Serial.print("📡 WiFi信号强度(RSSI): ");
    Serial.println(WiFi.RSSI());
    Serial.print("🔌 MAC地址: ");
    Serial.println(WiFi.macAddress());
  } else {
    Serial.println("\n❌ WiFi连接失败!");
    Serial.print("错误状态码: ");
    Serial.println(WiFi.status());
    Serial.println("排查方向:1.WiFi名称/密码 2.信号覆盖 3.路由器接入限制");
  }
}

void loop() {
  // 检测WiFi连接状态,断开则自动重连
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("\n⚠️ WiFi连接丢失,正在尝试重连...");
    WiFi.reconnect();
    delay(1000);
    
    if (WiFi.status() == WL_CONNECTED) {
      Serial.println("✅ 重连成功!IP地址: " + WiFi.localIP().toString());
    }
  } else {
    // WiFi正常则定时获取天气数据
    Serial.println("\n=== 开始获取天气数据 ===");
    getSeniverseWeather();
    delay(UPDATE_INTERVAL); // 按设定间隔更新,避免频繁请求
  }

  delay(5000); // 基础检测间隔
}

// ===================== 核心函数:获取心知天气数据 =====================
void getSeniverseWeather() {
  // 构建API请求URL(改用http,避免HTTPS证书问题)
  String url = "http://api.seniverse.com/v3/weather/now.json?key=";
  url += SENIVERSE_KEY;
  url += "&location=" + String(CITY_ID);
  url += "&language=zh-Hans&unit=c"; // 中文、摄氏度

  // 发起HTTP请求
  HTTPClient http;
  http.begin(wifiClient, url);
  http.setTimeout(5000); // 请求超时5秒

  Serial.print("请求URL: ");
  Serial.println(url);

  int httpCode = http.GET();
  if (httpCode != HTTP_CODE_OK) {
    Serial.printf("❌ API请求失败,错误码: %d\n", httpCode);
    http.end();
    return;
  }

  // 读取并解析JSON响应
  String response = http.getString();
  http.end();

  Serial.print("API响应数据: ");
  Serial.println(response);

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

  if (error) {
    Serial.printf("❌ JSON解析失败: %s\n", error.c_str());
    return;
  }

  // 提取天气数据
  const char* cityName = doc["results"][0]["location"]["name"];
  float temperature = doc["results"][0]["now"]["temperature"];
  const char* weatherDesc = doc["results"][0]["now"]["text"];
  float humidity = doc["results"][0]["now"]["humidity"];

  // 打印解析后的清晰数据
  printWeatherData(cityName, temperature, weatherDesc, humidity);
}

// ===================== 打印格式化天气数据 =====================
void printWeatherData(const char* city, float temp, const char* desc, float humidity) {
  Serial.println("\n=== 🌤️ 天气数据解析结果 🌤️ ===");
  Serial.printf("城市: %s\n", city);
  Serial.printf("实时温度: %.1f ℃\n", temp);
  Serial.printf("天气状况: %s\n", desc);
  Serial.printf("相对湿度: %.1f %%\n", humidity);
  Serial.println("==============================");
}

使用步骤

获取心知天气 API 密钥: 注册心知天气账号 → 进入「控制台」→ 「我的 API 密钥」→ 复制密钥替换代码中的SENIVERSE_KEY

修改配置项:替换代码中WIFI_SSIDWIFI_PASSWORDCITY_ID为自己的信息;

安装依赖库:在 VSCode 中安装 ArduinoJson 6.x 库;

上传代码:选择 ESP32S3 Dev Module 开发板,上传代码到硬件;

查看结果:打开串口监视器(波特率 115200),等待 WiFi 连接成功后,即可看到实时天气数据。

测试结果:

全部回复(0)
正序查看
倒序查看
现在还没有回复呢,说说你的想法