ค้นหาโค้ด

บทเรียน 28/31: รถยนต์-6 รถ Arduino ขับเคลื่อนด้วยตัวเองของ SunFounder โดยใช้ | Robojax

บทเรียนนี้เป็นส่วนหนึ่งของ: หลักสูตร Arduino ที่ใช้ชุดการเรียนรู้ 3-in-1 ของ SunFounder

บทเรียน 28/31: รถยนต์-6 รถ Arduino ขับเคลื่อนด้วยตัวเองของ SunFounder โดยใช้ | Robojax

ในโปรเจกต์นี้ เราจะสร้างรถยนต์ขับเคลื่อนอัตโนมัติพื้นฐานโดยใช้ Arduino เซนเซอร์อัลตราโซนิก และเซนเซอร์อินฟราเรดสองตัว นี่เป็นโปรเจกต์แนะนำที่ยอดเยี่ยมสำหรับการเรียนรู้เกี่ยวกับการนำทางอัตโนมัติ การรวมเซนเซอร์ และตรรกะการตัดสินใจ รถสามารถเคลื่อนที่ไปข้างหน้า ถอยหลัง และเลี้ยวเพื่อหลบหลีกอุปสรรค หาเส้นทางที่ชัดเจนได้ด้วยตัวเองอย่างมีประสิทธิภาพ โปรเจกต์นี้ใช้ชุดอุปกรณ์ SunFounder 3-in-1 Arduino และเป็นส่วนหนึ่งของหลักสูตร Arduino ของ Robojax

28-SunFounder-Car-6-Self-Driving-path

โปรเจกต์นี้ไม่ใช่แค่การสร้างของเล่น แต่เป็นการแนะนำเชิงปฏิบัติเกี่ยวกับแนวคิดหลักเบื้องหลังหุ่นยนต์อัตโนมัติ ตรรกะและเซนเซอร์เดียวกันนี้ถูกใช้ในการใช้งานจริง เช่น เครื่องดูดฝุ่นหุ่นยนต์ ยานพาหนะนำทางอัตโนมัติในคลังสินค้า และแม้แต่ระบบนำทางของหุ่นยนต์ที่ซับซ้อนมากขึ้น โดยการเข้าใจวิธีรวมการวัดระยะทางเข้ากับกฎการนำทางง่ายๆ คุณสามารถสร้างโปรเจกต์ต่างๆ ได้มากมาย เช่น:

  • สร้างหุ่นยนต์ขนาดเล็กที่สามารถนำทางในห้องและหลบหลีกเฟอร์นิเจอร์ได้
  • สร้างยานพาหนะอัตโนมัติที่สามารถเดินตามเส้นทางง่ายๆ หรือลาดตระเวนในพื้นที่ได้
  • เรียนรู้วิธีใช้อัลกอริทึมการหลบหลีกอุปสรรคพื้นฐานสำหรับโปรเจกต์หุ่นยนต์ขนาดใหญ่

ส่วนประกอบฮาร์ดแวร์

โปรเจกต์นี้ใช้ส่วนประกอบจากชุดอุปกรณ์ SunFounder 3-in-1 ชิ้นส่วนสำคัญ ได้แก่:

  • บอร์ด Arduino Uno
  • แชสซีรถยนต์ SunFounder 2WD หรือ 3-in-1 พร้อมมอเตอร์
  • โมดูลขับมอเตอร์ (เช่น L298N หรือที่คล้ายกัน)
  • เซนเซอร์วัดระยะอัลตราโซนิก HC-SR04
  • เซนเซอร์อินฟราเรดตรวจจับอุปสรรคสองตัว
  • สายจัมเปอร์และแหล่งจ่ายไฟสำหรับมอเตอร์

คู่มือการเดินสายไฟ

car_7_8_28_self_driving

