Fråga:
Finns det några signalutjämningsbibliotek för Arduino?
asheeshr
2014-02-16 19:57:38 UTC
view on stackexchange narkive permalink

Jag arbetar på en mobil robot som styrs via en trådlös 2,4 GHz-länk. Mottagaren är ansluten till Arduino Uno som fungerar ombord som huvudkontroll. Den mest kritiska (och huvudsakliga) ingångskanalen som kommer från mottagaren ger en mycket bullrig signal, vilket leder till många mindre förändringar i ställdonens utgång, även om dessa inte behövs.

 enter image description here Plott av Arduino-ingången i ett intervall på 30 sekunder. 

Jag letar efter bibliotek som kan utföra effektiv utjämning. Finns det några signalutjämningsbibliotek tillgängliga för Arduino (Uno)?

Vet inte om du kan hitta den här typen av bibliotek men jag är rädd att dessa kan behöva mycket CPU-kraft för en Arduino. Jag går hellre med en elektronisk lösning (lågpassfilter) om möjligt.
Jag är med jfpoilpret på detta. Jag tror att du behöver en elektronisk lösning. Jag skulle prova en stabiliseringskondensator, (enkelt lågpassfilter). Jag antar att du använder en ADC-kanal, så du bör sätta ett lock från den här kanalen till marken. Börja med värden runt 100pf och arbeta upp därifrån.
Fyra svar:
#1
+9
asheeshr
2014-03-07 20:14:24 UTC
view on stackexchange narkive permalink

Microsmooth är ett bibliotek med lättviktssignalutjämning som för närvarande utvecklas av mig.

Det jobbar fortfarande med och målet är att göra det lätt i form av minne och snabbt . Biblioteket tillhandahåller flera filter för utjämning:

  • Enkelt glidande medelvärde
  • Exponentiellt glidande medelvärde
  • Kumulativt glidande medelvärde
  • Savitzky Golay Filtrera
  • Ramer Douglas Pecker-algoritm
  • Kalmogorov Zurbenko Filter

För att använda biblioteket, ladda ner och lägg till det i källkatalogen. Lägg också till följande rad i källfilen:

  #include "microsmooth.h"  
Hej, jag har problem med att använda ditt bibliotek. Du skulle inte använda "Importera bibliotek ..." för att importera ditt bibliotek, eller hur? Jag försökte bara kopiera källan till min .ino-mapp, men jag får fel när jag saknar automicrosmooth.h, Serial definieras inte och saknas ';'. Fungerar det här biblioteket fortfarande? Tack
@waspinator Ledsen för det. Fixade felen. Tack för feedbacken!
#2
+7
David Cary
2014-03-26 22:37:56 UTC
view on stackexchange narkive permalink

Jag tror att jag ser många enstaka bruspinnar i din bullriga signal.

Medianfiltret gör det bättre att bli av med enstaka bruspinnar än något linjärt filter. (Det är bättre än något lågpassfilter, glidande medelvärde, viktat glidande medelvärde, etc. när det gäller dess svarstid och dess förmåga att ignorera sådana enstaka brusstegsavvikelser). -utjämningsbibliotek för Arduino, varav många inkluderar ett medianfilter.

signalutjämnande bibliotek på arduino.cc:

signalutjämningsbibliotek på github:

Skulle något som detta fungera i din robot? (Median-of-3 kräver väldigt lite CPU-kraft, och därmed snabb):

  /*median_filter.ino2014-03-25: startad av David Cary * / int median_of_3 (int a, int b, int c) {int the_max = max (max (a , före Kristus ); int the_min = min (min (a, b), c); // onödigt smart kod int_median = the_max ^ the_min ^ a ^ b ^ c; return (the_median);} int newest = 0; int recent = 0; int elder = 0; void setup () {Serial.begin (9600); // läs första värdet, initialisera med det. äldsta = slumpmässig (200); senaste = äldsta; nyaste = senaste; Serial.println ("exempel på medianfilter:");} ogiltig slinga () {
// släpp äldsta värdet och skift i senaste värdet äldsta = senaste; senaste = nyaste; nyaste = slumpmässig (200); Serial.print ("nytt värde:"); Serial.print (nyaste, DEC); int median = median_of_3 (äldsta, senaste, nyaste); Serial.print ("utjämnat värde:"); Serial.print (median, DEC); Serial.println (""); fördröjning (5000);}  
#3
+4
TheDoctor
2014-02-16 20:45:56 UTC
view on stackexchange narkive permalink

Har du provat ett lågpassfilter? Jag hittade ett exempel här och ett annat här.

Båda dessa bibliotek har en lista över data som läses från den analoga sensorn som du väljer är genomsnittet. Varje nytt sensorvärde läggs till i listan och den sista kastas ut så här:

  Lista: 3 4 3 3 4 3 5 3 2 3 4 3 ny läsning tillagd. gammal kastad ut / - / - Lista: 5 3 4 3 3 4 3 5 3 2 3 4 genomsnitt i listan  
Ganska mycket vad ett enkelt [FIR-filter] (https://en.wikipedia.org/wiki/Finite_impulse_response) gör med alla tryckvärden inställda på 1. Att fiska med kranvärdena kan förbättra signalen ytterligare, men kräver högre matte.
Obs: Den andra länken beräknar [kumulativt glidande medelvärde] (http://en.wikipedia.org/wiki/Moving_average#Cumulative_moving_average) vilket inte är ett praktiskt val för manöverdonskontroll, särskilt en som kan innebära frekvent start och stopp. Den utjämnade signalen kommer alltid att spåra toppvärdet för den faktiska signalen med ganska stor marginal.
#4
+2
akellyirl
2014-02-16 22:34:31 UTC
view on stackexchange narkive permalink

Du kan filtrera detta digitalt med ett lågpassfilter:

  int valueFilt = (1-0.99) * värde + 0,99 * valueFilt;  

Ändra 0,99 för att ändra avskurna frekvens (närmare 1.0 är lägre frekvens). Det faktiska uttrycket för det värdet är exp (-2 * pi * f / fs) där f är gränsvärdet du vill ha och fs är frekvensen som data samplas vid.

En annan typ av "digitalt filter "är ett händelsesfilter. Det fungerar bra på data som har outliers; t.ex. 9,9,8,10,9,25,9. Ett händelsesfilter returnerar det vanligaste värdet. Statistiskt är detta läget.

Statistiska medelvärden som medelvärde, läge osv. Kan beräknas med hjälp av Arduino genomsnittsbibliotek.

Ett exempel från Arduino Library-sidan hänvisas till:

  #include <Average.h> # define CNT 600int d [CNT]; void setup () {Serial.begin (9600);} void loop () {int i; för (i = 0; i<CNT; i ++) {d [i] = slumpmässig (500); } Serial.print ("Mean:"); Serietryck (medelvärde (d, CNT), DEC); Serial.print ("Mode:"); Serial.print (läge (d, CNT), DEC); Serial.print ("Max:"); Serial.print (maximum (d, CNT), DEC); Serial.print ("Min:"); Serial.print (minimum (d, CNT), DEC); Serial.print ("Standardavvikelse:"); Serial.print (stddev (d, CNT), 4); Serial.println (""); Serial.println (""); fördröjning (5000);}  
Observera att detta kommer att vara väldigt långsamt, eftersom det gör massor av implicita gjutningar för att flyta och tillbaka.


Denna fråga och svar översattes automatiskt från det engelska språket.Det ursprungliga innehållet finns tillgängligt på stackexchange, vilket vi tackar för cc by-sa 3.0-licensen som det distribueras under.
Loading...