ลองใช้บอร์ด Arduino ฟังคำสั่งภาษาไทย

Supachai Vorapojpisut
4 min readApr 15, 2024

--

ตอนเดือนธันวาคม 2566 ผมในนามของสมาคมสมองกลฝังตัวไทย (TESA) ประสานงานกับทาง AVNET จัดกิจกรรม hands-on workshop ในหัวข้อ Renesas Voice UI ที่ห้องอบรมอาคารสำนักงานนวัตกรรมแห่งชาติ (NIA) เสียดายที่ต้องใช้คอมพิวเตอร์ในการบันทึกระหว่างอบรม เลยไม่ได้ลองทำตามไปด้วย แต่ก็ยังได้เห็นประโยชน์ของเทคโนโลยีการจดจำคำสั่งเสียงของ Cyberon ที่ทาง Renesas ไปร่วมมือไว้ (ไม่ต้องจ่ายไลเซนส์สำหรับ MCU ในค่าย Renesas) ข้อหนึ่งที่เสียดายคือ บอร์ด Renesas Voice RA6E1 ที่เขาแจกให้กับผู้อบรม ไม่สามารถซื้อได้ทางช่องทางทั่วไปต้องขอเป็น sample ในกรณีพิเศษ รวมทั้งบอร์ด Renesas อื่นๆก็ใช้ทันทีไม่ได้ ต้องเป็นบอร์ดที่ถูกโปรแกรม license key ไว้ในหน่วยความจำแฟลช

กิจกรรมร่วม Renesas Voice UI Solutions โดย TESA x AVNET

ช่วงสงกรานต์กำลังจะเอาบอร์ด Voice RA6E1 มาทดลองหน่อย พอค้นข้อมูลเพิ่มเติมเลยไปเจอข่าวบอร์ด Arduino แท้ 4 รุ่น จะทดลองฟีเจอร์ Speech Recognition Engine แบบ trial ของ Cyberon เลยอยากจะลองหน่อย แต่หากอยากใช้งานแบบจริงจังก็ต้องจ่าย $9 เป็นค่าไลเซนส์ผ่านทาง Arduino Store พอดีมีบอร์ด Arduino Nano RP2040 อยู่ เลยคิดว่าอยากลองสักหน่อย เพราะขั้นตอนของ Renesas ที่พัฒนาด้วย e2 studio ค่อนข้างซับซ้อนหน่อย รวมทั้งเสี่ยงในการไปลบ license key ที่โปรแกรมในหน่วยความจำแฟลชหากไม่ใช้โค้ดตัวอย่าง

บอร์ด Arduino ที่ใช้กับ Cyberon Speech Recognition Engine ได้

เริ่มด้วยโค้ดตัวอย่าง

การขอ trial license จาก Cyberon ต้องเริ่มจากการดึงข้อมูล serial number จากตัวบอร์ดก่อน ขั้นตอนการดึง serial number สำหรับบอร์ด Arduino Nano RP2040 คือ

  1. ติดตั้ง ไลบรารี Cyberon_DSpotterSDK_Maker_RP2040
  2. เปิดโค้ดตัวอย่าง GetSerialNumber.ino
  3. build และ upload ลงในบอร์ด
  4. เช็ค serial number ที่พิมพ์จาก Serial
ชุด serial number ที่รายงานทาง Serial

ตัว serial number เอาไปลงทะเบียน trial license จะได้ license text สำหรับนำไปกรอกในไฟล์ CybLicense.h ตัว license text จะล็อคไว้แค่บอร์ดที่ขอ พอได้ตัว license text เลยขอลองโค้ดตัวอย่าง VR_LEDControl ที่มี model สำเร็จรูปภาษาอังกฤษ โดย trigger word คือ “Hey Arduino” และคำสั่งควบคุม LED 3 สีคือ “LED red” “LED green” “LED blue” และ “LED off” โค้ดตัวอย่างจะใช้ LED ขา 13 บนบอร์ดเพื่อแสดงสถานะ trigger (รอ) / command (คำสั่ง)

การตรวจสอบสถานะผ่าน LED และ Serial

