今天小標(biāo)給大家?guī)?lái)的是印度Maker的DeepSeek移動(dòng)終端項(xiàng)目,該項(xiàng)目使用ESP32開(kāi)發(fā)板作為主控,結(jié)合Wio Terminal的屏幕進(jìn)行DeepSeeek輸出顯示。

材料清單
Beetle ESP32 C6
面包板
跳線(xiàn)
Wio 終端
DFRobot Beetle ESP32 C6

多種通信協(xié)議:支持 Wi-Fi 6、藍(lán)牙 5、Zigbee 3.0 和 Thread 1.32。
超低功耗:具有深度睡眠模式,電流消耗僅為 14uA。
電池管理:集成鋰電池充電管理,使其適用于可穿戴應(yīng)用。
緊湊的尺寸:尺寸僅為 25*20.5 毫米,像硬幣一樣小。
Wio Terminal 是一個(gè)基于 ATSAMD51 微控制器的完整開(kāi)源開(kāi)發(fā)平臺(tái)。
![]()
它具有 2.4 英寸 LCD 屏幕、板載傳感器和無(wú)線(xiàn)連接選項(xiàng),使其成為各種應(yīng)用的絕佳選擇。主要功能包括:

高性能:配備 120MHz ARM Cortex-M4F 處理器
顯示屏:2.4 英寸 LCD 屏幕,分辨率為 320x240
連接性:通過(guò)附加模塊支持 Wi-Fi、藍(lán)牙和 LoRa。
多功能 I/O:包括 GPIO、數(shù)字、模擬、I2C、UART 和 SPI 接口。
內(nèi)置傳感器:具有陀螺儀、加速度計(jì)、麥克風(fēng)和光傳感器。
使用 Wio Terminal,可以輕松擴(kuò)展 Beetle ESP32 聊天機(jī)器人項(xiàng)目的功能,提供實(shí)時(shí)反饋和交互式顯示。
設(shè)置硬件
首先將 LED 連接到 Beetle ESP32。以下是引腳連接:
用電阻器將 LED1 連接到引腳 4。
這個(gè)簡(jiǎn)單的設(shè)置將使我們能夠通過(guò)閃爍的 LED 來(lái)可視化聊天機(jī)器人的活動(dòng)。
接下來(lái),通過(guò) UART 將 Wio 終端連接到 Beetle ESP32:
將 Wio Terminal 的 TX 引腳連接到 Beetle ESP32 C6 的 RX 引腳。
將 Wio Terminal 的 RX 引腳連接到 Beetle ESP32 C6 的 TX 引腳。
確保連接兩個(gè)設(shè)備的接地 (GND)。

這個(gè)簡(jiǎn)單的設(shè)置將允許我們通過(guò)在 Wio 終端上顯示 API 響應(yīng)來(lái)可視化聊天機(jī)器人的活動(dòng)。
連接Wi-Fi
要將 Beetle ESP32 連接到 Wi-Fi 網(wǎng)絡(luò),請(qǐng)使用以下代碼片段:
#include
const char* ssid = "Your_SSID";
const char* password = "Your_PASSWORD";
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("Connected to WiFi");
}
替換為本地實(shí)際 Wi-Fi 憑證 "Your_SSID""Your_PASSWORD"
創(chuàng)建 Web 服務(wù)器
接下來(lái),讓我們?cè)?Beetle ESP32 上設(shè)置一個(gè) Web 服務(wù)器:
// HTML content to be served const char index_html[] PROGMEM = R"rawliteral(DFRobot Chatbot ![]()
DFRobot Beetle ESP32 C3 Chatbot
Debug Panel
)rawliteral";
此代碼設(shè)置了一個(gè)基本的 Web 服務(wù)器,該服務(wù)器用作 HTML 頁(yè)面,用戶(hù)可以在其中輸入他們的問(wèn)題。

處理用戶(hù)問(wèn)題,首先導(dǎo)航到 Open router 并創(chuàng)建一個(gè)新的 API 密鑰。