การเดินสายไฟเป็นขั้นตอนแรกที่สำคัญในการทำให้รถขับเคลื่อนอัตโนมัติของคุณทำงานได้ การเชื่อมต่อตรงไปตรงมา แต่จำเป็นต้องตรวจสอบแต่ละจุดอย่างละเอียดเพื่อหลีกเลี่ยงความเสียหายต่อส่วนประกอบ ตรรกะเบื้องหลังการเดินสายไฟคือการเชื่อมต่อพินควบคุมของ Arduino เข้ากับตัวขับมอเตอร์และเซนเซอร์ เพื่อให้ Arduino สามารถอ่านข้อมูลและส่งคำสั่งได้

  • พินตัวขับมอเตอร์ (A-1B, A-1A, B-1B, B-1A): พินเหล่านี้ควบคุมความเร็วและทิศทางของมอเตอร์สองตัว เชื่อมต่อกับพิน Arduino 5, 6, 9 และ 10 ซึ่งรองรับ PWM ทำให้สามารถควบคุมความเร็วแบบแปรผันได้
  • เซนเซอร์อัลตราโซนิก (Trig และ Echo): พิน Trig ส่งคลื่นอัลตราโซนิกออกไป และพิน Echo รับสัญญาณสะท้อนกลับ พิน Trig เชื่อมต่อกับพิน Arduino 3 และพิน Echo เชื่อมต่อกับพิน Arduino 4
  • เซนเซอร์ IR (ซ้ายและขวา): เซนเซอร์เหล่านี้ตรวจจับว่ามีอุปสรรคอยู่ตรงหน้าหรือไม่ เซนเซอร์ IR ด้านซ้ายเชื่อมต่อกับพิน Arduino 8 และเซนเซอร์ IR ด้านขวาเชื่อมต่อกับพิน 7 เซนเซอร์เหล่านี้ใช้ตรวจสอบพื้นที่ด้านข้างของรถ

สำหรับคู่มือภาพโดยละเอียด โปรดดูแผนภาพการเดินสายไฟด้านล่าง ซึ่งแสดงการเชื่อมต่อแต่ละจุดอย่างชัดเจน

คำอธิบายโค้ด

โค้ดเขียนด้วยภาษาการเขียนโปรแกรม Arduino (C++) โปรแกรมเต็มรูปแบบสามารถดาวน์โหลดได้จากหน้าทรัพยากรที่ลิงก์ในคำอธิบายวิดีโอ มาดูส่วนสำคัญที่ผู้ใช้สามารถปรับแต่งได้ในสเก็ตช์นี้

การกำหนดพิน

ที่ด้านบนของโค้ด คุณกำหนดพินที่เชื่อมต่อ Arduino กับส่วนประกอบต่างๆ คุณสามารถเปลี่ยนได้หากใช้พินที่แตกต่างกันบนบอร์ดของคุณ

const int A_1B = 5;
const int A_1A = 6;
const int B_1B = 9;
const int B_1A = 10;

const int echoPin = 4;
const int trigPin = 3;

const int rightIR = 7;
const int leftIR = 8;

พิน A_1B, A_1A, B_1B และ B_1A ควบคุมตัวขับมอเตอร์แบบ H-bridge โดยการตั้งพินเหล่านี้เป็น HIGH หรือ LOW ในรูปแบบต่างๆ คุณสามารถควบคุมทิศทางของมอเตอร์แต่ละตัวได้ echoPin และ trigPin ใช้สำหรับเซนเซอร์อัลตราโซนิก และ rightIR และ leftIR ใช้สำหรับเซนเซอร์อินฟราเรด

ตัวแปรพฤติกรรมและตรรกะ

ตรรกะหลักของพฤติกรรมการขับเคลื่อนอัตโนมัติอยู่ในฟังก์ชัน loop() รถตัดสินใจตามค่าที่อ่านได้จากเซนเซอร์ IR และเซนเซอร์อัลตราโซนิก โค้ดกำหนดระยะทางเฉพาะที่ทำให้เกิดการกระทำที่แตกต่างกัน ตัวอย่างเช่น ตัวแปร distance วัดเป็นเซนติเมตร ตรรกะมีดังนี้:

  • หากระยะทางมากกว่า 50 ซม.: เส้นทางข้างหน้าชัดเจน รถจึงเคลื่อนที่ไปข้างหน้าด้วยความเร็ว 200
  • หากระยะทางอยู่ระหว่าง 2 ซม. ถึง 10 ซม.: รถอยู่ใกล้อุปสรรคเกินไป รถถอยหลังเป็นเวลาหนึ่งวินาที จากนั้นเลี้ยวซ้ายกลับเป็นเวลาครึ่งวินาทีเพื่อหาเส้นทางใหม่
  • หากระยะทางอยู่ระหว่าง 10 ซม. ถึง 50 ซม.: รถอยู่ใน "โซนเตือน" รถเคลื่อนที่ไปข้างหน้า แต่ด้วยความเร็วที่ช้าลงที่ 150