ตัว model ที่ใช้ตรวจจับคำสั่งเสียงจะอยู่ในรูป binary ในไฟล์ Model_L0.h (ไฟล์ขนาดเล็ก ความแม่นยำต่ำ) และไฟล์ Model_L1.h (ไฟล์ขนาดใหญ่ ความแม่นยำสูง) บอร์ด Nano RP2040 มีส่วนประมวลผลเป็น ARM Cortex-M0+ เลยถูกบังคับเลือกเป็น model แบบ L0 เพื่อลดภาระการประมวลผล ในขณะที่อีก 3 บอร์ดสามารถเลือกได้ว่าจะใช้ model แบบ L0 หรือ L1 รายการของคำสั่งและรหัสของ model จะอยู่ในไฟล์ Info.txt ใน folder ย่อย /data เนื้อหาของโค้ดตัวอย่างดูแล้วไม่ซับซ้อน โดยส่วนโค้ด callback จะได้รับข้อมูลของ event รหัสของคำ และพารามิเตอร์ที่ได้จากการตรวจพบคำ trigger/command

void VRCallback(int nFlag, int nID, int nScore, int nSG, int nEnergy) {
if (nFlag==DSpotterSDKHL::InitSuccess) {
// code to handle SDK init success event
} else if (nFlag==DSpotterSDKHL::GetResult) {
switch(nID) {
// code to handle voice commands
}
} else if (nFlag==DSpotterSDKHL::ChangeStage) {
switch(nID) {
// code to handle state changes: trigger <-> command
}
} else if (nFlag==DSpotterSDKHL::GetError) {
// code to handle SDK error
} else if (nFlag == DSpotterSDKHL::LostRecordFrame) {
// code to handle voice streaming issues
}
}

ลองจับเวลาในการประมวลผลส่วนโค้ดหลักคือ g_oDSpotterSDKHL.DoVR() พบว่าค่าเวลามากที่สุดซึ่งแสดงถึงจังหวะการประมวลผลข้อมูลเสียงในบัฟเฟอร์คือ 24 มิลลิวินาที การนับจำนวนครั้งที่พบรอบการประมวลผลคือ 3–4 ครั้งใน 1 วินาที แสดงว่ามี utilization ratio ไม่เกิน 10% จึงยังมีกรอบเวลาในการประมวลผลงานอื่นๆอีกพอสมควร เมื่อพิจารณาว่า RP2040 เป็นหน่วยประมวลผล ARM Cortex-M0+ ทำงานที่ 133 MHz ก็ค่อนข้างประทับใจพอสมควร หากเปลี่ยนไปใช้หน่วยประมวลผลกลุ่ม high-performance เช่น Cortex-M4, M7, … น่าจะประมวลผลสัญญาณหนักๆได้อีก

ผลการทดสอบเวลาประมวลผล

สลับไปใช้คำสั่งภาษาไทย

เมื่อเทียบกับ speech recognition ผ่าน Google Assistant จุดเด่นของ Cyberon ที่เหมาะกับการพัฒนาผลิตภัณฑ์กลุ่มเครื่องใช้ไฟฟ้ามีหลายด้าน ได้แก่

  • ทำงานแบบ offline จึงลดความซับซ้อนในการเชื่อมโยงเครือข่าย
  • ประมวลผลได้ด้วยไมโครคอนโทรลเลอร์
  • รองรับภาษาได้ถึง 40 ภาษา/สำเนียง

ประเด็นภาษาเป็นเรื่องสำคัญอย่างมากในการพัฒนาผลิตภัณฑ์สำหรับนำไปใช้ในสถานการณ์ smart home การแปลงคำสั่งจากเดิมภาษาอังกฤษมาเป็นคำสั่งภาษาไทยใช้การสร้าง model ใหม่จากข้อความที่เราเลือก ขั้นตอนที่อธิบายในโค้ดตัวอย่างมีดังนี้

  1. กรอกข้อมูล email device และบอร์ดที่ใช้ในเว็บตั้งค่า model และยอมรับ license การใช้งาน
  2. เลือกภาษาที่จะใช้เป็น project
  3. เลือกข้อความที่จะเป็น trigger และคำสั่ง
  4. หลังจากยืนยัน ไฟล์ model จะถูกส่งมาทาง email
การสร้าง model คำสั่งภาษาไทยแบบออนไลน์

พอเอาไฟล์ใน email ไปแทนไฟล์ CybLicense.h และไฟล์ Model_L0.h ในโค้ดตัวอย่าง VR_LEDControl เดิมก็จะสามารถทำงานได้ทันที แต่ปัญหาของ model ที่สร้างใหม่คือ การบังคับหน่วงเวลา 20 วินาทีสำหรับการรับ trigger แต่ละรอบ ซึ่งจะเห็นได้จากข้อความที่รายงานทาง Serial ประเด็นนี้เป็นส่วนหนึ่งของข้อจำกัดของ trial license (1 trigger, ไม่เกิน 20 คำสั่ง, …) เมื่อเทียบกับ full license

