Vraag:
Zijn er bibliotheken voor het afvlakken van signalen voor Arduino?
asheeshr
2014-02-16 19:57:38 UTC
view on stackexchange narkive permalink

Ik werk aan een mobiele robot die wordt bestuurd via een draadloze 2,4 GHz-verbinding. De ontvanger is verbonden met de Arduino Uno die aan boord dient als de hoofdcontroller. Het meest kritische (en belangrijkste) ingangskanaal dat van de ontvanger komt, produceert een zeer luidruchtig signaal, wat leidt tot veel kleine veranderingen in de uitvoer van de actuatoren, ook al zijn deze niet nodig.

 enter image description here Plot van de invoer van de Arduino in een interval van 30 seconden. 

Ik ben op zoek naar bibliotheken die efficiënte afvlakking kunnen uitvoeren. Zijn er bibliotheken voor het afvlakken van signalen beschikbaar voor de Arduino (Uno)?

Weet niet of je dit soort bibliotheken kunt vinden, maar ik ben bang dat deze te veel CPU-vermogen nodig hebben voor een Arduino. Ik ga liever voor een elektronische oplossing (laagdoorlaatfilter) indien mogelijk.
Ik ben hier met jfpoilpret over. Ik denk dat je een elektronische oplossing nodig hebt. Ik zou een stabilisatiecondensator proberen (eenvoudig laagdoorlaatfilter). Ik neem aan dat je een adc-kanaal gebruikt, dus je moet een dop van dit kanaal naar aarde plaatsen. Begin met waarden rond 100pf en werk vanaf daar verder.
Vier antwoorden:
#1
+9
asheeshr
2014-03-07 20:14:24 UTC
view on stackexchange narkive permalink

Microsmooth is een lichtgewicht bibliotheek voor het afvlakken van signalen die momenteel door mij wordt ontwikkeld.

Er wordt nog steeds aan gewerkt en het doel is om het lichtgewicht te maken in termen van geheugen en snel . De bibliotheek biedt meerdere filters voor vloeiend maken:

  • Eenvoudig voortschrijdend gemiddelde
  • Exponentieel voortschrijdend gemiddelde
  • Cumulatief voortschrijdend gemiddelde
  • Savitzky Golay Filter
  • Ramer Douglas Pecker-algoritme
  • Kalmogorov Zurbenko-filter

Om de bibliotheek te gebruiken, downloadt u deze en voegt u deze toe aan de bronmap. Voeg ook de volgende regel toe aan uw bronbestand:

  #include "microsmooth.h"  
Hallo, ik heb problemen met het gebruik van uw bibliotheek. U zou toch niet "Bibliotheek importeren ..." gebruiken om uw bibliotheek te importeren? Ik heb geprobeerd de broncode gewoon naar mijn .ino-map te kopiëren, maar ik krijg foutmeldingen over het ontbreken van automicrosmooth.h, het niet-gedefinieerde serienummer en het ontbreken van ';'. Werkt deze bibliotheek nog? Bedankt
@waspinator Sorry daarvoor. De fouten opgelost. Bedankt voor de feedback!
#2
+7
David Cary
2014-03-26 22:37:56 UTC
view on stackexchange narkive permalink

Ik denk dat ik veel single-sample ruispieken zie in je ruisige signaal.

Het mediaanfilter is beter in het wegwerken van single-sample ruispieken dan welk lineair filter dan ook. (het is beter dan welk laagdoorlaatfilter, voortschrijdend gemiddelde, gewogen voortschrijdend gemiddelde, enz. dan ook wat betreft de reactietijd en het vermogen om dergelijke uitschieters van ruispieken met één sample te negeren).

Er zijn in feite veel signalen -soepelende bibliotheken voor de Arduino, waarvan er vele een mediaanfilter bevatten.

signaalafvlakkingsbibliotheken op arduino.cc:

bibliotheken voor het afvlakken van signalen op github:

