【电机控制器】ESP32-C3语言模型——DeepSeek

news/2025/2/22 14:33:46

【电机控制器】ESP32-C3语言模型——DeepSeek


文章目录

    • @[TOC](文章目录)
  • 前言
  • 一、简介
  • 二、代码
  • 三、实验结果
  • 四、参考资料
  • 总结

前言

使用工具:


提示:以下是本篇文章正文内容,下面案例可供参考

一、简介

二、代码

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

// 替换为您的 WiFi 凭据
const char *ssid = "你需要改的地方";
const char *password = "你需要改的地方";

// 替换为您的 DeepSeek API 密钥
const char* apiKey = "你需要改的地方";

// DeepSeek API 端点
const char* host = "api.deepseek.com";
const int httpsPort = 443;

// 创建 WiFiClientSecure 对象
WiFiClientSecure client;

// 设置超时时间 (单位:毫秒)
const unsigned long timeout = 10000;

// 对话历史
const int maxHistory = 10; // 最大对话轮次
String conversationHistory[maxHistory]; // 存储对话历史
int historyIndex = 0; // 当前对话历史索引

// 函数声明
void connectToWiFi();
String askDeepSeek(String question);
void printResponse(String response);
void addToHistory(String role, String content);
void printHistory();

void setup() {
  Serial.begin(115200);

  // 连接到 WiFi
  connectToWiFi();

  // 关闭证书鉴权
  client.setInsecure();

  Serial.println("初始化完成,请输入您的问题:");
}

void loop() {
  // 检查串口是否有输入
  if (Serial.available()) {
    String question = Serial.readStringUntil('\n');
    question.trim(); // 去除换行符和空格

    if (question.length() > 0) {
      // 将用户问题添加到对话历史
      addToHistory("user", question);

      Serial.println("正在向 DeepSeek 提问...");
      String response = askDeepSeek(question);
      printResponse(response);

      // 将模型回复添加到对话历史
      addToHistory("assistant", response);

      // 打印当前对话历史
      printHistory();

      Serial.println("\n请输入下一个问题:");
    }
  }
}

// 连接到 WiFi
void connectToWiFi() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("正在连接到 WiFi...");
  }
  Serial.println("已连接到 WiFi");
}

// 向 DeepSeek 提问
String askDeepSeek(String question) {
  String response = "";

  // 连接到 DeepSeek API
  if (!client.connect(host, httpsPort)) {
    Serial.println("连接失败");
    return "连接失败";
  }

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

  // 构建请求体
  DynamicJsonDocument doc(1024);
  doc["model"] = "deepseek-chat";
  doc["stream"] = true;

  // 添加对话历史
  JsonArray messages = doc.createNestedArray("messages");
  for (int i = 0; i < historyIndex; i++) {
    JsonObject message = messages.createNestedObject();
    message["role"] = i % 2 == 0 ? "user" : "assistant"; // 交替用户和助手角色
    message["content"] = conversationHistory[i];
  }

  // 添加当前问题
  JsonObject newMessage = messages.createNestedObject();
  newMessage["role"] = "user";
  newMessage["content"] = question;

  String requestBody;
  serializeJson(doc, requestBody);

  request += "Content-Length: " + String(requestBody.length()) + "\r\n\r\n";
  request += requestBody;

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

  // 记录开始时间
  unsigned long startTime = millis();

  // 流式接收响应
  while (client.connected()) {
    // 检查超时
    if (millis() - startTime > timeout) {
      Serial.println("响应超时");
      break;
    }

    // 读取数据
    while (client.available()) {
      String line = client.readStringUntil('\n');
      if (line.startsWith("data: ")) {
        String jsonData = line.substring(6);
        DynamicJsonDocument doc(1024);
        deserializeJson(doc, jsonData);

        // 提取回复内容
        if (doc.containsKey("choices")) {
          String content = doc["choices"][0]["delta"]["content"];
          response += content;
        }

        // 提取思维链内容(假设字段为 "reasoning")
        if (doc.containsKey("choices") && doc["choices"][0].containsKey("delta") && doc["choices"][0]["delta"].containsKey("reasoning")) {
          String reasoning = doc["choices"][0]["delta"]["reasoning"];
          Serial.println("思维链: " + reasoning);
        }
      }
    }
  }

  // 断开连接
  client.stop();
  return response;
}

