Top

本文章為舊版Blogger內容轉移,目前暫停維護

使用 Arduino D1 製作 Wifi 自走車(上)

(搭配 AppInventor 2, IpCam)

一.摘要

  本專案將透過Arduino D1開發板作為核心來製作Wifi自走車。Arduino D1為一款擁有WiFi功能的Arduino開發版,相較於Arduino Yun更是便宜了不少,因此成為多數基礎物連開發的首選。然而Arduino D1 並不是沒有缺點,他的最大缺點「類比輸入只有一個腳位」導致許多感應器不能同時連到Arduino D1,不過對本文來說影響並不大,因此還是選擇了Arduino D1。

二.材料

材料名稱數量大約價格
Arduino D1 開發板1片180
自走車車體、減速馬達、車輪1組250
L9110直流馬達驅動板1片30
3.7V鋰電池2顆170
鋰電池電池座1個20
電源供應板1片50
16*2LCD ( 搭配I2C)1組100
HC-SR04 超音波感應模組1片25
超音波感應模組托架1個40
杜邦線數條50
M3銅柱、M3螺絲螺帽數個50
具有wifi功能之手機2台
App inventor 2
Arduino IDE

三.D1腳位及運作架構圖

  • Arduino D1

  • 配線圖

  • 流程圖

四.組裝車體

  車體組裝方式一各人有所不同,只要能運作即可,在此提供敝人的組裝方式:

  1. 馬達與輪子的部分就直接跳過吧,相信各位不用3分鐘就能組裝完成
  2. 底板下方的部分除了輪子外,L9110S馬達控制板也在此,並平行於馬達安裝,有6條杜邦線透過中間的圓孔穿透到底板上方連接Arduino D1及電源供應板。

     

  3. 底板上方的部分即是Arduino D1、電源供應板、以及被拖架拖著的HC-SR04 超音波感應模組,電源供應板將電池的7.4~8.4V降為5V供D1使用,另外,馬達控制板(L9110S)使用的是未經變壓過的電源驅動馬達。(詳細腳位接法請見3.D1腳位及運作架構圖)

     

  4. 頂板為LCD、電池和一部手機,並使用銅柱固定

     

五.車體Arduino程式碼

  關於Arduino IDE的設定可以參考佑來了的教學影片Arduino教學- WiFi無線入門。開發板須設定為WeMos D1(Retired)本專案以範例檔WifiWebServer的架構改寫(如有註解不當或缺失歡迎留言補充)

宣告部分

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
/*函式庫宣告*/ #include <ESP8266WiFi.h> #include <LiquidCrystal_I2C.h> #include <Wire.h> /*常數宣告*/ const char* ssid = "WIFIARD"; //Wifi SSID const char* password = "12345678"; //Wifi PassWord const double usPcm = 29.4; //microSecond Per cm. const float minDistance=10.00; //距離下限(若低於距離下限則馬達不得前進) /*變數宣告*/ String req = ""; //儲存接收到之字串 String stat =""; //車子狀態 //(B=測距模組失效,W=行進中,N=正常待命,D=距離前方障礙物過近) int Speed_L = 0 ; //左馬達速度 int Speed_R = 0 ; //右馬達速度 float distance; //hc-sr04 距離 /*腳位宣告*/ #define hc_trig D10 #define hc_echo D11 #define motor_L_A D0 #define motor_L_B D1 #define motor_R_A D2 #define motor_R_B D5 #define lcd_SDA D14 #define lcd_SCL D15 /*其他宣告*/ WiFiServer server(80); //伺服器port宣告 LiquidCrystal_I2C lcd(0x27, 16, 2); //LCD宣告

