Labels:
App Inventor
,
Arduino
,
Esp8266
於
4月 15, 2018
本文章為舊版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
- 配線圖
- 流程圖
四.組裝車體
車體組裝方式一各人有所不同,只要能運作即可,在此提供敝人的組裝方式:
- 馬達與輪子的部分就直接跳過吧,相信各位不用3分鐘就能組裝完成
- 底板下方的部分除了輪子外,L9110S馬達控制板也在此,並平行於馬達安裝,有6條杜邦線透過中間的圓孔穿透到底板上方連接Arduino D1及電源供應板。
- 底板上方的部分即是Arduino D1、電源供應板、以及被拖架拖著的HC-SR04 超音波感應模組,電源供應板將電池的7.4~8.4V降為5V供D1使用,另外,馬達控制板(L9110S)使用的是未經變壓過的電源驅動馬達。(詳細腳位接法請見3.D1腳位及運作架構圖)
- 頂板為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
61String 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
27void 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
65void 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介面
- 八.手機控制端程式碼
感謝您閱讀本文章
訂閱:
張貼留言
(
Atom
)
請問車體的板子和電源供應器在哪買的
回覆刪除板子的型號是qyf-dy02,露天蝦皮都能買的到
刪除不過比較特別的是這個板子只能做小電流的供電,因此僅適合做邏輯供電,馬達的部分我並沒有做降壓而是直接接電池的電壓(板子上有直通VCC/GND的腳位)
嗨我又來了
回覆刪除請問電池盒和電源供應板接線是怎麼接的?
能否麻煩您提供照片?
我將電池正負黏在一起插入DC-IN結果短路
不好意思我一直搞不清楚
圖片請參考:https://drive.google.com/open?id=1-685aKGXaA455DZr6XzzctsPj3RjT8Wz
刪除如果是使用"5.5mm接頭"輸入電源要注意:中間是正極外圍是負極(如果不確定的話直接把負極用杜邦線接GND正極接qyf-dy02上的直通腳位(如附圖))
以下是我的接線:所有GND都插GND,arduino板上或電源供應板的都可以
電源供應板上的5V邏輯電壓分別給:LCD跟超音波模組
電源直通的部分接給Arduino的"VCC"和L9110S的VCC