ESP Wroom 32调取Deepseek API,实现对话聊天

近期Deepseek的爆火,小编也来蹭一下热度,想着调取它的API来部署起来玩玩,哈哈哈~

话不多说下面说干货:

1.准备工作

(1)进入Deepseek官网(DeepSeek | 深度求索DeepSeek | 深度求索DeepSeek | 深度求索),点击右上角进入它提供的API开发平台。

(2)创建API key

注意:它自动生成的的API的key生成完之后是不能查看的,所以你需要自己手动保存起来!!!

(3)进入它提供的接口文档获取模型的URL

注意:它在这里已经有完善的API调取文档,根据自己的需求可以更换调取的模型,这里小编就用的它默认的DeepSeek-V3模型。

(4)在开始调用之前记得向你的账号充值,小编只充了10元还挺耐用的

2.代码

小编是在vscode里用platformio插件部署的Arduino环境,下面的代码是直接可以跑起来的。

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>

// ================= 硬件配置 =================
#define LED_PIN          2         // 使用 GPIO2 作为状态灯
#define PWM_CHANNEL      0         // LEDC 通道
#define PWM_FREQ         5000      // PWM 频率
#define PWM_RESOLUTION   8         // 8位分辨率 (0-255)

// ================= 网络配置 =================
const char *ssid = "wifi的名字";
const char *password = "wifi密码";

// ================= DeepSeek 配置 ==============
const char* apiKey = "你直接创建的API KEY";
const char* host = "调取的模型的URL";
const int httpsPort = 443;

// ================= 全局对象 ==================
WiFiClientSecure client;
unsigned long responseStartTime = 0;
bool isWaitingResponse = false;

// ================= LED 控制变量 ==============
int breatheBrightness = 0;        // 当前亮度值
int breatheStep = 5;              // 亮度变化步长
bool timeoutFlag = false;         // 超时标志

// ================= 对话历史 ==================
const int maxHistory = 10;
String conversationHistory[maxHistory];
int historyIndex = 0;

// ================= 函数声明 ==================
void connectToWiFi();
String askDeepSeek(String question);
void addToHistory(String role, String content);
void printHistory();
void ledFeedbackSetup();
void updateLedFeedback();
void triggerTimeoutEffect();

void setup() {
  Serial.begin(115200);
  
  // 初始化 LED 反馈系统
  ledFeedbackSetup();
  
  // 连接 WiFi
  connectToWiFi();
  
  // 配置 HTTPS 客户端
  client.setInsecure();
  
  Serial.println("\n系统初始化完成");
  Serial.println("请输入您的问题:");
}

void loop() {
  // 持续更新 LED 状态
  if (isWaitingResponse) {
    updateLedFeedback();
    
    // 检查超时(10秒)
    if (millis() - responseStartTime > 10000 && !timeoutFlag) {
      triggerTimeoutEffect();
      timeoutFlag = true;
      isWaitingResponse = false;
    }
  }

  // 处理用户输入
  if (Serial.available()) {
    String question = Serial.readStringUntil('\n');
    question.trim();
    
    if (question.length() > 0) {
      // 添加对话历史
      addToHistory("user", question);
      
      // 启动请求流程
      Serial.println("\n正在与 DeepSeek 通信...");
      isWaitingResponse = true;
      timeoutFlag = false;
      responseStartTime = millis();
      
      // 发送请求并获取响应
      String response = askDeepSeek(question);
      
      // 结束请求流程
      isWaitingResponse = false;
      ledcWrite(PWM_CHANNEL, 0);  // 关闭 LED
      
      // 处理响应
      Serial.println("\nDeepSeek 回复:");
      Serial.println(response);
      addToHistory("assistant", response);
      
      // 显示对话历史
      printHistory();
      
      Serial.println("\n请输入下一个问题:");
    }
  }
}

// ================= 网络连接函数 ================
void connectToWiFi() {
  Serial.print("正在连接 WiFi");
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  Serial.println("\nWiFi 已连接");
  Serial.print("IP 地址: ");
  Serial.println(WiFi.localIP());
}

