需求
通過Wi-Fi控制Arduino驅動的3V直流電機。這個方案使用外部6V或9V電源,ESP8266作為Wi-Fi模塊,Arduino作為主控制器,L298N作為電機驅動器。
手機/電腦 (Wi-Fi客戶端)
|
| (Wi-Fi)
|
ESP8266 (Wi-Fi模塊, AT指令模式)
|
| (串口通信)
|
Arduino Uno (主控制器)
|
| (數字引腳控制)
|
L298N (電機驅動模塊)
|
| (電力輸出)
|
3V直流電機
所需材料
- Arduino Uno
- ESP8266模塊 (如ESP-01)
- L298N電機驅動模塊
- 3V直流電機
- 外部電源:
- 6V或9V電池/電源適配器 (用于L298N電機驅動)
- 3.3V穩壓模塊 (如AMS1117-3.3V,用于ESP8266)
- 面包板和跳線
- 10kΩ電阻 (2個,用于ESP8266的GPIO0和RST引腳上拉)
連接步驟
1. 電源連接
組件 | 連接方式 |
---|---|
外部6V/9V電源 | 正極 → L298N的VM引腳 負極 → L298N的GND和Arduino的GND |
Arduino 5V | → L298N的VCC引腳 (邏輯供電) |
AMS1117-3.3V模塊 | 輸入 → 外部電源正極 (通過適當電阻分壓或使用Arduino 5V) 輸出 → ESP8266的VCC引腳 GND → 共同GND |
2. ESP8266與Arduino連接
ESP8266引腳 | 連接至Arduino引腳 | 備注 |
---|---|---|
VCC | AMS1117-3.3V輸出 | 必須使用外部3.3V供電 |
GND | Arduino GND | 共同接地 |
TX | 引腳10 (軟件串口RX) | ESP發送,Arduino接收 |
RX | 引腳11 (軟件串口TX) | Arduino發送,ESP接收 |
CH_PD (EN) | 通過10k電阻接3.3V | 使能引腳,接高電平 |
GPIO0 | 懸空 | 懸空為正常工作模式 |
RST | 通過10k電阻接3.3V | 復位引腳,上拉 |
3. L298N與Arduino連接
L298N引腳 | 連接至Arduino引腳 | 備注 |
---|---|---|
IN1 | 引腳5 | 控制電機方向 |
IN2 | 引腳6 | 控制電機方向 |
ENA | 引腳9 (PWM) | 控制電機速度 |
OUT1, OUT2 | 3V直流電機兩端 | 電機連接 |
4. L298N電源連接
L298N引腳 | 連接方式 |
---|---|
VM | 外部6V/9V電源正極 |
GND | 外部電源負極和Arduino GND |
VCC | Arduino 5V引腳 |
Arduino代碼
#include <SoftwareSerial.h>// 定義軟件串口引腳 (RX, TX)
SoftwareSerial esp8266(10, 11); // Arduino RX, Arduino TX// L298N控制引腳
const int IN1 = 5;
const int IN2 = 6;
const int ENA = 9;// Wi-Fi設置
const char* SSID = "Your_WiFi_SSID"; // 替換為您的Wi-Fi名稱
const char* PASSWORD = "Your_WiFi_Password"; // 替換為您的Wi-Fi密碼// 電機速度設置 (根據電源電壓調整)
// 對于3V電機,使用6V電源時PWM值約為128,使用9V電源時PWM值約為85
const int MOTOR_SPEED = 128; // 0-255范圍內調整// 全局變量
String wifiCommand = "";
bool isConnected = false;void setup() {// 初始化串口Serial.begin(115200);esp8266.begin(115200);// 設置L298N控制引腳pinMode(IN1, OUTPUT);pinMode(IN2, OUTPUT);pinMode(ENA, OUTPUT);// 初始狀態:電機停止digitalWrite(IN1, LOW);digitalWrite(IN2, LOW);analogWrite(ENA, 0);delay(2000); // 等待系統穩定Serial.println("Initializing ESP8266...");// 初始化ESP8266setupESP8266();
}void loop() {// 檢查ESP8266是否有數據可用if (esp8266.available()) {char c = esp8266.read();Serial.write(c); // 將數據轉發到串口監視器// 構建完整的命令字符串if (c == '\n') {processCommand(wifiCommand);wifiCommand = ""; // 清空命令字符串} else {wifiCommand += c;}}// 檢查串口監視器是否有輸入(用于調試)if (Serial.available()) {String command = Serial.readStringUntil('\n');processCommand(command);}
}void setupESP8266() {// 發送AT指令設置ESP8266sendATCommand("AT", "OK", 2000);sendATCommand("AT+CWMODE=1", "OK", 2000); // 設置為STA模式sendATCommand("AT+CIPMUX=1", "OK", 2000); // 允許多連接// 連接到Wi-FiString connectCmd = "AT+CWJAP=\"";connectCmd += SSID;connectCmd += "\",\"";connectCmd += PASSWORD;connectCmd += "\"";if (sendATCommand(connectCmd, "GOT IP", 10000)) {Serial.println("Wi-Fi connected!");isConnected = true;// 獲取IP地址sendATCommand("AT+CIFSR", "OK", 2000);// 啟動TCP服務器 on port 8888if (sendATCommand("AT+CIPSERVER=1,8888", "OK", 2000)) {Serial.println("TCP server started on port 8888");Serial.println("Ready to receive commands...");}} else {Serial.println("Failed to connect to Wi-Fi");}
}bool sendATCommand(String command, String expectedResponse, int timeout) {esp8266.println(command);Serial.println("Sent: " + command);long int startTime = millis();String response = "";while (millis() - startTime < timeout) {while (esp8266.available()) {char c = esp8266.read();response += c;}if (response.indexOf(expectedResponse) != -1) {Serial.println("Response: " + response);return true;}}Serial.println("Timeout. Response: " + response);return false;
}void processCommand(String command) {command.trim(); // 移除首尾空白字符if (command.length() == 0) return;Serial.println("Processing command: " + command);// 處理電機控制命令if (command == "F") {// 正轉digitalWrite(IN1, HIGH);digitalWrite(IN2, LOW);analogWrite(ENA, MOTOR_SPEED);Serial.println("Motor: FORWARD");} else if (command == "B") {// 反轉digitalWrite(IN1, LOW);digitalWrite(IN2, HIGH);analogWrite(ENA, MOTOR_SPEED);Serial.println("Motor: BACKWARD");} else if (command == "S") {// 停止digitalWrite(IN1, LOW);digitalWrite(IN2, LOW);analogWrite(ENA, 0);Serial.println("Motor: STOP");}else if (command == "STATUS") {// 返回狀態信息String status = "Wi-Fi: ";status += (isConnected ? "Connected" : "Disconnected");status += ", Motor: ";if (digitalRead(IN1) == HIGH && digitalRead(IN2) == LOW) {status += "FORWARD";} else if (digitalRead(IN1) == LOW && digitalRead(IN2) == HIGH) {status += "BACKWARD";} else {status += "STOPPED";}Serial.println(status);if (isConnected) {esp8266.println("AT+CIPSEND=0," + String(status.length()));delay(100);esp8266.println(status);}}else {Serial.println("Unknown command: " + command);}
}
使用步驟
-
硬件連接:按照上述連接圖正確連接所有組件
-
代碼修改:
- 將代碼中的
Your_WiFi_SSID
和Your_WiFi_Password
替換為您的實際Wi-Fi信息 - 根據您的電源電壓調整
MOTOR_SPEED
值:- 6V電源:約128 (50%占空比)
- 9V電源:約85 (33%占空比)
- 將代碼中的
-
上傳代碼:
- 將代碼上傳到Arduino Uno
- 上傳時確保斷開ESP8266的RX/TX連接,上傳完成后再接回
-
測試:
- 打開串口監視器(115200波特率)
- 觀察ESP8266初始化過程,記錄顯示的IP地址
- 使用網絡調試工具(如TCP客戶端)連接到該IP地址的8888端口
- 發送以下命令控制電機:
F
- 正轉B
- 反轉S
- 停止STATUS
- 獲取當前狀態
安全注意事項
- 電源隔離:確保電機電源與邏輯電源適當隔離,避免電流回灌
- 散熱:L298N在驅動電機時可能會發熱,確保有適當的散熱措施
- 電壓匹配:使用PWM控制電機速度,確保平均電壓不超過3V以保護電機
- 電流保護:考慮在電機回路中添加保險絲或電流傳感器,防止過流損壞
這個方案提供了一個完整的Wi-Fi控制電機系統,您可以通過手機或電腦遠程控制電機的轉動方向和速度。
esp8266啟動http服務
```cpp
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>// WiFi 配置
const char* ssid = "你的WiFi名稱";
const char* password = "你的WiFi密碼";// 創建 HTTP 服務器,監聽端口 80
ESP8266WebServer server(80);// 根路徑處理函數
void handleRoot() {// 返回 HTML 響應server.send(200, "text/html", "<h1>ESP8266 HTTP 服務器</h1><p>歡迎訪問 ESP8266 搭建的網頁!</p>");
}// 自定義路徑處理函數(例如 /data)
void handleData() {// 返回 JSON 數據String json = "{\"status\":\"ok\", \"message\":\"這是來自 ESP8266 的數據\"}";server.send(200, "application/json", json);
}// 404 頁面處理函數
void handleNotFound() {server.send(404, "text/plain", "頁面未找到");
}void setup() {Serial.begin(115200);// 連接 WiFiWiFi.begin(ssid, password);Serial.print("連接 WiFi...");while (WiFi.status() != WL_CONNECTED) {delay(500);Serial.print(".");}Serial.println("");Serial.println("WiFi 連接成功");Serial.println("IP 地址: " + WiFi.localIP().toString());// 注冊路徑處理函數server.on("/", handleRoot); // 根路徑server.on("/data", handleData); // 自定義數據路徑server.onNotFound(handleNotFound); // 未匹配路徑// 啟動 HTTP 服務器server.begin();Serial.println("HTTP 服務器已啟動");
}void loop() {// 處理客戶端請求(必須在 loop 中調用)server.handleClient();
}