不说废话直接上代码,标注:接入的是国内的通义千问
/**
*@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要代理!而且通义的模型也非常不错
发布评论