Zou zoiets in uw robot werken? (De mediaan-van-3 vereist zeer weinig CPU-vermogen, en dus fast):

  /*median_filter.ino2014-03-25: gestart door David Cary * / int median_of_3 (int a, int b, int c) {int the_max = max (max (a , b), c); int the_min = min (min (a, b), c); // onnodig slimme code int the_median = the_max ^ the_min ^ a ^ b ^ c; return (the_median);} int nieuwste = 0; int recent = 0; int oudste = 0; void setup () {Serial.begin (9600); // lees eerste waarde, initialiseer ermee. oudste = willekeurig (200); recent = oudste; nieuwste = recent; Serial.println ("mediaan filter voorbeeld:");} void loop () {
// laat oudste waarde vallen en verschuift in laatste waarde oudste = recent; recent = nieuwste; nieuwste = willekeurig (200); Serial.print ("nieuwe waarde:"); Serial.print (nieuwste, DEC); int median = median_of_3 (oudste, recentste, nieuwste); Serial.print ("afgevlakte waarde:"); Serial.print (mediaan, DEC); Serial.println (""); delay (5000);}  
#3
+4
TheDoctor
2014-02-16 20:45:56 UTC
view on stackexchange narkive permalink

Heb je een laagdoorlaatfilter geprobeerd? Ik vond een voorbeeld hier en een ander hier.

Beide bibliotheken hebben een lijst met gegevens die worden gelezen van de analoge sensor van uw keuze die is gemiddeld. Elke nieuwe sensorwaarde wordt aan de lijst toegevoegd en de laatste wordt als volgt weggegooid:

  Lijst: 3 4 3 3 4 3 5 3 2 3 4 3 nieuwe meting toegevoegd. oude weggegooid / - / - Lijst: 5 3 4 3 3 4 3 5 3 2 3 4 gemiddelde lijst  
Vrijwel wat een eenvoudig [FIR-filter] (https://en.wikipedia.org/wiki/Finite_impulse_response) doet met alle tikwaarden ingesteld op 1. Knoeien met de tikwaarden kan het signaal verder verbeteren, maar vereist hogere wiskunde.
Opmerking: de tweede link berekent het [cumulatief voortschrijdend gemiddelde] (http://en.wikipedia.org/wiki/Moving_average#Cumulative_moving_average), wat geen praktische keuze is voor actuatorbesturing, met name een waarbij vaak gestart en gestopt kan worden. Het afgevlakte signaal zal altijd de piekwaarde van het werkelijke signaal met een behoorlijke marge volgen.
#4
+2
akellyirl
2014-02-16 22:34:31 UTC
view on stackexchange narkive permalink

Je zou dit digitaal kunnen filteren met behulp van een laagdoorlaatfilter:

  int valueFilt = (1-0,99) * waarde + 0,99 * valueFilt;  

Verander de 0,99 om de afsnijfrequentie te wijzigen (dichter bij 1,0 is de lagere frequentie). De feitelijke uitdrukking voor die waarde is exp (-2 * pi * f / fs), waarbij f de gewenste afsnijfrequentie is en fs de frequentie waarop de gegevens worden gesampled.

Een ander type 'digitaal filter "is een gebeurtenisfilter. Het werkt goed op gegevens met uitschieters; bijv. 9,9,8,10,9,25,9. Een gebeurtenisfilter retourneert de meest voorkomende waarde. Statistisch gezien is dit de modus.

Statistische gemiddelden zoals gemiddelde, modus enz. Kunnen worden berekend met behulp van de Arduino-gemiddelde bibliotheek.

Een voorbeeld uit de Arduino Library-pagina waarnaar wordt verwezen:

  #include <Average.h> # definieer CNT 600int d [CNT]; void setup () {Serial.begin (9600);} void loop () {int ik; voor (i = 0; i<CNT; i ++) {d [i] = willekeurig (500); } Serial.print ("Mean:"); Serial.print (gemiddelde (d, CNT), DEC); Serial.print ("Mode:"); Serial.print (modus (d, CNT), DEC); Serial.print ("Max:"); Serial.print (maximum (d, CNT), DEC); Serial.print ("Min:"); Serial.print (minimum (d, CNT), DEC); Serial.print ("Standaarddeviatie:"); Serial.print (stddev (d, CNT), 4); Serial.println (""); Serial.println (""); delay (5000);}  
Merk op dat dit erg langzaam zal zijn, omdat het veel impliciete casts doet om te zweven en terug.


Deze Q&A is automatisch vertaald vanuit de Engelse taal.De originele inhoud is beschikbaar op stackexchange, waarvoor we bedanken voor de cc by-sa 3.0-licentie waaronder het wordt gedistribueerd.
Loading...