Servus,
ich muss einen Quadratur-encoder mit 500 Strichen auslesen und an einer
ganz bestimmten Position welche per SPI oder UART übergeben werden soll
eine LED ein und aus schalten.
Dazu möchte ich einen ATmega88 @ 10MHz o.ä. verwenden.
Ich müsste jetzt abschätzen, bis zu welcher Drehzahl ich damit noch
sinnvoll arbeiten kann, also wie schnell der Encoder Drehen darf, ohne
dass Flanken verloren gehen. Was meint ihr? sind 1000rpm möglich?
Mein Tip: (Ich hab sehr wenig Erfahrung!)
500Stiche => 2000 Flanken pro Umdrehung
In C programmiert rate ich ins blaue, dass ca. 500 Takte nötig sind um
ggf. ein UART/SPI Byte zu verarbeiten, den Encoder zu lesen und in einem
Zähler zu speichern, einen Vergleich, ob ein bestimmter Zählerwert
erreicht ist, durchzuführen und ggf. die LED zu schalten.
damit ergeben sich bei 10MHz 20000 "Programmdurchläufe". Oder anders mit
maximal 20kHz Flankentakt des Encoders geht nix verloren...
=> 20kHz / 2000 flanken/Umdrehung * 60 s/min = 600 U/min < 1000 U/min =
Ziel nicht erreicht.
Was sagt/schätzt ihr?
vielen Dank
Der Encoder hat SPI?
Wenn ja:
Warum taktest du den Chip nicht einfach was höher? Dann geht zwar die
Übertragungsgeschwindigkeit nicht höher? (Wenn du schon am maximum
bist...) aber immerhin die Verarbeitungsgeschwindigkeit. Also -> mehr
Rpm
Helfen kann ich dir nicht, aber daran habe ich auch mal geknobelt.
Ich hatte einen Motor der anfährt, recht schnell drehen kann und dann
wieder langsamer wird und so langsam stoppt.
Man konnte sich auf einer Webseite eine Strichmusterscheibe auf eine
Folie ausdrucken, das waren drei Stichmuster übereinander die binär
codiert waren.
(muss man sich mehrfach und im Kreis aufgewickelt vorstellen)
1 1 1
1 1 0
1 0 1
1 0 0
0 1 1
0 1 0
0 0 1
0 0 0
Wenn man es grob brauchte hat man einfach nur den äußersten Kreis
ausgelesen, wenn der Motor langsamer wurde hat man auch die inneren
Streifen genutzt.
Das kommt jetzt auf deinen Anwendungsfall drauf an, bei uns war das eine
gute und günstige (Rechenzeit) Lösung.
Wenn du es immer genau wissen musst geht das so natürlich nicht.
Du kannst den ATmega88 doch locker mit 20MHz laufen lassen, sogar
schneller.
Mike J. schrieb:> (muss man sich mehrfach und im Kreis aufgewickelt vorstellen)> 1 1 1> 1 1 0> 1 0 1> 1 0 0> 0 1 1> 0 1 0> 0 0 1> 0 0 0
Oh, bloß nicht so, sondern Gray-Code verwenden! Sonst läuft die
Abtastung nicht zuverlässig.
Ansonsten: 20'000 rpm sind ca. 333 Umdrehungen pro Sekunde. Sind bei 500
Strichen je Umdrehung 166'666 Striche pro Sekunde. Das lässt sich
problemlos mit einem ATtiny13A für 60 Cent auslesen. Man sollte das aber
besser nicht per Interrupt-Routine machen, sondern aktiv pollen, sonst
geht zu viel Rechenpower für die Verwaltung verloren.
P.S.: Ändere doch mal den Thread-Titel, damit man weiß, um was es
geht...
@ Nachtschicht:
Das wären alle 6us ein neuer Wert.
Was mich nur irritiert ist die Angabe, dass er das per SPI auslesen
will.
Wenn es ein Absolutwertgeber ist, dann müsste er alle 6us per SPI einen
neuen Absolutwert auslesen.
Ich weiss nicht, wie schnell das SPI vom ATmega rennt, aber bei 4 MBit/s
wären das 250ns/Bit und 2us/Byte zzgl. Rechenzeit. Und der absolute
Positionswert ist sicher größer als nur ein Byte. Könnte dann also
durchaus sehr knapp werden.
im text steht doch dass nur der Triggerwert für die led ber SPI
übertragen wird.
wennd er motor nur in eine richtung dreht, dann kannst du die compare
einheit nutzen, dann musst du nur einmal das register setzen und dann
warten bis der interrupt kommt.
Du brauchst mindestens 33 kHz Abtastrate für das Quadratur-Signal. Per
Timer-Interrupt z.B. mit 50 kHz oder höher abtasten. 50 Zyklen für den
Interrupt der State-Machine die den Encoder auswertet sollten reichen.
Das ergibt 2,5 Millionen Taktzyklen pro Sekunde. Also erst 25% von den
10 MHz verbraucht.
Selbst bei 75 kHz Abtastrate und 75 Zyklen für den Interrupt sind erst
56% vom 10-MHz-Takt verbraucht.
Also, im Prinzip kein Problem.
Es gibt allerdings ein anderes Problemfeld: Jitter. Wenn Jitter kritisch
ist, braucht es entweder mehr Hirnschmalz oder eben eine kleine externe
Hardware.
Ich hab mich wohl nicht so ausgedrückt wie ich wollte:
Der Encoder ist ein normaler Quadratur-Encoder mit den Signalen A, B und
Z, wobei A und B Rechtecksignale mit 90° elektrischem Phasenversatz
ausgeben und Z eben das Index-Signal um Absolutpositionen bestimmen zu
können.
Dieser Encoder sitzt an einer Welle, die mit bis zu 1000rpm drehen
können soll und im gesamten Drehzahlbereich (0-1000rpm) eine LED auf
maximale Genauigkeit schalten können soll.
Maximale Genauigkeit heißt bei diesem Encoder mit 500 Strichen, dass auf
1/2000 Umdrehung genau geschaltet werden soll.
@Profi:
50 Zyklen schätze ich für äußerst sportlich ein. Ich meine mich zu
erinnern, dass es irgendwo mal einen Thread gab indem ein
Timer-Interrupt möglichst schnell ausgeführt werden sollte. In dem
Interrupt sollte nur ein 16bit Integer inkrementiert werden und der
gesamte Interrupt war kaum unter 64 Zyklen zu bringen... Ich kann falsch
liegen aber sind 50 Zyklen wirklich realistisch?
> In C programmiert rate ich ins blaue, dass ca. 500 Takte nötig sind um> ggf. ein UART/SPI Byte zu verarbeiten, den Encoder zu lesen und in einem> Zähler zu speichern, einen Vergleich, ob ein bestimmter Zählerwert> erreicht ist, durchzuführen und ggf. die LED zu schalten.
while(1)
{
if(UCSRA.RXC) schaltposition=UDR;
new_quadrature_value=quadrature_input; // z.B. PINB
position+=table[last_quadrature_value][new_quadrature_value];
led=position>schaltposition;
last_quadrature_value=new_quadrature_value;
}
sind in Assembler gerade mal 16 Befehle, ein 10MHz ATmega
schafft also über 100000 Umdrehungen pro Sekunde, oder
über 6 Mio Umdrehungen pro Minute damit zu erkennen,
selbst wenn die Schaltposition durch mehrere Bytes definiert
wird.