PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Drehencoder auswerten



MartinFunk
10.05.2007, 11:55
Hi,
ich habe hier einen drehencoder den ich mit einem mega16 auswerte, Ausgang A ist an INT1 und Ausgang B an PIND.4 wen ich ihn mit diesem code auswerte funktioniert das ganze nur wen ich schnell am encoder drehe. Bei langsamem drehen egal in welche richtung geht der wert immer in den minus bereich.

Hier mein code:

ISR(INT1_vect)
{
char cSREG;
cSREG = SREG; // Statusregister puffern in Variable cSREG //
if bit_is_clear(PIND,PIND3) //falling edge!
{
if bit_is_clear(PIND,4) //linksrum
{
enc--;
}
else
{
enc++;
}
}
else //rising edge
{
if bit_is_clear(PINC,4) //rechtsrum
{
enc++;
}
else
{
enc--;
}
}

SREG = cSREG; // Statusregister aus Variable cSREG retten //
}

Der interrupt ist auf steigende und fallende flanken eingestellt.


GICR |= (1<<INT1);
MCUCR |= (1<<ISC10);


Danke schonmal im vorraus.

MfG Martin

BlinkyBill
10.05.2007, 12:03
else //rising edge
{
if bit_is_clear(PINC,4) //rechtsrum

Warum denn PINC ?

sorry, bin mit dem compiler nicht vertraut, aber ich nehme an, dass der Buchstaben den Port bezeichnet ?


gruss

MartinFunk
10.05.2007, 12:10
upps da ist wohl ein fehler bei copieren pasiert es muss heisen PIND.

Funktioniert trotzdem nicht!

Ja, der buchstabe bezeichnet den port.

Hat noch jemand ne idee?

MfG Martin

BlinkyBill
10.05.2007, 12:12
und oben ?

bit_is_clear(PIND,PIND3)

muss dass dann nicht heissen

bit_is_clear(PIND,3) ?

Kannst du den Interrupt auch on change machen, oder nur auf steigende oder fallende flanke ?

Da reichts nämlich dann, die Zustände zu vergleichen.

Beide Pins gleich: Rechtsrum, else Linksrum... Oder andersrum, je nachdem, wie dus angeschlossen hast.

MartinFunk
10.05.2007, 12:16
das ist egal PIND3 ist als 3 definiert macht keinen unterschied was man da schreibt.

MartinFunk
10.05.2007, 17:11
kann mit keiner helfen?

BlinkyBill
11.05.2007, 07:07
hast du das was ich noch geschrieben habe mal Probiert ? Also einfach nur vergleichen ?

BlinkyBill
11.05.2007, 07:08
hast du das was ich noch geschrieben habe mal Probiert ? Also einfach nur vergleichen ?

So ungetestet auf den ersten Blick sollte dein Programm das schon richtig auswerten... vor allem wenns geschwindigkeitsabhängig ist. Stimmt das Signal des Encoders, oder ist vielleicht eine Lichtschranke verschoben (weiss ja nicht, was für einen du hast)

robo junior
11.05.2007, 07:47
Hallo

ich hab mir jetzt das Datenblatt vom Mega16 nicht angeschaut, aber ich nehme mal an Int0 ist PD3?
Dann zuerst mal was soll dieser Teil:


char cSREG;
cSREG = SREG; // Statusregister puffern in Variable cSREG //

SREG = cSREG; // Statusregister aus Variable cSREG retten //


du änderst das Statusregister doch gar nicht? warum also diese Zwischenspeicherung. Außerdem kann (normalerweise?) eine ISR doch eh nicht von einem anderen Interrupt unterbrochen werden (oder hab ich da was falsch verstanden?).

Dann zu deinem eigentlichen Problem. Du benutzt ja eine Variable, die du hoch bzw. runter zählst.
Ich würde es so machen (bzw. habe es so gemacht). Eine Variable, die die Impulse zählt und eine zweite, die die Richtung dazu angibt. (ich habe das ganze für eine Motorenregelung benutzt, wobei der Regler mit 100Hz aufgerufen wurde, sodass die kleine Ungenauigkeit (wenn der Motor von einer Laufrichtung zur nächsten Wechselt) nicht so schlimm ist).

Machs doch einfach so: Setzt den Interrupt Port auf steigene Flanke. Dann zählst du bei jedem Interrupt die Zählvariable hoch und überprüfst ob der zweite Port high oder low ist. Jenachdem setzt du dann deine Richtungsvariable auf 1 oder 0 (oder wie auch immer). Alternativ um die Genauigkeit zu steigern (von der Impulsanzahl) kannst du natürlich auch den Interrupt bei steigender und fallender Flanke auslösen, beide Impulse zählen. (du könntest sogar noch den 2. Port als Interruptport nehmen und von diesem auch noch die Impulse zählen. dadurch hast du dann insgesamt viermal so viele Impulse pro Motordrehung.)

MartinFunk
12.05.2007, 10:03
Hi,
es funtioniert jetzt, hab den interrupt auf steigende flanke gesetzt und ein kleines delay eingefügt.

BlinkyBill
14.05.2007, 06:45
also hatte es wohl doch was damit zu tun, dass die Signale icht ganz passen?
Hast du ein oszi, mit dem du die Signale aufzeigen könntest ? Interessiert mich jetzt direkt auch ;)

gruß

MartinFunk
16.05.2007, 16:05
Hi,
sorry das ich erst so spät schreibe aber ich war in den letzten tagen auf abschlussfahrt.

Ich habe das signal schon mit einem oszi angekuckt hab aber keine auffälligkeiten feststellen können.

MfG Martin