pic basic code:
Context Save
If PULS_A = 1 Then
If PULS_B = 1 Then
Dec TELLER
Else
Inc TELLER
EndIf
Toggle LED
EndIf
Je moet je wel realiseren dat dit niet nauwkeurig is.
Als de boel tot stilstand komt met A=1 en B=0. Dat zou kunnen want allevier de combinaties komen voor. Als ie nu een micrometer achteruit gaat zodat A weer nul wordt. Geen interrupt als je die op positive edge triggert, en als dat wel gebeurt dan zorgt de eerste if dat er niets gebeurt. Maar als ie nu weer een micrometer naar voren kruipt, dan is B nogsteeds nul en incrementeert de teller. Deze voor/achter, kan gebeuren omdat je encoder fysiek staat te trillen maar ook als de encoder precies op een randje staat en het elektrisch niveau precies rond het omslagpunt zit, dan kan je deze situatie krijgen.
Wat ik wel eens gedaan heb is dat ik een 16-entry array heb gemaakt en dan zet ik A en B in een twee-bit variabele en die vul ik aan met A en B uit de vorige interrupt. De array vertelt dan wat er moet gebeuren. op 0b0000 staat dan: oude waarde AB=00, nieuwe waarde AB=00 dan.... doe niets: er is niets veranderd. Als het goed is krijg je dan geen interrupt, zo is de helft van de entries in de tabel voor nop. op positie 1, 0b0001 staat dan als AB van 00 naar 01 gaat. Deze overgang zit in bovenstaande code als een decrement. -1 in de tabel (Daar zal wel geen interrupt gebeuren en er zal wel niet geteld worden: mijn code telt op alle flanken en zal 4x sneller tellen, dus met de 500 counts encoder tot 2000 tellen in 1 omwenteling). De volgende entry: 2 = 0b0010 is de enige waar bovenstaande code van lambiek een telactie deed. Dit is van 00 naar 10, dus A is hoog geworden, terwijl B laag bleef: increment: +1 in de tabel.
code:
interrupt pcint (void)
{
static unsigned char old;
unsigned char cur;
static const signed char table [16] = {
0, -1, 1, 0,
-1, 0, 0, 1,
... };
cur = (digitalRead (PIN_A) << 1) | digitalRead (PIN_B);
count += table[(old << 2) | cur];
old = cur;
}
}