แนะนำการใช้งานบอร์ด Arduino Uno R4 Minima (ตอนที่ 1)#
Keywords: Arduino Uno R4 Minima, Renesas R7FA4M1A, FreeRTOS
บทความนี้นำเสนอเกี่ยวกับ Arduino Uno R4 Minima พร้อมตัวอย่างการเขียนโค้ด Arduino เพื่อทดลองใช้งานบอร์ดในเบื้องต้น
- แนะนำบอร์ด Arduino Uno R4
- Arduino Renesas Bootloader
- Arduino Core for Renesas
- ตัวอย่างโค้ดที่ 1: LED Blink
- ตัวอย่างโค้ดที่ 2: LED Breathing Effect
- ตัวอย่างโค้ดที่ 3: Arduino I/O Toggle (No Delay)
- ตัวอย่างโค้ดที่ 4: Fast I/O Toggle with Direct Pin Manipulation
- ตัวอย่างโค้ดที่ 5: Timer-based I/O Toggle
- ตัวอย่างโค้ดที่ 6: FreeRTOS-based I/O Toggle
แนะนำบอร์ด Arduino Uno R4#
บอร์ด Arduino Uno R4 มี 2 รุ่น คือ Arduino Uno R4 Minima และ Arduino Uno R4 WiFi ในบทความนี้ จะกล่าวถึงเฉพาะ Uno R4 Minima เท่านั้น
คุณสมบัติของบอร์ด Uno R4 Minima โดยสรุปเป็นข้อ ๆ ดังนี้
- MCU: Renesas
R7FA4M1AB3CFM(Arm Cortex-M4 @ 48MHz) - On-chip Memory:
- SRAM: 32 kB
- Flash: 256 kB
- EEPROM (emulated in Flash): 8 kB
- Operating Voltage: 5V
- Voltage Supply:
- USB Type-C: 5V DC
- VIN pin / DC-jack connector: 6-24V DC
- Switching (buck) regulator: ISL854102FRZ-T (5V/1.2A output max.)
- Digital I/O Pins: 14
- DC Current per I/O Pin: 8mA
- PWM Pins: 6x pins (
D3,D5,D6,D9,D10,D11) - Analog Input Pins: 6 (
A0~A5pins)- ADC Resolution: 14-bit
- Analog Output (DAC): 1 Pin (
A0pin)- DAC Resolution: 12-bit
- USB 2.0 Full-Speed:
- USB CDC:
SerialorSerialUSB(USB CDC virtual COM port)
- USB CDC:
- RTC (Real-Time Clock):
- No pins for battery backup
- 1x OpAmp:
- IN+/IN-:
A1andA2pins - OUT:
A3pin
- IN+/IN-:
- 1x UART:
Serial1(Hardware Serial):D0(SCI9_RX) /D1(SCI9_TX) pins
- 1x I2C:
A4(SDA) pin /A5(SCL) pin - 1x SPI:
D10(SS) pinD11(COPI/MOSI) pinD12(CIPO/MISO) pinD13(SCK) pin
- 1x CAN Bus Controller (CAN 2.0A/CAN 2.0B standard)
D4(CANRX) /D5(CANTX)
AREF(Input) Pin: Analog reference voltageRESET(Input) Pin: MCU reset, active-lowBOOT(Input) Pin: Enter bootloader modeIOREF(Output) Pin: +5V I/O reference voltage- 1x Arduino-style ICSP Connector: 2x3 pins
- 1x SWD Connector: 2x5 pins (2mm pin spacing)
- Arduino USB DFU bootloader: preinstalled
- Schematic: PDF (local copy)

