สารบัญ:
วีดีโอ: QuickFFT: FFT ความเร็วสูงสำหรับ Arduino: 3 ขั้นตอน
2024 ผู้เขียน: John Day | [email protected]. แก้ไขล่าสุด: 2024-01-30 13:03
Arduino ทั่วไปมี RAM และกำลังประมวลผลที่จำกัด และ FFT เป็นกระบวนการที่ต้องใช้คอมพิวเตอร์มาก สำหรับแอปพลิเคชันแบบเรียลไทม์จำนวนมาก ข้อกำหนดเพียงอย่างเดียวคือการรับความถี่ที่มีแอมพลิจูดสูงสุดหรือจำเป็นในการตรวจจับความถี่สูงสุด
หนึ่งในคำแนะนำของฉัน ฉันได้เตรียมรหัสสำหรับ FFT ที่สามารถพบได้ที่นี่: EasyFFT
รหัสนี้สามารถทำ FFT ได้ถึง 128 ตัวอย่างบน Arduino nano ไม่สามารถสุ่มตัวอย่างที่สูงกว่านี้ได้เนื่องจากหน่วยความจำที่จำกัดของ Arduino ฉันได้ปรับเปลี่ยนฟังก์ชันเล็กน้อยเพื่อปรับปรุงความเร็วและลดการใช้หน่วยความจำ การปรับเปลี่ยนนี้ช่วยให้ Arduino ดำเนินการ FFT ได้เร็วขึ้นห้าเท่าและใช้หน่วยความจำเกือบครึ่งหนึ่ง คำแนะนำนี้ไม่ครอบคลุมถึงการทำงานของ FFT สามารถดูข้อมูลอ้างอิงได้ที่ EasyFFT
ขั้นตอนที่ 1: การทำงาน
ฟังก์ชัน FFT ทั่วไปได้รับการแก้ไขเพื่อปรับปรุงความเร็วโดยมีความแม่นยำน้อยลง ดังที่แสดงในภาพ สัญญาณทดสอบจะต้องคูณด้วยรูปคลื่นไซน์หรือโคไซน์ ค่าเหล่านี้สามารถอยู่ระหว่าง 0 ถึง 1 ดังนั้นการคูณแบบลอยตัวจึงเป็นสิ่งจำเป็น ใน Arduino การคูณแบบลอยตัวจะช้าเมื่อเทียบกับการดำเนินการจำนวนเต็ม
ในฟังก์ชันนี้ คลื่นไซน์/โคไซน์จะถูกแทนที่ด้วยคลื่นสี่เหลี่ยม เนื่องจากเราต้องคูณสัญญาณทดสอบด้วยคลื่นสี่เหลี่ยมซึ่งอาจมีค่า 0, 1 หรือ -1 ด้วยเหตุนี้ เราจึงสามารถแทนที่การคูณแบบลอยตัวเป็นการบวกหรือการลบจำนวนเต็มได้ สำหรับการบวกหรือลบจำนวนเต็ม Arduino เร็วขึ้นประมาณ 5 เท่า ทำให้แก้ได้เร็วขึ้นประมาณ 5 เท่า
เนื่องจากการปรับเปลี่ยนนี้ ขณะนี้ค่าช่องเก็บความถี่สามารถจัดเก็บเป็นจำนวนเต็ม (ซึ่งก่อนหน้านี้ลอยอยู่) และเราได้รับประโยชน์จากการใช้หน่วยความจำที่ลดลงอีก ใน Arduino Nano นั้น int ใช้หน่วยความจำ 2 ไบต์ในขณะที่ float ใช้หน่วยความจำ 4 ไบต์ ด้วยข้อได้เปรียบนี้ในโค้ดใหม่ เราจึงสามารถดำเนินการ FFT ได้เกือบ 256 ตัวอย่าง (จากเดิม 128 ตัวอย่าง)
ใน Normal FFT เราจำเป็นต้องเก็บค่า sine เพื่อให้การแก้ปัญหาเร็วขึ้น ในฟังก์ชันใหม่ เนื่องจากเราไม่ต้องการค่าไซน์/โคไซน์อีกต่อไป เราจึงสามารถกำจัดมันและบันทึกหน่วยความจำบางส่วนได้
การดำเนินการ:
การใช้ฟังก์ชันนี้ตรงไปตรงมา เราสามารถคัดลอกฟังก์ชันที่ส่วนท้ายของโค้ด ฟังก์ชั่นนี้สามารถดำเนินการได้โดยใช้คำสั่งด้านล่าง:
float f= Q_FFT(data, 256, 100);ในฟังก์ชัน Q_FFT,
data: เทอมนี้เป็นอาร์เรย์ที่มีค่าสัญญาณ ขนาดตัวอย่างที่แนะนำคือ 2, 4, 8, 32, 64, 128, 256, 512, … เป็นต้นไป ถ้าขนาดตัวอย่างไม่ใช่ของค่าเหล่านี้ จะถูกตัดไปที่ด้านล่างสุดของค่าที่ใกล้ที่สุด ตัวอย่างเช่น ถ้าขนาดกลุ่มตัวอย่าง 75 กว่า FFT จะดำเนินการกับจำนวนตัวอย่าง 64 ตัวอย่าง ขนาดตัวอย่างสูงสุดถูกจำกัดโดย RAM ที่มีอยู่บน Arduino
เทอมที่สองระบุจำนวนตัวอย่างในอาร์เรย์ และเทอมสุดท้ายคือความถี่สุ่มตัวอย่างในหน่วย Hz
ขั้นตอนที่ 2: รหัส
ส่วนนี้อธิบายการดัดแปลงที่ทำในโค้ด EasyFFT ที่ต้องจำไว้ในขณะที่ทำการแก้ไขในโค้ด
1. ตามที่อธิบายไว้ก่อนหน้านี้ จะใช้เลขจำนวนเต็มเพื่อทำ FFT Int ใน Arduino เป็นตัวเลข 16 บิตและสามารถมีค่าได้ตั้งแต่ -32768 ถึง 32768 เมื่อใดก็ตามที่ค่าของ int นี้เกินช่วงนี้จะทำให้เกิดปัญหา เพื่อขจัดปัญหานี้หลังจากการคำนวณระดับ หากค่าใดเกิน 15,000 อาร์เรย์ที่สมบูรณ์จะถูกหารด้วย 100 ซึ่งจะป้องกันไม่ให้ int ล้น
2. การคำนวณแอมพลิจูด: ในการคำนวณแอมพลิจูด ส่วนจริงและจินตภาพจะต้องยกกำลังสองและรากที่สองของผลรวม การยกกำลังสองและรากที่สองของฟังก์ชันต้องใช้เวลา เพื่อให้กระบวนการเร็วขึ้น โค้ดนี้จะทำขนาดบางส่วนของส่วนจริงและส่วนจินตภาพ สิ่งนี้แม่นยำน้อยกว่าและอาจนำไปสู่ข้อสรุปที่ไม่ถูกต้องในบางกรณี คุณอาจเลือกที่จะกลับไปใช้วิธีการปกติสำหรับการคำนวณขนาด แต่จะใช้เวลามากขึ้นและคุณต้องจัดการบางอย่างเพื่อเก็บตัวเลขเหล่านี้
3. รหัสนี้ไม่มีโมดูลสำหรับการตรวจจับจุดสูงสุดหลายจุด มันจะเลือกค่าที่มีแอมพลิจูดสูงสุด (ไม่รวมตัวเลขแรกที่เป็น DC offset) หากคุณต้องการพีคหลายจุด คุณสามารถอ้างอิงโค้ด EasyFFT และทำการแก้ไขที่จำเป็นได้ที่นี่ ในกรณีนั้น อาร์เรย์/ตัวแปรบางตัวจำเป็นต้องประกาศเป็นตัวแปรส่วนกลางด้วย
4. ฟังก์ชั่นประกอบด้วยบรรทัดต่อไปนี้:
unsigned int Pow2[13]={1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};
การประกาศตัวแปรข้างต้นเป็นตัวแปรส่วนกลาง (วางที่จุดเริ่มต้นของโค้ด) จะช่วยประหยัดเวลาได้ 1 มิลลิวินาทีในการดำเนินการทุกครั้ง
5. ไม่เหมือนกับฟังก์ชัน EasyFFT ที่จัดเก็บจุดสูงสุด 5 อันดับแรกไว้ในอาร์เรย์ที่กำหนดไว้ล่วงหน้า ฟังก์ชันนี้จะคืนค่าโฟลต ค่านี้แสดงถึงความถี่ที่มีแอมพลิจูดสูงสุดในหน่วย Hz ดังนั้นการแสดงโค้ดจะออกมาประมาณนี้
float f= Q_FFT(ข้อมูล, 256, 100);
6. การตรวจจับสูงสุด: เมื่อพบความถี่ที่มีแอมพลิจูดสูงสุด ฟังก์ชันนี้จะใช้แอมพลิจูดของความถี่ก่อนและหลังเพื่อคำนวณผลลัพธ์ที่แม่นยำ แอมพลิจูดที่ใช้ในการคำนวณนี้ยังเป็นผลรวมของโมดูลัสด้วย (ไม่ใช่รากที่สองของผลรวมกำลังสอง)
ถ้า Fn คือความถี่ที่มีแอมพลิจูดสูงสุด ความถี่สามารถคำนวณได้จากสูตรด้านล่าง
F= จริง = (A n-1 *Fn-1 + An-1 *Fn-1 + An-1 *Fn-1) / (An-1+An+An+1)
โดยที่ An คือแอมพลิจูดของ n ความถี่และ Fn-1 คือค่าความถี่
ขั้นตอนที่ 3: ผลลัพธ์:
เวลาในการแก้ปัญหาจะแสดงในการเปรียบเทียบภาพด้านบนกับ EasyFFT ความเร็วของมันแสดงด้วยการเปรียบเทียบ
สำหรับข้อมูลตัวอย่างที่มีคลื่นไซน์ 3 คลื่นที่มีความถี่ต่างกันจะแสดงขึ้น ผลลัพธ์จาก QuickFFT ถูกเปรียบเทียบกับผลลัพธ์ของ Scilab ดังที่เราเห็นในภาพ 3 พีคที่มีแอมพลิจูดสูงสุดจับคู่กับเอาต์พุต Scilab อย่างไรก็ตาม เอาต์พุตมีเสียงรบกวนมาก ซึ่งอาจทำให้เข้าใจผิดสำหรับบางแอปพลิเคชัน ดังนั้นจึงควรตรวจสอบรหัสให้ถูกต้องก่อนสมัคร
ฉันหวังว่าคุณจะพบว่ารหัสนี้มีประโยชน์สำหรับโครงการของคุณ ในกรณีที่มีข้อสงสัยหรือข้อเสนอแนะโปรดแสดงความคิดเห็น
แนะนำ:
Arduino FFT Visualizer พร้อมไฟ LED ที่สามารถระบุตำแหน่งได้: 4 ขั้นตอน
Arduino FFT Visualizer พร้อมไฟ LED ที่สามารถระบุตำแหน่งได้: บทช่วยสอนนี้จะอธิบายวิธีสร้าง Audio Visualizer ด้วย Arduino Uno และ LED บางตัวที่สามารถระบุตำแหน่งได้ นี่เป็นโครงการที่ฉันอยากทำมาสักระยะแล้ว เพราะฉันเป็นคนดูดเสียงแสงปฏิกิริยา ไฟเหล่านี้ใช้ FFT (Fast Fou
DIY FFT Audio Spectrum Analyzer: 3 ขั้นตอน
DIY FFT Audio Spectrum Analyzer: เครื่องวิเคราะห์สเปกตรัม FFT เป็นอุปกรณ์ทดสอบที่ใช้การวิเคราะห์ฟูริเยร์และเทคนิคการประมวลผลสัญญาณดิจิทัลเพื่อให้การวิเคราะห์สเปกตรัม การใช้การวิเคราะห์ฟูริเยร์ทำให้สามารถแปลงค่าหนึ่งค่าใน ตัวอย่างเช่น โดเมนเวลาต่อเนื่องที่แปลง
EasyFFT: Fast Fourier Transform (FFT) สำหรับ Arduino: 6 ขั้นตอน
EasyFFT: Fast Fourier Transform (FFT) สำหรับ Arduino: การวัดความถี่จากสัญญาณที่จับได้อาจเป็นงานที่ยาก โดยเฉพาะใน Arduino เนื่องจากมีกำลังในการคำนวณต่ำกว่า มีวิธีการต่างๆ ที่ใช้ได้ในการจับภาพการข้ามศูนย์ซึ่งจับความถี่โดยการตรวจสอบจำนวนครั้งที่
การลอยแบบอะคูสติกด้วย Arduino Uno ทีละขั้นตอน (8 ขั้นตอน): 8 ขั้นตอน
การลอยแบบอะคูสติกด้วย Arduino Uno ทีละขั้นตอน (8 ขั้นตอน): ตัวแปลงสัญญาณเสียงล้ำเสียง L298N Dc ตัวเมียอะแดปเตอร์จ่ายไฟพร้อมขา DC ตัวผู้ Arduino UNOBreadboardวิธีการทำงาน: ก่อนอื่น คุณอัปโหลดรหัสไปยัง Arduino Uno (เป็นไมโครคอนโทรลเลอร์ที่ติดตั้งดิจิตอล และพอร์ตแอนะล็อกเพื่อแปลงรหัส (C++)
1024 ตัวอย่าง FFT Spectrum Analyzer โดยใช้ Atmega1284: 9 ขั้นตอน
1024 ตัวอย่าง FFT Spectrum Analyzer โดยใช้ Atmega1284: บทช่วยสอนที่ค่อนข้างง่ายนี้ (เมื่อพิจารณาถึงความซับซ้อนของหัวข้อนี้) จะแสดงให้คุณเห็นว่าคุณสามารถสร้างเครื่องวิเคราะห์สเปกตรัม 1024 ตัวอย่างที่ง่ายมากโดยใช้บอร์ดประเภท Arduino (1284 Narrow) และพล็อตเตอร์แบบอนุกรมได้อย่างไร Arduino compa ทุกชนิด