將以下代碼添加到您的項(xiàng)目中:
HTTPClient http;
http.begin("https://openrouter.ai/api/v1/chat/completions");
http.addHeader("Content-Type", "application/json");
http.addHeader("Authorization", String("Bearer ") + apiKey);
StaticJsonDocument<512> jsonDoc;
jsonDoc["model"] = "deepseek/deepseek-r1-distill-llama-70b"; // deepseek/deepseek-r1-distill-llama-70b //openai/gpt-4o-mini-2024-07-18
JsonArray messages = jsonDoc.createNestedArray("messages");
JsonObject systemMessage = messages.createNestedObject();
systemMessage["role"] = "system";
systemMessage["content"] = "Answer the user's question concisely and informatively.";
JsonObject userMessage = messages.createNestedObject();
userMessage["role"] = "user";
userMessage["content"] = question;
String requestBody;
serializeJson(jsonDoc, requestBody);
Serial.println("Sending HTTP POST request...");
int httpResponseCode = http.POST(requestBody);
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
String response = http.getString();
Serial.print("HTTP Response: ");
Serial.println(response);
StaticJsonDocument<1024> responseDoc;
DeserializationError error = deserializeJson(responseDoc, response);
if (!error) {
String assistantResponse = responseDoc["choices"][0]["message"]["content"].as();
Serial.print("Assistant Response: ");
Serial.println(assistantResponse); // Print the assistant response
Serial1.println(assistantResponse);
return response; // Return entire API response
} else {
return "Failed to parse JSON response.";
}
}
不要忘記替換為 OpenAI 的實(shí)際 API 密鑰。"Your_API_Key"
最后,讓我們?cè)谔幚韱?wèn)題時(shí)通過(guò)閃爍 LED 來(lái)添加一些視覺(jué)反饋:
int led0 = 15;
int led1 = 4;
void setup() {
pinMode(led0, OUTPUT);
pinMode(led1, OUTPUT);
}
void loop() {
digitalWrite(led0, HIGH);
digitalWrite(led1, LOW);
delay(100);
digitalWrite(led0, LOW);
digitalWrite(led1, HIGH);
delay(100);
}
Beetle ESP32 C6 代碼:
這是完整的草圖,請(qǐng)將憑據(jù)更改為您的憑據(jù)。
#include#include #include #include int led0 = 15; int led1 = 4; // WiFi credentials const char* ssid = ""; const char* password = ""; const char* apiKey = ""; // Create WebServer object on port 80 WebServer server(80); // HTML content to be served const char index_html[] PROGMEM = R"rawliteral( DFRobot Chatbot ![]()
DFRobot Beetle ESP32 C3 Chatbot
Debug Panel
)rawliteral"; // Function to process the user question and get the response String processQuestion(String question) { Serial.print("User Question: "); Serial.println(question); // Print the user question if (WiFi.status() == WL_CONNECTED) { HTTPClient http; http.begin("https://openrouter.ai/api/v1/chat/completions"); http.addHeader("Content-Type", "application/json"); http.addHeader("Authorization", String("Bearer ") + apiKey); StaticJsonDocument<512> jsonDoc; jsonDoc["model"] = "deepseek/deepseek-r1-distill-llama-70b"; // deepseek/deepseek-r1-distill-llama-70b //openai/gpt-4o-mini-2024-07-18 JsonArray messages = jsonDoc.createNestedArray("messages"); JsonObject systemMessage = messages.createNestedObject(); systemMessage["role"] = "system"; systemMessage["content"] = "Answer the user's question concisely and informatively."; JsonObject userMessage = messages.createNestedObject(); userMessage["role"] = "user"; userMessage["content"] = question; String requestBody; serializeJson(jsonDoc, requestBody); Serial.println("Sending HTTP POST request..."); int httpResponseCode = http.POST(requestBody); Serial.print("HTTP Response code: "); Serial.println(httpResponseCode); String response = http.getString(); Serial.print("HTTP Response: "); Serial.println(response); StaticJsonDocument<1024> responseDoc; DeserializationError error = deserializeJson(responseDoc, response); if (!error) { String assistantResponse = responseDoc["choices"][0]["message"]["content"].as(); Serial.print("Assistant Response: "); Serial.println(assistantResponse); // Print the assistant response Serial1.println(assistantResponse); return response; // Return entire API response } else { return "Failed to parse JSON response."; } } return "WiFi not connected!"; } void setup() { // Start Serial Monitor Serial.begin(115200); Serial1.begin(9600, SERIAL_8N1, /*rx =*/17, /*tx =*/16); pinMode(led0, OUTPUT); pinMode(led1, OUTPUT); // Connect to Wi-Fi WiFi.begin(ssid, password); Serial.print("Connecting to WiFi..."); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.print("."); } Serial.println(" Connected to WiFi"); // Print ESP32 Local IP Address Serial.print("ESP32 IP Address: "); Serial.println(WiFi.localIP()); // Serve HTML content server.on("/", HTTP_GET, []() { server.send_P(200, "text/html", index_html); }); // Handle POST request from the web page server.on("/getQuestion", HTTP_POST, []() { if (server.hasArg("plain")) { String body = server.arg("plain");
Wio 終端代碼 :
將以下代碼上傳到 Wio 終端,從 Beetle 獲取數(shù)據(jù)并在屏幕上打印出來(lái)。
#include
#include// Include the graphics library (this includes the sprite functions)
// Create a SoftwareSerial object on pins 2 (RX) and 3 (TX)
SoftwareSerial mySerial(2, 3); // RX, TX
// Initialize the TFT screen
TFT_eSPI tft = TFT_eSPI(); // Create object "tft"
// Screen dimensions
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
void setup() {
Serial.begin(115200);
mySerial.begin(9600);
// Initialize the TFT screen
tft.begin();
tft.setRotation(3); // Set the screen orientation (1 for landscape mode)
tft.fillScreen(TFT_BLACK); // Clear the screen with black color
tft.setTextColor(TFT_WHITE); // Set text color to white
tft.setTextSize(2); // Set text size
// Print initial message to the screen
tft.drawString("Waiting for data...", 10, 10);
}
void loop() {
while (mySerial.available()) {
String str = mySerial.readString(); // Read the incoming data as a string
str.trim();
Serial.println(str);
// Clear the screen and display the new data with text wrapping
tft.fillScreen(TFT_BLACK); // Clear the screen with black color
printWrappedText(str, 10, 10, SCREEN_WIDTH - 20, 2);
mySerial.println("initialization done.");
}
}
// Function to print wrapped text on the screen
void printWrappedText(String str, int x, int y, int lineWidth, int textSize) {
tft.setCursor(x, y);
tft.setTextSize(textSize);
int cursorX = x;
int cursorY = y;
int spaceWidth = tft.textWidth(" ");
int maxLineWidth = lineWidth;
String word;
for (int i = 0; i < str.length(); i++) {
if (str[i] == ' ' || str[i] == '
') {
int wordWidth = tft.textWidth(word);
if (cursorX + wordWidth > maxLineWidth) {
cursorX = x;
cursorY += tft.fontHeight();
}
tft.drawString(word, cursorX, cursorY);
cursorX += wordWidth + spaceWidth;
if (str[i] == '
') {
cursorX = x;
cursorY += tft.fontHeight();
}
word = "";
} else {
word += str[i];
}
}
if (word.length() > 0) {
int wordWidth = tft.textWidth(word);
if (cursorX + wordWidth > maxLineWidth) {
cursorX = x;
cursorY += tft.fontHeight();
}
tft.drawString(word, cursorX, cursory);
}
}
串行終端響應(yīng):

