ค้นหาโค้ด

บทเรียน 29/31: รถยนต์-7 การควบคุมรถอัจฉริยะ SunFounder โดยใช้รีโมทคอนโทรล | Robojax

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

บทเรียน 29/31: รถยนต์-7 การควบคุมรถอัจฉริยะ SunFounder โดยใช้รีโมทคอนโทรล | Robojax

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

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

  • การสร้างหุ่นยนต์ควบคุมระยะไกลสำหรับงานระบบอัตโนมัติภายในบ้าน เช่น หุ่นยนต์ขนส่งขนาดเล็ก
  • การสร้างยานพาหนะที่ตั้งโปรแกรมได้สำหรับการแข่งขันหุ่นยนต์เพื่อการศึกษา
  • การพัฒนารีโมทคอนโทรลแบบกำหนดเองสำหรับสไลเดอร์กล้องหรือกลไกแพน-ทิลต์
  • การสร้างต้นแบบอินเทอร์เฟซผู้ใช้สำหรับระบบอัตโนมัติที่ใหญ่และซับซ้อนยิ่งขึ้น

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

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

  • ชุด Arduino 3-in-1 ของ SunFounder: ประกอบด้วยโครงรถอัจฉริยะ บอร์ดขับมอเตอร์ และบอร์ด Arduino
  • รีโมทอินฟราเรด: รีโมทมาตรฐานที่มาพร้อมกับชุดอุปกรณ์
  • โมดูลรับสัญญาณ IR: เซนเซอร์ที่จะถอดรหัสสัญญาณจากรีโมท
  • LED และตัวต้านทาน 330 โอห์ม: ใช้เป็นตัวบ่งชี้ภาพเพื่อยืนยันว่ามีการกดปุ่ม (ในวิดีโอที่ 04:08)
  • สายจัมเปอร์: สำหรับทำการเชื่อมต่อที่จำเป็นบนเบรดบอร์ด

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

car_9_lesson_29_wriing_for_IR

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

นี่คือคำแนะนำทีละขั้นตอนสำหรับการเชื่อมต่อ:

  1. ตัวรับสัญญาณ IR: ตัวรับสัญญาณ IR มีสามพิน พินบวกเชื่อมต่อกับราง 5V บนเบรดบอร์ด พินกราวด์เชื่อมต่อกับราง GND พินสัญญาณ ซึ่งเป็นพินสุดท้าย เชื่อมต่อกับดิจิทัลพิน 11 บนบอร์ด Arduino ของคุณ (ในวิดีโอที่ 05:29)
  2. LED ภายนอก: เชื่อมต่อขาหนึ่งของตัวต้านทาน 330 โอห์มเข้ากับดิจิทัลพิน 13 บน Arduino เชื่อมต่อขาอีกข้างของตัวต้านทานเข้ากับขาที่ยาวกว่า (แอโนด) ของ LED ขาที่สั้นกว่า (แคโทด) ของ LED ควรเชื่อมต่อกับราง GND บนเบรดบอร์ด (ในวิดีโอที่ 04:08)
  3. บอร์ดขับมอเตอร์: พินสี่พินสำหรับบอร์ดขับมอเตอร์ (A_1B, A_1A, B_1B, B_1A) เชื่อมต่อกับพิน 5, 6, 9 และ 10 บน Arduino ตามลำดับ การตั้งค่านี้ได้ครอบคลุมไว้แล้วในบทเรียนก่อนหน้า (ในวิดีโอที่ 06:44)

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

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

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

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

const int IR_RECEIVE_PIN = 12;  // กำหนดหมายเลขพินสำหรับเซนเซอร์ IR
const int A_1B = 5;
const int A_1A = 6;
const int B_1B = 9;
const int B_1A = 10;
  • IR_RECEIVE_PIN: ค่าคงที่นี้กำหนดดิจิทัลพินที่เชื่อมต่อกับพินสัญญาณของตัวรับสัญญาณ IR ของคุณ หากคุณเชื่อมต่อกับพินอื่น คุณจะเปลี่ยนตัวเลขตรงนี้
  • A_1B, A_1A, B_1B, B_1A: ค่าคงที่เหล่านี้แมปกับพินควบคุมสี่พินบนบอร์ดขับมอเตอร์ของคุณ พินเหล่านี้ควบคุมความเร็วและทิศทางของมอเตอร์ซ้ายและขวา

