mikrocontroller.net

Forum: FPGA, VHDL & Co. Noise Filter für UART?


Autor: Michael Fischer (mifi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

die genauen Eigenschaften des Filters kann ich leider nicht beschreiben, 
nur die Umgebung für die er benutzt werden soll.

Für eine RS485 UART Übertragung (8,N,1) mit 2MBit wollte ich evt. 
Störungen am Empfänger filtern. Hierfür wird für die Synchronisation 
natürlich das Signal erst einmal über zwei FFs geführt. Danach soll 
folgender "Filter" eingesetzt werden:

   signal noise_sr : std_logic_vector(2 downto 0)  := (others => '0');
   signal rxd      : std_logic := '0'; 


   process (clk_i)
   begin
      if rising_edge(clk_i) then
      
         if (rxd_i = '1') then
            noise_sr <= noise_sr(1 downto 0) & '1';
         end if;   
         
         if (rxd_i = '0') then
            noise_sr <= '0' & noise_sr(2 downto 1);
         end if;   
         
         if (noise_sr = "000") then
            rxd <= '0';
         end if;   
         
         if (noise_sr = "111") then
            rxd <= '1';
         end if;   
         
      end if;
   end process;


clk_i beträgt hier 96MHz. rxd_i ist das synchronisierte Signal und rxd 
das Signal nach dem Filter. Ist das Signal (rxd_i) 1 so wird diese von 
rechts in den Filter geschoben. Bei einer 0 wird diese von links 
geschoben. Steht der Filter auf 0 ist der Ausgang auch 0, entsprechend 
gilt dies für die 1. Ich meine das dies eine gleitende Mittelwertbildung 
ist.

Als Alternative könnte man auch eine 2 aus 3 Auswahl umsetzen.

Das rxd Signal soll später 16 fach abgetastet werden, und die Mitte (#8) 
gibt dann den Wert für das entsprechende Bit an.

Wie ist nach Eurer Erfahrung hier das richtige Vorgehen?

Viele Grüße,
Michael

Autor: TestX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso nimmst du nicht einen klassischen Ansatz wie einen TP Filter ?

Was du da machst ist ziemlicher Murks... wenn du das Signal "abtasten" 
willst solltest du es auch analog sampeln..überleg dir mal wieviel sinn 
es macht hier nur digital eine Art "Mittelwert" zu bilden..

Autor: Michael Fischer (mifi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie meinst Du das mit "solltest du es auch analog sampeln"? Ich glaube 
nicht das es eine gute Idee wäre einen echten TP vor den RS485 
Transceiver zu setzen.

Autor: TestX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Such mal nach "slew rate" in zusammenhang mit rs485 oder auch can 
transceivern.

Autor: Achim S. (achs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael F. schrieb:
> die Mitte (#8)gibt

warum wertest Du denn dann nicht genau die Signale dort aus? Also die 
Mehrheit aus #7,#8 und #9

Wenn alle 3 gleich sind, ... OK gut.
Wenn einer anders ist (33%), dann ist Dein Signal doch so verrauscht, 
dass die Startflanke und die Auswertung des Rests nur geraten ist. Der 
Gewinn durch bessere Digitalverarbeitung ist dann vernachlässigbar.

Autor: Michael Fischer (mifi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Achim

das mit der #7,#8 und #9 habe ich mir auch schon überlegt. Und die Frage
ist ob das Vergleichbar ist mit einer 2 aus 3 Auswahl wenn dies schon 
mit dem Signal selbst gemacht wird.

Gruß,
Michael

: Bearbeitet durch User
Autor: Gustl Buheitel (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Um eine Taste zu entprellen habe ich mal das hier geschrieben:
library ieee;
use ieee.std_logic_1164.all;
use IEEE.numeric_std.all;

entity Pin_debounce is
  Port (  CLK  : in STD_LOGIC;
    PIN_in  : in STD_LOGIC;
    PIN_out : out STD_LOGIC);
end Pin_debounce;

architecture Verhalten of Pin_debounce is

signal wert: unsigned(3 downto 0);

begin

process
  begin
  wait until rising_edge(CLK);
  
  if PIN_in = '1' then
    if wert < 15 then wert <= wert +1; end if;
  else
    if wert > 0 then wert <= wert -1; end if;
  end if;
  
  PIN_out <= wert(3);
end process;

end Verhalten;

Das ist eigentlich auch ein gleitender Mittelwert und so ein Tiefpass.

Autor: Achim S. (achs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gustl B. schrieb:

> Das ist eigentlich auch ein gleitender Mittelwert und so ein Tiefpass.

Kein Tiefpass. Denn Dein Filter hat keinerlei Hysterese oder Dämpfung. 
Er lässt selbst die maximale Frequenz (Abtastfrequenz) ungefiltert 
durch, wenn er zufällig grad in der Mitte ist.

Gleichwohl hat er eine Phasenverschiebung von bis zu 15  Takten.

Dein Filter wäre der von oben, wenn Du ein Ausgangs-Flag einbaust, dass 
bei +15 high wird, bei -15 low und sich sonst nicht ändert. Dann ist die 
maximale Ausgangsfrequenz ein 30tel der Eingangsfrequenz, also ein 
Tiefpass.

von gleitendem Mittelwert kann man bei beiden m.E. nicht sprechen, da 
der Ausgang immer genau einer der beiden Maximalwerte ist. Es wird also 
genau nichts gemittelt.

: Bearbeitet durch User
Autor: Achim S. (achs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael F. schrieb:
> Und die Frage
> ist ob das Vergleichbar ist mit einer 2 aus 3 Auswahl wenn dies schon
> mit dem Signal selbst gemacht wird.

Meist gibt es 2 Probleme bei UART-Signalen:

1) Erkennung der Startflanke. Meist wird diese (beim ersten Zeichen) zu 
später erkannt, da die Leitung in maximaler Sättigung ist (seit 
Stunden der Ruhepegel;-)

2) Erkennung des letzten Pegels. Bei 8+2+1 = 11 Bits müssen Taktfehler 
(Quartz, UART-Teiler, Synchronisation) kleiner als 3% bzw. 1/2 Bit 
bleiben.

Die Flanken dazwischen sind quasi "sicherer", die Pegel zum 
Abtastzeitpunkt "stabiler".

Mit Deinem Ansatz erkennst Du die Startflanke grundsätzlich erst ein 
paar Takte später. Das könntest Du zwar noch konstant korrigieren, wäre 
aber ein Problem, wenn das Signal da toggelt.

Da die Startflanke in der Regel sowieso verzögert ist, ist es am 
einfachsten und effektivsten, sofort auf dieses Signal zu reagieren und 
von dort nach 15,16 und 17 Takten die Mehrheit zu bestimmen.

Wenn Du wirkliche Spikes auf der Leitung (ein high trotz dauerhaftem 
low) hast, solltest Du an analog und nicht digital handeln.

: Bearbeitet durch User
Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
TestX schrieb:
> Was du da machst ist ziemlicher Murks...
Mitnichten. Ich würde auch in etwa diesen Ansatz gehen.

Allerdings ohne diese Rechts-Links-Schieberei (auch wenn ich 
Schieberegister liebe). Diese aufwändige versteckte "Summiererei" macht 
die Sache ziemlich undurchschaubar...

Mein Ansatz wäre also der hier (mit einem etwas breiteren 
Schieberegister):
   process (clk_i)
   begin
      if rising_edge(clk_i) then
      
         noise_sr <= noise_sr(5 downto 0) & rxd_i;
        
         if (noise_sr = (others=>'0')) then
            rxd <= '0';
         end if;   
         
         if (noise_sr = (others=>'1')) then
            rxd <= '1';
         end if;   
         
      end if;
   end process;

Michael F. schrieb:
> wollte ich evt. Störungen am Empfänger filtern.
Solange du nicht weißt, was du filtern musst und wie oft es 
auftritt, kann jeder Schuss ins Blaue gleich gut oder schlecht treffen. 
Mein erster Schritt wäre also, diese Störungen zu qualifizieren und zu 
analysieren...

: Bearbeitet durch Moderator
Autor: Gustl Buheitel (-gb-)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
OK OK, ja, kein gleitender Mittelwert, der Ausgang ist das MSB des 
gleitenden Mittelwerts. Sprich bei 16 Samplewerten wird eine '1' 
ausgegeben wenn der gleitende Mittelwert > 7 ist, sonst '0'.

Wieso so und nicht wie Lothar ein langes Schieberegister bei dem auf 
alles '0' oder alles '1' geprüft wird?
Weil wenn ein Rauschen da ist vielleicht nie der Zustand alles '0' 
erreicht wird sondern nur fast alles '0'. Ob das jetzt sinnvoll ist weiß 
ich nicht.

Autor: Michael Fischer (mifi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Lothar,

mit Deiner Version habe ich etwas Bauchschmerzen.Wenn hier 5 Takte eine 
1 vorhanden waren, und dann eine 0 kommt, braucht es erneut 6x eine 1 um 
am Ausgang wirklich eine 1 zu bekommen. Darum die Idee mit dem 
rechts/links schieben.

@Achim,
Ich glaube ich weiss was Du meinst. Das man die Startflanke etwas spät 
erkennt und dadurch sich der Abtastpunkt immer weiter nach hinten 
verschiebt.

Ich glaube man muss das mal testen wie es reagiert. Bei einem Clock vom 
96MHz und einer Bitrate vom 2MHz habe ich 48 Clocks Zeit. Bei #24 ist 
die Mitte wo man abtasten sollte. Die Startflanke wird über ein 
Schieberegister erkannt, evt. darf man hier den Counter dann nicht auf 0 
setzen, sondern schon auf 2 oder 3.

Und wie Lothar schon angemerkt hat. Erst mal schauen wie die Störungen 
später wirklich aussehen.

Danke für Eure Anmerkungen.

Gruß,
Michael

: Bearbeitet durch User
Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael F. schrieb:
> Darum die Idee mit dem rechts/links schieben.
Das ist nichts anderes als ein Zähler mit Hysterese:
signal noise_cnt : integer range 0 to 3 := 0;
:
:
   process (clk_i)
   begin
      if rising_edge(clk_i) then
      
         if rxd_i='1' and noise_cnt<3 then
            noise_cnt <= noise_cnt + 1;
         end if;

         if rxd_i='0' and noise_cnt>0 then
            noise_cnt <= noise_cnt - 1;
         end if;   
        
         if (noise_cnt = 0) then
            rxd <= '0';
         end if;   
         
         if (noise_cnt = 3) then
            rxd <= '1';
         end if;   
         
      end if;
   end process;

: Bearbeitet durch Moderator
Autor: Achim S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gustl B. schrieb:
> Wieso so und nicht wie Lothar ein langes Schieberegister bei dem auf
> alles '0' oder alles '1' geprüft wird?

Lothars Ansatz ist quasi außer Konkurrenz, da (wie Michael schon 
anmerkt) jede einzelne 0 wieder n 1en erfordert und umgekehrt.

Dein Ansatz und Michaels sind dagegen gleichwertig. 15 Bit bei Michael 
entspräche Zählen bis 15 bei Dir. In beiden sind die gleichen Schwellen 
möglich:
Alles 0 oder 1 entspricht 0 bzw. 15 bei Dir.
Deine abfrage entspricht Bit 8 bei Michael.
Sämtliche Zwischenwerte wären möglich, also 1 bei > 10 und 0 bei <5.

Autor: Edi. M. (Firma: Industrie 1.0) (elektromeister)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Diese Hysterese-Grenzen kann Ich nicht empfehlen. Die speichern die 
Geschichte von Störungen und schaffen ein Level, das mit der neuen 
Störung nichts zu tun hat.

Solche Sachen filtert man diskret und dann mit einem AKF.

Autor: Michael Fischer (mifi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ist ein "AKF"?
Ist damit ein "Aktives Filter" gemeint?
Hast Du hier auch einen Vorschlag den man gut in VHDL umsetzen kann?

Autor: Edi. M. (Firma: Industrie 1.0) (elektromeister)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Auto-Korrelations-Filter

Es passt sich den Pegeln automatisch an. D.h. Du sampelst das Signal 
passend ab und wirst die Spitzen diskret raus. Rest Filterung mit 
Glättung.

Autor: Jürgen Schuhmacher (engineer) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Gustl B. schrieb:
> Das ist eigentlich auch ein gleitender Mittelwert und so ein Tiefpass.

Das ist ein Integrator, der nur bedingt ein klassischer Tiefpass ist.
Da muss man gfs noch differenzieren, um Gleichanteil wegzukriegen. Das 
läuft dann auf ein CIC hinaus. Da kann man oft auch einen trägen 
Tiefpass nehmen, wie ich es beim Entprellen-Artikel reingeschrieben 
habe. Normalerweise reicht sowas.

Generell ist der Tiefpass und Filterung nötig, wenn man runtersampelt, 
um z.B. auf der Datentaktrate arbeiten zu können.

Autor: Thomas U. (thomasu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei dem Ansatz, wenn nur 6 Takte betrachtet werden, reicht der scope 
gerade für 1/6 der Taktfrequenz und dämpft nur Frequenzen im Bereich 
16MHz aufwärts weg. Was ist mit tieffrequenteren Störungen?

Autor: Weltbester FPGA-Pongo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gustl B. schrieb:
> OK OK, ja, kein gleitender Mittelwert, der Ausgang ist das MSB des
> gleitenden Mittelwerts. Sprich bei 16 Samplewerten wird eine '1'
> ausgegeben wenn der gleitende Mittelwert > 7 ist, sonst '0'.
Wenn die Signale zu sehr verrauscht sind, sodaß es zu Sprüngen um den 
Mittelwert kommen kann, weil ...

Beitrag "Gleitender Mittelwert rauscht"

... dann kann man das auch so machen, dass über einen sehr langen 
Zeitraum integriert und dann wieder differenziert wird:

Beitrag "Differenzieren in VHDL"

Läuft auf sowas hinaus:

Beitrag "Decimator-Schaltung für Puls-Datenstrom"

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.