Mục lục:

QuickFFT: FFT tốc độ cao cho Arduino: 3 bước
QuickFFT: FFT tốc độ cao cho Arduino: 3 bước

Video: QuickFFT: FFT tốc độ cao cho Arduino: 3 bước

Video: QuickFFT: FFT tốc độ cao cho Arduino: 3 bước
Video: [MikroTik] Sử Dụng QuickSet Để Cấu Hình Internet Và Bật FastTrack Giúp RB750Gr3 Chạy Hết Công Suất 2024, Tháng mười một
Anonim
QuickFFT: FFT tốc độ cao cho Arduino
QuickFFT: FFT tốc độ cao cho Arduino

Arduino điển hình có RAM và sức mạnh xử lý hạn chế, và FFT là một quá trình đòi hỏi nhiều tính toán. Đối với nhiều ứng dụng thời gian thực, yêu cầu duy nhất là nhận được tần số với biên độ tối đa hoặc yêu cầu để phát hiện các đỉnh tần số.

Trong một trong những tài liệu hướng dẫn của tôi, tôi đã chuẩn bị một mã cho FFT có thể tìm thấy ở đây: EasyFFT

Mã này có thể thực hiện FFT lên đến 128 mẫu trên Arduino nano. Số lượng mẫu cao hơn mức này là không thể do bộ nhớ của Arduino có hạn. Tôi đã sửa đổi chức năng một chút để cải thiện tốc độ và giảm tiêu thụ bộ nhớ. Sửa đổi này cho phép Arduino thực hiện FFT nhanh hơn năm lần và tiêu tốn gần một nửa bộ nhớ. Tài liệu hướng dẫn này không bao gồm Hoạt động của FFT, bạn có thể tìm thấy tài liệu tham khảo tại EasyFFT.

Bước 1: Làm việc

Đang làm việc
Đang làm việc
Đang làm việc
Đang làm việc
Đang làm việc
Đang làm việc
Đang làm việc
Đang làm việc

Chức năng FFT điển hình được sửa đổi để cải thiện tốc độ với độ chính xác thấp hơn. Như trong hình, một tín hiệu thử nghiệm cần được nhân với các dạng sóng sin hoặc cosine. Các giá trị này có thể nằm trong khoảng từ 0 đến 1, vì vậy việc thực hiện phép nhân nổi là bắt buộc. trong Arduino, phép nhân nổi chậm so với phép toán số nguyên.

Trong hàm này, sóng sin / cosine được thay thế bằng sóng vuông. Vì chúng ta phải nhân một tín hiệu thử nghiệm với một sóng vuông có thể có giá trị 0, 1 hoặc -1. Do đó, chúng ta có thể thay thế phép nhân nổi thành phép cộng hoặc phép trừ số nguyên. Đối với Arduino, phép cộng hoặc trừ số nguyên nhanh hơn khoảng 5 lần. Điều này làm cho việc giải quyết nhanh hơn khoảng 5 lần.

Do sự sửa đổi này, giờ đây các giá trị bin tần số có thể được lưu trữ dưới dạng số nguyên (trước đây là float) và chúng tôi nhận được một lợi thế khác là tiêu thụ bộ nhớ thấp hơn. Trong Arduino Nano, int tiêu thụ 2 byte bộ nhớ trong khi float tiêu thụ 4 byte bộ nhớ. Do ưu điểm này trong mã mới, chúng tôi có thể thực hiện FFT cho gần 256 mẫu (trước đây là 128 mẫu).

Trong FFT thông thường, chúng tôi cần lưu trữ giá trị sin để tạo giải pháp nhanh hơn. Trong hàm mới, vì chúng ta không cần các giá trị sin / cosin nữa, chúng ta có thể loại bỏ nó và tiết kiệm một số bộ nhớ.

Thực hiện:

Thực hiện chức năng này là thẳng về phía trước. Chúng ta chỉ cần sao chép hàm tại đoạn mã. Chức năng này có thể được thực thi bằng lệnh dưới đây:

float f = Q_FFT (dữ liệu, 256, 100); Trong hàm Q_FFT,

dữ liệu: thuật ngữ này là một mảng có các giá trị tín hiệu, kích thước mẫu được đề xuất là 2, 4, 8, 32, 64, 128, 256, 512,… trở đi. nếu kích thước mẫu không thuộc các giá trị này, nó sẽ được cắt xuống phía dưới gần nhất của các giá trị. ví dụ, nếu kích thước mẫu là 75 hơn FFT sẽ được thực hiện cho 64 số lượng mẫu. Số lượng kích thước mẫu tối đa bị giới hạn bởi RAM có sẵn trên Arduino.

