Guten Abend allerseits :)
Ich bin zurzeit dabei, folgenden Encoder via Raspberry Pi [B+]
auszulesen:
https://www.siko-global.com/adbimage/1713/asset_original/datenblatt-msk2000.pdf
(Datenblatt Siko MSK2000)
Dieser hat folgende Auflösung: 0,25 mm.
Das Ziel ist, dass ich durch den Encoder die aktuelle Position erfahre
(bei senkrechter Bewegung). Der Encoder wird mit einer maximalen
Geschwindigkeit von 10 m/s verfahren, das ergibt:
40.000 Pulse/Sekunde (wenn man die volle Auflösung betrachtet).
Die erste Hürde konnte ich bereits durch Hilfe in diesem Forum
bewältigen. Der Encoder stellt 4 Signalleitungen bereit, wovon 2 die
invertierten Signale darstellen (RS422 Standard). Das ganze wird von
einem RS422 Receiver IC ausgewertet, welcher dem Raspberry Pi TTL
Signale zur Verfügung stellt. Funktioniert soweit einwandfrei (überprüft
mit dem Ossi).
Nun fehlt noch die softwareseitige Auswertung der Signale, und da kommt
die Hauptfrage ins Spiel:
Kann der raspberry pi mit einer solchen Auflösung umgehen? In einem
initialen Testprogramm kam ich beim senkrechten Verfahren nicht wieder
auf den Ausgangswert zurück, sprich es gehen Signale verloren. Das erste
Programm wurde mit der wiringPi Bibliothek umgesetzt. Hier der
Programmcode:
// Remove encoder from linked list and de-allocate storage
137
enc=encList;
138
while((enc!=NULL)&&(enc->Num!=num)){
139
prevEnc=enc;
140
enc=enc->Next;
141
}
142
if(enc==NULL){
143
return;
144
}
145
146
// Remove encoder from list
147
prevEnc->Next=enc->Next;
148
free(enc);
149
}
150
// [EOF]
Ich könnte mir vorstellen, dass man bessere Programmlaufzeiten erreicht,
wenn man auf die wiringPi Bibliothek verzichtet. Alternativ habe ich von
der pigpio Bibliothek gelesen, welche wohl etwas schneller sein soll.
Hier werden aber auch lediglich ca. 8000 Interrupts/s als machbar
angegeben. Wenn ich richtig gerechnet habe, wären es in meinem Fall
40.000 Interrupts/sekunde...
Was würdet ihr empfehlen? Meine Gedanken sind:
- pigpio Bibliothek testen
- Encoder mit einem Arduino separat auslesen
- einen IC verwenden, welcher den Encoder auswertet (habe damit noch
keine Erfahrung, bin aber mehrmals drüber gestolpert beim recherchieren)
Mein Wunsch wäre dabei natürlich beim Raspberry Pi bleiben zu können.
Dieser liest aktuell bereits zwei weitere Sensoren via SPI Bus aus
(deswegen auch meine Befürchtung, dass der Encoder zusätzlich zuviel
Last sein könnte).
Viele Grüße,
Niko
> Wenn ich richtig gerechnet habe, wären es in meinem Fall> 40.000 Interrupts/sekunde...
Du brauchst mehr wie 4x40000 Timerinterrupts pro Sekunde. Und die
zuverlaessig. Viel Glueck. :-)
> - einen IC verwenden, welcher den Encoder auswertet (habe damit noch> keine Erfahrung, bin aber mehrmals drüber gestolpert beim recherchieren)
Das waere eine Moeglichkeit. Eine andere waere es einen Microcontroller
zu verwenden der bereits die passende Hardware integriert hat. Oder sich
ein kleines CPLD zu programmieren.
> Mein Wunsch wäre dabei natürlich beim Raspberry Pi bleiben zu können.
Fuer hardwarenahe und vollem timingkritische Sachen ist das Dingen eher
ungeeignet.
Olaf
Olaf schrieb:>> Wenn ich richtig gerechnet habe, wären es in meinem Fall>> 40.000 Interrupts/sekunde...>> Du brauchst mehr wie 4x40000 Timerinterrupts pro Sekunde. Und die> zuverlaessig. Viel Glueck. :-)
Ack
Niko U. schrieb:> Kann der raspberry pi mit einer solchen Auflösung umgehen?
Warum nimmst du nicht einen Arduino mit ARM Controller. Der kann das mit
seinem Timer/Counter per Hardware erledigen.
Ich würde dir ebenfalls zu einem CPLD raten.
Decodierung (Richtung / Counts) im CPLD in einen 16-bit breiten Counter.
Dann reicht es dir diesen Counter (z.B. per SPI) im Extremfall nur 1x
pro Sekunde auszulesen, und trotzdem verpasst du keinen einzigen Count
oder Überlauf.
Niko U. schrieb:> Das Ziel ist, dass ich durch den Encoder die aktuelle Position erfahre> (bei senkrechter Bewegung). Der Encoder wird mit einer maximalen> Geschwindigkeit von 10 m/s verfahren, das ergibt:
Servus,
ein µC ist für Echtzeit besser geeignet. Als Beispiel, wie auch schon
öffters genannt: stm32f103c8 mini board. Kostet lächerliche 2€. Plus
vielleicht noch ein ST Link V2 Clone. Dort hast du 4 Timer, sodass du 4
Encoder anschließen kannst. Für Arduino Sekte gibt es das: mini maple
clone.
Stelle dir vor die Beere hängt für 0,5 s irgendwo fest, dann bist du
schon 5m weiter. Vergiss das ganz schnell mal.
Nehme die Beere für Lan-Übertragung, Bildschirmausgabe, was weiß ich
noch aber für eine schnelle Regelung sollte es schon ein µC sein.
Ein kleines Problem ist der 16 bit Timer. Aber mit ein paar Zeilen Code
kann man alles locker zurecht biegen. Oder man nimmt einen Controller
mit 32bit Timer.
Ich bin mit den stm32f103c8 sehr zufrieden. Damit konnte ich bisjetzt
alles ohne irgendwelche Auslastung regeln.
mfg
@ aSma>>
Irgendwie läuft Dein Vorschlag auf einen "Eigenbau" des vorher
vorgeschlagenen LFLS7166-S hinaus.
Stimmt, das Teil kostet ganz schön ziemlich und die Beschaffung wird
wohl nicht ganz ohne sein. Aber nachdem Du Deinen Liebling aufgebaut,
angepasst und programmiert hast, wirst Du es wohl bereuen diesen
Vorschlag gemacht zu haben, weil Joe F's Lösung bereits läuft.
Sollte es aber um das Basteln um des Bastelns willen gehen, könnte ich
mich mit deinem Ansatz anfreunden.
Als reinen Quadraturdekoder würde aber auch ein 08/15 µP reichen.
Vorausgesetzt, er hat sonst nichts zu tun.
@ Sebastian S. (amateur)
Lasse dir erstmal die Zahlen durchgehen:
> Der Encoder wird mit einer maximalen> Geschwindigkeit von 10 m/s verfahren ...
Wenn du immer noch der Meinung bist, dass es mit der Beere geht, dann
viel Spaß. Vorher musst du den Linux Kernel raushauen und selber was
zusammen programmieren. Oder man müsste sich reinlesen und einen
Echtzeitkernen erstellen. Vielleicht geht es dann bei langsamer
Geschwindigkeit.
Auch als Beispiel eingeführt ist Linux CNC mit der Beere. Läuft auch
perfekt allerdings mit einen Pic µC, der die Echtzeit Ausgabe übernimmt.
> Stimmt, das Teil kostet ganz schön ziemlich und die Beschaffung wird> wohl nicht ganz ohne sein. Aber nachdem Du Deinen Liebling aufgebaut,> angepasst und programmiert hast, wirst Du es wohl bereuen diesen> Vorschlag gemacht zu haben, weil Joe F's Lösung bereits läuft.
Er kann sich das schon kaufen. Wird aber merken, dass es nicht so laufen
wird wie gewünscht, wegen der Latenzzeit.
> Als reinen Quadraturdekoder würde aber auch ein 08/15 µP reichen.> Vorausgesetzt, er hat sonst nichts zu tun.
Wozu diesen Stress? Ich würde auf einen µC mit Encoder Interface setzen.
Darauf soll die Regelung laufen + Bus-Kommunikation mit der Beere. Dann
braucht man sich nicht die Beine zu brechen bei einer Multiplikation.
mfg
Das mit dem 08/15 µP war wörtlich gemeint.
Ein ATTiny mit 20MHz hat, so nichts anderes zu tun ist, 20000000/40000 =
500 Taktzyklen pro Dings. Das reich lange, um einen Zähler zu
aktualisieren.
Ein paar Abfragen, wie's denn steht, sollten wohl auch noch zu
beantworten sein.
Auch eine Abfrage, ob eine vorher angegebene Position (Zählerstand)
erreicht ist, bzw. das setzen eines Pins, sollten problemlos machbar
sein.
Würde mich nicht wundern, wenn in solchen Chips nicht auch was Ähnliches
ist, nur mit anderem Etikett.
Sebastian S. schrieb:> Würde mich nicht wundern, wenn in solchen Chips nicht auch was Ähnliches> ist, nur mit anderem Etikett.
Eher ein CPLD oder FPGA, das ist besser geeignet, man braucht ja nur
einen 32bit-Zähler, und in Hardware kann der dann auch einige MHz
zählen. Gute Werkzeugmaschinen mit 1 µ Auflösung und 10 m/s brauchen das
leicht.
Georg
wow... danke für das viele Feedback :) Damit hätte ich jetzt nicht
gerechnet :)
Also vlt. etwas zum Hintergrund, warum ich den raspi nutze und nicht
einen reinen uc:
Ich werte Beschleunigungsdaten in Matlab aus, der Encoder soll dabei als
Positionsreferenz dienen. Da es für den Raspberry Pi offizielle
Unterstützung seitens Matlab/Simulink gibt, ist die Wahl hierauf
gefallen :) Zusätzlich nutze ich als Schnittstelle zum Pi einen Wifi USB
Stick, was sich hier sehr einfach umsetzen ließ.
Die Auswertung der Beschleunigungssensoren läuft soweit (2 Stück, via
SPI angebunden). Das ganze lässt sich dann in Simulink auswerten.
Mit den 10 m/s war ich wohl etwas übereifrig. Ich denke mal das wäre
beim Verfahren per Hand auch schwer umzusetzen. Als Referenz sind wohl
eher 1 m/s angedacht.
An ein Arduino Board habe ich auch schon gedacht, jedoch müsste ich dann
die Anbindung an den vorhandenen Raspberry Pi umsetzen, da dieser ja mit
Matlab /Simulink kommuniziert. Ich habe diesbezüglich aber auch schon
Beispiele gesehen, die dass per SPI Bus lösen (und den nutze ich ja
sowieso schon für die Beschleunigungssensoren). Wäre erstmal ein Ansatz
:)
Von CPLDs habe ich noch nichts gehört :) Auf den ersten Blick hört sich
das definitiv nach einer Lösung an, ich würde aber aus Zeitgründen
lieber auf eine fertige Lösung zurückgreifen. Die Einarbeitung in diese
Thematik würde mich jetzt zuviel Zeit kosten. Aber danke für den Tipp,
merke ich mir mal für zukünftige Projekte :)
Auf Linux kann ich leider auch nicht verzichten, da dann die Einbindung
in Matlab/Simulink nicht mehr funktionieren würde. Im Endeffekt wandelt
Simulink das erzeugte Modell auch nur in C Code um, ich habe aber keinen
Überblick, was bei der erstmaligen Einbindung des Raspberry Pis (bei der
auch zeitgleich das Raspbian Image auf die SD Karte geschrieben wird) an
Parametern auf dem Pi gesetzt wird.
Die fertigen ICs von USdigital habe ich auch schon entdeckt. Kennt
jemand alternativen zu diesen, die man auch bei conrad o.ä. beziehen
kann? Ich habe bei USdigital mal eine Anfrage gestellt, wie lange die
Lieferung bei denen dauern würde (normalerweise dauert so etwas ja gerne
mal einen Monat, dann brauche ich den IC auch nicht mehr :P).
Hab jetzt noch den LS7366R gefunden. Sehe jetzt auf die Schnelle nur das
Eval Board mit dem LS7366R drauf, aber wäre ja auch ne Möglichkeit :)
@aSma
Du schlägst uC mit Encoder interface vor, schwebt dir da spontan etwas
im Kopf rum? Das würde ja in die gleiche Richtung wie mit dem arduino
board laufen (nur wäre mir jetzt neu, dass arduino boards ein encoder
interface haben).
VG
Niko
Servus,
> Du schlägst uC mit Encoder interface vor, schwebt dir da spontan etwas> im Kopf rum? Das würde ja in die gleiche Richtung wie mit dem arduino> board laufen (nur wäre mir jetzt neu, dass arduino boards ein encoder> interface haben).
Ich schrieb dazu schon was:
aSma>> schrieb:> Autor: aSma>> (Gast)> Datum: 21.05.2016 23:34
Stm32f103c8 mini board oder mini maple clone. Ich arbeite nicht mit
arduino IDE, deshalb muss du dich selber schlau lesen. Zudem könnte man
einen ST Link V2 Clone kaufen. Aber Arduino programmiert glaube ich über
FTDI Chip...
Das Problem bei einen "Echtzeitkernel" ist die Latenzzeit. Bei 1m/s
Verfahrgeschwindigkeit, so würde ich eine Abtastzeit von 1ms anstreben.
Jetzt müsste man sich schlau lesen wie groß die Latenzen beim
"Echtzeitkernel" liegen.
Du hast momentan ein normales Betriebssystem drauf, welches
Ereignisgesteuert ist. Die Latenzen kann man nicht voraussagen.
Angenommen während eines Versuches macht jemand den Browser auf oder
eine email kommt an: Absturtz.
Versuchen mal Klug. Es gibt mehrere Wege nach Rom.
PS: suche auch nach "Quadrature Decoder chip 32 bit". Manchnal will man
nur schnell an Ziel kommen.
Warum das nicht funktioniert liegt einfach daran das es keine Interrupts
im Userspace gibt.
Die WiringPi Lib macht vermutlich nichts anderes als den GPIO beim
Treiber zu registrieren. So lange kein Interrupt auftritt wird der
Thread schlafen gelegt.
Beim Auftreten des Ereignisses weckt ein Kernelthread den Userthread auf
und kopiert die Daten in den Userspace.
So ganz direkt läuft das nicht ab. Erst prüft der Treiber ob die ISR auf
ihn war dann beendet er die ISR und ruft den SoftIRQ auf. Diese Routine
wird je nach Priorität ausgeführt wenn dort eine Funktion registriert
ist. Man kann aber dafür sorge das diese gleich nach dem ISR
abgearbeitet wird. Das sorgt für zusätzliche Latenz. Jedenfalls irrend
eine Funktion weckt den Userthread auf.
Das ganze funktioniert auch deswegen schlecht weil jedes mal der Thread
schlafen und aufgeweckt werden muss und bevor der schläft neue Daten da
sind. Die dann verloren sind, außerdem werden durch deinen ISR alle
anderen gesperrt.
Das ganze ist schon möglich aber mit einen Kernel Treiber und ich glaube
da fehlt dir etwas das Verständnis was im Kernel so alles abläuft ;)
Außerdem wird dein Code im Userspace so oft aufgerufen das er durch den
schedule keine zeit erhält alle Ticks zu lesen.
Du merkst das funktioniert so nicht, da muss externe Hardware ran.
Hallo,
du solltest auch deine Encode Funktion schneller machen, denke ich.
Wie das geht, zeigt Peter D. hier
Beitrag "Drehgeber auslesen"https://www.mikrocontroller.net/articles/Drehgeber
und 40.000 / Sekunde
Da hat der µC für einen Impuls 25µs Zeit.
Ein einfacher Atmel der sonst nichts weiter macht als das und das
Ergebnis ausgibt schafft das. Ohne Interrupt, reines Polling. Mit 16MHz
dauert 1 Takt 62,5ns.
Niko U. schrieb:> Das würde ja in die gleiche Richtung wie mit dem arduino> board laufen (nur wäre mir jetzt neu, dass arduino boards ein encoder> interface haben).
Dann hast du wieder was dazu gelernt. ;-)
Wolfgang schrieb:> Warum nimmst du nicht einen Arduino mit ARM Controller.
Eben z.Bsp einen sam3x (Arduino DUE) der hat einen Quadrature Decoder
mit drauf und kann sogar Hardwareseitig den Speed berechnen.
http://www.atmel.com/images/atmel-11057-32-bit-cortex-m3-microcontroller-sam3x-sam3a_datasheet.pdf
Die Frage ist aber wie oft er den Wert braucht. Denn sonst muss er
weitere Funktionen auslagern. Z.Bsp Interrupt bei bestimmter Position
etc.
Anbindung könnte recht einfach über USB Seriell erledigt werden. Es
kommt darauf an was man mit dem Wert machen will.
Zaehler schrieb:> Chip für das Zählen kaufen und per spi anbinden:>> iC Haus iC-MD>> https://www.ichaus.de/product/iC-MD> Veit Devil:> Da hat der µC für einen Impuls 25µs Zeit.> Ein einfacher Atmel der sonst nichts weiter macht als das und das> Ergebnis ausgibt schafft das. Ohne Interrupt, reines Polling. Mit 16MHz> dauert 1 Takt 62,5ns.
Ich halte die Tiny-Lösung für sehr nützlich.
SPI dürfte für den Tiny,während er nichts anderes tut als den Impuls
auszuwerten,dann auch kein Problem.
Nach Wahl mit Indeximpuls.
Nach Wahl mit Interruptpin für die SPI-Abfrage oder Dauerfeuer als Paket
mit ChipSelect.
Der Tiny macht das sicherlich auch noch mit 4 Encodern Problemlos falls
nötig.
Nimm für sowas immer einen eigenen Microcontroller. Die haben sowas in
Hardware und kein Overhead durch ein Betriebssystem.
Bei einer Lösung habe ich auch einfach einen Arduino über USB an den
Raspi gehängt. Das funktioniert wunderbar. Da reicht sogar eine
Stromversorgung.
Ich habe jetzt nicht geprüft, ob deine 40000 Pulse richtig sind. Aber
40000 Pulse/Sek ergibt alle 25us ein Puls. Die Latenzzeit des RPi ist
dafür zu langsam, deshalb verliert er Pulse. Selbst mit einem RPi3 und
dem Linux-Realtimepatch wirst du das auf die Art nicht schaffen.
Hier sind Messungen mit einem RPi zu
sehen:https://emlid.com/raspberry-pi-real-time-kernel/
Mit dem RPi3 wird es etwas besser sein aber wohl nicht ausreichen.
Wie oben schon erwähnt, mit Kernel-Mode-Treiber konnte es gehen.
Ansonsten einen kleinen AVR, wie vorgeschlagen.
Das trifft aber nur zu wenn der Code im Userspace läuft. Da wird nichts
anderes gemacht als die Abarbeitung in einen festgelegten Zeit zu
garantieren.
Im Kernel selber werden Zeiten erstaunlich gut eingehalten. Wenn dies
nicht so wäre würden Probleme mit Hardware unausweichlich.
Um die Aufgabe zu lösen muss der Zeitkritische Teil im Kernel ablaufen.
Wenn man sich auskennt ist die Aufgabe schon lösbar.
So ich habe etwas Zeit aufgebracht die Möglichkeiten des Kernel etwas
auszuprobieren.
Hierzu habe ich ein Kernelmodul gebaut das den GPIO toggelt. Von außen
lassen sich diverse Zeiten einstellen.
Mit den Timer Funktionen des Kernels respektive Timerliste lassen sich
nur Zeiten bis 10ms realisieren. Die kleinst mögliche Zeit sind diese
10ms das hängt mit dem Interrupt des Kernels zusammen. Die Liste wird
wenn erforderlich alle 10ms abgearbeitet.
Mit den hrtimern geht mehr. Hier wird die Funktion sofort ausgeführt.
Zeiten von 40µS sind machbar. Allerdings ist das System schon etwas
schwerfällig. Zeiten drunter führen dazu das es nicht mehr reicht den
hrtimer in die Zukunft zu stellen bevor dieser die Zeit zum auslösen
erreicht. Das führt dazu das die Funktion sofort ausgeführt wird. Der
Pin toggelt mit 500ns und das System ist kaum noch ansprechbar.
Also für das Problem ist es nicht ratsam das direkt im Kernel zu lösen.
10ms oder mehr sind überhaupt kein Problem mit dem hrtimer werden diese
extrem gut eingehalten.
Die mögliche Lösung wäre dies über DMA zu realisieren. Das geht aus dem
Userspace . http://abyz.co.uk/rpi/pigpio/download.html
"sampling and time-stamping of GPIO 0-31 between 100,000 and 1,000,000
times per second. "
Du sampelst den GPIO per DMA ein Beispiel mit einen Encoder gibt es dort
auch.
Du hast einen hrtimer mit weniger als 40us Interrupts ausführen lassen?
Super Idee um den RPi lahmzulegen ;-)
Das kann man nur mit GPIO IRQs lösen bei der hohen Auflösung. Also immer
wenn ein Flankenwechsel stattfindet, einen IRQ, der die Eingänge liest
und die Zähler entsprechend anpasst. Pollend im Timer-IRQ ist das wohl
kaum zu machen.
Hier hat das jemand mit IRQs gemacht.
https://sites.google.com/site/hamlinhomeprojects/projects/raspberry-pi-isr
Damit sollte könnte funktionieren.
Allerdings muss man dafür sorgen, das da nicht ein Kontakt auf
"Dauerprellen" steht, sonst steht der RPi auch.
Niko U. schrieb:> Von CPLDs habe ich noch nichts gehört :) Auf den ersten Blick hört sich> das definitiv nach einer Lösung an, ich würde aber aus Zeitgründen> lieber auf eine fertige Lösung zurückgreifen.
Nur keine Scheu. Auch CPLDs sind kein Hexenwerk, insbesondere bei solch
kleinen Aufgaben nicht.
Wenn Du einigermaßen fitt bist, hast Du an einem Wochenende die
Toolchain installiert und bist soweit eine LED blinken zu lassen. Dann
den Decoder und ein (z.B.) SPI Interface zu implementieren dauert
vielleicht 4 weitere Tage (mit dem nötigsten VHDL lernen).
Und danach hast Du die Technologie mal benutzt und keine Angst mehr
davor. Es lohnt sich, echt!
Hey,
danke nochmal für euer überragendes Feedback :) Das ist ja echt
unglaublich :D
Also, da es schnell gehen soll (die Zeit für meine Masterarbeit ist
leider begrenzt...), habe ich mich jetzt für den LS7366R entschieden.
Der ist auch in Deutschland erhältlich:
http://www.macnica.eu/de/lsi/csi
(ob man da als Privatkunde bestellen kann, ist die andere Frage).
Die schnellere Variante:
http://www.mouser.de/ProductDetail/MikroElektronika/MIKROE-1917/?qs=%2fha2pyFadujB117G9yeeSZHQKrX2qpppY2A13zdz4KA%3d
Dann sitzt das ganze Zwar auf einer überdimensionierten Platine, aber
für den Testaufbau wirds erstmal reichen :)
In dem Sinne,
ein angenehmes Wochenende :)
@Marco H. (damarco)
>Das geht auch einfacher>http://de.farnell.com/xmos/xk-stk-a8dev/dev-board-...
Welche Drogen nimmst du? Das Board vom OP schließt man an SPI an, Daten
gemäß Datenblatt auslesen, fertig. Den Controller muss man noch
programmieren, dazu muss man sich einarbeiten, das dauert hne spezielle
Vorkenntnisse locker 1-4 Wochen!
Leute gibt's . . .
Viel billiger wenn man das externe Board was man bauen muss noch
berücksichtigt.
Für 14€ ist das unschlagbar. Denn mit dem Xmos lässt sich viel mehr
anstellen. Man könnte auch einen Ethernet Slice drauf stecken und die
Werte sogar mit PTP versenden. Mit dem RPI undenkbar. Auch die
Auswertung und Steuerung könnte man in dem Xmos quasi in Echtzeit
realisieren.
Per SPI und optionalen Kernel Modul lassen sich die Dinge die man in RPI
braucht übertragen.
Denn der Hintergedanke ist das man ja die Werte z.Bsp zum Regeln relativ
schnell und mit kalkulierbarer Latenz benötigt. Vorgänge in dem Xmos
sind Zeitlich Planbar. Ähnlich wie bei einen FPGA.
Zumal ist die Technologie recht interessant ;) Außerdem in C
Programmierbar.
Kurzes feedback:
Die von mir gewählte Variante läuft einwandfrei :) Hat mich einen Tag
arbeit gekostet und läuft wie gewünscht :D
danke nochmal an alle für euer Feedback :)
VG