PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ATMega32 mit mehreren Drehgebern



jcrypter
10.09.2010, 09:59
Guten Morgen liebes Forum,

ich beschäftige mich gerade damit wie man Drehgeber an dem Mega32 anschließt.
http://www.reichelt.de/?;ACTION=3;LA=444;GROUP=B29;GROUPID=3714;ARTICLE=7 3921;START=0;SORT=artnr;OFFSET=16;SID=29qRJmhawQAR 0AAD8QouY9aa90e7f1281e5c6eacbf53e7a2a9946

Ich habe ein Bespiel gefunden wie man einen Drehgeber anschließt und auswertet.
http://www.mschrod.de/Elektronik/AVR/Atmega%20Allgemein/drehgeber/Drehgeber.html

Wie verhält es sich nun aber wenn man mehrere Drehgeber auswerten will?
Konkret geht es darum zwei Motoren mit einem Controller zu steuern und die Drehgeber auszuwerten.

Das Beispiel arbeitet mit externen Interrups, allerdings hat der Mega32 keine vier Interrupt-Pins die ich für zwei Drehgeber bräuchte.

Wie kann man hierbei vorgehen?

Danke für eure Mühe und eure Ideen!
Crypi

oberallgeier
10.09.2010, 11:09
Hi,

... wie man Drehgeber an dem Mega32 ... allerdings hat der Mega32 keine vier Interrupt-Pins die ich für zwei Drehgeber bräuchte ...soweit ich die Materie (theoretisch) kenne, brauchst Du für einen Drehgeber im Prinzip nur einen Interrupt. Der "andere" Pin des Drehgebers kann für die Drehrichtungserkennung in der ISR des einen Interrupts ganz normal ausgewertet werden.

ABER Du könntest Dir natürlich auch einen ~644~ holen. Der ist pinkompatibel zum m32, hat deutlich mehr Speicher (Flash, SRAM und EEPROM), hat drei "reine" externe Interrupts und Du kannst fast alle Pinns als PCINTx definieren. Solche PCINTnx habe ich auch schon mit Erfolg verwendet (aber noch nie für Drehgeber und bisher nur an m168/m328).

[/size]mel-doc 8011M–AV R–08/09 auf Seite 67]... The External Interrupts are triggered by the INT2:0 pin or any of the PCINT31:0 pins ...Softwaremässig sind diese zusätzlichen Interrupts in zwei Gruppen an zwei verschiedene Interruptvektoren gebunden - muss man halt berücksichtigen.

jcrypter
10.09.2010, 11:35
Hi,

... wie man Drehgeber an dem Mega32 ... allerdings hat der Mega32 keine vier Interrupt-Pins die ich für zwei Drehgeber bräuchte ...soweit ich die Materie (theoretisch) kenne, brauchst Du für einen Drehgeber im Prinzip nur einen Interrupt. Der "andere" Pin des Drehgebers kann für die Drehrichtungserkennung in der ISR des einen Interrupts ganz normal ausgewertet werden.

Dass heißt, den zweiten Pin kann man an einen beliebigen Port hängen um die Drehrichtung auszuwerten?

Crypi

wkrug
10.09.2010, 11:52
Bei meiner letzten Drehgeber Routine hab ich den Drehgeber im Timer 0 Overflow Interrupt gemacht, der alle 2ms abgefragt wird.

Der letzte Zustand wird in einer Variable abgespeichert.
Nur wenn sich daran was geändert hat wird eine Auswerte Routine ausgeführt, die Abhängig vom Ursprungszustand eine weitere Variable hoch oder runter zählt. Es werden nur Ereignisse gezählt, die in den Grey Code passen.

Dadurch findet auch gleich eine Entprellung des Drehgebers statt.

Das Ganze liesse sich relativ einfach auf 2 oder noch mehr Drehgeber erweitern.

Die Drehgeberfrequenz darf dabei allerdings nicht zu hoch werden, sonst könnten Impulse "übersehen" werden.

Man könnte die Timerintervalle noch weiter verkürzen um das zu verhindern.

Bei mir wird der Drehimpulsgeber von Hand bedient, was ja nun auch nicht sehr schnell geht.

Den Codeschnipsel kannst Du gerne haben, der ist allerdings in "C".

oberallgeier
10.09.2010, 12:01
... den zweiten Pin ... an einen beliebigen Port hängen um die Drehrichtung auszuwerten ...
... soweit ich die Materie (theoretisch) kenne ....Wie geschrieben - soweit ich weiß . . . .

Aber Du drehst doch Deine Geber von Hand, da ist der vorletzte Satz von wkrug DIE Möglichkeit . . . .

jcrypter
10.09.2010, 12:47
Danke für eure Antworten!
Ich versuche das nochmal zusammen zufassen.
Ich schließe zwei Drehgeber an beliebige Pins des Controllers an.
Der Timer checkt jetzt nach einer vorgegebenen Zeit den Zustand der Pins.
Die Variablen werden hochgezählt.
Wie ändert sich denn der Zustand an den Pins?

Je mehr Impulse pro Umdrehung der Drehgeber sendet, desto größer wird auch die Wahrscheinlichkeit, dass einer übersehen wird, oder? Natürlich ist das auch abhängig von der Drehgeschwindigkeit.

Crypi