Số hạng thứ hai xác định số lượng mẫu trong một mảng và số hạng cuối cùng là tần số lấy mẫu tính bằng Hz.

Bước 2: Mã

Phần này giải thích sửa đổi được thực hiện trong mã EasyFFT cần được ghi nhớ trong khi thực hiện sửa đổi trong mã, 1. Như đã giải thích trước đây, ở đây các số nguyên được sử dụng để làm FFT. Int trong Arduino là một số 16 bit và có thể chứa các giá trị từ -32768 đến 32768. bất cứ khi nào giá trị của int này vượt quá phạm vi này, nó sẽ gây ra sự cố. để loại bỏ vấn đề này sau khi tính toán từng cấp độ. nếu bất kỳ giá trị nào vượt quá 15000 mảng hoàn chỉnh sẽ được chia cho 100. điều này sẽ ngăn int bị tràn.

2. Tính biên độ: Để tính biên độ, phần thực và phần ảo cần bình phương và căn bậc hai của tổng. bình phương và căn bậc hai của hàm là thời gian. để làm cho quá trình nhanh hơn, mã này sẽ chỉ đơn giản là thực hiện một số mức độ lớn của các phần thực và ảo. Điều này chắc chắn ít chính xác hơn và có thể dẫn đến kết luận sai trong một số trường hợp. bạn có thể chọn quay lại phương pháp Bình thường để tính toán độ lớn nhưng sẽ mất nhiều thời gian hơn và bạn cũng cần thực hiện một số sắp xếp để lưu trữ những con số này.

3. Mã này không có mô-đun để phát hiện nhiều đỉnh. Nó sẽ chỉ cần chọn giá trị với biên độ tối đa (không bao gồm số đầu tiên là độ lệch DC). Nếu bạn cần nhiều đỉnh, bạn có thể tham khảo mã EasyFFT và thực hiện sửa đổi cần thiết tại đây. Trong trường hợp đó, một số mảng / biến cũng cần được khai báo là biến toàn cục.

4. Hàm chứa dòng sau:

unsigned int Pow2 [13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};

khai báo các biến ở trên là một biến toàn cục (dán nó vào đầu mã) sẽ tiết kiệm ở đâu đó thời gian 1 mili giây cho mỗi lần thực thi.

5. Không giống như hàm EasyFFT, trong đó 5 đỉnh hàng đầu được lưu trữ trong mảng được xác định trước. Hàm này sẽ trả về một giá trị float. giá trị này biểu thị tần số có biên độ cực đại tính bằng Hz. Vì vậy, biểu diễn của mã sẽ giống như thế này.

float f = Q_FFT (dữ liệu, 256, 100);

6. Phát hiện đỉnh: Khi tìm thấy tần số với biên độ tối đa, hàm này sử dụng biên độ của tần số ngay trước và sau nó để tính toán kết quả chính xác. Biên độ được sử dụng trong phép tính này cũng là tổng của môđun (không phải là căn bậc hai của tổng bình phương)

nếu Fn là tần số có biên độ cực đại thì tần số có thể được tính theo công thức dưới đây.

Thực tế F = (A n-1 * Fn-1 + An-1 * Fn-1 + An-1 * Fn-1) / (An-1 + An + An + 1)

trong đó An là biên độ của tần số n và Fn-1 là giá trị tần số.

Bước 3: Kết quả:

Kết quả
Kết quả
Kết quả
Kết quả

Thời gian giải quyết được hiển thị trong hình ảnh trên so sánh với EasyFFT. Tốc độ của nó được hiển thị với so sánh.

Đối với dữ liệu mẫu có 3 sóng hình sin với các tần số khác nhau được hiển thị. Kết quả từ QuickFFT được so sánh với đầu ra Scilab. Như chúng ta có thể thấy trong hình 3 đỉnh với biên độ tối đa phù hợp với đầu ra Scilab. Tuy nhiên, đầu ra có nhiều tạp âm, có thể gây hiểu nhầm cho một số ứng dụng. Vì vậy, bạn nên kiểm tra mã đúng cách trước khi áp dụng cho ứng dụng của mình.

Tôi hy vọng bạn thấy mã này hữu ích cho dự án của bạn. Trong trường hợp có bất kỳ câu hỏi hoặc gợi ý nào, xin vui lòng bình luận.

Đề xuất: