De opdrachten

Complexe getallen en een ringbuffer

Klassen voor getallen in rechthoekige en poolvorm, met omrekening en rekenkunde, en een circulaire buffer met vaste grootte als template, met een lopende som en gemiddelde. Beide worden in de latere opdrachten hergebruikt.

Voortschrijdende gemiddelden

Een desktopapplicatie (wxWidgets) die meetdata gladstrijkt met een voortschrijdend gemiddelde op de ringbuffer of een exponentieel gemiddelde, getekend als staven met het gemiddelde als lijn. Hetzelfde voortschrijdend gemiddelde draaide daarna op het embedded bord, waar een oscilloscoop liet zien dat het als laagdoorlaatfilter werkt: een sinus van 1 Hz gaat door, een van 3 Hz wordt gedempt en een van 5 Hz wordt geblokkeerd.

FFT op de desktop

Een applicatie die het spectrum van een signaal berekent met de FFTW-bibliotheek (een reëel-naar-complex-transformatie) en amplitude en fase plot, met onze klassen Complex en PolarNumber voor de omrekening.

Ontwerp van een FIR-filter in vaste komma

Een tool die een FIR-banddoorlaatfilter ontwerpt: een sinc-laagdoorlaatfilter dat naar de middenfrequentie is verschoven en gevormd met een rechthoek-, driehoek- of Hamming-venster, opgeslagen als 16-bits vaste-komma-coëfficiënten met een verzadigingscontrole. Het plot ook de frequentierespons.

FIR-filter in real time op de STM32

Het ontworpen filter (4 kHz bemonstering, doorlaatband 200–600 Hz, filterorde 64, Hamming-venster) draait op een STM32 in een real-timelus: een sample lezen van de ADC, filteren en schrijven naar de DAC. De multiply-accumulate-stap gebruikt de single-cycle-instructies van de Cortex-M4 (SMLABB en SMLAD), met loop unrolling die vier taps per ronde verwerkt.

Illustratie van de signaalverwerkingsopdrachten: de respons van het voortschrijdend gemiddelde, de respons van het FIR-banddoorlaatfilter en de real-timeketen van ADC naar DAC
Illustratie, berekend uit de ontwerpparameters: het voortschrijdend gemiddelde, de frequentierespons van het banddoorlaatfilter en de real-timeketen op de STM32.

Hoe het is gebouwd

  • Dezelfde code op de desktop en op het bord. De ringbuffer en het FIR-filter zijn één keer geschreven en hergebruikt: eerst in desktopapplicaties, later op de STM32, waar een variant van de buffer met vaste grootte wordt gebruikt.
  • Rekenen in vaste komma. Samples en coëfficiënten zijn 16-bits gehele getallen. Producten worden in 32 bits opgeteld, teruggeschaald en gecontroleerd op verzadiging, zodat het resultaat niet kan overlopen.
  • Filterontwerp vanaf de basis. De coëfficiënten van het banddoorlaatfilter komen uit een naar de middenfrequentie verschoven sinc-laagdoorlaatfilter dat met een venster is gevormd; de tool berekent ook de frequentierespons uit de opgeslagen coëfficiënten.
  • Generieke en geoptimaliseerde versie. Het generieke filter blijft als terugvaloptie. Met een compile-optie schakel je over naar de versie die de multiply-accumulate-instructies van de processor gebruikt (één tap met SMLABB, twee taps met SMLAD) en de lus uitrolt tot vier taps per ronde, met een kleine lus voor de overgebleven taps.
  • Een real-timelus. Het bord stelt de ADC-bemonsteringsfrequentie in (4 kHz), wacht op elke nieuwe sample, zet hem om van de ongetekende 24-bitswaarde van de ADC naar een getekende 16-bits sample, filtert hem en schrijft het resultaat naar de DAC.

Wie wat gebouwd heeft

Dit was een duoproject. De cursus leverde de applicatieframeworks aan (de wxWidgets-GUI, de STM32-boardondersteuning en de opdrachtskeletten met stubs); wij hebben de hierboven beschreven signaalverwerkingsonderdelen geïmplementeerd.

Tools

  • C++
  • FFT (FFTW)
  • FIR-filters
  • Vaste komma
  • STM32 (Cortex-M4)
  • wxWidgets

Meer weten over dit project?

Ik loop je graag door het project heen.