Სარჩევი:
- ნაბიჯი 1: შესავალი სიხშირის გარდაქმნაში
- ნაბიჯი 2: სწრაფი ფურიეს ტრანსფორმაცია
- ნაბიჯი 3: კოდის ახსნა
- ნაბიჯი 4: კოდის ახსნა: FFT ფუნქცია
- ნაბიჯი 5: კოდის ტესტირება
- ნაბიჯი 6: დასკვნა
ვიდეო: EasyFFT: სწრაფი ფურიეს ტრანსფორმაცია (FFT) არდუინოსთვის: 6 ნაბიჯი
2024 ავტორი: John Day | [email protected]. ბოლოს შეცვლილი: 2024-01-30 10:16
დატყვევებული სიგნალიდან სიხშირის გაზომვა შეიძლება იყოს რთული ამოცანა, განსაკუთრებით არდუინოზე, რადგან მას აქვს დაბალი გამოთვლითი ძალა. არსებობს მეთოდები ნულოვანი გადაკვეთის დასაფიქსირებლად, სადაც სიხშირე აღირიცხება რამდენჯერ გადალახავს სიგნალი ნულოვან ხაზებს მოცემულ დროში. ასეთი მეთოდი შეიძლება არ იმუშაოს, როდესაც სიგნალი არის სხვადასხვა სიხშირის კომბინაცია.
ეს რატომღაც ძნელია კოდირება, თუ არ ხარ ასეთი ფონიდან. ვინაიდან მეკარეა, ეს კოდი შეიძლება იყოს ძალიან სასარგებლო მუსიკასთან, სიგნალის ანალიზთან დაკავშირებული სხვადასხვა პროექტებისთვის. ამ პროექტის მოტივი იყო მოემზადებინა კოდი, რომლის განხორციელებაც ადვილია არდუინოზე, მის ფონზე მოხვედრის გარეშე.
ეს პროექტი არ განმარტავს FFT– ს მუშაობას, არამედ განმარტავს FFT ფუნქციის გამოყენებას. იგივე პროცესი ასევე ახსნილია თანდართულ ვიდეოში.
თუ თქვენ დაინტერესებული ხართ მხოლოდ კოდის გამოყენებით და არა მისი ახსნით. შეგიძლიათ პირდაპირ გადახვიდეთ მე –3 საფეხურზე.
ნაბიჯი 1: შესავალი სიხშირის გარდაქმნაში
ნებისმიერი სიგნალი შეიძლება შედგებოდეს სხვადასხვა სინუსოიდული ტალღების კომბინაციისგან. ასე რომ, დროზე დაფუძნებული ნებისმიერი სიგნალი ასევე შეიძლება ნაჩვენები იყოს, როგორც სხვადასხვა ამპლიტუდის სინუსების კომბინაცია.
მე შევეცადე აეხსნა DFT (ფურიეს დისკრეტული გარდაქმნა) მუშაობის ერთ – ერთი წინა ინსტრუქცია (https://www.instructables.com/id/Arduino-Frequency…). ეს მეთოდები ძალიან ნელია ნებისმიერი რეალურ დროში გამოყენებისთვის. რაც მას თითქმის უსარგებლოს ხდის.
სურათზე ნაჩვენებია სიგნალი, რომელიც არის ორი სიხშირის f2 და f5 კომბინაცია. ეს სიგნალი მრავლდება f1– დან f5 მნიშვნელობების საცდელი სინუსური ტალღებით.
მათემატიკურად შეიძლება ნაჩვენები იყოს, რომ განსხვავებული ჰარმონიული მონაცემთა ნაკრების გამრავლების ჯამი სხვადასხვა სიხშირით ნულის ტოლია (მონაცემთა უფრო მეტმა რაოდენობამ შეიძლება გამოიწვიოს ბატარეის შედეგი). ჩვენს შემთხვევაში, თუ ამ ორ გამრავლების სიხშირეს აქვს იგივე (ან ძალიან ახლო) სიხშირე, გამრავლების ჯამი არის არა ნული რიცხვი.
ასე რომ, თუ ჩვენი სიგნალი გამრავლებულია f1- ით, გამრავლება იქნება ნული (რეალურ გამოყენებისთვის ნულთან ახლოს). იგივე ეხება f3, f4. თუმცა, მნიშვნელობისთვის, f2 და f5 გამომავალი არ იქნება ნული, მაგრამ მნიშვნელოვნად უფრო მაღალი ვიდრე დანარჩენი მნიშვნელობები.
აქ სიგნალი შემოწმებულია 5 სიხშირით, ამიტომ სიგნალი უნდა გამრავლდეს ხუთ სიხშირეზე. ასეთი ინტენსიური გაანგარიშება უფრო მეტ დროს მოითხოვს. მათემატიკურად ნაჩვენებია, რომ N რაოდენობის ნიმუშისთვის საჭიროა N*N კომპლექსური გამრავლება.
ნაბიჯი 2: სწრაფი ფურიეს ტრანსფორმაცია
DFT– ის გამოთვლის უფრო სწრაფი შესაქმნელად FFT ალგორითმი შეიმუშავეს ჯეიმს ქულმა და ჯონ ტუკიმ. ეს ალგორითმი ასევე განიხილება, როგორც მე -20 საუკუნის ერთ -ერთი ყველაზე მნიშვნელოვანი ალგორითმი. ის ყოფს სიგნალს უცნაურ და თანმიმდევრულ ნაწილად, რაც ამცირებს საჭირო გამოთვლებს. მისი გამოყენებით მთლიანი საჭირო კომპლექსური გამრავლება შეიძლება შემცირდეს NlogN- მდე. რაც მნიშვნელოვანი გაუმჯობესებაა.
თქვენ შეგიძლიათ მიუთითოთ ქვემოთ მოცემული ცნობები, რომლებიც მე მოვიხსენიე კოდის წერისას FFT მათემატიკის დეტალური გაგებისთვის:
1.
2.
3.
4.
ნაბიჯი 3: კოდის ახსნა
1. სწრაფი სინუსი და კოსინუსი:
გამოთვლა FFT იღებს მნიშვნელობას სხვადასხვა სინუსისა და კოსინუსის მრავალჯერ. Arduino– ს ჩამონტაჟებული ფუნქცია არ არის საკმარისად სწრაფი და საჭირო დროის კარგ მნიშვნელობას ატარებს. რაც კოდს მნიშვნელოვნად ანელებს (აორმაგებს დროს 64 ნიმუშზე). ამ საკითხის საპირისპიროდ სინუსის მნიშვნელობა 0 -დან 90 გრადუსამდე ინახება 255 -ის ჯერადად. ამით აღმოიფხვრება რიცხვების შენახვის აუცილებლობა float– ის სახით და შეგვიძლია მისი შენახვა როგორც ბაიტი, რომელიც არდუინოს 1/4 ადგილს იკავებს. Sine_data საჭიროებს ჩასვას კოდის თავში, რომ გამოცხადდეს გლობალურ ცვლადად.
Sine_data– ს გარდა, მასივი სახელწოდებით f_peaks გამოცხადებულია გლობალურ ცვლადად. FFT ფუნქციის ყოველი გაშვების შემდეგ ეს მასივი განახლდება. სადაც f_peaks [0] არის ყველაზე დომინანტური სიხშირე და შემდგომი მნიშვნელობები კლებადობით.
ბაიტი sine_data [91] = {0, 4, 9, 13, 18, 22, 27, 31, 35, 40, 44, 49, 53, 57, 62, 66, 70, 75, 79, 83, 87, 91, 96, 100, 104, 108, 112, 116, 120, 124, 127, 131, 135, 139, 143, 146, 150, 153, 157, 160, 164, 167, 171, 174, 177, 180, 183, 186, 189, 192, 195, 198, 201, 204, 206, 209, 211, 214, 216, 219, 221, 223, 225, 227, 229, 239, 231, 233, 235, 236, 238, 240, 241, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255, 255}; float f_peaks [5];
ვინაიდან ჩვენ შენახული გვაქვს სინუსის მნიშვნელობა 0 -დან 90 გრადუსამდე, ნებისმიერი სინუსის ან კოსინუსის ღირებულება შეიძლება გამოითვალოს. ქვემოთ მოცემულია რიცხვის პირველი რაუნდი ნულოვან ათეულამდე და დააბრუნეთ მნიშვნელობა შენახული მონაცემებიდან. ამ მეთოდს სჭირდება მხოლოდ ერთი მცურავი განყოფილება. ეს შეიძლება კიდევ უფრო შემცირდეს სინუსების მნიშვნელობების პირდაპირ შენახვით (არა 255 მრავალჯერადი). მაგრამ ეს ჭამს მეხსიერებას არდუინოზე.
ზემოაღნიშნული პროცედურის გამოყენება ამცირებს სიზუსტეს, მაგრამ აუმჯობესებს სიჩქარეს. 64 ქულისთვის ის იძლევა 8ms უპირატესობას და 128 ქულისთვის უპირატესობას ანიჭებს 20ms.
ნაბიჯი 4: კოდის ახსნა: FFT ფუნქცია
FFT შეიძლება შესრულდეს მხოლოდ 2, 4, 8, 16, 32, 64 და ასე შემდეგ. თუ მნიშვნელობა არ არის 2^n, მაშინ ის მიიღებს ღირებულების ქვედა მხარეს. მაგალითად, თუ ჩვენ ვირჩევთ ნიმუშის ზომას 70, ის მხოლოდ პირველ 64 ნიმუშს განიხილავს და დანარჩენს გამოტოვებს.
ყოველთვის რეკომენდირებულია ნიმუშის ზომა 2^n. რომელიც შეიძლება იყოს:
2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, …
ორი მცურავი out_r და out_im მიიღებს დიდი რაოდენობით მეხსიერებას. Arduino– სთვის ნანო არ იმუშავებს 128 – ზე მეტ (და ზოგიერთ შემთხვევაში 128 – ზე) ნიმუშზე არსებული მეხსიერების არარსებობის გამო.
ხელმოუწერელი int მონაცემები [13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};
int a, c1, f, o, x; a = N; for (int i = 0; i <12; i ++) // დონის გამოთვლა {if (data <= a) {o = i;}} int in_ps [data [o] = {}; // შეყვანის თანმიმდევრობა float out_r [data [o] = {}; // ტრანსფორმაციის რეალური ნაწილი float out_im [data [o] = {}; // გარდასახვის წარმოსახვითი ნაწილი
შემდგომი ნაკადი შემდეგია:
1. კოდი წარმოქმნის ოდნავ შეცვლილ წესრიგს მოცემული ნიმუშის ზომისათვის (დეტალები ბიტის უკუქცევის შესახებ მითითებებზე: ნაბიჯი 2)
2. შეყვანილი მონაცემები შეკვეთილი გენერირებული შეკვეთის მიხედვით, 3. შესრულებულია FFT
4. გამოთვლილი კომპლექსური რიცხვის ამპლიტუდა, 5. მწვერვალები გამოვლენილი და მოწესრიგებულია კლებადობით
6. შედეგებზე წვდომა შესაძლებელია f_peaks– დან.
[სხვა მონაცემებზე წვდომისათვის (გარდა პიკის სიხშირისა) კოდი უნდა შეიცვალოს ისე, რომ ადგილობრივი ცვლადი იყოს გადაწერილი წინასწარ განსაზღვრულ გლობალურ ცვლადზე]
ნაბიჯი 5: კოდის ტესტირება
სამკუთხედის ტალღის ნიმუში მოცემულია შეყვანის სახით. ამ ტალღისთვის შერჩევის სიხშირეა 10 ჰც და თავად ტალღის სიხშირე არის 1.25 ჰერცი.
როგორც ნაჩვენებია ნედლეული გამომავალიდან, მნიშვნელობა შეესაბამება Scilab– ის მიერ გამოთვლილ FFT– ს. თუმცა, ეს მნიშვნელობები არ არის ზუსტად იგივე, რაც ჩვენ დაბალი სიზუსტით, მაგრამ უფრო სწრაფი სინუსური ტალღა.
გამომავალი სიხშირის მასივის სიხშირეა 1.25 და 3.75. არ არის აუცილებელი ზუსტი მნიშვნელობის მიღება ყოველ ჯერზე. როგორც წესი, ამ რიცხვებს სიხშირის ურნები ეწოდება. ასე რომ გამომავალი მნიშვნელობა შეიძლება იყოს სადმე განსაზღვრულ ყუთებში.
სიჩქარე:
არდუინო ნანოსთვის საჭიროა:
16 ქულა: 4 ms32 ქულა: 10 ms 64 ქულა: 26 ms 128 ქულა: 53 ms
ნაბიჯი 6: დასკვნა
ეს FFT კოდი შეიძლება გამოყენებულ იქნას რეალურ დროში პროგრამებში. რადგან გაანგარიშების დასრულებას დაახლოებით 30 ms სჭირდება. თუმცა, მისი გარჩევადობა შეზღუდულია რიგი ნიმუშებით. ნიმუშის რაოდენობა შეზღუდულია არდუინოს მეხსიერებით. Arduino Mega– ს ან სხვა უმაღლესი ხარისხის დაფის გამოყენებით შესაძლებელია სიზუსტის გაუმჯობესება.
თუ თქვენ გაქვთ რაიმე შეკითხვა, წინადადება ან შესწორება, მოგერიდებათ კომენტარის გაკეთება.
განახლება (2/5/21)
განახლებები: // ----------------------------- FFT ფუნქცია --------------- ---------------------------------- // float FFT (int in , int N, float Frequency)
N ტიპის მონაცემები შეიცვალა მთელი რიცხვით (არსებული ბაიტი) 255 ნიმუშის ზომის მხარდასაჭერად. თუ ნიმუშის ზომაა <= 128, უნდა იქნას გამოყენებული მონაცემთა ბაიტის ტიპი.
გირჩევთ:
უფრო იაფი ESP8266 WiFi ფარი არდუინოსთვის და სხვა მიკროსკოპისთვის: 6 ნაბიჯი (სურათებით)
უფრო იაფი ESP8266 WiFi ფარი არდუინოსთვის და სხვა მიკროსქემისთვის: განახლება: 29 ოქტომბერი 2020 ტესტირებული ESP8266 დაფის ბიბლიოთეკით V2.7.4 - სამუშაოები განახლება: 23 სექტემბერი 2016 არ გამოიყენოთ Arduino ESP დაფის ბიბლიოთეკა V2.3.0 ამ პროექტისათვის. V2.2.0 სამუშაოები განახლება: 2016 წლის 19 მაისი ამ პროექტის 14 -ე მუხლი გადახედავს ბიბლიოთეკებსა და სამუშაო კოდს
სწრაფი გადამრთველი 50 დოლარამდე! Kazeshifter Arduino რეგულირებადი სწრაფი გადამრთველი: 7 ნაბიჯი
სწრაფი გადამრთველი 50 დოლარამდე! Kazeshifter Arduino რეგულირებადი სწრაფი გადამრთველი: გამარჯობა სუპერბაიკის ან მოტოციკლის მოყვარულებო! ამ სასწავლო ინსტრუქციით მე გაგიზიარებთ თუ როგორ უნდა გააკეთოთ საკუთარი სწრაფი Shifter იაფად! მათთვის, ვინც ზარმაცი კითხულობს ამ ინსტრუქციას, უბრალოდ უყურეთ ჩემს ვიდეოს! შენიშვნა: უკვე იყენებს საწვავის ინექციის სისტემას, რაღაც
QuickFFT: მაღალი სიჩქარის FFT არდუინოსთვის: 3 ნაბიჯი
QuickFFT: მაღალი სიჩქარის FFT Arduino– სთვის: ტიპიურ Arduino– ს აქვს შეზღუდული ოპერატიული მეხსიერება და დამუშავების ძალა და FFT არის გამოთვლების ინტენსიური პროცესი. მრავალი რეალურ დროში გამოყენებისთვის, ერთადერთი მოთხოვნაა მიიღოთ სიხშირე მაქსიმალური ამპლიტუდით ან საჭიროა სიხშირის მწვერვალების გამოსავლენად. ერთ-ერთ
სწრაფი, სწრაფი, იაფი, კარგი გარეგნობის LED ოთახის განათება (ნებისმიერისთვის): 5 ნაბიჯი (სურათებით)
სწრაფი, სწრაფი, იაფი, კარგი გარეგნობის მქონე LED ოთახის განათება (ნებისმიერისთვის): მოგესალმებით ყველას :-) ეს არის ჩემი პირველი სასწავლო ინსტრუქცია, ასე რომ კომენტარებს მივესალმები :-) ის, რაც მე იმედი მაქვს გაჩვენებთ არის ის, თუ როგორ უნდა გააკეთოთ სწრაფი LED განათება, რომელიც არის TINY ბუგეტი. რა გჭირდებათ: საკაბელო LED რეზისტორები (510Ohms 12V) სტეპელები
სწრაფი და მარტივი რბილი გადამრთველები (სწრაფი პროტოტიპისთვის): 5 ნაბიჯი
სწრაფი და მარტივი რბილი გადამრთველები (სწრაფი პროტოტიპისთვის): რბილი გადამრთველების დამზადების მრავალი განსხვავებული გზა არსებობს. ეს ინსტრუქცია გვიჩვენებს რბილი ჩამრთველის ძალიან სწრაფი პროტოტიპის კიდევ ერთ ვარიანტს, გამტარ ქსოვილის ნაცვლად ალუმინის ლენტის გამოყენებით და გამტარი ძაფის ნაცვლად მყარი მავთულის გამოყენებით, რომელიც