>ตัวอย่างใช้งาน>
/N32G031_SERVO_SMOOTH

กวาดเซอร์โวแบบนุ่มนวล

N32G031_SERVO_SMOOTH

บทนำ

โปรเจกต์ระดับเริ่มต้นที่ออกแบบมาเพื่อสอนการควบคุมเซอร์โวมอเตอร์โดยใช้ไมโครคอนโทรลเลอร์ N32G031 โดยเน้นเป็นพิเศษที่การเคลื่อนไหวที่ราบรื่นไร้การกระตุก (Smooth Sweep) โปรเจกต์นี้ทำหน้าที่เป็นเครื่องมือการเรียนรู้พื้นฐานที่ยอดเยี่ยมสำหรับวิทยาการหุ่นยนต์และการประยุกต์ใช้ For Loop ที่ออกแบบมาสำหรับเด็กและผู้เริ่มต้น โปรเจกต์นี้ได้รับการปรับแต่งอย่างสมบูรณ์แบบสำหรับเวิร์กโฟลว์ข้ามแพลตฟอร์มโดยใช้ UnityMbed

MCU เป้าหมายNations N32G031 (Cortex-M0)
ขาสัญญาณที่ใช้งานPA1 (ซอฟต์แวร์ PWM)
รูปแบบการเคลื่อนไหวกวาดแบบนุ่มนวล (0°–90°)

วิดีโอสาธิตการทำงาน

การต่อวงจร

อุปกรณ์สาย / ขาอุปกรณ์ (Pin)ขาบอร์ด N32G031หมายเหตุ & คำแนะนำ
เซอร์โวมอเตอร์ (เช่น SG90)น้ำตาล / ดำGNDกราวด์ร่วมของระบบ (Common System Ground)
เซอร์โวมอเตอร์ (เช่น SG90)แดง (VCC)5Vแหล่งจ่ายไฟหลักของมอเตอร์ (Motor Power Supply)
เซอร์โวมอเตอร์ (เช่น SG90)ส้ม / เหลืองPA1ขาสัญญาณควบคุม (Control Signal Pin - PWM Bit-Banging)

การทำงาน & ลอจิกการทำงาน

เมื่อเปิดเครื่องและจ่ายไฟ แขนกลเซอร์โวจะกวาดองศาอย่างต่อเนื่องตามลูป 4 จังหวะดังต่อไปนี้:

จังหวะที่ 1 : 0° ➔ 45°

กวาดแขนจาก 0° ไปยัง 45°

ค่อยๆ กวาดแขนจาก 0 ไปยัง 45 องศา (PULSE_0_DEG ➔ PULSE_45_DEG) และหน่วงเวลาพักตำแหน่ง

จังหวะที่ 2 : 45° ➔ 90°

กวาดแขนจาก 45° ไปยัง 90°

ค่อยๆ กวาดแขนจาก 45 ไปยัง 90 องศา (PULSE_45_DEG ➔ PULSE_90_DEG) และหน่วงเวลาพักตำแหน่ง

จังหวะที่ 3 : 90° ➔ 45°

กวาดแขนกลับจาก 90° มายัง 45°

ค่อยๆ กวาดแขนกลับจาก 90 มายัง 45 องศา (PULSE_90_DEG ➔ PULSE_45_DEG) และหน่วงเวลาพักตำแหน่ง

จังหวะที่ 4 : 45° ➔ 0°

กวาดแขนกลับจาก 45° มายัง 0°

ค่อยๆ กวาดแขนกลับจาก 45 มายัง 0 องศา (PULSE_45_DEG ➔ PULSE_0_DEG) และหน่วงเวลาพักตำแหน่ง ก่อนเริ่มรอบใหม่

main.c
// UnityMbed — Smooth Servo Sweep Control @ N32G031
#include "n32g031.h"
#include "n32g031_gpio.h"
#include "n32g031_rcc.h"

/* ====================================================================
 * [โซนปรับแต่งฮาร์ดแวร์ / Hardware Calibration Zone]
 * ค่า Pulse width สำหรับกำหนดตำแหน่งองศาต่างๆ
 * ==================================================================== */
#define PULSE_0_DEG     2250   // 0 องศา (หันซ้ายสุด / Far Left)
#define PULSE_45_DEG    3325   // 45 องศา (กึ่งกลางซ้าย / Mid-Left)
#define PULSE_90_DEG    4400   // 90 องศา (ตั้งฉาก/ตรงกลาง / Perpendicular / Center)

/* ฟังก์ชันหน่วงเวลาแบบลูป */
void Delay_Loop(volatile uint32_t count) {
  while(count--) { __NOP(); }
}

