Hallo Leute,
ich bin am verzeweifeln. Ich schaffe es einfach nicht vernünftig einen Drehimpulsgeber auszuwerten. Ich habe mir dafür jetzt einen extra guten (und teuren) Geber mit optischer Auswertung gekauft, um das Problem mit dem Prellen einigermassen in den Griff zu bekommen. Der Geber hat 32 Rastungen pro Umdrehung und ich würde gerne einen Impuls pro Rastung nach links oder rechts erhalten.
Ich habe dafür sogar extra einen Atmel Tiny 2313 verbaut, der nichts anderes zu tun hat wie den Encoder auszuwerten. Leider springt der Wert trotzdem oft in die falsche Richtung, wenn ich drehe. Egal bei welcher Geschwindigkeit.
Hier mal mein Code bis jetzt:
Code:
#define AVRGCC
#include <avr/io.h>
#include <compiler.h>
/**
PD2 Spur A
PD3 Spur B
PB0 links
PB1 rechts
1 2 3 4
A 0 1 1 0
B 0 0 1 1
**/
#define Links1 PORTB = (PORTB | (1<<PB0))
#define Links0 PORTB = ~(~PORTB | (1<<PB0))
#define Rechts1 PORTB = (PORTB | (1<<PB1))
#define Rechts0 PORTB = ~(~PORTB | (1<<PB1))
#define SpurA ((PIND & 0b00000100) == 0)
#define SpurB ((PIND & 0b00001000) == 0)
bool lastDir = TRUE;
U8 read (void)
{
if (SpurA)
{
if (SpurB)
return (3);
else
return (2);
}
else
{
if (SpurB)
return (4);
else
return (1);
}
}
void links (void)
{
U8 i1;
Links0;
for (i1 = 0; i1 < 0xFF; i1++)
asm volatile ("NOP");
Links1;
lastDir = FALSE;
}
void rechts(void)
{
U8 i1;
Rechts0;
for (i1 = 0; i1 < 0xFF; i1++)
asm volatile ("NOP");
Rechts1;
lastDir = TRUE;
}
int main (void)
{
U8 AlterStatus;
U8 NeuerStatus;
U8 i1;
DDRB = 0b00000011;
PORTB = 0b00000011;
DDRD = 0b00000000;
PORTD = 0b00001100;
for (i1 = 0; i1 < 0xFF; i1++)
asm volatile ("NOP");
AlterStatus = read ();
while (1)
{
NeuerStatus = read ();
if (AlterStatus != NeuerStatus)
{
switch (AlterStatus)
{
case 1: { switch (NeuerStatus)
{
case 2: { rechts (); break; }
case 3: { if (lastDir)
rechts ();
else
links ();
break;
}
case 4: { links (); break; }
}
break;
}
case 2: { switch (NeuerStatus)
{
case 1: { links (); break; }
case 3: { rechts (); break; }
case 4: { if (lastDir)
rechts ();
else
links ();
break;
}
}
break;
}
case 3: { switch (NeuerStatus)
{
case 1: { if (lastDir)
rechts ();
else
links ();
break;
}
case 2: { links (); break; }
case 4: { rechts (); break; }
}
break;
}
case 4: { switch (NeuerStatus)
{
case 1: { rechts (); break; }
case 2: { if (lastDir)
rechts ();
else
links ();
break;
}
case 3: { links (); break; }
}
break;
}
}
AlterStatus = NeuerStatus;
}
}
return (0);
}
Wer kann mir sagen wo es hängt, oder einen Code schicken, der auch funktioniert. Der Tiny arbeitet mit dne Werkseinstellungen der Fuses und ohne Quarz mit der internen Takterzeugung..
Viele Grüße
Andreas
Lesezeichen