ถัดไป คุณจะพบตัวแปรสำคัญที่ควบคุมพฤติกรรมของรถ

int speed = 150;
  • speed: ตัวแปรนี้กำหนดความเร็วเริ่มต้นของรถ ค่าสามารถอยู่ในช่วง 0 ถึง 255 ในโปรเจกต์นี้ คุณสามารถเปลี่ยนได้โดยใช้ปุ่ม "+" และ "-" บนรีโมท โค้ดยังรวมตรรกะเพื่อป้องกันไม่ให้ความเร็วเกิน 255 หรือลดลงต่ำกว่า 0 (ในวิดีโอที่ 09:22)

ตรรกะหลักของการควบคุมระยะไกลถูกจัดการในฟังก์ชัน loop() เมื่อมีการกดปุ่ม ฟังก์ชัน decodeKeyValue() จะแปลรหัส IR ดิบเป็นสตริงง่ายๆ เช่น "2" สำหรับการเดินหน้าหรือ "+" สำหรับการเพิ่มความเร็ว ทำให้คำสั่ง if ที่ตามมาอ่านและแก้ไขได้ง่ายมาก (ในวิดีโอที่ 07:58)

ฟังก์ชันที่กำหนดเอง เช่น moveForward(), turnRight() และ moveLeft() คือส่วนที่ควบคุมการทำงานของมอเตอร์ แต่ละฟังก์ชันรับค่า speed ปัจจุบันเป็นอาร์กิวเมนต์ ตัวอย่างเช่น moveForward(speed) จะขับมอเตอร์ทั้งสองไปข้างหน้าด้วยความเร็วที่กำหนด ความแตกต่างหลักระหว่าง "การเลี้ยว" และ "การเคลื่อนที่" คือ การเลี้ยวจะหมุนล้อทั้งสองในทิศทางตรงกันข้าม ทำให้รถหมุนอยู่กับที่ ในขณะที่การเคลื่อนที่จะหมุนเพียงล้อเดียว ทำให้รถโค้งรอบล้อที่หยุดนิ่ง (ในวิดีโอที่ 10:14)

การสาธิตโปรเจกต์สด

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

  • การควบคุมความเร็ว: การกดปุ่ม "+" จะเพิ่มความเร็วขึ้น 50 ในขณะที่ปุ่ม "-" จะลดความเร็วลง ความเร็วจะถูกจำกัดสูงสุดที่ 255 และต่ำสุดที่ 0 เพื่อปกป้องมอเตอร์ (ในวิดีโอที่ 11:56)
  • การเคลื่อนที่แบบชั่วขณะ: เมื่อคุณกดปุ่มทิศทาง เช่น "2" (ไปข้างหน้า) หรือ "8" (ถอยหลัง) รถจะเคลื่อนที่เป็นเวลาหนึ่งวินาทีแล้วหยุดโดยอัตโนมัติ นี่คือคุณสมบัติด้านความปลอดภัยที่สร้างไว้ในโค้ด (ในวิดีโอที่ 13:09)
  • การเลี้ยวและการบังคับรถ: ปุ่มที่จัดเรียงเป็นรูปกากบาทบนรีโมตทำหน้าที่เหมือนจอยสติ๊ก การกด "4" หรือ "6" จะเลี้ยวรถไปทางซ้ายหรือขวาในตำแหน่งเดิม การกดปุ่มแนวทแยง เช่น "1" หรือ "3" จะทำการ "เคลื่อนที่ซ้าย" หรือ "เคลื่อนที่ขวา" ซึ่งเป็นการเลี้ยวที่คมชัดกว่าโดยที่ล้อหนึ่งหยุดนิ่ง (ในวิดีโอที่ 16:42)

สิ่งที่คุณอาจสังเกตได้คือ รถไม่ได้ขับเป็นเส้นตรงอย่างสมบูรณ์แบบเสมอไป ซึ่งมักเกิดจากความแตกต่างเล็กน้อยของมอเตอร์หรือความตึงของการประกอบรถ ซึ่งเป็นลักษณะทั่วไปและปกติของชุดอุปกรณ์เหล่านี้ (ในวิดีโอที่ 15:14)

