Zabawy z FFT na STM32F103C8T6 (bluepill)

Procesor STM32F103C8T6 z rdzeniem ARM®Cortex®-M3 mogącym pracować z taktowaniem do 72MHz. 20KB SRAM i 64KB FLASH są zaletami, ale brak FPU w tej serii poważnie zmniejsza wydajność obliczeniową dla FFT, które zwykle wykorzystują typ danych float.

Uwaga 1: W tych eksperymentach nie jest wykorzystywany ADC – sample są generowane przez zdefiniowaną funkcję.

Uwaga 2: Wykorzystałem bibliotekę https://github.com/leeshineSZ/fft_for_stm32 – w razie jakby zniknęła z sieci, załączam:

fft_for_stm32-master

Uwaga 3: Do pomiarów wydajności wykorzystuję timer TIM1 w roli zwykłego timera/licznika. Okres ustawiony na max, tj. 65535. Prescaler na 1000. Ponieważ zegar trafia z linii APB2, to w moim przypadku daje to 72MHz na wejściu, po prescalerze 72KHz. Daje to (1/72KHz) 13,89us na pojedynczą inkrementację licznika. Wystarczy zerować rejestr licznika TIM1->CNT przed pomiarem, i odczytać rejestr po zakończeniu pomiaru, a potem przemnożyć przez 13,89us, żeby otrzymać czas potrzebny na wykonanie obliczeń.

Najpierw sprawdzałem, ile zajmuje mnożenie liczb float, a dokładniej zmiennej przez stałą. Jest to ok 3,43us, wliczając obieg pętli for.

Obliczenia FFT dla tablicy 128 próbek zajmują 6,5ms. Do tego trzeba doliczyć wyliczanie modułów liczb zespolonych – kolejne 0,93ms. Łącznie 7,43ms.

Daje to ok. 134Hz częstotliwości aktualizacji widma. Jest to tylko 128 próbek, czyli realnie 64 wartości w widmie – może wystarczyć do spektrometru na led-ach, gdzie mamy kilkanaście pasków.

Dla 1024 próbek FFT 61ms + moduł 7,4ms = 68,5ms, co daje częstotliwość odświeżania 14,6Hz – dosyć mało jak na wizualizację “real time”.

Wniosek 1: Częstotliwość próbkowania jest niezależna od ilości próbek, jakie bierzemy do analizy.

Wniosek 2: Więcej próbek – znacznie więcej czasu na obliczenia. Warto tą kwestię najpierw przemyśleć, bo zmiana nie ogranicza nam pasma, jedynie rozdzielczość.

Wniosek 3: Nie zastosowałem tu okien, co powoduje, że np. w widmie fali prostokątnej ciężko się jest jej doszukać – kolejne prążki szybko gasną, zwłasza jak nie “trafimy” z częstotliwością.

Wniosek 4: Fajnie by było wyeliminować floaty i skorzystać z np obliczeń stałoprzecinkowych.

Wniosek 5: Żeby wartości modułów odpowiadały rzeczywistości, należy ich amplitudy podzielić przez [0,5 x ilość próbek].

Wizualizacja obliczeń dla fali prostokątnej, 128 próbek i dokładnie “trafionej” (jeden cały okres):

Widać niską wartość składowej stałej i szybko malejące prążki nieparzyste – parzyste są równe składowej stałej. Nie wiem skąd ta składowa stała – jest dokładnie 64 próbek o wartości -30 i 64 próbki o wartości 30. Takiego rezultatu spodziewałbym się, gdybym miał o jedną próbkę dodatnią na plusie. Chyba że chodzi o aliasing – w końcu nie ograniczałem pasma prostokątowi.

Kod pisany w STM32CubeIDE.

STM32 obsługa enkodera na przykładzie STM32F103C8T6 (bluepill)

Konfiguracja STM32CubeMX

W przykładzie: STM32F103C8T6, użycie TIMERA2, enkoder na pinach PA0, PA1

 

Zmiany w kodzie programu (main.c):

Przed główną pętlą

W pętli głównej, odczyt wartości enkodera:

Wartości uzyskiwane będą z przedziału 0 – [Counter Period] – w naszym przypadku 0 – 1000 włącznie. Po przekroczeniu wartości 1000 licznik zaczyna zliczać dalej od zera.

Nie trzeba uruchamiać przerwań, ani wykonywać dodatkowych konfiguracji.


Przykład uruchomienia na płytce Bluepill:

Enkoder podpięty pod wejścia PA0, PA1 – jak w konfiguracji.

Udostępniam projekt z kodami źródłowymi oraz binarnymi, które były używane do testów: encoder_test

W kodzie zaimplementowana jest obsługa wirtualnego portu szeregowego pod USB, oraz zmiana tempa błyskania LED PC13 w zależności od wartości licznika enkodera.

Powyższy opis w pliku PDF do wydruku: STM32 obsługa enkodera inkrementalnego

OLED-AG-L-12864-05-WHITE-1i3 – biblioteka Eagle

Wyświetlacz OLED 1.3″ z dystrybucji firmy Artronic – największy niewymagający zewnętrznej przetwornicy napięcia.
Dokumentacja:
Hardware: http://www.artronic.com.pl/o_produkcie.php?id=2075
Software: http://www.artronic.com.pl/pdf/pl/SH1106.pdf
Potencjalna biblioteka Arduino: https://github.com/wonho-maker/Adafruit_SH1106
Biblioteka Eagle 7.1.1:
oled_artronic
Footprint w 2 wersjach – “płaskiej”, oraz ze slotem w PCB i taśmą lutowaną od spodu płytki.
Uwaga: biblioteka (jeszcze) nie sprawdzona w praktyce!