Hallo Zusammen, ich bin gerade dabei, ein kleines Projekt mit meinem Artik7 zu programmieren wo ich einen Drehgeber mit VHDL emulieren möchte. Im Gegensatz zum Code von Lothar Miller wird die Position als analoges Signal eingelesen, dann digitalisiert und A und B als digitale Ausgangssignale erzeugt (invertierte Funktionalität des Lothar Miller Codes). Der ADC ist bereits eingerichtet und ich kann das analoge Positionssignal einlesen und in ein std_logic_vector Signal umwandeln. Um nun A und B mit einer Zeitverzögerung zu erzeugen, muss ich zuerst die Drehrichtung des std_logic_vector (oder die Positionsanzeige) erkennen und dann eine entsprechende Logik programmieren. Hat jemand eine Idee, wie ich die Drehrichtung erkennen kann (um zu wissen, ob ein std_logic_vector inkrementiert oder dekrementiert)? oder hat jemand eine Idee, ob ein solcher Code irgendwo anders programmiert ist? Beste Grüsse Michael
:
Bearbeitet durch User
Wenn ich dich richtig verstehe, is das was ähnliches wie ich mal hier vorgestellt habe: Beitrag "Feedback erstes VHDL-Projekt" Bei mir gab es allerdings beim Rohsignal wrap-arounds, sodass die Logik etwas mehr beachten musste. Im speziellen mussten die Sprünge im Rohsignal erkannt und beseitigt werden, um einen durchgängigen Zähler für den Quadraturausgang zu erhalten.
Ja D. schrieb: > Hat jemand eine Idee, wie ich die > Drehrichtung erkennen kann (um zu wissen, ob ein std_logic_vector > inkrementiert oder dekrementiert)? Warum nimmst Du einen std_logic_vector, wenn Du Zahlenwerte vergleichen willst? Nimm' stattdessen einen signed oder unsigned Wert und Du kannst unmittelbar auf größer oder kleiner testen.
Ja D. schrieb: > Um nun A und B mit einer > Zeitverzögerung zu erzeugen, muss ich zuerst die Drehrichtung des > std_logic_vector (oder die Positionsanzeige) erkennen und dann eine > entsprechende Logik programmieren. Hat jemand eine Idee, wie ich die > Drehrichtung erkennen kann (um zu wissen, ob ein std_logic_vector > inkrementiert oder dekrementiert)? oder hat jemand eine Idee, ob ein > solcher Code irgendwo anders programmiert ist? Man braucht einen 2. Zähler, der die Anzahl/Position der schon ausgegebenen Pulse repräsentiert. Die Differenz zum Analogwert gibt dir die Richtung vor. Sprich, der interne Zähler läuft dem ADC-Wert hinterher. Beitrag "Re: 0-10V Signal in Drehimpulsgeber Signal Umwandeln"
Ja D. schrieb: > wo ich einen Drehgeber mit VHDL emulieren möchte. Was heißt "emulieren"? Dasheißt für mich, du möchtest das Verhalten eines Drehgebers erzeugen, also z.B. aus einer Position die Werte AB generieren. Was du aber im Folgesatz beschreibst, ist ein blosses Auswerten eines Analogsignals. Woher kommt das Analogsignal und wie sieht es aus? XY-Poti? Angenommen, man kann das Signal in einen Winkel übersetzen, dann muss einfach nur für A = 0 ... 180 und für B=90 ...270 eine 1 ausgegeben werden. 000 ... 090 A=1, B=0 090 ... 180 A=1, B=1 180 ... 270 A=0, B=1 279 ... 360 A=0, B=0
Ja D. schrieb: > Hat jemand eine Idee, wie ich die > Drehrichtung erkennen kann Sind beide Signale sinusförmig? Wenn ja, würde ich die Phase zwischen den beiden Signalen ermitteln. Alternativ: Umwandeln in ein Rechtecksignal (Komparator) und dann die klassischen Verfahren anwenden. Duke
Ja D. schrieb: > Im Gegensatz zum Code von Lothar Miller wird die Position als analoges > Signal eingelesen Ist das ein sin/cos Geber wie hier beschrieben: http://www.servotechnik.de/fachwissen/geber/f_beitr_00_410.htm Ja D. schrieb: > Um nun A und B mit einer Zeitverzögerung zu erzeugen, muss ich zuerst > die Drehrichtung des std_logic_vector (oder die Positionsanzeige) > erkennen und dann eine entsprechende Logik programmieren. Hat jemand > eine Idee, wie ich die Drehrichtung erkennen kann (um zu wissen, ob ein > std_logic_vector inkrementiert oder dekrementiert)? Mit hoher Wahrscheinlichkeit ist der Ansatz falsch. Du musst da nichts umdrehen, weil dir ja der Geber immer die aktuelle Posittion liefert. > oder hat jemand eine Idee Beschreibe doch mal, was du hast (mit Typbezeichnungen usw usf) und dann zeichne mal ein Diagramm mit dem Signalverlauf am Eingang und was du daraus machen sollst. Ja D. schrieb: > ob ein solcher Code irgendwo anders programmiert ist? Solltest du für den besten Lerneffekt die Aufgabe nicht besser selber lösen, statt irgendwas im Internetz zusammenzukopieren?
:
Bearbeitet durch Moderator
Lothar M. schrieb: > Solltest du für den besten Lerneffekt die Aufgabe nicht besser selber > lösen, statt irgendwas im Internetz zusammenzukopieren? ja, wobei: Eine richtige Drehgeber-Emulation, mit der man etwas anfangen kann, funktioniert schon noch ein wenig komplizierter, je nachdem was der Anwender benötigt. Meistens will er ja seine Ausgangs-Elektronik und die Signalverarbeitung optimieren. - Drehgeber haben mehrere Impulswechsel pro Vollkreis - die Kontakte prellen. d.h. sie haben einen während des Schaltens veränderlichen Widerstand, der auch nochmal 0 werden kann - die Kontakte prellen unterschiedlich lange und schnell - die Kontakte haben unterschiedliche Mikro-Positionen, die nicht exakten Winkelteilungen 1/n entsprechen - die Kontakte haben unterschiedliche elektrische Ruhewiderstände - die Kontakte altern und verschmutzen, sodass die Widerstände steigen - die Kontakte kratzen beim Drehen - Die Drehgeber haben mitunter mechanische und/oder magnetische Rastpunkte - die Rastpunkte haben eine unterschiedliche mechanische Stärke - die Rastpunkte liegen nicht exakt auf ganzzahligen Winkelteilungen 1/n - die Rastpunkte sind gegenüber den Kontakten teilweise um eine halbe Rastweite versetzt, sodass die Kontakte nicht im Bereich der Rastpunkte liegen und damit effektiv weniger prellen - die Welle nimmt bei schnellen Bewegungen ein Rotationsmoment auf - die Welle schleift - die Welle schwingt in sich nach - der Knopf hat eine Trägheit - der Knopf schwingt nach (Für einen Wellen-Drehgeber ersetze "Knopf" durch "Getriebe" oder "Achse".) Ich habe ein komplettes VHDL-Modell für solche Drehgeber, in welchem alle diese Parameter einstellbar sind. Funktioniert realistisch bis 30kUPM bei 60MHz. Angeschlossen werden z.B. virtuelle Reihen- und pullup-Widerstände und Versorgungs-Spannungen, gefolgt von Kapazitäten, die ebenfalls parametrierbar sind. Ausgabe ist ebenfalls eine virtuelle Spannung, die mit EMI-noise beaufschlagt werden kann und an die man einen Komparator anschließen kann, der eine parametrierbare Hysterese hat. Damit bekommt man dann die digitalen A/B/(C) Signale mit allen möglichen Varianzen.
Jürgen S. schrieb: > je nachdem was der Anwender benötigt. Ja, das ist noch unklar... Jürgen S. schrieb: > Eine richtige Drehgeber-Emulation, mit der man etwas anfangen kann, > funktioniert schon noch ein wenig komplizierter Ich glaube, das Wort "Emulation" wurde vom TO falsch verwendet. Ich vermute, er will einfach nur einen sin/cos-Geber einlesen und daraus A/B/0-Quadratur Signale machen. Das ist im ersten Ansatz eigentlich ganz einfach, es müssen nur hinreichend große ROM/RAM vorbelegt werden, dann kann ich mit den AD-Werten als Adressvektor direkt die A/B/0-Werte auslesen. Alternativ kann man eine Impulsnachlaufregelung basteln, oder..., oder...
Hallo Zusammen, sorry für meine späte Antwort. Eigentlich möchte ich einen Encodersensor, den ich nicht habe, in VHDL simulieren. Der Encoder ist Teil einer Strecke, die ich auf einem echtzeitfähigen Controller simuliere. Von dem Controller kann ich aber nur analoge Signale ausgeben, also ist die Idee, dass ich die Rotorposition als analoges Signal ausgebe und in das FPGA einlese, wo dann die Schaltimpulse A/B erzeugt werden. Dazu muss ich das analoge Signal einlesen, die Richtung erkennen und die Schaltimpulse erzeugen. Beste Grüsse Michael
Für die Richtungserkennung kann man natürlich das gewandelte Signal, das ich als std_logic_vector habe, in Integer umwandeln und mit einem vorherigen vergleichen, aber ich habe vor ein paar Jahren die Erfahrung gemacht, dass ein vhdl-Prozess, der auf Integer-Zahlen empfindlich ist, ziemlich instabil ist.
> Eine richtige Drehgeber-Emulation, mit der man etwas anfangen kann, > funktioniert schon noch ein wenig komplizierter, je nachdem was der > Anwender benötigt. Meistens will er ja seine Ausgangs-Elektronik und die > Signalverarbeitung optimieren. > das klingt wirklich nach einem detaillierten und teilweise notwendigen Entwurf. Ich habe schon an so etwas gedacht, um fehlerhafte Schaltimpulse zu erzeugen, damit ich sehen kann, wie die Weiterverarbeitung der Signale mit solchen Störungen umgehen kann.
> Warum nimmst Du einen std_logic_vector, wenn Du Zahlenwerte vergleichen > willst? > > Nimm' stattdessen einen signed oder unsigned Wert und Du kannst > unmittelbar auf größer oder kleiner testen. Für die Richtungserkennung kann man natürlich das gewandelte Signal, das ich als std_logic_vector habe, in Integer umwandeln und mit einem vorherigen vergleichen, aber ich habe vor ein paar Jahren die Erfahrung gemacht, dass ein vhdl-Prozess, der auf Integer-Zahlen empfindlich ist, ziemlich instabil ist.
Ja D. schrieb: > aber ich habe vor ein paar Jahren die Erfahrung gemacht, dass ein vhdl- > Prozess, der auf Integer-Zahlen empfindlich ist, ziemlich instabil ist. Dir ist grundlegend schon klar, dass "ein Prozess" an sich nicht "empfindlich" sein kann? Was da "empfindlich" sein kann, ist eine ungünstig beschriebene Hardware. Denn natürlich darfst du z.B. niemals zwei Integer einfach so kombinatorisch vergleichen und auf dieses Vergleichsergebnis asynchron reagieren. Denn dann spuckt dir natürlich jeder Glitch und jeder Spike in die Suppe. Mit höchster Wahrscheinlichkeit hast du damals genau diese Erfahrung gemacht. Allerdings hast du aus dieser Erfahrung nichts gelernt, denn das, was du da gerade basteln willst, läuft auf das selbe Ergebnis hinaus: du willst asynchron einen Analogwert ausgeben, diesen völlig asynchron wandeln und dann in irgendwelche Impulse übersetzen. Beschreib doch mal die Lösung, wie du sie dir vorstellst, denn offenbar macht dir dabei eine wie auch immer gerartete "Richtungserkennung" Probleme. Und überleg mal eine Antwort auf diese Fragen: Wie willst du die Position in dem Analogwert unterbringen? Wie willst du die "Unendlichkeit" eines Drehgebers abbilden? Was passiert bei Rauschen und Störungeinkopplungen auf dem Analogwert? Oder soll der Analogwert eine Geschwindigkeit abbilden? Das wäre sowieso die einfachere Möglichkeit, denn wenn der ADC eine Absolutposition ausgeben soll, dann kannst du mit einem 10-Bit-DAC gerade mal 1 einzige Umdrehungen eines 256er-Drehgebers mit 4-fach-Auswertung abbilden...
Ja D. schrieb: > Von dem Controller kann ich aber nur analoge Signale > ausgeben, also ist die Idee, dass ich die Rotorposition als analoges > Signal ausgebe und in das FPGA einlese, wo dann die Schaltimpulse A/B > erzeugt werden. Dazu muss ich das analoge Signal einlesen, die Richtung > erkennen und die Schaltimpulse erzeugen. d.h. du kriegst die Position als AD-gewandelten Digitalwert? Dann gilt das was ich hier schrieb: Ralf schrieb: > Angenommen, man kann das Signal in einen Winkel übersetzen, dann muss > einfach nur für A = 0 ... 180 und für B=90 ...270 eine 1 ausgegeben > werden. > > 000 ... 090 A=1, B=0 > 090 ... 180 A=1, B=1 > 180 ... 270 A=0, B=1 > 270 ... 360 A=0, B=0 Muss halt noch etwas Hysterese rein und zwar in den Winkelwert. Der darf nicht wackeln, sondern muss nur in einer Richtung laufen. Das Beispiel hier aus dem Artikelbereich von Danegger ist doch so etwas ...
> Was da "empfindlich" sein kann, ist eine ungünstig beschriebene > Hardware. Denn natürlich darfst du z.B. niemals zwei Integer einfach so > kombinatorisch vergleichen und auf dieses Vergleichsergebnis asynchron > reagieren. Denn dann spuckt dir natürlich jeder Glitch und jeder Spike > in die Suppe. Mit höchster Wahrscheinlichkeit hast du damals genau diese > Erfahrung gemacht. > Danke, du hast natürlich recht. Das ist genau das, was ich vermeiden wollte... Ich hoffe, ich lerne aus meinen Fehlern. Zu meiner Verteidigung muss ich sagen, dass ich das letzte Mal vor 3 Jahren VHDL geschrieben habe und nicht annähernd so erfahren bin wie du > Beschreib doch mal die Lösung, wie du sie dir vorstellst, denn offenbar > macht dir dabei eine wie auch immer gerartete "Richtungserkennung" > Probleme. Ich habe hier ein entsprechendes Bild des Vorhabens beigefügt. > Und überleg mal eine Antwort auf diese Fragen: > Wie willst du die Position in dem Analogwert unterbringen? Der Vorschlag von Ralph ist wirklich spannend, nur müsste man prinzipiell auch wissen, ob das digitalisierte Positionssignal inkrementiert oder dekrementiert. Ralf schrieb: > Angenommen, man kann das Signal in einen Winkel übersetzen, dann muss > einfach nur für A = 0 ... 180 und für B=90 ...270 eine 1 ausgegeben > werden. > > 000 ... 090 A=1, B=0 > 090 ... 180 A=1, B=1 > 180 ... 270 A=0, B=1 > 270 ... 360 A=0, B=0 > Wie willst du die "Unendlichkeit" eines Drehgebers abbilden? durch Aufteilung des Positionssignals in 4 Winkelsektoren kann ich die Ausgabe eines Gary-Codes nach jeder Periode wiederholen > Was passiert bei Rauschen und Störungeinkopplungen auf dem Analogwert? Ich werde ein analoges Differenzsignal für die Übertragung zwischen dem Controller und dem FPGA verwenden, so dass die Einkopplung von Störungen reduziert wird. > Oder soll der Analogwert eine Geschwindigkeit abbilden? nein
Ralf schrieb: > Angenommen, man kann das Signal in einen Winkel übersetzen, dann muss > einfach nur für A = 0 ... 180 und für B=90 ...270 eine 1 ausgegeben > werden. > > 000 ... 090 A=1, B=0 > 090 ... 180 A=1, B=1 > 180 ... 270 A=0, B=1 > 279 ... 360 A=0, B=0 vielen Dank für den Vorschlag
Lothar M. schrieb: > Das ist im ersten Ansatz eigentlich ganz einfach, es müssen nur > hinreichend große ROM/RAM vorbelegt werden, dann kann ich mit den > AD-Werten als Adressvektor direkt die A/B/0-Werte auslesen. Warum als Tabelle und nicht analytisch, mathematisch? Das Umsetzen von Winkel auf AB ist - wenn man meine Liste von oben mit den ganzen Einflüssen zur Seite lässt - ja nun eigentlich trivial, oder? Eine Tabelle würde ich eher hernehmen, um ein Sin/Cos-Signal aus der Position zu generieren (was man mein Modell selbstredend auch kann). Ja D. schrieb: > Ich werde ein analoges Differenzsignal für die Übertragung zwischen dem > Controller und dem FPGA verwenden, so dass die Einkopplung von Störungen > reduziert wird. Das wird nicht reichen, weil schon die Drehgebersignale verrauscht sind. Sie sind es gerade durch Wellenschwingungen. Man kann auf schnellen Maschinengebern regelrecht die Phasenmodulation von Störungen messen und im Einzelfall sogar diese als Signal hernehmen, um Körperschall aufzugreifen. Dann wirken die Encoder als Mikrofone :-) Zur Zeichnung: Wenn es analoges Signal des Typs X,Y ist, wie hier im Raume steht, dann braucht es in der analogen Welt einen Komparator. Der aber sollte wie ein Schmitt-Trigger funktionieren, also zwei Schaltschwellen haben. Gfs braucht es noch ein auto-gain, um selbige nachzuregeln. Ja D. schrieb: > dass ich das letzte Mal vor 3 Jahren VHDL geschrieben habe das ist ein reines Digitalthema. Mit einem Microcontroller müsste man es genau so machen. Ja D. schrieb: > Ich habe schon an so etwas gedacht, um fehlerhafte > Schaltimpulse zu erzeugen, damit ich sehen kann, wie die > Weiterverarbeitung der Signale mit solchen Störungen umgehen kann. Genau dafür werden solche Modelle genutzt - wenn auch oft einfacher. ... und letztlich dient die Emulation sicher dazu, die nachfolgende Auswertung zu testen, nehme ich an.
Ja D. schrieb: > Ich habe hier ein entsprechendes Bild des Vorhabens beigefügt. Ich kann das Analogsignal nicht der A/B Spur zuordnen. Kannst du die mal übereinander malen? Dabei musst du bedenken, dass es abgesehen von den Maximalwerten jeden Analogwert 2x gibt. Wenn ich dir sage: der Analogwert ist 0.707 vom Maximalwert, dann kannst du mir nicht sagen, ob ich damit 45° oder 135° meine. >> Wie willst du die "Unendlichkeit" eines Drehgebers abbilden? > durch Aufteilung des Positionssignals in 4 Winkelsektoren kann ich die > Ausgabe eines Gary-Codes nach jeder Periode wiederholen Ich möchte behaupten, dass du das nicht ganz fertig gedacht hast. Zeig doch mal, wie du das Analogsignal da auf den Graycode abbilden willst. Und vor allem: wie du es schaffst, die Übergänge des Analogsignals so zu gestalten, dass dieser Graycode nicht nur immer vor- und zurückläuft.
> Ich kann das Analogsignal nicht der A/B Spur zuordnen. Kannst du die mal > übereinander malen? Dabei musst du bedenken, dass es abgesehen von den > Maximalwerten jeden Analogwert 2x gibt. Wenn ich dir sage: der > Analogwert ist 0.707 vom Maximalwert, dann kannst du mir nicht sagen, ob > ich damit 45° oder 135° meine. auch hier hast Du völlig recht, ich werde die Winkelinformation vom Controller in Form eines Sägezahnsignals ausgeben zwischen 0 und 2*pi, dann hätte ich das Problem nicht mehr. > Ich möchte behaupten, dass du das nicht ganz fertig gedacht hast. Zeig > doch mal, wie du das Analogsignal da auf den Graycode abbilden willst. > Und vor allem: wie du es schaffst, die Übergänge des Analogsignals so > zu gestalten, dass dieser Graycode nicht nur immer vor- und zurückläuft. Ich werde zunächst versuchen, es pragmatisch und nicht sehr clever zu lösen, indem ich die Drehrichtung als digitales Signal aus dem Controller lese und je nach Zustand entscheide, ob ich vorwärts oder rückwärts drehe....wahrscheintlich bilde ich mir dadurch unnötige Jitter
Ja D. schrieb: > ich werde die Winkelinformation vom Controller in Form eines > Sägezahnsignals ausgeben zwischen 0 und 2*pi, dann hätte ich das Problem > nicht mehr. Ein Sägezahn steigt theoretisch linear vom Minimalwert zum Maximalwert und fällt in der Zeit 0 wieder auf den Minimalwert. Und jetzt kommt der Knackpunkt: in der Praxis gibt es aber keine unendlich steilen Flanken, deshalb läuft das im Analogwert codiert Bitmuster langsam "hoch" und schnell wieder "runter". Und dazwischen gibt es alle möglichen Glitches und Spikes.
Lothar M. schrieb: > Und jetzt kommt der Knackpunkt: in der Praxis gibt es aber keine > unendlich steilen Flanken, Nun ja, ein schneller GaAs-Schalttransi, dann geht es sogar für FPGA-Eingänge zackig genug :-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.