NodeMcu上的ESP8266本身有SoftAP的功能,可以拿來當成Wifi基地台來用(本文沒用到網際網路),所以我們來製作一個可以透過手機上的Wifi來控制小車吧。
硬體材料:
1. NodeMcu 板子 x 1
2. Micro USB 連接線 x 1
3. 5V 直流馬達 x 2
4. 公對公杜邦線 x 4
5. 母對母杜邦線 x 6
6. L9110S 馬達驅動板 x 1
7. 小車底盤 x 1
8. 小車輪子 x 2
9. 萬向輪 x 1
10. 緊固件 x 4
11. 長螺絲 x 4
12. 短螺絲 (長8根、短2根)
13. 螺帽 x 10
14. 行動電源 x 1
硬體電路:
上圖電路是以L298N來表示L9110S。
接線對應腳位:
L9110S馬達驅動板
- B-1A 接 NodeMcu D2
- B-1B 接 NodeMcu D1
- A-1A 接 NodeMcu D4
- A-1B 接 NodeMcu D3
- VCC 接 NodeMcu 3.3V
- GND 接 NodeMcu GND
完成圖:
Arduino IDE 程式:
先安裝Websocket程式庫,筆者是用 Markus Sattler 的版本
筆者是修改此程式庫的範例:WebSocketServer_LEDcontrol
程式碼:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* WifiCar.ino | |
* | |
*/ | |
#include <Arduino.h> | |
#include <ESP8266WiFi.h> | |
#include <ESP8266WiFiMulti.h> | |
#include <WebSocketsServer.h> | |
#include <ESP8266WebServer.h> | |
#include <ESP8266mDNS.h> | |
#include <Hash.h> | |
#define MOTORA_E D1 // Motor A Forward pin | |
#define MOTORA_P D2 // Motor A PWM | |
#define MOTORB_E D3 // Motor B Forward pin | |
#define MOTORB_P D4 // Motor B PWM | |
#define USE_SERIAL Serial | |
void stopIt() { | |
delay(500); | |
digitalWrite(MOTORA_E, LOW); | |
digitalWrite(MOTORA_P, LOW); | |
digitalWrite(MOTORB_E, LOW); | |
digitalWrite(MOTORB_P, LOW); | |
} | |
ESP8266WiFiMulti WiFiMulti; | |
ESP8266WebServer server = ESP8266WebServer(80); | |
WebSocketsServer webSocket = WebSocketsServer(81); | |
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) { | |
switch(type) { | |
case WStype_DISCONNECTED: | |
USE_SERIAL.printf("[%u] Disconnected!\n", num); | |
break; | |
case WStype_CONNECTED: { | |
IPAddress ip = webSocket.remoteIP(num); | |
USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); | |
// send message to client | |
webSocket.sendTXT(num, "Connected"); | |
} | |
break; | |
case WStype_TEXT: | |
USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); | |
if(payload[0] == 'f') { | |
digitalWrite(MOTORA_E, LOW); | |
digitalWrite(MOTORA_P, HIGH); | |
digitalWrite(MOTORB_E, LOW); | |
digitalWrite(MOTORB_P, HIGH); | |
stopIt(); | |
} | |
if(payload[0] == 'b') { | |
digitalWrite(MOTORA_E, HIGH); | |
digitalWrite(MOTORA_P, LOW); | |
digitalWrite(MOTORB_E, HIGH); | |
digitalWrite(MOTORB_P, LOW); | |
stopIt(); | |
} | |
if(payload[0] == 'l') { | |
digitalWrite(MOTORA_E, LOW); | |
digitalWrite(MOTORA_P, LOW); | |
digitalWrite(MOTORB_E, LOW); | |
digitalWrite(MOTORB_P, HIGH); | |
stopIt(); | |
} | |
if(payload[0] == 'r') { | |
digitalWrite(MOTORA_E, LOW); | |
digitalWrite(MOTORA_P, HIGH); | |
digitalWrite(MOTORB_E, LOW); | |
digitalWrite(MOTORB_P, LOW); | |
stopIt(); | |
} | |
break; | |
} | |
} | |
void setup() { | |
USE_SERIAL.begin(115200); | |
USE_SERIAL.println(); | |
USE_SERIAL.println(); | |
USE_SERIAL.println(); | |
pinMode(MOTORA_E, OUTPUT); | |
pinMode(MOTORA_P, OUTPUT); | |
pinMode(MOTORB_E, OUTPUT); | |
pinMode(MOTORB_P, OUTPUT); | |
stopIt(); | |
for(uint8_t t = 4; t > 0; t--) { | |
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); | |
USE_SERIAL.flush(); | |
delay(1000); | |
} | |
WiFi.softAP("holan", "12345678"); | |
IPAddress myIP = WiFi.softAPIP(); | |
USE_SERIAL.print("AP IP address: "); | |
USE_SERIAL.println(myIP); | |
// start webSocket server | |
webSocket.begin(); | |
webSocket.onEvent(webSocketEvent); | |
if(MDNS.begin("esp8266")) { | |
USE_SERIAL.println("MDNS responder started"); | |
} | |
// handle index | |
server.on("/", []() { | |
// send index.html | |
server.send(200, "text/html", | |
"<html><head><script>" | |
"var connection = new WebSocket('ws://'+location.hostname+':81/', ['arduino']);" | |
"connection.onopen = function(){connection.send('Connect ' + new Date());};" | |
"connection.onerror = function(error){console.log('WebSocket Error ', error);};" | |
"connection.onmessage = function(e){console.log('Server: ', e.data);};" | |
"function forward(){connection.send('f');}" | |
"function backward(){connection.send('b');}" | |
"function right(){connection.send('r');}" | |
"function left(){connection.send('l');}" | |
"</script></head><body>" | |
"<b>Wifi Car</b><br/><br/>" | |
"<button type=\"button\" onclick=\"forward()\">Forward</button>" | |
"<button type=\"button\" onclick=\"backward()\">Backward</button>" | |
"<button type=\"button\" onclick=\"right()\">Right</button>" | |
"<button type=\"button\" onclick=\"left()\">Left</button>" | |
"<br/></body></html>"); | |
}); | |
server.begin(); | |
// Add service to MDNS | |
MDNS.addService("http", "tcp", 80); | |
MDNS.addService("ws", "tcp", 81); | |
} | |
void loop() { | |
webSocket.loop(); | |
server.handleClient(); | |
} |
延伸的應用:
製作球形機器人,可參考以Arduino 打造球形機器人一文。
2 則留言:
想問開發版是要調整到哪個版本??
是NodeMCU 1.0(ESP-12E Module)嗎??
這篇文章是用 ESP8266 NodeMCU Lua v2 ,其他版本應該也可以使用。
張貼留言