prettyprint

2020年5月17日 星期日

遙控微控制器小車篇(三) Joystick 遙控

本實驗使用ESP8266與Arduino pro mini微控制器,透過WiFi遙控小車。

使用元件
  1. TT馬達+65mm 車輪 X 4
  2.  L298N 直流馬達驅動板
  3. ESP8266 mini X 2
  4. Arduino pro mini X 1
  5. 搖桿
微控制器小車:使用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);

 
}

沒有留言:

張貼留言