โปรเจครถบังคับ ขับเคลื่อน 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
เรียนรู้เพิ่มเติมตามลิงค์นี้ http://robotsiam.blogspot.com/2016/08/l298n-motor-driver-connect-arduino-r3.html
เรียนรู้เพิ่มเติมตามลิงค์นี้ 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 โดยมีรูปแบบประโยคคำสั่งดังนี้
นอกจากการใช้คำสั่ง if เพื่อกำหนดเงื่อนไขเพื่อให้โปรแกรมเลือกที่จะทำงานสายงานใดแล้ว ในภาษา C ยังมีคำสั่ง switch อีกคำสั่งหนึ่ง เพื่ออำนวยความสะดวกแก่ผู้เขียนโปรแกรม ในการที่นำมาใช้แทนคำสั่ง if ที่ซ้อนกันหลาย ๆ ชั้น โดยที่คำสั่ง switch จะนำค่าของตัวแปรที่อยู่หลังคำสั่ง switch มาเปรียบเทียบกับค่าที่อยู่หลัง case แต่ละคำสั่ง ถ้าตรงกัน ก็จะทำสายงานที่อยู่ใน case นั้น ๆ แต่ถ้าไม่ตรงกับ case ใด ๆ เลย จะทำหลังคำสั่ง default โดยมีรูปแบบประโยคคำสั่งดังนี้
ประโยค 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 โวลต์ เท่านั้น
จึง ทดลองแก้ไขการต่อ แบตเตอรี่ นำไฟจากแบตเตอรี่ลิเธียม 18650 ไปต่อตรงกับ L298N Motor Driver (ไม่ต่อกับ พอร์ต Power Supply ของ บอร์ด Arduino UNO R3 ) และ นำไฟ 5 โวลต์ ที่ออกจาก L298N ต่อออกไปเลี้ยง บอร์ด Arduino UNO R3 ตามรูปการต่อวงวงจร
จากนั้น ทดลองนำ โทรศัพท์มือถือ แอนดรอยด์ เปิด บลูทูธ แล้ว ดาวน์โหลดและติดตั้ง โปรแกรม Arduino Bluetooth RC Car ดังนี้
สังเกตุ เมื่อเปิดขึ้นมา รูปวงกลมซ้ายมือ จะเป็นสีแดง
คลิกที่ ไอคอนเฟือง ขวามือสุด แล้ว เลือก Connect to car
เลือก HC-05
สังเกตุ รูปวงกลมซ้ายมือเป็นสีเขียวแสดงว่า โปรแกรมสามารถใช้งานได้แล้ว ทดลองควบคุมดูเลยครับ
วีดีโอผลลัพธ์การทำงานของ โปรเจครถบังคับ ขับเคลื่อน 2 ล้อ Arduino กับ แอพแอนดรอยด์
By : http://www.robotsiam.com/
ไม่มีความคิดเห็น:
แสดงความคิดเห็น