不说废话直接上代码,标注:接入的是国内的通义千问

/**
*@Author: edge
*@CreateTime: 2024/12/5
*@Description: use ESP8266 to connect to the Internet and use the API of Tongyi Lingma to ask questions.
*@Version: 0.1
*/
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
#include <U8g2lib.h>

// 连接到 Wi-Fi
const char* ssid = "";
const char* password = "";

// 通义千问 API 地址和密钥
const char* apiHost = "dashscope.aliyuncs";
const char* apiPath = "/compatible-mode/v1/chat/completions";
const char* apiKey = "";  // 替换为你自己的 API 密钥
// 初始化 OLED
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 5, /* data=*/ 4, /* cs=*/ 13, /* dc=*/ 12, /* reset=*/ 14);
String reply;  // 定义全局变量
void setup() {

  // 初始化 OLED
  u8g2.begin();
  u8g2.enableUTF8Print();

  // 连接到 Wi-Fi
  Serial.begin(9600);
  WiFi.begin(ssid, password);
 
  // 等待 Wi-Fi 连接
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nConnected to Wi-Fi!");
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_unifont_t_chinese2);
  u8g2.drawUTF8(0, 10, "ConnectedtoWiFi!");
  u8g2.sendBuffer();

  Serial.println("IP Address: " + WiFi.localIP().toString());

}

// 发送消息到通义千问 API
void sendMessageToTongyiLingma(const String& prompt) {
  WiFiClientSecure client;
  client.setInsecure();  // 不验证证书,开发测试环境使用

  if (!client.connect(apiHost, 443)) {
    Serial.println("Connection to Tongyi Lingma API failed!");
    return;
  }

  // 配置请求路径和负载内容
  String payload = "{\"model\": \"qwq-32b-preview\", \"messages\": [{\"role\": \"user\", \"content\": \"" + prompt + "\"}]}";

  // 发送 HTTP 请求
  client.print(String("POST ") + apiPath + " HTTP/1.1\r\n" +
               "Host: " + apiHost + "\r\n" +
               "Authorization: Bearer " + apiKey + "\r\n" +
               "Content-Type: application/json\r\n" +
               "Content-Length: " + payload.length() + "\r\n\r\n" +
               payload);

  // 等待响应头
  while (client.connected()) {
    String line = client.readStringUntil('\n');
    if (line == "\r") break;  // 响应头结束
  }

  // 读取并解析响应
  String response = client.readString();
  Serial.println("Response: " + response);

  // 解析 JSON 响应,提取通义千问回复内容
  DynamicJsonDocument doc(2048);  // 调整 JSON 文档大小,适应 API 响应
  DeserializationError error = deserializeJson(doc, response);

  if (error) {
    Serial.print("JSON parsing failed: ");
    Serial.println(error.c_str());
    return;
  }

  // 提取回复内容
  reply = doc["choices"][0]["message"]["content"].as<String>();
  Serial.println("Tongyi Lingma Response: " + reply);
  // 在 OLED 上显示回复内容
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_unifont_t_chinese2);
  u8g2.drawUTF8(0, 20, reply.c_str());
  u8g2.sendBuffer();
  

  client.stop();
}

// 滚动显示回复内容
int scrollOffset = 0;

void scrollDisplay(const char* str) {
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_unifont_t_chinese2);
  u8g2.drawUTF8(scrollOffset, 20, str);
  u8g2.sendBuffer();
  scrollOffset -= 2;  // 每次滚动2个像素
  if (scrollOffset + u8g2.getStrWidth(str) < 0) {
    scrollOffset = 128;  // 重新开始滚动
  }
}

void loop() {
  // 发送问题到 Tongyi Lingma
  delay(10000);  // 每10秒钟发送一次请求·
  sendMessageToTongyiLingma("Who are you?");
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_unifont_t_chinese2);
  u8g2.drawUTF8(0, 20, "Q Who are you?");
  u8g2.sendBuffer();
  delay(1000);
  for (int i = 0; i < 100; i++) {
    scrollDisplay(reply.c_str());
    delay(20);
  }  
  delay(1000);

  sendMessageToTongyiLingma("What time is it?");
   u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_unifont_t_chinese2);
  u8g2.drawUTF8(0, 20, "What time is it?");
  for (int i = 0; i < 20; i++) {  // 滚动64次
    scrollDisplay(reply.c_str());
    delay(20);  // 每次滚动间隔200毫秒
  }
  u8g2.sendBuffer();
  delay(1000);
  for (int i = 0; i < 64; i++) {  // 滚动64次
    scrollDisplay(reply.c_str());
    delay(20);  // 每次滚动间隔200毫秒
  }
}

loop里的是做测试使用,后续可以根据你的需要去做一些事情

至于为什么不用openai而选择通义千问,因为访问openai要代理!而且通义的模型也非常不错