oberallgeier
10.09.2010, 13:09
... Je mehr Impulse ... desto ... übersehen ...In solchen Fällen rechne ich nach der Methode Milchmädchen. Bei Dir also: abschätzen, wie schnell Du drehst (z.B. in Upsec) - mal Impulse pro Umdrehung. Diese x Impulse pro Umdrehung mal genüsslich betrachten unter der Angabe, wieviel Megahertz Dein Controller macht. Vorteil beim Pollen im Timerinterrupt wäre ja, dass Du immer gleichzeitig beide Encoder auslesen könntest.

Dein ALPS STEC12E macht 24 I/Umd. Wenn ich mich bemühe, drehe ich einen dünnen Drehknopf höchstens 10 x pro Sekunde. Gäbe also bei zwei Encodern allenfalls 500 Hz. WENN ich einen Controller langsam laufen lasse, macht der 1 MHz. . . . . . . . Meine bevorzugten m168/m328 machen 20 MHz . . . . . . . Wenn die nix anders zu tun bekommen ausser Encoder auslesen, sind die total gelangweilt (aber Du willst ja sicher mit dem ausgelesenen Wert etwas machen).

jcrypter
10.09.2010, 13:18
Ok, danke für deine Analyse :)
Ich denke das trifft es so ganz gut.

Wie würde ich die Pins abfragen?
So wie man auch einen Taster abfragen würde?

Crypi

wkrug
10.09.2010, 13:25
Das Coding ist immer
00 - 10 - 11 - 01
ausgehend von einem Zustand kann als nächstes immer nur der Code rechts oder Links davon als nächstes kommen. Je nach dem ob man rechts oder links rum dreht.
Ich stell den Code, obwohl in C, trotzdem mal ein...
Im Prinzip dürfte es mit BASCOM ja genauso gehen.


// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{

// Rotary Encoder PD2 + PD3
uc_rot=(PIND&0b00001100);
if(uc_mode>100) //Hab das Modus abhängig gemacht
{
// Diese 4 Ursprungszustände sind möglich
if(uc_oldrot==0b00000000)
{
if(uc_rot==0b00001000){ui_sendbuffer[uc_position]-=2;}; //Die Variable wird runter gezählt
if(uc_rot==0b00000100){ui_sendbuffer[uc_position]+=2;}; //Die Variable wird hoch gezählt
}
if(uc_oldrot==0b00001000)
{
if(uc_rot==0b00001100){ui_sendbuffer[uc_position]-=2;};
if(uc_rot==0b00000000){ui_sendbuffer[uc_position]+=2;};
}
if(uc_oldrot==0b00001100)
{
if(uc_rot==0b00000100){ui_sendbuffer[uc_position]-=2;};
if(uc_rot==0b00001000){ui_sendbuffer[uc_position]+=2;};
}
if(uc_oldrot==0b00000100)
{
if(uc_rot==0b00000000){ui_sendbuffer[uc_position]-=2;};
if(uc_rot==0b00001100){ui_sendbuffer[uc_position]+=2;};
}
}
uc_oldrot=uc_rot; //Der aktuelle Zustand wird für den nächsten Durchlauf abgespeichert

}

jcrypter
10.09.2010, 13:35
Ok, danke!

Ihr habt mir sehr geholfen!
Dann werde ich mal daran gehen mir zwei Drehgeber zu bestellen.

viele Grüße,
Crypi

Razzorhead
10.09.2010, 14:53
Kurze zwischenfrage: wie benutzt man so einen drehgeber? Ich meine wie kriege ich die welle da dran, und ans rad? =o

LG raz

oberallgeier
10.09.2010, 15:09
... wie benutzt man so einen drehgeber ... wie kriege ich die welle da dran, und ans ...Gaaaaanz oben im Thread steht ein Link zu dem Drehgeber, den jcrypter verwenden möchte. Schau Dir den mal an (den Drehgeber, nicht den Link) und wenn dann noch Fragen offen sind . . . . . dann frag halt nochmal.

jcrypter
10.09.2010, 15:14
Ich werde ein Zahnrad an die Welle und eins an den Schaft des Drehgebers setzen. Über die Übersetzung kannst Du die Impulszahl pro Umdrehung der Welle noch erhöhen.

Crypi

wkrug
11.09.2010, 04:54
Für den Einsatz so eines Drehgebers an einem Antrieb würde ich aber eine Type ohne Rastung verwenden.
Guck mal bei Reichelt die Bestellnummer: ENC 62P22-N0S
Link: http://www.reichelt.de/?;ACTION=3;LA=444;GROUP=C23;GROUPID=3283;ARTICLE=6 7480;START=0;SORT=artnr;OFFSET=16;SID=31xMU@ZawQAR 8AADnbAMMb298688fb4c32d3a7750512d9e4cbb19

Das ist eine optische Type und hat somit auch wenig mechanischen Verschleiß. Das Teil ist allerdings auch relativ teuer ( ~10€ ) - Man müsste halt gucken, wo es so etwas günstiger gibt.

Noch was...
ALPS gibt für diesen Drehencoder 30000 Zyklen an.
Das bedeutet eine Lebenszeit von 30000 vollen Umdrehungen vor und zurück.

Grayhill gibt immerhin 2Millionen Zyklen an.