// 打印回复内容
void printResponse(String response) {
  Serial.println("DeepSeek 回复:");
  Serial.println(response);
}

// 添加对话历史
void addToHistory(String role, String content) {
  if (historyIndex < maxHistory) {
    conversationHistory[historyIndex] = content;
    historyIndex++;
  } 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++) {
    Serial.println((i % 2 == 0 ? "用户: " : "助手: ") + conversationHistory[i]);
  }
}

三、实验结果

回复结果为空,deepseek最近的服务器看起来情况不太好啊 - -
在这里插入图片描述

四、参考资料

【ESP32接入国产大模型之Deepseek】
立创开发板入门ESP32C3第八课 修改AI大模型接口为deepseek3接口

总结

本文仅仅简单介绍了【电机控制器】ESP32-C3语言模型——DeepSeek,评论区欢迎讨论。


http://www.niftyadmin.cn/n/5862395.html

相关文章

Lua C API :使用 lua_tonumber 函数从 Lua 栈中提取数值

lua_tonumber 是 Lua C API 中的一个重要函数&#xff0c;用于从 Lua 栈中提取数值并将其转换为 C 中的 lua_Number 类型。这个函数非常有用&#xff0c;尤其是在 C 与 Lua 交互时&#xff0c;能够轻松地从 Lua 环境中获取数值并进行处理。 函数原型 lua_Number lua_tonumber…

Go 语言结合 Redis 实现固定窗口、滑动窗口、令牌桶和漏桶限流算法的示例代码

固定窗口算法 原理&#xff1a;将时间划分为固定大小的窗口&#xff0c;在每个窗口内对请求进行计数。如果请求数超过设定的阈值&#xff0c;则拒绝后续请求&#xff0c;直到进入下一个窗口。代码&#xff1a; package mainimport ("fmt""time""git…

如何将Python函数打包成.so库?

将Python函数打包成.so库的基本流程 安装依赖&#xff1a; 安装Cython&#xff1a;pip install cython安装OpenCV的Python包和开发库&#xff1a;pip install opencv-python # Ubuntu系统安装OpenCV开发库 sudo apt-get install libopencv-dev编写Cython代码&#xff08;.pyx文…

Unity游戏制作中的C#基础(4)数组声明和使用

一、数组的声明 在 C# 中&#xff0c;声明数组有多种方式&#xff0c;每种方式都有其适用的场景&#xff0c;下面为你逐一详细介绍&#xff1a; 1. 直接初始化声明 这种方式直观且便捷&#xff0c;在声明数组的同时就为其赋初值&#xff0c;让数组从诞生之初就拥有了具体的数据…

让浏览器AI起来:基于大模型Agent的浏览器自动化工具

最近有个非常火的项目,利用大模型Agent驱动浏览器完成各种操作,如网页搜索、爬虫分析、机票酒店预定、股票监控等,号称全面替代所有在浏览器上的操作,试用方式还是比较简单的,以下将进行简单介绍。 快速开始 通过pip安装: pip install browser-use安装web自动化框架:…

神经网络八股(三)

1.什么是梯度消失和梯度爆炸 梯度消失是指梯度在反向传播的过程中逐渐变小&#xff0c;最终趋近于零&#xff0c;这会导致靠前层的神经网络层权重参数更新缓慢&#xff0c;甚至不更新&#xff0c;学习不到有用的特征。 梯度爆炸是指梯度在方向传播过程中逐渐变大&#xff0c;…

c++ std::list使用笔记

c std::list使用笔记 1. 包含头文件2. 创建和初始化 std::list3. 添加元素4. 删除元素5. 访问元素6. 遍历 std::list7. 容量相关操作8. 其他常用操作9. 示例代码总结 std::list 是 C 标准库中的一个双向链表容器。与 std::vector 不同&#xff0c; std::list 不支持随机访问&…

单片机 Bootloade与二进制文件的生成

单片机的 Bootloader 是一种特殊的程序&#xff0c;负责在单片机上电后初始化硬件、更新用户应用程序&#xff08;固件&#xff09;&#xff0c;并将控制权移交给用户程序。以下是其运行机制和关键流程的详细说明&#xff1a; 1、单片机 Bootloader 的核心作用 固件更新&…