函式宣告

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
String get_process_Message(WiFiClient client){ //接收並處理資料 req = client.readStringUntil('\r'); /* * req=> GET /資料 HTTP/1.1 * replace(A, B) A換為B */ req.replace("GET /", "");//去頭 req.replace("HTTP/1.1", "");//去尾 client.flush(); Speed_L =req.substring(0,1).toInt()-5; Speed_R =req.substring(1,2).toInt()-5; } void dataToHtml(WiFiClient client){ //資訊製網 String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n< !DOCTYPE HTML > < html >,"; s += String(String(Speed_L) + "," + String(Speed_R) + "," + String(distance) + "," + String(stat) + ",< /html >"); client.print(s); } void printLcd(LiquidCrystal_I2C lcd, int R, int C, String text){ //LCD輸出 lcd.setCursor(R, C); lcd.print(text); } float Ranging(){ //測距 float duration; float distance; digitalWrite(hc_trig, HIGH); delayMicroseconds(200); digitalWrite(hc_trig, LOW); duration = pulseIn (hc_echo, HIGH); distance = duration/2/usPcm; return(distance-1); } void set_Motor(int Speed_L, int Speed_R){ //設定馬達速度 if(Speed_L>0){//設定左輪 analogWrite(motor_L_A,map(Speed_L,0,4,300,800)); analogWrite(motor_L_B,0); }else if(Speed_L<0){ analogWrite(motor_L_A,0); analogWrite(motor_L_B,map(Speed_L,0,-4,300,800)); }else{//(Speed_L==0) analogWrite(motor_L_A,0); analogWrite(motor_L_B,0); } if(Speed_R>0){//設定右輪 analogWrite(motor_R_A,map(Speed_R,0,4,300,800)); analogWrite(motor_R_B,0); }else if(Speed_R<0){ analogWrite(motor_R_A,0); analogWrite(motor_R_B,map(Speed_R,0,-4,300,800)); }else{//(Speed_R==0) analogWrite(motor_R_A,0); analogWrite(motor_R_B,0); } }

初始化部分

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
void setup() { pinMode (hc_trig , OUTPUT); pinMode (hc_echo , INPUT ); pinMode (motor_L_A, OUTPUT); pinMode (motor_L_B, OUTPUT); pinMode (motor_R_A, OUTPUT); pinMode (motor_R_B, OUTPUT); Wire.begin(lcd_SDA, lcd_SCL); lcd.begin(); printLcd(lcd, 0, 0, "WELCOME"); delay(1000); lcd.clear(); printLcd(lcd, 0, 0, "Connect to WIfi"); printLcd(lcd, 0, 1, "SSID:"); printLcd(lcd, 5, 1, ssid); WiFi.begin(ssid, password);//連線至指定wifi while (WiFi.status() != WL_CONNECTED) { //連線中 delay(500); } server.begin(); //啟用伺服器 lcd.clear(); printLcd(lcd, 0, 0, "WiFi connected!"); printLcd(lcd, 0, 1, WiFi.localIP().toString()); delay(1000); }

迴圈部分

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
void loop() { if (WiFi.status() != WL_CONNECTED) { //檢查連線 lcd.clear(); printLcd(lcd, 0, 0, "Lose connected!"); delay(2000); return; } WiFiClient client = server.available(); if (!client) { //未接收訊息要做的事 distance =Ranging(); if(distance == -1.00){ stat="B"; }else if(distance < minDistance){ //若車子距離前方障礙物過近則馬達不得前進 if(Speed_L>0){ Speed_L=0; } if(Speed_R>0){ Speed_R=0; } stat="D"; }else if(Speed_L!=0 | Speed_R!=0){ stat="W"; }else{ stat="N"; } set_Motor(Speed_L, Speed_R); lcd.clear(); printLcd(lcd, 0, 0, String(distance)); printLcd(lcd, 10, 0, String(Speed_L)); printLcd(lcd, 13, 0, String(Speed_R)); dataToHtml(client); delay(100); return; } while(!client.available()){ delay(1); } //接收到資料要做的事 get_process_Message(client); distance =Ranging(); if(distance == -1.00){ stat="B"; }else if(distance < minDistance){ //若車子距離前方障礙物過近則馬達不得前進 if(Speed_L>0){ Speed_L=0; } if(Speed_R>0){ Speed_R=0; } stat="D"; }else if(Speed_L!=0 | Speed_R!=0){ stat="W"; }else{ stat="N"; } set_Motor(Speed_L, Speed_R); lcd.clear(); printLcd(lcd, 0, 0, String(distance)); printLcd(lcd, 10, 0, String(Speed_L)); printLcd(lcd, 13, 0, String(Speed_R)); dataToHtml(client); delay(10); }

以下三部分請見 使用 Arduino D1 製作 Wifi 自走車(下)

  • 六.即時影像傳輸
  • 七.手機控制端App介面
  • 八.手機控制端程式碼

感謝您閱讀本文章

4 則留言 :

  1. 請問車體的板子和電源供應器在哪買的

    回覆刪除
    回覆
    1. 板子的型號是qyf-dy02,露天蝦皮都能買的到
      不過比較特別的是這個板子只能做小電流的供電,因此僅適合做邏輯供電,馬達的部分我並沒有做降壓而是直接接電池的電壓(板子上有直通VCC/GND的腳位)

      刪除
  2. 嗨我又來了
    請問電池盒和電源供應板接線是怎麼接的?
    能否麻煩您提供照片?
    我將電池正負黏在一起插入DC-IN結果短路
    不好意思我一直搞不清楚

    回覆刪除
    回覆
    1. 圖片請參考:https://drive.google.com/open?id=1-685aKGXaA455DZr6XzzctsPj3RjT8Wz
      如果是使用"5.5mm接頭"輸入電源要注意:中間是正極外圍是負極(如果不確定的話直接把負極用杜邦線接GND正極接qyf-dy02上的直通腳位(如附圖))
      以下是我的接線:所有GND都插GND,arduino板上或電源供應板的都可以
      電源供應板上的5V邏輯電壓分別給:LCD跟超音波模組
      電源直通的部分接給Arduino的"VCC"和L9110S的VCC

      刪除