ค่าเกณฑ์เหล่านี้ (50 ซม., 10 ซม. และ 2 ซม.) และความเร็ว (200 และ 150) เป็นตัวแปรหลักที่คุณสามารถปรับเปลี่ยนเพื่อเปลี่ยนพฤติกรรมของรถได้ ตัวอย่างเช่น คุณอาจเพิ่มระยะ "ปลอดภัย" เป็น 60 ซม. หากรถของคุณเคลื่อนที่เร็ว

ฟังก์ชันที่กำหนดเอง

โค้ดมีฟังก์ชันที่กำหนดเองหลายฟังก์ชันเพื่อควบคุมการเคลื่อนที่ของรถ ฟังก์ชันเหล่านี้ถูกใช้ตลอดทั้งลูปหลักเพื่อทำให้โค้ดสะอาดและเข้าใจง่ายขึ้น

  • moveForward(int speed): ฟังก์ชันนี้จะตั้งค่าพินของมอเตอร์เพื่อขับรถไปข้างหน้า พารามิเตอร์ speed (0-255) ควบคุมความเร็วในการหมุนของมอเตอร์
  • moveBackward(int speed): คล้ายกับ moveForward แต่จะกลับทิศทางของมอเตอร์เพื่อให้รถเคลื่อนที่ถอยหลัง
  • backLeft(int speed) และ backRight(int speed): ฟังก์ชันเหล่านี้จะเลี้ยวรถโดยการหมุนมอเตอร์หนึ่งตัวในทิศทางย้อนกลับในขณะที่อีกตัวหยุดนิ่ง ซึ่งเป็นการเลี้ยวแบบหมุนรอบจุดที่ช่วยให้รถเปลี่ยนทิศทางได้อย่างมีประสิทธิภาพ
  • stopMove(): ฟังก์ชันนี้จะหยุดมอเตอร์ทั้งหมดโดยการตั้งค่าพินควบคุมทั้งหมดให้เป็น LOW
  • readSensorData(): ฟังก์ชันนี้จะส่งพัลส์จากเซนเซอร์อัลตราโซนิกและวัดเวลาที่เสียงสะท้อนกลับมา จากนั้นจะคำนวณระยะทางเป็นเซนติเมตรและส่งค่ากลับ

การสาธิตโครงการสด

(ในวิดีโอที่ 07:09) ในการสาธิต รถถูกวางในสภาพแวดล้อมที่มีสิ่งกีดขวางหลากหลาย เช่น กล่องและผนัง ตรรกะของรถจะมองเห็นได้ชัดเจนขณะที่มันนำทาง เมื่อเซนเซอร์อัลตราโซนิกตรวจพบผนังหรือสิ่งกีดขวางที่อยู่ห่างมากกว่า 50 ซม. มันจะขับไปข้างหน้าอย่างมั่นใจ เมื่อมันเข้าใกล้มากขึ้น เซนเซอร์อินฟราเรดที่ด้านข้างจะตรวจสอบพื้นที่ว่าง

หากตรวจพบสิ่งกีดขวางทางซ้าย รถจะทำการเลี้ยวถอยหลังขวาเพื่อหลีกเลี่ยง และในทางกลับกัน เมื่อรถพบว่าตัวเองอยู่ในพื้นที่แคบ เช่น ใต้โต๊ะ (ในวิดีโอที่ 07:49) มันจะใช้ฟังก์ชันถอยหลังและเลี้ยวเพื่อช่วยตัวเองออกมาและหาทางที่ชัดเจน รถจะอ่านสภาพแวดล้อมอย่างต่อเนื่องและตัดสินใจ ซึ่งแสดงให้เห็นถึงระบบควบคุมแบบตอบสนองที่ไม่พึ่งพาเส้นทางที่วางแผนไว้ล่วงหน้า