รูป: บอร์ด Uno R4 Minima และ Uno R4 WiFi (Source: Arduino.cc)
Arduino Renesas Bootloader#
ชิป Renesas RA Series มี ROM Boot Firmware ติดตั้งมาจากโรงงาน อยู่ในหน่วยความจำ ROM ภายในชิป ซึ่งสามารถใช้สำหรับการโปรแกรม "เฟิร์มแวร์" (Firmware) ในหน่วยความจำแฟลชภายใน ผ่านอินเทอร์เฟซต่าง ๆ เช่น USB-FS หรือ UART ได้
แต่สำหรับบอร์ด Uno R4 Minima ผู้พัฒนาได้จัดทำ Arduino Renesas Bootloader ไว้สำหรับการอัปโหลด โปรแกรม (ไฟล์เฟิร์มแวร์) ไปยังตัวชิป ผ่านทาง USB และบอร์ด Uno R4 ได้มีการติดตั้ง Arduino Renesas Bootloader มาพร้อมใช้งานแล้ว
Arduino Renesas Bootloader
- ใช้สำหรับชิป Renesas RA series MCUs เช่น
- RA4M1 (Uno R4 Minima and WiFi)
- RA6M5 (Portenta C33)
- ใช้ไลบรารี
TinyUSBสำหรับการเชื่อมต่อผ่าน USB - ใช้โพรโตคอล DFU (Device Firmware Upgrade) ในการโปรแกรมหน่วยความจำ Flash
- ผู้ใช้สามารถเข้าสู่โหมด Arduino Bootloader ได้ โดยการกดปุ่มรีเซตแบบ "Double Tap"
- ไฟล์สำหรับ Arduino Renesas Bootloader มีให้ดาวน์โหลด จำแนกตามบอร์ด
- Uno R4 Minima:
dfu_minima.hex - Uno R4 WiFi:
dfu_wifi.hex - Uno R4 Nano:
dfu_nano.hex
- Uno R4 Minima:
Uno R4: CAN Bus
- ชิป RA4M1 มีวงจร CAN Controller อยู่ภายใน สามารถนำไปใช้งานได้กับระบบบัส CAN (Controller Area Network)
- รองรับการทำงานตามโพรโตคอล CAN 2.0A / 2.0B ความเร็วสูงสุด 1Mbps
- จะต้องมีการต่ออุปกรณ์เสริม คือ โมดูล หรือ วงจร CAN Transceiver
- ขา I/O ของบอร์ด Uno R4 รองรับสัญญาณลอจิกระดับ 5V ดังนั้นจึงต้องใช้กับชิป CAN Transceiver ที่รองรับ 5V เช่น
- MCP2551
- TJA1050
- มีไลบรารีสำหรับการเขียนโค้ดใช้งานได้อย่างสะดวก:
Arduino_CAN - ดูเอกสารเพิ่มเติม: Uno R4 Minima - CAN Tutorial
Uno R4: Ethernet Shield
- เนื่องจากบอร์ด Uno R4 มีรูปแบบ Form Factor เหมือน Uno R3 และมีแรงดันลอจิก +5V เหมือนกัน ดังนั้น จึงรองรับ Arduino Ethernet Shield ที่ใช้ชิป W5100 หรือ W5500 ได้ด้วย
- แต่ชิปไมโครคอนโทรลเลอร์ของ Uno R4 มีขนาดของหน่วยความจำมากกว่า Uno R3 ดังนั้น การเขียนโปรแกรมเพื่อใช้งาน ผ่านเครือข่าย Ethernet / Internet โดยใช้ไลบรารี Arduino Ethernet ก็ลดปัญหาข้อจำกัดเรื่องหน่วยความจำ
Arduino Core for Renesas#
ในการเขียนโปรแกรม Arduino Sketch สำหรับบอร์ด Arduino Uno R4 จะต้องมีการติดตั้ง Arduino Core for Renesas โดยสามารถค้นหาและติดตั้งได้ใน Arduino IDE ในส่วน Boards Manager

รูป: การติดตั้ง Arduino Core for Renesas
จากนั้นจึงสามารถเลือกบอร์ด Arduino Uno R4 ซึ่งในกรณีตัวอย่างนี้คือ Arduino Uno R4 Minima แล้วทำขั้นตอน Build และ Upload โดยจะต้องเลือกพอร์ต Serial ให้ตรงกับบอร์ดที่เชื่อมต่อใช้งานในขณะนั้น

รูป: ตัวอย่างข้อความเอาต์พุตที่เกิดขึ้นในขณะทำขั้นตอน Upload
ถ้ากดปุ่ม BOOT ของบอร์ด แบบ Double-Tap จะทำให้บอร์ด Arduino Uno R4 เข้าสู่โหมด DFU USB และสามารถอัปโหลดไฟล์เฟิร์มแวร์ไปยังบอร์ดได้เช่นกันผ่าน DFU Port ตามรูปตัวอย่าง