บทต่างๆ

  • [00:00] แนะนำการควบคุมรถอัจฉริยะด้วยรีโมตอินฟราเรด
  • [01:15] สิ่งที่ต้องมีและบทเรียนก่อนหน้าที่จำเป็น
  • [01:56] ภาพรวมของเอกสารโปรเจกต์
  • [02:29] ทำความเข้าใจฟังก์ชันปุ่มต่างๆ ของรีโมตคอนโทรล
  • [03:29] คำแนะนำการเดินสายไฟทีละขั้นตอนสำหรับตัวรับอินฟราเรดและ LED
  • [05:51] การเปิดและโหลดโค้ดโปรเจกต์
  • [07:41] คำอธิบายโค้ด: ลูป การถอดรหัสปุ่ม และการดำเนินการ
  • [09:22] การจำกัดความเร็วและคุณสมบัติด้านความปลอดภัยในโค้ด
  • [10:08] คำอธิบายฟังก์ชันการเคลื่อนที่ของมอเตอร์
  • [11:49] การสาธิตสด: ทดสอบการควบคุมความเร็วและการกระพริบ LED
  • [13:27] การสาธิตสด: ไปข้างหน้า ถอยหลัง และการเลี้ยว
  • [14:31] การสาธิตรถเต็มรูปแบบด้วยกำลังและการเคลื่อนที่

ภาพ

Car 9 lesson 29 wiring for IR
Car 9 lesson 29 wiring for IR
896-Lesson 29/31: Car-7 Controlling SunFounder Smart Car using Remote Controller
ภาษา: C++
/*
Lesson 29/31: Car-7 Controlling SunFounder Smart Car using Remote Controller
Get this code and watch video Download and resource page https://robojax.com/RJT612

*/
#include <IRremote.h>

const int IR_RECEIVE_PIN = 12;  // Define the pin number for the IR Sensor

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


int speed = 150;

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

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

  //IR remote
  IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);  // Start the IR receiver // Start the receiver
  Serial.println("REMOTE CONTROL START");

}

void loop() {

  if (IrReceiver.decode()) {
    //    Serial.println(results.value,HEX);
    String key = decodeKeyValue(IrReceiver.decodedIRData.command);
    if (key != "ERROR") {
      Serial.println(key);

      if (key == "+") {
        speed += 50;
      } else if (key == "-") {
        speed -= 50;
      } else if (key == "2") {
        moveForward(speed);
        delay(1000);
      } else if (key == "1") {
        moveLeft(speed);
      } else if (key == "3") {
        moveRight(speed);
      } else if (key == "4") {
        turnLeft(speed);
      } else if (key == "6") {
        turnRight(speed);
      } else if (key == "7") {
        backLeft(speed);
      } else if (key == "9") {
        backRight(speed);
      } else if (key == "8") {
        moveBackward(speed);
        delay(1000);
      }

      if (speed >= 255) {
        speed = 255;
      }
      if (speed <= 0) {
        speed = 0;
      }
      delay(500);
      stopMove();
    }

    IrReceiver.resume();  // Enable receiving of the next value
  }
}

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 turnRight(int speed) {
  analogWrite(A_1B, speed);
  analogWrite(A_1A, 0);
  analogWrite(B_1B, speed);
  analogWrite(B_1A, 0);
}

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

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

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

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);
}


String decodeKeyValue(long result)
{
  switch(result){
    case 0x16:
      return "0";
    case 0xC:
      return "1"; 
    case 0x18:
      return "2"; 
    case 0x5E:
      return "3"; 
    case 0x8:
      return "4"; 
    case 0x1C:
      return "5"; 
    case 0x5A:
      return "6"; 
    case 0x42:
      return "7"; 
    case 0x52:
      return "8"; 
    case 0x4A:
      return "9"; 
    case 0x9:
      return "+"; 
    case 0x15:
      return "-"; 
    case 0x7:
      return "EQ"; 
    case 0xD:
      return "U/SD";
    case 0x19:
      return "CYCLE";         
    case 0x44:
      return "PLAY/PAUSE";   
    case 0x43:
      return "FORWARD";   
    case 0x40:
      return "BACKWARD";   
    case 0x45:
      return "POWER";   
    case 0x47:
      return "MUTE";   
    case 0x46:
      return "MODE";       
    case 0x0:
      return "ERROR";   
    default :
      return "ERROR";
    }
}

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

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

ไฟล์📁

ไลบรารี Arduino (zip)