如何用ESP32实现简短的AI对话

开发板型号:ESP32 WROOM 32

配置流程

引入必要的库:

  • #include <WiFi.h>: 用于管理 ESP32 的 WiFi 连接。
  • #include <HTTPClient.h>: 用于发起 HTTP 请求。
  • #include <ArduinoJson.h>: 用于处理 JSON 数据。

定义常量:

  • ssidpassword: WiFi 网络的 SSID 和密码。
  • apiKey: API 密钥,用来验证身份。
  • inputText: 发送给 API 的初始文本。
  • apiUrl: API 的 URL 地址。

函数定义:

getGPTAnswer(String inputText): 这个函数负责与 API 通信。它创建了一个HTTPClient对象,设置了超时时间,并开始与 API URL 建立连接。然后,它构造了一个 JSON 格式的数据作为请求体,包含了模型信息和用户输入的文本。接着,它发送 POST 请求,并根据返回的状态码判断是否成功。如果成功(状态码为 200),则解析 JSON 响应,并提取出回答文本;如果不成功,则打印错误信息。

setup() 函数:

  • 初始化串行通信。
  • 设置 ESP32 以 STA 模式连接到指定的 WiFi 网络。
  • 等待直到 WiFi 连接成功,并打印设备的 IP 地址。
  • 使用初始的inputText调用getGPTAnswer函数获取 API 的回答,并通过串口打印出来。

loop() 函数:

  • 检查是否有新的串行输入。
  • 如果有新的输入,读取至换行符,并将此输入作为inputText
  • 再次调用getGPTAnswer函数来获取针对新输入的回答,并通过串口打印。

配置代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <WiFi.h> // 引入WiFi库,用于管理ESP32的WiFi连接
#include <HTTPClient.h> // 引入HTTPClient库,用于发起HTTP请求
#include <ArduinoJson.h> // 引入ArduinoJson库,用于处理JSON数据

const char* ssid = "Your_SSID"; // 定义WiFi的SSID
const char* password = "Your_PASSWORD"; // 定义WiFi的密码

const char* apiKey = "Your_API"; // 设置API

String inputText = "你好,通义千问!"; // 定义要发送给API的文本
String apiUrl = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation"; // 定义API的URL

String answer; // 用于存储API返回的答案
String getGPTAnswer(String inputText) { // 定义一个函数,用于获取GPT的答案
HTTPClient http; // 创建一个HTTPClient对象
http.setTimeout(10000); // 设置超时时间为10000毫秒
http.begin(apiUrl); // 开始连接到API的URL
http.addHeader("Content-Type", "application/json"); // 添加HTTP头,指定内容类型为JSON
http.addHeader("Authorization", String(apiKey)); // 添加HTTP头,设置授权信息
// 构造请求的负载,包含模型信息和输入文本
String payload = "{\"model\":\"qwen-turbo\",\"input\":{\"messages\":[{\"role\": \"system\",\"content\": \"这里输入prompt。\"},{\"role\": \"user\",\"content\": \"" + inputText + "\"}]}}";
int httpResponseCode = http.POST(payload); // 发送POST请求,并获取响应码
if (httpResponseCode == 200) { // 如果响应码为200,表示成功
String response = http.getString(); // 获取响应体
http.end(); // 结束HTTP连接

// 解析JSON响应
DynamicJsonDocument jsonDoc(1024); // 创建一个JSON文档对象
deserializeJson(jsonDoc, response); // 反序列化JSON数据
String outputText = jsonDoc["output"]["text"]; // 从JSON中提取输出文本
return outputText; // 返回输出文本
} else { // 如果响应码不是200,表示请求失败
http.end(); // 结束HTTP连接
Serial.printf("Error %i \n", httpResponseCode); // 打印错误信息
return "<error>"; // 返回错误标记
}
}

void setup() { // setup函数,在设备启动时运行一次
Serial.begin(115200); // 初始化串行通信,设置波特率为115200

WiFi.mode(WIFI_STA); // 设置WiFi为STA(客户端)模式
WiFi.begin(ssid, password); // 使用提供的SSID和密码连接到WiFi网络
Serial.print("Connecting to WiFi .."); // 打印连接WiFi的信息
while (WiFi.status() != WL_CONNECTED) { // 等待WiFi连接成功
Serial.print('.'); // 打印点以表示正在尝试连接
delay(1000); // 每秒尝试一次
}
Serial.println(WiFi.localIP()); // 打印设备的IP地址
answer = getGPTAnswer(inputText); // 获取API的答案
Serial.println("通义千问: " + answer); // 打印答案
}

void loop() { // loop函数,设备运行期间循环执行
if (Serial.available()) { // 检查串行端口是否有数据可读
inputText = Serial.readStringUntil('\n'); // 读取输入文本,直到遇到换行符
Serial.println("\n 提问:" + inputText); // 打印输入文本

answer = getGPTAnswer(inputText); // 再次获取API的答案
Serial.println("回答: " + answer); // 打印答案
}
}