โปรเจครถบังคับ ขับเคลื่อน 2 ล้อ Arduino กับ แอพแอนดรอยด์ อุปกรณ์ที่ต้องใช้ก็คือ
1. 2WD Smart Car Robot Chassis Kits
2. Arduino UNO R3 - Made in italy
3. Motor Drive Module L298N
4. HC-05 Bluetooth Master Slave
5. สาย Jumper Female to Male ยาว 20cm.
6. สาย Jumper Male to Male ยาว 20cm.
7. รางถ่านแบบ 18650 ใส่ถ่าน 3 ก้อน
8. แบตเตอรี่ลิเธียม 18650 จำนวน 3 ก้อน
9. เสารองแผ่นพีซีบีโลหะแบบเหลี่ยม 6 mm 12 ชิ้น
เริ่มต้นด้วยการ ประกอบ Smart Robot Car Chassis Kit
1. 2WD Smart Car Robot Chassis Kits
2. Arduino UNO R3 - Made in italy
3. Motor Drive Module L298N
4. HC-05 Bluetooth Master Slave
5. สาย Jumper Female to Male ยาว 20cm.
6. สาย Jumper Male to Male ยาว 20cm.
7. รางถ่านแบบ 18650 ใส่ถ่าน 3 ก้อน
8. แบตเตอรี่ลิเธียม 18650 จำนวน 3 ก้อน
9. เสารองแผ่นพีซีบีโลหะแบบเหลี่ยม 6 mm 12 ชิ้น
เริ่มต้นด้วยการ ประกอบ Smart Robot Car Chassis Kit
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdXYINWxYM6qsCLDIgDqwBA93Pft3fHCEQFCDi6QoLKZJiE2UH66VQcsk7Af6nNPRMftv7SDEhFtjoGgguCkehT7wGLBYDlMhRW4Dn2xIFdVcFs4sTE-oPpO14w0XG8oDHD3_JjjKYL3jV/s640/L298N-motor-driver-connect-Arduino-R3.jpg)
เรียนรู้เพิ่มเติมตามลิงค์นี้ http://robotsiam.blogspot.com/2016/08/l298n-motor-driver-connect-arduino-r3.html
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXB5aMOEjq0TnfYrCLCnXAFAC19jpi3kufBaReTEpj-b5VeMneBYKvejEFBmlxONd2k6hVUI2AmS5LZqX98X7dlKdryqSSi0vewH2XstiRagfplm7Utc1sqdgg_0cRckE1C0TLY6AbvxaD/s640/Arduino-UNO-R3-hc-05.png)
เรียนรู้เพิ่มเติมตามลิงค์นี้ http://robotsiam.blogspot.com/2016/08/hc-05-bluetooth-module.html
จะได้รูปการต่อวงจรทั้งหมดดังนี้
เปิดโปรแกรม Arduino (IDE) เขียน โค้ด และ Upload ไปยังบอร์ด Arduino UNO ดังนี้
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(9, 10);
int dir1PinA = 2;
int dir2PinA = 3;
int speedPinA = 6;
int dir1PinB = 4;
int dir2PinB = 5;
int speedPinB = 7;
void setup()
{
Serial.begin(9600);
pinMode(dir1PinA,OUTPUT);
pinMode(dir2PinA,OUTPUT);
pinMode(speedPinA,OUTPUT);
pinMode(dir1PinB,OUTPUT);
pinMode(dir2PinB,OUTPUT);
pinMode(speedPinB,OUTPUT);
pinMode(8,OUTPUT);
digitalWrite(8, HIGH);
Serial.begin(9600);
BTSerial.begin(9600);
}
void loop()
{
if (BTSerial.available())
Serial.write(BTSerial.read());
if (Serial.available())
BTSerial.write(Serial.read());
if (BTSerial.available() > 0) {
int inByte = BTSerial.read();
int speed;
switch (inByte) {
case 'F':
analogWrite(speedPinA, 500);
analogWrite(speedPinB, 500);
digitalWrite(dir1PinA, LOW);
digitalWrite(dir1PinB, HIGH);
digitalWrite(dir2PinA, HIGH);
digitalWrite(dir2PinB, LOW);
Serial.println("Motor 1 Forward");
Serial.println("Motor 2 Forward");
Serial.println(" ");
break;
case 'S':
analogWrite(speedPinA, 0);
digitalWrite(dir1PinA, LOW);
digitalWrite(dir2PinA, HIGH);
Serial.println("Motor 1 Stop");
analogWrite(speedPinB, 0);
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, HIGH);
Serial.println("Motor 2 Stop");
Serial.println(" ");
break;
case 'B':
analogWrite(speedPinA, 500);
digitalWrite(dir1PinA, HIGH);
digitalWrite(dir2PinA, LOW);
Serial.println("Motor 1 Back");
analogWrite(speedPinB, 500);
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, HIGH);
Serial.println("Motor 2 Back");
Serial.println(" ");
break;
case 'L':
analogWrite(speedPinA, 0);
digitalWrite(dir1PinA, LOW);
digitalWrite(dir2PinA, HIGH);
Serial.println("Motor 1 Left");
analogWrite(speedPinB, 500);
digitalWrite(dir1PinB, HIGH);
digitalWrite(dir2PinB, LOW);
Serial.println("Motor 2 Left");
Serial.println(" ");
break;
case 'R':
analogWrite(speedPinA, 500);
digitalWrite(dir1PinA, LOW);
digitalWrite(dir2PinA, HIGH);
Serial.println("Motor 1 Right");
analogWrite(speedPinB, 0);
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, HIGH);
Serial.println("Motor 2 Right");
Serial.println(" ");
break;
case 'I':
analogWrite(speedPinA, 150);
digitalWrite(dir1PinA, LOW);
digitalWrite(dir2PinA, HIGH);
Serial.println("Motor 1 Forward L");
analogWrite(speedPinB, 500);
digitalWrite(dir1PinB, HIGH);
digitalWrite(dir2PinB, LOW);
Serial.println("Motor 2 Forward L");
Serial.println(" ");
break;
case 'G':
analogWrite(speedPinA, 500);
digitalWrite(dir1PinA, LOW);
digitalWrite(dir2PinA, HIGH);
Serial.println("Motor 1 Forward R");
analogWrite(speedPinB, 150);
digitalWrite(dir1PinB, HIGH);
digitalWrite(dir2PinB, LOW);
Serial.println("Motor 2 Forward R");
Serial.println(" ");
break;
case 'J':
analogWrite(speedPinA, 200);
digitalWrite(dir1PinA, HIGH);
digitalWrite(dir2PinA, LOW);
Serial.println("Motor 1 Back L");
analogWrite(speedPinB, 500);
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, HIGH);
Serial.println("Motor 2 Back L");
Serial.println(" ");
break;
case 'H':
analogWrite(speedPinA, 500);
digitalWrite(dir1PinA, HIGH);
digitalWrite(dir2PinA, LOW);
Serial.println("Motor 1 Back R");
analogWrite(speedPinB, 200);
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, HIGH);
Serial.println("Motor 2 Back R");
Serial.println(" ");
break;
default:
for (int thisPin = 2; thisPin < 11; thisPin++)
{
digitalWrite(thisPin, LOW);
}
}
}
}
ประโยค switch หนึ่งประโยคจะมีกี่ case ก็ได้ หรือไม่มีเลยก็ได้ และอาจมี default เป็นตัวเลือกเสริม
ประโยคคำสั่ง break
เป็นคำสั่งที่ใช้ในการหลุดออกจากเงื่อนไข โดยไม่ต้องทำงานจนจบบล๊อกของคำสั่ง
การนำคำสั่ง break มาซ้อนไว้ใน case ต่าง ๆ ของคำสั่ง switch จะช่วยให้โปรแกรมไม่ล่วงล้ำเข้าไปทำใน case ที่อยู่ถัดไป แต่ถ้าไม่มีประโยคคำสั่ง break เมื่อทำ case ใด ๆ เสร็จเรียบร้อยแล้ว คอมไพล์เลอร์ก็จะให้ไปทำใน case ที่อยู่ถัดไปเรื่อย ๆ จนกว่าจะจบบล๊อกของประโยคคำสั่ง switch จากนั้นจะทำงานต่อไป ในประโยคคำสั่งที่อยู่ถัดไป
SoftwareSerial BTSerial(9, 10);
int dir1PinA = 2;
int dir2PinA = 3;
int speedPinA = 6;
int dir1PinB = 4;
int dir2PinB = 5;
int speedPinB = 7;
void setup()
{
Serial.begin(9600);
pinMode(dir1PinA,OUTPUT);
pinMode(dir2PinA,OUTPUT);
pinMode(speedPinA,OUTPUT);
pinMode(dir1PinB,OUTPUT);
pinMode(dir2PinB,OUTPUT);
pinMode(speedPinB,OUTPUT);
pinMode(8,OUTPUT);
digitalWrite(8, HIGH);
Serial.begin(9600);
BTSerial.begin(9600);
}
void loop()
{
if (BTSerial.available())
Serial.write(BTSerial.read());
if (Serial.available())
BTSerial.write(Serial.read());
if (BTSerial.available() > 0) {
int inByte = BTSerial.read();
int speed;
switch (inByte) {
case 'F':
analogWrite(speedPinA, 500);
analogWrite(speedPinB, 500);
digitalWrite(dir1PinA, LOW);
digitalWrite(dir1PinB, HIGH);
digitalWrite(dir2PinA, HIGH);
digitalWrite(dir2PinB, LOW);
Serial.println("Motor 1 Forward");
Serial.println("Motor 2 Forward");
Serial.println(" ");
break;
case 'S':
analogWrite(speedPinA, 0);
digitalWrite(dir1PinA, LOW);
digitalWrite(dir2PinA, HIGH);
Serial.println("Motor 1 Stop");
analogWrite(speedPinB, 0);
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, HIGH);
Serial.println("Motor 2 Stop");
Serial.println(" ");
break;
case 'B':
analogWrite(speedPinA, 500);
digitalWrite(dir1PinA, HIGH);
digitalWrite(dir2PinA, LOW);
Serial.println("Motor 1 Back");
analogWrite(speedPinB, 500);
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, HIGH);
Serial.println("Motor 2 Back");
Serial.println(" ");
break;
case 'L':
analogWrite(speedPinA, 0);
digitalWrite(dir1PinA, LOW);
digitalWrite(dir2PinA, HIGH);
Serial.println("Motor 1 Left");
analogWrite(speedPinB, 500);
digitalWrite(dir1PinB, HIGH);
digitalWrite(dir2PinB, LOW);
Serial.println("Motor 2 Left");
Serial.println(" ");
break;
case 'R':
analogWrite(speedPinA, 500);
digitalWrite(dir1PinA, LOW);
digitalWrite(dir2PinA, HIGH);
Serial.println("Motor 1 Right");
analogWrite(speedPinB, 0);
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, HIGH);
Serial.println("Motor 2 Right");
Serial.println(" ");
break;
case 'I':
analogWrite(speedPinA, 150);
digitalWrite(dir1PinA, LOW);
digitalWrite(dir2PinA, HIGH);
Serial.println("Motor 1 Forward L");
analogWrite(speedPinB, 500);
digitalWrite(dir1PinB, HIGH);
digitalWrite(dir2PinB, LOW);
Serial.println("Motor 2 Forward L");
Serial.println(" ");
break;
case 'G':
analogWrite(speedPinA, 500);
digitalWrite(dir1PinA, LOW);
digitalWrite(dir2PinA, HIGH);
Serial.println("Motor 1 Forward R");
analogWrite(speedPinB, 150);
digitalWrite(dir1PinB, HIGH);
digitalWrite(dir2PinB, LOW);
Serial.println("Motor 2 Forward R");
Serial.println(" ");
break;
case 'J':
analogWrite(speedPinA, 200);
digitalWrite(dir1PinA, HIGH);
digitalWrite(dir2PinA, LOW);
Serial.println("Motor 1 Back L");
analogWrite(speedPinB, 500);
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, HIGH);
Serial.println("Motor 2 Back L");
Serial.println(" ");
break;
case 'H':
analogWrite(speedPinA, 500);
digitalWrite(dir1PinA, HIGH);
digitalWrite(dir2PinA, LOW);
Serial.println("Motor 1 Back R");
analogWrite(speedPinB, 200);
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, HIGH);
Serial.println("Motor 2 Back R");
Serial.println(" ");
break;
default:
for (int thisPin = 2; thisPin < 11; thisPin++)
{
digitalWrite(thisPin, LOW);
}
}
}
}
เพิ่มเติมการเรียนรู้ ภาษา C
นอกจากการใช้คำสั่ง if เพื่อกำหนดเงื่อนไขเพื่อให้โปรแกรมเลือกที่จะทำงานสายงานใดแล้ว ในภาษา C ยังมีคำสั่ง switch อีกคำสั่งหนึ่ง เพื่ออำนวยความสะดวกแก่ผู้เขียนโปรแกรม ในการที่นำมาใช้แทนคำสั่ง if ที่ซ้อนกันหลาย ๆ ชั้น โดยที่คำสั่ง switch จะนำค่าของตัวแปรที่อยู่หลังคำสั่ง switch มาเปรียบเทียบกับค่าที่อยู่หลัง case แต่ละคำสั่ง ถ้าตรงกัน ก็จะทำสายงานที่อยู่ใน case นั้น ๆ แต่ถ้าไม่ตรงกับ case ใด ๆ เลย จะทำหลังคำสั่ง default โดยมีรูปแบบประโยคคำสั่งดังนี้
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdYK7G3BHDTXHXwe07BI3SpA13iIxatTELRyllyD3UPtW_1Zv7zN5P7VlQ4203ThEomdnYzy1lWt6RSa6WKncpSH3-qE4CXmX2sbr3jFRBCWo2O_X49rXTg47n4XsD56cotF8EPLBGJhA3/s1600/switch_case.png)
นอกจากการใช้คำสั่ง if เพื่อกำหนดเงื่อนไขเพื่อให้โปรแกรมเลือกที่จะทำงานสายงานใดแล้ว ในภาษา C ยังมีคำสั่ง switch อีกคำสั่งหนึ่ง เพื่ออำนวยความสะดวกแก่ผู้เขียนโปรแกรม ในการที่นำมาใช้แทนคำสั่ง if ที่ซ้อนกันหลาย ๆ ชั้น โดยที่คำสั่ง switch จะนำค่าของตัวแปรที่อยู่หลังคำสั่ง switch มาเปรียบเทียบกับค่าที่อยู่หลัง case แต่ละคำสั่ง ถ้าตรงกัน ก็จะทำสายงานที่อยู่ใน case นั้น ๆ แต่ถ้าไม่ตรงกับ case ใด ๆ เลย จะทำหลังคำสั่ง default โดยมีรูปแบบประโยคคำสั่งดังนี้
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdYK7G3BHDTXHXwe07BI3SpA13iIxatTELRyllyD3UPtW_1Zv7zN5P7VlQ4203ThEomdnYzy1lWt6RSa6WKncpSH3-qE4CXmX2sbr3jFRBCWo2O_X49rXTg47n4XsD56cotF8EPLBGJhA3/s1600/switch_case.png)
ประโยค switch หนึ่งประโยคจะมีกี่ case ก็ได้ หรือไม่มีเลยก็ได้ และอาจมี default เป็นตัวเลือกเสริม
ประโยคคำสั่ง break
เป็นคำสั่งที่ใช้ในการหลุดออกจากเงื่อนไข โดยไม่ต้องทำงานจนจบบล๊อกของคำสั่ง
ตัวอย่างตามโค้ดด้านบน เช่น
switch (inByte) {
case 'F':
analogWrite(speedPinA, 500);
analogWrite(speedPinB, 500);
digitalWrite(dir1PinA, LOW);
digitalWrite(dir1PinB, HIGH);
digitalWrite(dir2PinA, HIGH);
digitalWrite(dir2PinB, LOW);
Serial.println("Motor 1 Forward");
Serial.println("Motor 2 Forward");
Serial.println(" ");
break;
case 'H':
analogWrite(speedPinA, 500);
digitalWrite(dir1PinA, HIGH);
digitalWrite(dir2PinA, LOW);
Serial.println("Motor 1 Back R");
analogWrite(speedPinB, 200);
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, HIGH);
Serial.println("Motor 2 Back R");
Serial.println(" ");
break;
default:
case 'F':
analogWrite(speedPinA, 500);
analogWrite(speedPinB, 500);
digitalWrite(dir1PinA, LOW);
digitalWrite(dir1PinB, HIGH);
digitalWrite(dir2PinA, HIGH);
digitalWrite(dir2PinB, LOW);
Serial.println("Motor 1 Forward");
Serial.println("Motor 2 Forward");
Serial.println(" ");
break;
case 'H':
analogWrite(speedPinA, 500);
digitalWrite(dir1PinA, HIGH);
digitalWrite(dir2PinA, LOW);
Serial.println("Motor 1 Back R");
analogWrite(speedPinB, 200);
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, HIGH);
Serial.println("Motor 2 Back R");
Serial.println(" ");
break;
default:
การนำคำสั่ง break มาซ้อนไว้ใน case ต่าง ๆ ของคำสั่ง switch จะช่วยให้โปรแกรมไม่ล่วงล้ำเข้าไปทำใน case ที่อยู่ถัดไป แต่ถ้าไม่มีประโยคคำสั่ง break เมื่อทำ case ใด ๆ เสร็จเรียบร้อยแล้ว คอมไพล์เลอร์ก็จะให้ไปทำใน case ที่อยู่ถัดไปเรื่อย ๆ จนกว่าจะจบบล๊อกของประโยคคำสั่ง switch จากนั้นจะทำงานต่อไป ในประโยคคำสั่งที่อยู่ถัดไป
รถสามารถวิ่งได้ แต่ทำความเร็วได้ไม่ดีเท่าที่ควร (ช้ามาก) และทดลองนำไฟ 6 โวลต์ ต่อกับ บร์อด L298N Motor Driver โดยตรง มอเตอร์ก็ไม่สามารถหมุนได้
จึง ปรับปรุง เปลี่ยนแบตเตอรี่ เป็น แบตเตอรี่ลิเธียม 18650 (ขนาดใหญ่กว่า แบตเตอรี่ ขนาด AA ปรกติ) แรงดันไฟเฉลี่ย 3.7V (3400 mAh) จำนวน 3 ก้อน ได้ไฟรวมประมาณ 11.1 โวลต์ และ ก็ต้องเปลี่ยน รางถ่าน เป็นแบบ 18650 ใส่ถ่านได้ 3 ก้อน แบบวงจรอนุกรม ด้วย
V คือ Volt (โวลต์) เป็นค่าความต่างศักดิ์ไฟฟ้า คล้ายๆแรงดันไฟ นึกภาพถึง แรงดันน้ำ แรงดันลม ความดันเลือด (เป็นแรงดันไฟ หรือ แรงดันไฟฟ้า)
mAh คือ m = มิลลิ , A = แอมป์ , h = ชั่วโมง หมายถึง ถ่านก้อนนี้สามารถจ่ายกระแสได้ กี่มิลิแอมป์ ใน 1 ชั่วโมง (เป็นความจุไฟ หรือ กระแสไฟฟ้า)
รุูจัก : Li-ion (ลิเธี่ยมไอออน) และ Li-Mn (ลิเธี่ยมแมงกานีส หรือเรียกอีกอย่างว่า High Drain) ขนาดของตัวจะมาเป็นรหัสครับเช่น 18650 ข้อดี คือ สามารถชาร์จได้ แต่ ไม่ควรใช้จนไฟหมดหรือแรงดันต่ำกว่าที่กำหนดเอาไว้เพราะจะทำให้เซลล์แบตฯ เสียหายไม่สามารถนำมาใช้ได้อีก
รถบังคับสามารถ วิ่งทำความเร็วได้เพิ่มมากขึ้น แต่ก็ยังเร็วไม่เท่าที่ควร และ บร์อด Arduino UNO R3 จะรับไฟมากเกินไปด้วย ซึ่งปรกติจะใช้เพียง 5 โวลต์ เท่านั้น
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcXKYSE1kLxRoIiOin9msSn-6eQHK6XRwnlg-drRX39nH5vyk4ioLmPe_djEsDyUFUzemeITvqFQOXrPc5uFfciAAZZo-xFp5Jj0igE8D0ID4mv-ocdsxic26oiyFDg_S8fouIyMPxUvah/s640/2015.jpg)
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgz0Dke-iu4PiJjgCvsN51xzV-b5jhwgd2a_EPvx2guEGa-PS0vAsPYY6POM6oRVBxa4dwP-sT7X6ig3q0seJKoLBhAoeBxbJautFfYTsrAC8Nj9ExCXMkloGpcZZoidQeo7KApVs1KtDw1/s640/2014_0.jpg)
จึง ทดลองแก้ไขการต่อ แบตเตอรี่ นำไฟจากแบตเตอรี่ลิเธียม 18650 ไปต่อตรงกับ L298N Motor Driver (ไม่ต่อกับ พอร์ต Power Supply ของ บอร์ด Arduino UNO R3 ) และ นำไฟ 5 โวลต์ ที่ออกจาก L298N ต่อออกไปเลี้ยง บอร์ด Arduino UNO R3 ตามรูปการต่อวงวงจร
จากนั้น ทดลองนำ โทรศัพท์มือถือ แอนดรอยด์ เปิด บลูทูธ แล้ว ดาวน์โหลดและติดตั้ง โปรแกรม Arduino Bluetooth RC Car ดังนี้
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhE-IYUn2iPGw3jCF-e9HW6iuPJwmeJLLgV0knnlaUjtS7hVICSR139eynAN_EeHBT4uw9qFvnRQ8ojIgqyUlp2ruB8AfhAHaQDbcXKatqmVshMpMNRv5sj55qqL16457NsrKbM5dGgRBYK/s1600/1976.jpg)
สังเกตุ เมื่อเปิดขึ้นมา รูปวงกลมซ้ายมือ จะเป็นสีแดง
คลิกที่ ไอคอนเฟือง ขวามือสุด แล้ว เลือก Connect to car
เลือก HC-05
สังเกตุ รูปวงกลมซ้ายมือเป็นสีเขียวแสดงว่า โปรแกรมสามารถใช้งานได้แล้ว ทดลองควบคุมดูเลยครับ
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2kaK5Ou1Lb8MkrSCwm4-DQKhTFTSOZnNXp24e2FgzilKhJCZh20veWjUXqA5yFFHKI55K4xJsTEzI3pri8SZe7PcxQxIaqc9ZPgAz3o4xrxfl57t9JKHWd_SOXN7uVqSeuXuNXXVdK_yy/s640/1967.jpg)
วีดีโอผลลัพธ์การทำงานของ โปรเจครถบังคับ ขับเคลื่อน 2 ล้อ Arduino กับ แอพแอนดรอยด์
By : http://www.robotsiam.com/
ไม่มีความคิดเห็น:
แสดงความคิดเห็น