// ================= API 请求函数 ================
String askDeepSeek(String question) {
  String response = "";

  if (!client.connect(host, httpsPort)) {
    Serial.println("连接服务器失败");
    return "连接错误:无法建立连接";
  }

  // 构建 JSON 请求体
  DynamicJsonDocument doc(2048);
  doc["model"] = "deepseek-chat";
  doc["stream"] = true;
  
  JsonArray messages = doc.createNestedArray("messages");
  
  // 添加历史对话
  for (int i = 0; i < historyIndex; i++) {
    JsonObject msg = messages.createNestedObject();
    msg["role"] = (i % 2 == 0) ? "user" : "assistant";
    msg["content"] = conversationHistory[i];
  }
  
  // 添加当前问题
  JsonObject newMsg = messages.createNestedObject();
  newMsg["role"] = "user";
  newMsg["content"] = question;

  // 序列化 JSON
  String requestBody;
  serializeJson(doc, requestBody);

  // 构建 HTTP 请求
  String request = String("POST /v1/chat/completions HTTP/1.1\r\n") +
                  "Host: " + host + "\r\n" +
                  "Authorization: Bearer " + apiKey + "\r\n" +
                  "Content-Type: application/json\r\n" +
                  "Connection: close\r\n" +
                  "Content-Length: " + requestBody.length() + "\r\n\r\n" +
                  requestBody;

  // 发送请求
  client.print(request);

  // 流式接收响应
  while (client.connected()) {
    String line = client.readStringUntil('\n');
    if (line.startsWith("data: ")) {
      String jsonData = line.substring(6);
      
      DynamicJsonDocument doc(2048);
      deserializeJson(doc, jsonData);

      // 解析响应内容
      if (doc.containsKey("choices")) {
        const char* content = doc["choices"][0]["delta"]["content"];
        if (content) response += String(content);
      }
    }
  }

  client.stop();
  return response;
}

// ================= LED 反馈系统 ================
void ledFeedbackSetup() {
  // 配置 PWM 通道
  ledcSetup(PWM_CHANNEL, PWM_FREQ, PWM_RESOLUTION);
  ledcAttachPin(LED_PIN, PWM_CHANNEL);
}

void updateLedFeedback() {
  static unsigned long lastUpdate = 0;
  
  // 非阻塞式定时更新
  if (millis() - lastUpdate > 30) {
    lastUpdate = millis();
    
    breatheBrightness += breatheStep;
    
    // 反转亮度变化方向
    if (breatheBrightness >= 255 || breatheBrightness <= 0) {
      breatheStep = -breatheStep;
    }
    
    // 更新 PWM 输出
    ledcWrite(PWM_CHANNEL, breatheBrightness);
  }
}

void triggerTimeoutEffect() {
  Serial.println("\n请求超时!");
  for (int i = 0; i < 3; i++) {
    ledcWrite(PWM_CHANNEL, 255);  // 全亮
    delay(150);
    ledcWrite(PWM_CHANNEL, 0);    // 全灭
    delay(150);
  }
}

// ================= 对话历史管理 ================
void addToHistory(String role, String content) {
  if (historyIndex < maxHistory) {
    conversationHistory[historyIndex++] = content;
  } else {
    // 移除最早记录
    for (int i = 0; i < maxHistory-1; i++) {
      conversationHistory[i] = conversationHistory[i+1];
    }
    conversationHistory[maxHistory-1] = content;
  }
}

void printHistory() {
  Serial.println("\n当前对话历史:");
  for (int i = 0; i < historyIndex; i++) {
    String prefix = (i % 2 == 0) ? "用户: " : "助手: ";
    Serial.println(prefix + conversationHistory[i]);
  }
}

上述代码实现用户通过串口助手向ESP Wroom 32发送并接收数据将数据传入云端DeepSeek-V3模型中分析数据并回答,再通过串口助手传回显示回答。

效果展示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值