然后在 Web 瀏覽器中打開(kāi) IP 地址。

接下來(lái),輸入提示符。

您可以在 Wio 終端屏幕中看到響應(yīng)。

如果您想查看整個(gè) API 響應(yīng),只需按網(wǎng)站上的 Debug log 按鈕即可。這將顯示完整的 API 響應(yīng)以進(jìn)行調(diào)試。

結(jié)論
通過(guò)此項(xiàng)目,您已經(jīng)使用 Beetle ESP32 和 Wio Terminal 創(chuàng)建了一個(gè)基本的聊天機(jī)器人??梢酝ㄟ^(guò)添加更多功能(例如更多交互式網(wǎng)頁(yè)、高級(jí)錯(cuò)誤處理或集成其他 API)來(lái)進(jìn)一步擴(kuò)展此設(shè)置。DFRobot Beetle ESP32 C6 的緊湊尺寸和多功能功能,結(jié)合強(qiáng)大的 Wio 終端,使其成為各種物聯(lián)網(wǎng)應(yīng)用的絕佳選擇。
-
移動(dòng)終端
+關(guān)注
關(guān)注
1文章
216瀏覽量
25549 -
ESP32
+關(guān)注
關(guān)注
21文章
1049瀏覽量
20534 -
DeepSeek
+關(guān)注
關(guān)注
2文章
821瀏覽量
2679
原文標(biāo)題:創(chuàng)客項(xiàng)目秀|基于ESP32和Wio Terminal的DeepSeeek終端
文章出處:【微信號(hào):ChaiHuoMakerSpace,微信公眾號(hào):柴火創(chuàng)客空間】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
《電子發(fā)燒友電子設(shè)計(jì)周報(bào)》聚焦硬科技領(lǐng)域核心價(jià)值 第2期:2025.03.3--2025.03.7
WIO Terminal +MCP2515 實(shí)現(xiàn)車(chē)輛OBD的速度監(jiān)控
esp32 例程 藍(lán)牙_wifi&藍(lán)牙MCU 該不該選ESP32
ESP32/STM32電源系統(tǒng)開(kāi)源項(xiàng)目
ESP32低成本板開(kāi)源項(xiàng)目
ESP32開(kāi)源項(xiàng)目分享
使用ESP32制作ESP RainMaker IoT項(xiàng)目
使用Wio終端擴(kuò)展Arduboy
ESP32 UWB室內(nèi)定位測(cè)試開(kāi)源項(xiàng)目
使用Wio Terminal和Tensorflow Lite創(chuàng)建智能氣象站
基于ESP32的開(kāi)源項(xiàng)目
Seeed Wio終端開(kāi)源分享
ESP32開(kāi)源項(xiàng)目

基于ESP32和Wio Terminal的DeepSeeek移動(dòng)終端項(xiàng)目
評(píng)論