รูป: การอัปโหลดไฟล์เฟิร์มแวร์ไปยังบอร์ดในโหมด DFU USB
ตัวอย่างโค้ดที่ 1: LED Blink#
โค้ดตัวอย่างนี้ใช้สำหรับกระพริบ LED บนบอร์ด Arduino Uno R4 Minima โดยให้ LED
เปลี่ยนสถานะทุก ๆ 500 มิลลิวินาที (0.5 วินาที) และตรวจสอบเวลาโดยการเรียกใช้คำสั่ง millis()
โดยไม่ใช้ delay() ทำให้ไมโครคอนโทรลเลอร์สามารถทำงานอื่นร่วมกันได้ระหว่างรอเวลา
ภายในฟังก์ชัน setup() มีการเปิดใช้งาน Serial Monitor และกำหนดขา LED_BUILTIN
เป็นเอาต์พุต ส่วนในฟังก์ชัน loop() จะตรวจสอบช่วงเวลาที่ผ่านไป และสลับสถานะ LED ด้วยคำสั่ง
digitalWrite() เพื่อให้ LED กระพริบต่อเนื่องอัตโนมัติและมีอัตราคงที่
#include <Arduino.h>
constexpr uint32_t UPDATE_INTERVAL_MS = 500;
void setup() {
Serial.begin(115200);
while (!Serial && millis() < 3000) { delay(1); }
Serial.println(F("Arduino Uno R4 Minima"));
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
static uint32_t ts = 0;
uint32_t now = millis();
if (now - ts >= UPDATE_INTERVAL_MS) {
ts = now;
// toggle the LED
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
}
ตัวอย่างโค้ดที่ 2: LED Breathing Effect#
โค้ดตัวอย่างนี้สร้างเอฟเฟกต์ "Breathing LED" โดยใช้เทคนิคการสร้างสัญญาณ PWM (Pulse Width Modulation) เพื่อปรับความสว่างของ LED ให้ค่อย ๆ เพิ่มและลดอย่างต่อเนื่อง
หลักการสำคัญคือการใช้คำสั่ง analogWrite() ควบคุมค่า Duty Cycle
ของสัญญาณ PWM ขนาด 8 บิต มีค่าในช่วง 0–255
ค่าดังกล่าวจะสัมพันธ์กับระดับความสว่างของ LED ตัวแปร brightness
ใช้เก็บค่าความสว่างปัจจุบัน ส่วน fade_step ใช้กำหนดทิศทางการเปลี่ยนค่า
เมื่อความสว่างถึงค่าสูงสุดหรือต่ำสุด โปรแกรมจะกลับทิศทางการเปลี่ยนค่าอัตโนมัติ
ทำให้เกิดเอฟเฟกต์คล้ายการหายใจ
#include <Arduino.h>
constexpr int PWM_MAX = 255;
constexpr uint32_t UPDATE_INTERVAL_MS = 5;
void setup() {
Serial.begin(115200);
while (!Serial && millis() < 3000) { delay(1); }
Serial.println(F("Arduino Uno R4 Minima - Breathing LED"));
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
static uint32_t ts = 0;
static int brightness = 0;
static int fade_step = 1;
uint32_t now = millis();
if (now - ts >= UPDATE_INTERVAL_MS) {
ts = now;
// Update LED brightness
analogWrite(LED_BUILTIN, brightness);
// Update brightness level
brightness += fade_step;
// Reverse direction at limits
if (brightness >= PWM_MAX) {
brightness = PWM_MAX;
fade_step = -1;
}
else if (brightness <= 0) {
brightness = 0;
fade_step = 1;
}
}
}
ตัวอย่างโค้ดที่ 3: Arduino I/O Toggle (No Delay)#
โค้ดตัวอย่างนี้ใช้สำหรับสลับสถานะของ LED บนบอร์ด Arduino อย่างต่อเนื่อง
โดยไม่ใช้คำสั่ง delay() จึงไม่มีการหน่วงเวลาภายในลูปหลัก
โปรแกรมจะอ่านสถานะปัจจุบันของ LED ด้วย digitalRead()
แล้วกลับค่าลอจิก ก่อนส่งกลับไปยัง digitalWrite() ทำให้ LED
ถูกสลับระหว่าง ON และ OFF (ติด/ดับ) อย่างรวดเร็วที่สุด
ตามความเร็วการทำงานของไมโครคอนโทรลเลอร์
หลักการสำคัญของตัวอย่างนี้คือ การควบคุมขา I/O แบบดิจิทัลและการทำงานของลูปที่ทำซ้ำอย่างต่อเนื่อง โดยไม่มีการหน่วงเวลา แล้วลองใช้เครื่องมือวัด เช่น ออสซิลโลสโคปวัดสัญญาณเอาต์พุต
#include <Arduino.h>
void setup() {
Serial.begin(115200);
while (!Serial && millis() < 3000) { delay(1); }
Serial.println(F("Arduino Uno R4 Minima"));
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
// Toggle the LED as fast as possible
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
ถัดไปเป็นตัวอย่างการใช้ออสซิลโลสโคปวัดสัญญาณ ซึ่งได้ความถี่ของสัญญาณเอาต์พุตประมาณ 228.67kHz หรือมีคาบเวลาประมาณ 4.373 usec และมีระยะเวลาในการสลับสถานะลอจิก ทุก ๆ 2.122 usec ตามค่าที่วัดได้

รูป: ตัวอย่างการวัดสัญญาณเอาต์พุตที่ขา D13 ด้วยออสซิลโลสโคป (RIGOL DHO814) วัดความกว้างพัลส์ได้ประมาณ 2.12 usec
แม้ว่าจะเขียนโค้ดใน loop() ให้สลับสถานะเอาต์พุตอย่างต่อเนื่อง แต่เมื่อวัดสัญญาณด้วยออสซิลโลสโคป
อาจพบว่าความกว้างของพัลส์ (Pulse Width) หรือคาบสัญญาณบางช่วงไม่คงที่
สาเหตุหลักเกิดจากการทำงานของ Interrupt และระบบเบื้องหลังของ Arduino Framework หรือไมโครคอนโทรลเลอร์ จะต้องทำงานบางช่วงเวลาสำหรับ เช่น USB / Serial communication ซึ่งสามารถแทรกการทำงานของ CPU ได้ชั่วคราว ทำให้ช่วงเวลาระหว่างการสลับสถานะของขา I/O มีระยะเวลายาวขึ้นกว่าปกติในบางจังหวะ

รูป: ตัวอย่างช่วงเวลาที่ตรวจพบว่า สัญญาณพัลส์ที่ความกว้างกว่าปรกติ วัดค่าได้ประมาณ 4.75 usec
ตัวอย่างโค้ดที่ 4: Fast I/O Toggle with Direct Pin Manipulation#
โค้ดตัวอย่างนี้ใช้เทคนิคควบคุมขา I/O โดยตรงผ่านรีจิสเตอร์ของไมโครคอนโทรลเลอร์ Renasas
(Direct Register Access) เพื่อสลับสถานะลอจิกของ LED ด้วยความเร็วสูงที่สุด
แทนการใช้ฟังก์ชันระดับสูงของ Arduino API เช่น digitalWrite() และ digitalRead()
ภายใน loop() โปรแกรมจะเข้าถึงรีจิสเตอร์ PODR11 ของพอร์ต P1.11 โดยตรง
และใช้ตัวดำเนินการ XOR (^= 1) เพื่อกลับสถานะบิตของขา LED
ทำให้ลดขั้นตอนการทำงานของ Arduino Framework ได้อย่างมาก
เมื่อเปรียบเทียบกับตัวอย่างโค้ดก่อนหน้าซึ่งใช้ digitalWrite() และ digitalRead()
การทำงานของโค้ดนี้ จะเร็วกว่ามาก จึงเหมาะสำหรับงานที่ต้องการความเร็วสูง เช่น
การสร้างสัญญาณดิจิทัลความถี่สูง การวัดประสิทธิภาพ I/O หรือการทดลองระดับ low-level
กับฮาร์ดแวร์ไมโครคอนโทรลเลอร์
#include <Arduino.h>
/* Arduino Uno R4 Minima
* Fastest possible LED toggle using direct port access.
* LED_BUILTIN on Uno R4 Minima: D13 -> Port P1.11
*/
#include "r_ioport.h"
// see: https://renesas.github.io/fsp/group___i_o_p_o_r_t.html
void setup() {
Serial.begin(115200);
while (!Serial && millis() < 3000) { delay(1);}
Serial.println(F("Arduino Uno R4 Minima - Fast LED Toggle"));
pinMode(LED_BUILTIN, OUTPUT);
}
// #define R_PORT0 ((R_PORT0_Type *) R_PORT0_BASE)
// see: https://github.com/arduino/ArduinoCore-renesas/variants/MINIMA/
// -> includes/ra/fsp/src/bsp/cmsis/Device/RENESAS/Include/R7FA4M1AB.h
void loop() {
// Toggle the P1.11 pin directly
R_PORT1->PODR_b.PODR11 ^= 1;
}
จากการทดลองวัดสัญญาณเอาต์พุตด้วยออสซิลโลสโคป จะเห็นได้ว่า ความถี่ของสัญญาณได้ประมาณ 1 MHz (มีคาบประมาณ 1 usec และมีความกว้างพัลส์ประมาณ 500 nsec) ซึ่งเร็วกว่าการทำงานของโค้ดในตัวอย่างที่แล้ว

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

รูป: ตัวอย่างสัญญาณในช่วงเวลาที่มีระยะเวลาในสลับลอจิกไม่คงที่

รูป: ตัวอย่างการตั้งค่า Trigger Type โดยเลือกเป็น Pulse เพื่อตรวจสอบความกว้างของพัลส์ ที่มากกว่าค่าที่กำหนดไว้ เช่น 2.5 usec (โดยให้มากกว่า 0.5 usec) ซึ่งจะพบว่า มีบางช่วงเวลาที่มีสัญญาณพัลส์ กว้างกว่าค่าในช่วงปรกติอย่างเห็นได้ชัด
การใช้คำสั่งระดับล่าง (Low-Level Programming) เพื่อเข้าถึงรีจิสเตอร์ที่เกี่ยวข้องกับ I/O และกำหนดค่าลอจิกโดยตรง อีกรูปแบบหนึ่ง มีตัวอย่างดังนี้ จะเห็นได้ว่า ในตัวอย่างนี้มีการปิดการทำงานของอินเทอร์รัพท์ของระบบด้วยคำสั่ง noInterrupts()
R_PORT1->PCNTR3 คือ การเข้าถึงรีจิสเตอร์ควบคุมพอร์ต I/O ของไมโครคอนโทรลเลอร์โดยตรง
ในกรณีนี้เป็นรีจิสเตอร์ Port Control Register หมายเลข 3 ของพอร์ต PORT1
เพื่อสั่งให้ขา I/O เปลี่ยนสถานะลอจิกแบบ Set/Reset ได้โดยตรง
#include <Arduino.h>
// P111 bit mask in the two halves of PCNTR3.
static constexpr uint32_t P111_SET = (1UL << 11); // POSR.B11
static constexpr uint32_t P111_RESET = (1UL << (11 + 16)); // PORR.B11
void setup() {
// pinMode() handles the PFS unlock dance (PWPR), sets PMR=GPIO, and
// PDR=output for P111. After this point we never touch the pin
// through the Arduino API again.
pinMode(13, OUTPUT);
// Stop SysTick / USB / UART IRQs from stealing cycles mid-loop.
noInterrupts();
// Toggle the I/O pin (D13 / P111 pin)
for (;;) {
R_PORT1->PCNTR3 = P111_SET;
R_PORT1->PCNTR3 = P111_RESET;
}
}
void loop() {
}

รูป: ตัวอย่างสัญญาณเอาต์พุต วัดความถี่ได้ 6MHz
ตัวอย่างโค้ดที่ 5: Timer-based I/O Toggle#
โค้ดตัวอย่างนี้ใช้ฮาร์ดแวร์ GPT (General PWM Timer) ของไมโครคอนโทรลเลอร์ Renesas R7FA4M1
เพื่อสร้างสัญญาณเอาต์พุตที่มีความถี่คงที่ และแม่นยำ โดยไม่ต้องอาศัยการวนลูปใน loop()
หลักการสำคัญคือการตั้งค่า Timer ให้ทำงานแบบ Periodic Interrupt ที่มีอัตรา Toggle Rate เช่น
2 kHz, 20 kHz หรือ 200 kHz
และเมื่อ Timer Overflow จะเรียกฟังก์ชัน timer_callback() อัตโนมัติ ภายในฟังก์ชัน Callback
ดังกล่าว มีการสลับสถานะขา P1.11 (D13) และใช้เวลาในการทำงานของซีพียูให้น้อยที่สุด
แนวทางนี้แตกต่างจากตัวอย่างก่อนหน้า ซึ่งใช้ CPU ทำคำสั่งเพื่อวนลูปตรวจสอบและสลับสถานะขาโดยตรง ทำให้ความกว้างพัลส์อาจไม่คงที่จากการทำงานเบื้องหลังของระบบ แต่ในตัวอย่างนี้ วงจร Hardware Timer จะเป็นตัวกำหนดจังหวะเวลาแทน CPU จึงเหมาะสำหรับงานสร้างสัญญาณความถี่สูง แต่ถ้าจะใช้ความถี่สูงมาก ๆ จะมีข้อจำกัดของ Interrupt Overhead
#include <Arduino.h>
// Arduino Uno R4 core version 1.5.3
// see: https://github.com/arduino/ArduinoCore-renesas/releases
#include <FspTimer.h>
#include "bsp_api.h"
constexpr float FREQ_HZ = 2e5f; // Toggle rate: 200 kHz
FspTimer timer;
void timer_callback(timer_callback_args_t *p_args) {
(void)p_args;
R_PORT1->PODR_b.PODR11 ^= 1; // Toggle D13 = P111
}
bool initTimer() {
// Timer type variable required by old API
uint8_t timer_type = GPT_TIMER;
// Request available GPT timer
int8_t channel = FspTimer::get_available_timer(timer_type);
if (channel < 0) {
Serial.println("No timer available!");
return false;
}
Serial.print("Using channel: ");
Serial.println(channel);
bool ok = timer.begin(
TIMER_MODE_PERIODIC,
timer_type,
channel,
FREQ_HZ,
50.0f,
timer_callback);
if (!ok) {
Serial.println("Timer begin failed!");
return false;
}
ok = timer.setup_overflow_irq();
if (!ok) {
Serial.println("IRQ setup failed");
return false;
}
ok = timer.open();
if (!ok) {
Serial.println("Timer open failed");
return false;
}
ok = timer.start();
if (!ok) {
Serial.println("Timer start failed");
return false;
}
return true;
}
void setup() {
Serial.begin(115200);
while (!Serial && millis() < 3000) { delay(1); }
Serial.println("Uno R4 Minima - GPT Timer Test");
pinMode(LED_BUILTIN, OUTPUT);
if (!initTimer()){
while(1) { delay(1); } //blocking
}
Serial.println("Timer running");
}
ตัวอย่างการวัดสัญญาณเอาต์พุตด้วยออสซิลโลสโคป ซึ่งมีการทดลองใช้อัตรา Toggle Rate ที่แตกต่างกัน

รูป: สัญญาณเอาต์พุต วัดความถี่ได้ 1 kHz (Toggle Rate: 2 kHz)

รูป: สัญญาณเอาต์พุต วัดความถี่ได้ 10 kHz (Toggle Rate: 20 kHz)

รูป: สัญญาณเอาต์พุต วัดความถี่ได้ 100 kHz (Toggle Rate: 200 kHz)
ตัวอย่างโค้ดที่ 6: FreeRTOS-based I/O Toggle#
โค้ดตัวอย่างนี้สาธิตการใช้ระบบปฏิบัติการเวลาจริง FreeRTOS ร่วมกับ Arduino Uno R4 Minima โดยสร้างทาสก์ Task) แยกสำหรับควบคุมการกระพริบ LED
หลักการสำคัญคือการแบ่งงานออกเป็นทาสก์อิสระ และให้ FreeRTOS scheduler
เป็นผู้จัดสรรเวลาการทำงานของ CPU ภายในฟังก์ชัน ledTask() ซึ่งจะสลับสถานะ LED
แล้วหยุดรอด้วยคำสั่ง vTaskDelay() เป็นการหน่วงเวลาแบบ Non-blocking ของ FreeRTOS
ทำให้ทาสก์อื่น (ถ้ามี) สามารถทำงานได้พร้อม ๆ กันได้ในระบบ
pdMS_TO_TICKS() เป็น C Macro ของ FreeRTOS
ที่ใช้แปลงหน่วยเวลา มิลลิวินาที (ms) ให้เป็นจำนวน Ticks ของระบบปฏิบัติการ (RTOS ticks)
vTaskDelay(pdMS_TO_TICKS(BLINK_INTERVAL_MS)); จะทำให้ทาสก์หน่วงเวลาไว้ ตามค่าที่กำหนดไว้โดย
BLINK_INTERVAL_MS (เช่น 5 มิลลิวินาที)
ในฟังก์ชัน setup() มีการสร้างทาสก์ ด้วยคำสั่ง xTaskCreate() และเริ่ม FreeRTOS Scheduler
ด้วย vTaskStartScheduler() หลังจากนั้น FreeRTOS จะเข้าควบคุมการทำงานแทน loop()
ของ Arduino
#include <Arduino.h>
#include <Arduino_FreeRTOS.h>
/*
Arduino Uno R4 Minima
FreeRTOS LED Blink Example
The Renesas Arduino core already includes FreeRTOS.
*/
constexpr uint32_t BLINK_INTERVAL_MS = 5;
// Task entry function for LED toggle
void ledTask(void *pvParameters) {
(void) pvParameters;
pinMode(LED_BUILTIN, OUTPUT);
while (1) {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
// FreeRTOS delay
vTaskDelay( pdMS_TO_TICKS(BLINK_INTERVAL_MS) );
}
}
void setup() {
Serial.begin(115200);
while (!Serial && millis() < 3000) { delay(1); }
Serial.println("Uno R4 Minima - FreeRTOS Blink");
#ifdef tskKERNEL_VERSION_NUMBER
Serial.print(F("FreeRTOS Version : "));
Serial.println(tskKERNEL_VERSION_NUMBER);
#else
Serial.println(F("FreeRTOS version macro not found"));
#endif
// Create a FreeRTOS task
BaseType_t status = xTaskCreate(
ledTask, // task function
"LED", // task name
256, // task stack size (in words)
nullptr, // task parameters (arguments)
1, // task priority
nullptr); // task handle
if (status != pdPASS) {
Serial.println("Task creation failed!");
while (1) {} // Blocking
}
Serial.println("Task created...");
vTaskStartScheduler(); // Start the FreeRTOS scheduler
for(;;);
}
void loop() {
}
ตัวอย่างการวัดสัญญาณเอาต์พุตด้วยออสซิลโลสโคป มีดังนี้

รูป: สัญญาณเอาต์พุต วัดความถี่ได้ 100 Hz (คาบเวลา 10 msec)
กล่าวสรุป#
บทความนี้ได้นำเสนอข้อมูลเกี่ยวกับวงจรบนบอร์ดและการใช้งาน Arduino Uno R4 Minima มีตัวอย่างการเขียนโปรแกรม Arduino Sketch โดยใช้ Arduino IDE ในเบื้องต้น บอร์ดที่ได้นำมาใช้งานเป็นบอร์ดราคาถูกที่ทำงานได้เหมือนกับ Arduino Uno R4 Minima ผลิตมาจากประเทศจีน และสามารถใช้แทนกันได้ หรือนำมาใช้แทนที่บอร์ด Arduino Uno R3 (legacy) สำหรับผู้ที่สนใจและเริ่มต้นใช้งานบอร์ด Arduino
บทความที่เกี่ยวข้อง
- แนะนำการใช้งานบอร์ด Arduino Uno R4 WiFi ในเบื้องต้น
- แนะนำการใช้งานบอร์ด Arduino Uno R4 Minima (ตอนที่ 2)
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
Created: 2026-05-17 | Last Updated: 2026-05-25