/* ====================================================================
 * ฟังก์ชันย่อย: ขยับทีละก้าว (ส่งสัญญาณ PWM 1 รอบคลื่น)
 * ==================================================================== */
void Servo_Step(uint32_t pulse_width) {
  GPIO_SetBits(GPIOA, GPIO_PIN_1);
  Delay_Loop(pulse_width);
  GPIO_ResetBits(GPIOA, GPIO_PIN_1);
  Delay_Loop(100000);
}

/* ====================================================================
 * ฟังก์ชันหลัก: ขยับแบบนุ่มนวลจากมุมหนึ่งไปอีกมุมหนึ่ง (Smooth Movement)
 * ==================================================================== */
void Smooth_Move(uint32_t start_pulse, uint32_t end_pulse) {
  // ถ้าจุดหมายอยู่ไกลกว่า ให้ค่อยๆ เพิ่มค่า Pulse
  if (start_pulse < end_pulse) {
      for (uint32_t p = start_pulse; p <= end_pulse; p += 20) {
          Servo_Step(p);
      }
  }
  // ถ้าจุดหมายอยู่น้อยกว่า ให้ค่อยๆ ลดค่า Pulse
  else {
      for (uint32_t p = start_pulse; p >= end_pulse; p -= 20) {
          Servo_Step(p);
      }
  }
}

/* ====================================================================
 * จุดเริ่มต้นการทำงานหลัก: ลูปกวาดองศาแบบนุ่มนวลเป็นรอบ (Periodic Smooth Sweep)
 * ==================================================================== */
int main(void) {
  /* กำหนดค่าเริ่มต้นฮาร์ดแวร์ GPIOA Pin 1 เป็น Push-Pull Output */
  RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
  GPIO_InitType GPIO_InitStructure;
  GPIO_InitStruct(&GPIO_InitStructure);
  GPIO_InitStructure.Pin = GPIO_PIN_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);

  while(1) {
      /* 1. ค่อยๆ กวาดแขนจาก 0 ไป 45 องศา */
      Smooth_Move(PULSE_0_DEG, PULSE_45_DEG);
      Delay_Loop(5000000); // พักตำแหน่ง

      /* 2. ค่อยๆ กวาดแขนจาก 45 ไป 90 องศา */
      Smooth_Move(PULSE_45_DEG, PULSE_90_DEG);
      Delay_Loop(5000000);

      /* 3. ค่อยๆ กวาดแขนกลับจาก 90 มา 45 องศา */
      Smooth_Move(PULSE_90_DEG, PULSE_45_DEG);
      Delay_Loop(5000000);

      /* 4. ค่อยๆ กวาดแขนกลับจาก 45 มา 0 องศา เพื่อเริ่มรอบใหม่ */
      Smooth_Move(PULSE_45_DEG, PULSE_0_DEG);
      Delay_Loop(5000000);
  }
}

ไอเดียการเรียนรู้ & ต่อยอดด้วย AI

นักเรียนและผู้เรียนสามารถใช้ AI Assistant ใน UnityMbed เพื่อช่วยสำรวจ แก้ไขบั๊ก และปรับปรุงฟังก์ชันของโปรเจกต์นี้:

1

การเคลื่อนไหวแบบสมูท (Smooth Movement)

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

2

การปรับจูนฮาร์ดแวร์ (Hardware Calibration)

สัมผัสประสบการณ์จริงในการปรับแต่งค่าพารามิเตอร์ฮาร์ดแวร์ (Pulse Width) เพื่อตั้งศูนย์และเทียบมุม 0, 90 และ 180 องศาให้ตรงกับเซอร์โวมอเตอร์จริงแต่ละตัว

3

การประยุกต์ใช้ For Loop ในการเขียนโปรแกรม

เห็นภาพการทำงานของคำสั่ง For Loop อย่างชัดเจนผ่านการมองเห็นแขนกลขยับทีละขั้นตอนเมื่อค่าตัวแปรในลูปเพิ่มขึ้นหรือลดลง

4

ความท้าทายเรื่องความเร็ว

ลองปรับค่า step increment ใน Smooth_Move (เช่น p += 20 และ p -= 20) — ถ้าเปลี่ยนเป็น += 50 แขนจะหมุนเร็วขึ้นหรือไม่? หรือถ้าเปลี่ยนเป็น += 5 จะได้เอฟเฟกต์ Slow Motion หรือไม่?

คู่มือการ Build และ Flash

1

เปิดโปรเจกต์ (Open Project): เปิดโฟลเดอร์โปรเจกต์นี้ใน IDE โดยตรง

2

Build & Flash: เพียงคลิกปุ่ม Build และ Flash บนแถบเครื่องมือของอินเทอร์เฟซ