บทของวิดีโอ

  • [00:00] แนะนำโครงการรถขับเคลื่อนด้วยตนเอง
  • [00:28] เกี่ยวกับชุดอุปกรณ์ 3-in-1 ของ SunFounder
  • [01:32] เปิดโค้ดและภาพรวม
  • [02:02] คำอธิบายโครงสร้างโค้ดและฟังก์ชันใหม่
  • [03:11] การตั้งค่าพินในฟังก์ชัน Setup
  • [03:28] ตรรกะหลักในการตัดสินใจในลูป
  • [05:41] การสาธิตสด: รถกำลังทำงาน
  • [07:09] การสาธิตกับสิ่งกีดขวางและการติดตามผนัง
  • [09:58] บทสรุปและความคิดเห็นสุดท้าย

ภาพ

28 SunFounder Car 6 self-driving path
28 SunFounder Car 6 self-driving path
Car 7 8 28 self driving
Car 7 8 28 self driving
897-Lesson 28/31: Car-6 SunFounder self Driving Arduino car
ภาษา: C++
/*
Lesson 28/31: Car-6 SunFounder self Driving Arduino car
Get this code and watch video Download and resource page https://robojax.com/RJT611
https://www.youtube.com/watch?v=IyninXUcsn0
*/
const int A_1B = 5;
const int A_1A = 6;
const int B_1B = 9;
const int B_1A = 10;

const int echoPin = 4;
const int trigPin = 3;

const int rightIR = 7;
const int leftIR = 8;

float readSensorData() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  float distance = pulseIn(echoPin, HIGH) / 58.00; //Equivalent to (340m/s*1us)/2
  return distance;
}


void moveForward(int speed) {
  analogWrite(A_1B, 0);
  analogWrite(A_1A, speed);
  analogWrite(B_1B, speed);
  analogWrite(B_1A, 0);
}

void moveBackward(int speed) {
  analogWrite(A_1B, speed);
  analogWrite(A_1A, 0);
  analogWrite(B_1B, 0);
  analogWrite(B_1A, speed);
}


void backLeft(int speed) {
  analogWrite(A_1B, speed);
  analogWrite(A_1A, 0);
  analogWrite(B_1B, 0);
  analogWrite(B_1A, 0);
}

void backRight(int speed) {
  analogWrite(A_1B, 0);
  analogWrite(A_1A, 0);
  analogWrite(B_1B, 0);
  analogWrite(B_1A, speed);
}

void stopMove() {
  analogWrite(A_1B, 0);
  analogWrite(A_1A, 0);
  analogWrite(B_1B, 0);
  analogWrite(B_1A, 0);
}

void setup() {
  Serial.begin(9600);

  //motor
  pinMode(A_1B, OUTPUT);
  pinMode(A_1A, OUTPUT);
  pinMode(B_1B, OUTPUT);
  pinMode(B_1A, OUTPUT);

  //ultrasonic
  pinMode(echoPin, INPUT);
  pinMode(trigPin, OUTPUT);

  //IR obstacle
  pinMode(leftIR, INPUT);
  pinMode(rightIR, INPUT);
}

void loop() {

  int left = digitalRead(leftIR);  // 0: Obstructed   1: Empty
  int right = digitalRead(rightIR);

  if (!left && right) {
    backLeft(150);
  } else if (left && !right) {
    backRight(150);
  } else if (!left && !right) {
    moveBackward(150);
  } else {
    float distance = readSensorData();
    Serial.println(distance);
    if (distance > 50) { // Safe
      moveForward(200);
    } else if (distance < 10 && distance > 2) { // Attention
      moveBackward(200);
      delay(1000);
      backLeft(150);
      delay(500);
    } else {
      moveForward(150);
    }
  }
}

สิ่งที่คุณอาจต้องการ

แหล่งข้อมูลและเอกสารอ้างอิง

ไฟล์📁

ไลบรารี Arduino (zip)