|
SDK สำหรับ TESAIoT Dev Kit
คู่มืออ้างอิง API และ Tutorial (MTB & µPython)
|
task ของเรดาร์และสาย DSP ของมันเป็นซอร์สของเทมเพลตฝั่ง CM55 ในทั้ง 2 แพ็กเกจ ส่วนการเรียก sensors.radar* ทั้ง 3 ตัวเป็นไคลเอนต์ IPC บาง ๆ ที่วางอยู่บน task นั้น และมีเฉพาะบน mtb-mpy บน mtb-only ให้อ่านสถานะเดียวกันผ่านตัวแปร extern และฟังก์ชันวินิจฉัย 2 ตัว ซึ่งเป็นสิ่งที่หน้าจอบนบอร์ดทำอยู่ในทั้งสอง variant
เมื่อจบบทนี้จะดึงค่าแฟล็กการมีอยู่ ค่าพลังงาน และระยะถึงยอดคลื่นแรกออกจาก BGT60TR13C ได้ ตั้งเกณฑ์การตรวจจับและเก็บค่าฐานของ clutter ใหม่ได้ และ — เมื่อตัวเลขค้าง ซึ่งเป็นความล้มเหลวที่เซนเซอร์ตัวนี้มีอยู่จริง — อ่านชุดข้อมูลวินิจฉัย 3 ค่า 2 ชุดที่บอกได้ว่า สิ่งใด ใน 3 สิ่งที่หยุดไป: ลิงก์ SPI ตัวจัดลำดับเฟรม หรือตัว task เอง
เรดาร์อยู่บน CM55 ทั้งหมด tesaiot_radar_task() (radar_task.h:96) ยก SPI ขึ้น ตั้งค่า BGT60TR13C แล้วจึงวนถาม: อ่านหนึ่งเฟรมคำนวณพลังงาน ปรับแฟล็กการมีอยู่ ตัวแปรทั่วไปชนิด volatile 3 ตัวพาผลลัพธ์ไปให้ผู้ที่ต้องการ — tesaiot_radar_presence_detected (:72), tesaiot_radar_current_energy (:77) และ tesaiot_radar_initialized (:82) ไม่มี lock: เป็นการอ่านเวิร์ด 3 ครั้ง
สาย DSP เป็นผู้อ่านรายที่สองของเฟรมชุดเดียวกัน radar_dsp.c/h รันไปป์ไลน์ขนาด 128 ตัวอย่าง — RADAR_DSP_N มีค่า 128 (radar_dsp.h:29) — ผ่าน radar_dsp_process() (:48) เก็บ snapshot ของระยะไว้ให้ radar_dsp_snapshot() (:59) ดึงไปใช้ และรับเกณฑ์การตรวจจับผ่าน radar_dsp_set_threshold_x10() (:52) ค่าเริ่มต้นที่คอมไพล์มาคือ RADAR_DSP_THRESHOLD_DB 6.0 (radar_dsp.h:32)
MicroPython เป็นไคลเอนต์ ไม่ใช่ไดรเวอร์ การเรียกฝั่ง Python ทั้ง 3 ตัวเป็นการเดินทางไป-กลับผ่าน IPC เข้าสู่ task นั้น ด้วยงบการลองใหม่และ timeout ชุดเดียวกัน: ลองส่ง 20 ครั้ง ห่างกันครั้งละ 100 µs แล้วรอคำตอบ 500 ms (modsensors.c:301-303) sensors.radar() ส่ง IPC_CMD_RADAR_STATUS (modsensors.c:306) ส่วน radar_range() และ radar_config() ใช้ฟังก์ชันช่วยตัวเดียวกันคือ radar_dsp_ipc_roundtrip() (modsensors.c:367) จึงใช้คู่บัฟเฟอร์ในหน่วยความจำร่วมชุดเดียวกัน — โดยเจตนา เพราะพื้นที่ร่วมเต็มแล้วบนชุดคิตบางรุ่นความล้มเหลวทั้ง 2 แบบโยน OSError: "radar IPC send failed" เมื่อ pipe ไม่รับข้อความ และ "radar IPC timeout" เมื่อ CM55 ไม่ตอบภายใน 500 ms
radar_range() มีรูปแบบความล้มเหลวแบบที่สี่ซึ่งไม่ใช่ความล้มเหลวของ IPC หากคำตอบกลับมาโดย initialized เป็น false มันจะโยน OSError("radar dsp not running") (modsensors.c:417-419) — ลิงก์ปกติดี เพียงแต่สาย DSP ยังไม่ขึ้น
ความหมายของเกณฑ์ รวมถึงค่าพิเศษ sensors.radar_config(threshold_db) (modsensors.c:444):
ไม่มีวิธีอ่านค่าเกณฑ์ปัจจุบันกลับมา
Edge AI ระบายชุด chirp ชุดเดียวกัน ภายใต้ BENTO_HAS_EDGE_AI=1 ฟังก์ชัน radar_ai_frame_next() (radar_task.h:147) ส่ง chirp ขนาด 128 ตัวอย่างทุกชุดให้โมเดลตามลำดับ ผ่าน ring ลึก 8 ช่อง ไฟล์ header บันทึกไว้ว่าเหตุใดจึงต้องมี ring นี้: ช่องเก็บแบบเก็บเฉพาะชุดล่าสุดทิ้ง chirp ทุกชุดยกเว้นชุดสุดท้ายของแต่ละรอบการประมวลผลทำให้ chirp เพียง 88 ชุดต่อวินาทีจาก 200 ชุดต่อวินาทีของเรดาร์ไปถึงโมเดล และทำลายรูปแบบดอปเพลอร์ระหว่าง chirp ที่เครือข่ายใช้จำแนก มันเป็น API แบบผู้อ่านรายเดียว — คือการป้อนข้อมูลให้ ai_engine บน CM55 — และไม่ควรเพิ่มผู้อ่านรายที่สอง
บนหน้าจอ หน้าเรดาร์สะท้อนตัวแปรทั่วไป 2 ตัวเดียวกันนี้ หน้าจอกับ REPL จึงไม่มีทางขัดแย้งกันได้
การได้ OSError("radar dsp not running") ที่นี่หมายความว่า initialized เป็น false ในคำตอบ: สายยังไม่ขึ้น ซึ่งต่างจาก "ไม่มีเป้าหมาย"
radar_config(0.05) หรือ radar_config(61) จะโยน ValueError ค่าศูนย์เป็นค่าเดียวนอกช่วง 0.1..60.0 ที่ใช้ได้ และมันหมายถึงสิ่งอื่นโดยสิ้นเชิง
ขั้นนี้เป็นขั้นวินิจฉัย และเป็นภาษา C ในทั้งสอง variant — ไม่มี binding ฝั่ง Python สำหรับฟังก์ชันสถิติ 2 ตัวนี้
| ค่าที่อ่านได้ | ความหมาย |
|---|---|
| tries ไต่ขึ้น fails เป็น 0 | ตัวจัดลำดับเฟรมหยุดชะงัก และ watchdog กำลังแก้ให้วินาทีละครั้ง — เป็นเรื่องจริง และแก้ตัวเองได้ |
| tries และ fails ไต่ขึ้นพร้อมกัน | ลิงก์ SPI ล่ม การเริ่มตัวจัดลำดับใหม่ใช้ไม่ได้ และจะไม่มีวันใช้ได้ |
| tries นิ่ง ในขณะที่ frames ค้าง | ตัว task ของเรดาร์เองไม่ได้ทำงาน |
| loops ค้าง โดย phase อยู่ที่ค่าของ SPI | ติดอยู่ในการวนที่ไม่มีขอบเขตภายในชั้นแพลตฟอร์มของผู้ผลิต รออยู่บนแฟล็กที่มีเพียงอินเทอร์รัปต์ของ SCB เท่านั้นที่ล้างได้ ไม่มีสิ่งใดที่อยู่ถัดไปกู้มันได้ |
| loops ไต่ขึ้น frames ค้าง | ลูปปกติดี และเซนเซอร์หยุดส่งข้อมูล |
อาการบน UI ที่ว่า "พลังงานค้างหลังผ่านไปหนึ่งถึงสองนาที" คืออาการของ 3 แถวแรก และการเรียก 2 ตัวนี้คือสิ่งที่แยกมันออกจากกัน การเดาระหว่างทั้งสามจากหน้าจอทำไม่ได้
| mtb-mpy | mtb-only | |
|---|---|---|
| การมีอยู่ / พลังงาน | sensors.radar() ผ่าน IPC | อ่าน tesaiot_radar_presence_detected และ tesaiot_radar_current_energy ตรง ๆ บน CM55 |
| ระยะ | sensors.radar_range() | radar_dsp_snapshot() (radar_dsp.h:59) |
| เกณฑ์ | sensors.radar_config(db) | radar_dsp_set_threshold_x10() (radar_dsp.h:52) |
| ข้อมูลวินิจฉัย | ไม่มีจากฝั่ง Python | tesaiot_radar_recover_stats(), tesaiot_radar_loop_stats() — ขั้นที่ 4 |
| การป้อนข้อมูลให้ Edge AI | เข้าถึงจากฝั่ง Python ไม่ได้ | radar_ai_frame_next() ผู้อ่านรายเดียว |
| สิ่งที่สังเกตได้ | หน้าเรดาร์ พร้อมกับ dict | หน้าเรดาร์อย่างเดียว |