使用元件
- TT馬達+65mm 車輪 X 4
- L298N 直流馬達驅動板
- ESP8266 mini X 2
- Arduino pro mini X 1
- 搖桿
微控制器小車:使用ESP8266控制小車移動與速度,WiFi設定成SoftAP模式,開起WebServer接受搖桿端送來的移動參數。
搖控端使用一顆ESP8266設成Station模式,發送搖桿參數給受控小車。
LED指示燈亮時表示WiFi連線為異常狀態,系統會嘗試重連,當WiFi Ready時LED熄滅。
因ESP8266只有1個analog port。因此再使用一顆Arduino pro mini A0與A1 port讀取搖桿參數。ESP8266與Arduino間以I2C通訊。
實驗結果只有ESP8266設成master, Arduino設成slaver才能成功。反之則失敗。
線路圖
完成影片:
程式碼
1.ESP8266微控制器小車
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
int speed = 512;
const char* ssid = "esp8266car";
const char* pwd = "your-password";
ESP8266WebServer server(8080);
const int PIN1A=D2;
const int PIN1B=D1;
const int PIN2A=D5;
const int PIN2B=D6;
void handleRoot() {
String action = "";
int x=500, y=500;
int mspeed=0, tspeed=0;
int direct=0;
int turn=0;
int a1=0, a2=0, b1=0, b2=0;
for (uint8_t i = 0; i < server.args(); i++) {
if (server.argName(i) == "x") x=server.arg(i).toInt();
if (server.argName(i) == "y") y=server.arg(i).toInt();
}
if (x < 400) {
turn=1;
tspeed = 1024-x;
} else {
if (x > 600) {
turn=-1;
tspeed = x;
} else {
turn=0;
tspeed = 0;
}
}
if (y < 400) {
direct=1;
mspeed = 1024-y;
} else {
if (y > 600) {
direct=-1;
mspeed = y;
} else {
direct=0;
mspeed = 0;
}
}
if (direct != 0 && turn == 0) {
if (direct > 0) {
a1 = mspeed;
a2 = mspeed;
}
if (direct < 0) {
b1 = mspeed;
b2 = mspeed;
}
}
if (direct == 0 && turn != 0) {
if (turn > 0) a2 = tspeed;
if (turn < 0) a1 = tspeed;
}
if (direct != 0 && turn != 0) {
if (direct > 0){
a1 = mspeed;
a2 = mspeed;
if (turn > 0) a1 = 1024-tspeed;
if (turn < 0) a2 = 1024-tspeed;
}
if (direct < 0) {
b1 = mspeed;
b2 = mspeed;
if (turn > 0) b1 = 1024-tspeed;
if (turn < 0) b2 = 1024-tspeed;
}
}
analogWrite(PIN1A, a1);
analogWrite(PIN1B, b1);
analogWrite(PIN2A, a2);
analogWrite(PIN2B, b2);
server.send(200, "text/html", "");
}
void setup() {
// put your setup code here, to run once:
delay(1000);
WiFi.mode(WIFI_AP_STA);
WiFi.softAP(ssid, pwd);
server.on("/move", handleRoot);
server.begin();
Serial.begin(115200);
Serial.println(WiFi.softAPIP());
pinMode(PIN1A, OUTPUT);
pinMode(PIN1B, OUTPUT);
pinMode(PIN2A, OUTPUT);
pinMode(PIN2B, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
server.handleClient();
}
2.ESP8266 搖桿WiFi發射
#include <Wire.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#define pinSDA D1
#define pinSCL D2
#define pinIndicator D3
String motion;
char ich;
bool isNewMotion;
int tx, ty;
String sx, sy;
const char* ssid = "esp8266car";
const char* password = "your-password";
char url[100];
WiFiClient client;
void carMotion(int x, int y) {
HTTPClient http;
sprintf(url, "http://192.168.4.1:8080/move?x=%d&y=%d",x,y);
http.begin(client, url);
int httpCode = http.GET();
// httpCode will be negative on error
if (httpCode > 0) {
digitalWrite(pinIndicator,LOW);
// file found at server
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = http.getString();
Serial.println(payload);
}
} else {
// send error
digitalWrite(pinIndicator,HIGH);
}
http.end();
}
void setup() {
pinMode(pinIndicator, OUTPUT);
Wire.begin(pinSDA, pinSCL); /* join i2c bus with SDA=D1 and SCL=D2 of NodeMCU */
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
// LED light
digitalWrite(pinIndicator,HIGH);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
// LED off : connect OK
digitalWrite(pinIndicator,LOW);
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
Wire.requestFrom(8, 14); /* request & read data of size 14 from slave */
motion = "";
isNewMotion=false;
while(Wire.available()){
char c = Wire.read();
motion += c;
isNewMotion=true;
}
if (isNewMotion) {
//Serial.println(motion);
tx = motion.indexOf(",");
ty = motion.indexOf("E",tx);
sx=motion.substring(0,tx);
sy=motion.substring(tx+1,ty);
tx=sx.substring(sx.indexOf("=")+1).toInt();
ty =sy.substring(sy.indexOf("=")+1).toInt();
carMotion(tx,ty);
}
}
3.Arduino pro mini讀取搖桿
#include <Wire.h>
char buf[20];
String recv;
void setup() {
Wire.begin(8); /* join i2c bus with address 8 */
Wire.onReceive(receiveEvent); /* register receive event */
Wire.onRequest(requestEvent); /* register request event */
}
void loop() {
delay(100);
}
// function that executes whenever data is received from master
void receiveEvent(int howMany) {
recv = "";
while (0 <Wire.available()) {
char c = Wire.read(); /* receive byte as a character */
recv +=c; /* print the character */
}
}
// function that executes whenever data is requested from master
void requestEvent() {
sprintf(buf, "x=%d,y=%dE", analogRead(A0), analogRead(A1));
Wire.write(buf);
delay(10);
}