การทดลองคำสั่งเสียงแบบภาษาไทย

ผลของการทดลองพูดคำสั่งเรียงตามลำดับ รู้สึกได้ว่าการตรวจจับคำสั่งจากเสียงพูดภาษาไทยยังไม่เป๊ะนัก อาจจะเกิดจากการใช้ model ระดับ L0 ที่ความแม่นยำต่ำ คำสั่ง “ไฟเขียวติด” (แทนคำสั่ง “LED green”) ตรวจจับไม่ได้เลย ในขณะที่คำสั่งอื่นตรวจจับได้ ok ส่วนคำ trigger คือ “สวัสดีครับ” ต้องออกเสียงช้าหน่อยถึงจะตรวจพบ แต่พอลองสลับไปใช้ Google Translate ออกเสียงพูด กลับแม่นยำกว่า

เชื่อมต่อออนไลน์

บอร์ด Arduino Nano RP2040 Connect มีโมดูล u-blox NINA-WT102 (ไส้ในคือ ESP32) สำหรับเชื่อมต่อเครือข่ายไร้สาย WiFi และ Bluetooth การเพิ่มฟีเจอร์ให้กับระบบสั่งการด้วยเสียงจึงเป็นเรื่องที่ไม่ยากนัก โดยทดลองไอเดียด้วยโพรโทคอล MQTT ที่มี overhead น้อยหน่อย ผมใช้ Platform.io ในการ build โค้ดตัวอย่าง จึงเริ่มด้วยการเพิ่มไลบรารี WiFiNINA (ทดแทนไลบรารี WiFi มาตรฐาน), PubSubClient, และ ArduinoJSON แล้วจึงไปปรับแก้โค้ด การเพิ่มความปรับแก้โค้ดก็เลือกทำทั้ง 2 ทาง

  • ตอนได้รับคำสั่งเสียง ให้รายงานสถานะเป็น JSON ไปยัง MQTT broker
  • เปิดรับ command ควบคุม LED ในรูปแบบ JSON ผ่านทาง MQTT

ตอนเพิ่มส่วนโค้ดโพรโทคอล MQTT เข้ากับโค้ดตัวอย่าง ผมเจอข้อความ lost recording frame รัวๆ จนทำให้ไม่สามารถตรวจจับคำสั่งเสียงได้เลย การไล่หาจุดปัญหาพบว่าช่วงการลองเช็คว่ายังเชื่อมต่อกับ MQTT broker หรือไม่ ซึ่งเป็นรูปแบบที่นิยมเขียนกัน ทำให้เกิดการหน่วงเวลาจนรับข้อมูลเสียงบางส่วนไม่ทัน ดังนั้นจึงต้องเลือกให้เชื่อมต่อ WiFi/MQTT ภายในฟังก์ชัน setup() ซึ่งก็ดีขึ้นทันที

การทดลองฟีเจอร์ Voice Command + MQTT

終わりに (ในตอนท้าย)

การทดลอง Speech Recognition Engine ที่ Arduino ร่วมมือกับ Cyberon ก็ถือว่าประทับใจในแง่โค้ดที่เรียบง่ายและขั้นตอนที่สะดวกด้วยเครื่องมือออนไลน์ แต่การหน่วงเวลาถึง 20 วินาทีในการตรวจจับข้อความ trigger ก็เหมือนเป็นการบังคับกลายๆให้จ่ายเงิน $9 เพื่อไปปลดล็อกข้อจำกัดนี้ แถมการจ่ายเงินนี้จะล็อกตามบอร์ดไม่ใช่ตามคนซื้อ ดังนั้นคนที่อยากจะเอาไปทำ project อะไรก็ควรจะรับรู้เงื่อนไขนี้ก่อน เพราะอาจงบบานปลายได้หากต้องขยายจำนวนอุปกรณ์ สำหรับผู้ประกอบการ การเลือกใช้ฮาร์ดแวร์ที่มีข้อตกลงกับ Cyberon ไว้ก่อน เช่น Renesas ดูแล้วจะเป็นทางเลือกที่ดีกว่ามาก แต่ก็คงต้องคุยกับทางทีมงาน Renesas หรือตัวแทนจำหน่าย เช่น AVNET ให้ลงตัวก่อน

--

--

Supachai Vorapojpisut
Supachai Vorapojpisut

Written by Supachai Vorapojpisut

Assistant Professor at Thammasat University

No responses yet