Hallo,
wenn das pollen nicht zu langsam ist, kannste das gern einen "fremden" Praxistest unterziehen. Wäre mal interessant zu wissen.
Pins ins Zeile 144 ändern und losgehts 
/*
* https://forum.arduino.cc/index.php?topic=583310.0
*/
using Register = volatile byte *;
// UNO, Nano, Pro Mini usw.
#if defined(__AVR_ATmega328P__) | defined(__AVR_ATmega328__) | defined(__AVR_ATmega168P__) | defined(__AVR_ATmega168__)
constexpr byte pinMaske[] = {0b1, 0b10, 0b100, 0b1000, 0b10000, 0b100000, 0b1000000, 0b10000000, 0b1, 0b10, 0b100, 0b1000, 0b10000, 0b100000, 0b1, 0b10, 0b100, 0b1000, 0b10000, 0b100000,};
constexpr Register portList[] = {&PORTD, &PORTD, &PORTD, &PORTD, &PORTD, &PORTD, &PORTD, &PORTD, &PORTB, &PORTB, &PORTB, &PORTB, &PORTB, &PORTB, &PORTC, &PORTC, &PORTC, &PORTC, &PORTC, &PORTC,};
constexpr Register ddrList[] = {&DDRD, &DDRD, &DDRD, &DDRD, &DDRD, &DDRD, &DDRD, &DDRD, &DDRB, &DDRB, &DDRB, &DDRB, &DDRB, &DDRB, &DDRC, &DDRC, &DDRC, &DDRC, &DDRC, &DDRC,};
constexpr Register pinList[] = {&PIND, &PIND, &PIND, &PIND, &PIND, &PIND, &PIND, &PIND, &PINB, &PINB, &PINB, &PINB, &PINB, &PINB, &PINC, &PINC, &PINC, &PINC, &PINC, &PINC,};
// #endif
// Mega
#elif defined(__AVR_ATmega2560__) | defined(__AVR_ATmega1280__)
constexpr byte pinMaske[] = {0b1, 0b10, 0b10000, 0b100000, 0b100000, 0b1000, 0b1000, 0b10000, 0b100000, 0b1000000, 0b10000, 0b100000, 0b1000000, 0b10000000, 0b10, 0b1, 0b10, 0b1, 0b1000, 0b100, 0b10, 0b1, 0b1, 0b10, 0b100, 0b1000, 0b10000, 0b100000, 0b1000000, 0b10000000, 0b10000000, 0b1000000, 0b100000, 0b10000, 0b1000, 0b100, 0b10, 0b1, 0b10000000, 0b100, 0b10, 0b1, 0b10000000, 0b1000000, 0b100000, 0b10000, 0b1000, 0b100, 0b10, 0b1, 0b1000, 0b100, 0b10, 0b1, 0b1, 0b10, 0b100, 0b1000, 0b10000, 0b100000, 0b1000000, 0b10000000, 0b1, 0b10, 0b100, 0b1000, 0b10000, 0b100000, 0b1000000, 0b10000000,};
constexpr Register portList[] = {&PORTE, &PORTE, &PORTE, &PORTE, &PORTG, &PORTE, &PORTH, &PORTH, &PORTH, &PORTH, &PORTB, &PORTB, &PORTB, &PORTB, &PORTJ, &PORTJ, &PORTH, &PORTH, &PORTD, &PORTD, &PORTD, &PORTD, &PORTA, &PORTA, &PORTA, &PORTA, &PORTA, &PORTA, &PORTA, &PORTA, &PORTC, &PORTC, &PORTC, &PORTC, &PORTC, &PORTC, &PORTC, &PORTC, &PORTD, &PORTG, &PORTG, &PORTG, &PORTL, &PORTL, &PORTL, &PORTL, &PORTL, &PORTL, &PORTL, &PORTL, &PORTB, &PORTB, &PORTB, &PORTB, &PORTF, &PORTF, &PORTF, &PORTF, &PORTF, &PORTF, &PORTF, &PORTF, &PORTK, &PORTK, &PORTK, &PORTK, &PORTK, &PORTK, &PORTK, &PORTK,};
constexpr Register ddrList[] = {&DDRE, &DDRE, &DDRE, &DDRE, &DDRG, &DDRE, &DDRH, &DDRH, &DDRH, &DDRH, &DDRB, &DDRB, &DDRB, &DDRB, &DDRJ, &DDRJ, &DDRH, &DDRH, &DDRD, &DDRD, &DDRD, &DDRD, &DDRA, &DDRA, &DDRA, &DDRA, &DDRA, &DDRA, &DDRA, &DDRA, &DDRC, &DDRC, &DDRC, &DDRC, &DDRC, &DDRC, &DDRC, &DDRC, &DDRD, &DDRG, &DDRG, &DDRG, &DDRL, &DDRL, &DDRL, &DDRL, &DDRL, &DDRL, &DDRL, &DDRL, &DDRB, &DDRB, &DDRB, &DDRB, &DDRF, &DDRF, &DDRF, &DDRF, &DDRF, &DDRF, &DDRF, &DDRF, &DDRK, &DDRK, &DDRK, &DDRK, &DDRK, &DDRK, &DDRK, &DDRK,};
constexpr Register pinList[] = {&PINE, &PINE, &PINE, &PINE, &PING, &PINE, &PINH, &PINH, &PINH, &PINH, &PINB, &PINB, &PINB, &PINB, &PINJ, &PINJ, &PINH, &PINH, &PIND, &PIND, &PIND, &PIND, &PINA, &PINA, &PINA, &PINA, &PINA, &PINA, &PINA, &PINA, &PINC, &PINC, &PINC, &PINC, &PINC, &PINC, &PINC, &PINC, &PIND, &PING, &PING, &PING, &PINL, &PINL, &PINL, &PINL, &PINL, &PINL, &PINL, &PINL, &PINB, &PINB, &PINB, &PINB, &PINF, &PINF, &PINF, &PINF, &PINF, &PINF, &PINF, &PINF, &PINK, &PINK, &PINK, &PINK, &PINK, &PINK, &PINK, &PINK,};
// #endif
#else
#error "This AVR type is currently not yet supported."
#endif
constexpr Register getOutPort(const byte pin) {
return portList[pin];
};
constexpr Register getDdrPort(const byte pin) {
return ddrList[pin];
};
constexpr Register getInPort(const byte pin) {
return pinList[pin];
};
constexpr byte getMaske(const byte pin) {
return pinMaske[pin];
};
template <byte pin_a, byte pin_b, byte raster = 0, int _min = 0, int _max = 0>
class GrayEncoder // Klassenname "GrayEncoder"
{
protected: // private wird zu protected, nur intern zugängliche Elemente ...
int relMin;
int relMax;
byte shift; // Zählkorrektur wegen Steps pro Rastung
volatile long rel_counter; // relativer Zähler, veränderbar
volatile long abs_counter; // absoluter Zähler, nicht veränderbar
int direction; // Richtungsanzeige +1 / -1
int enc_delta;
int last;
byte phase_a; // erste Phase
byte phase_b; // zweite Phase
long abs_old;
int getPhases() {
int n = 0; // new
phase_a = bool(*getInPort(pin_a) & getMaske(pin_a));
phase_b = bool(*getInPort(pin_b) & getMaske(pin_b));
if ( phase_a ) n = 3;
if ( phase_b ) n ^= 1; // convert gray to binary
return n;
}
void update_RelativCounter () {
long new_abs = abs_counter >> shift; // halbiert, geviertelt oder ... Steps pro Rastung
if ( new_abs != abs_old) {
if (new_abs > abs_old) {
rel_counter++;
}
else {
rel_counter--;
}
abs_old = new_abs;
if (rel_counter < relMin) {
rel_counter = relMax;
}
else if (rel_counter > relMax) {
rel_counter = relMin;
}
}
}
public: // von außen zugängliche Elemente ...
GrayEncoder ():
// Initialisierungsliste
relMin(_min),
relMax(_max),
shift(raster/2),
rel_counter(_min), // Zähler
abs_counter(0), // Zähler
direction(0), // Richtungsanzeige +1 / -1
abs_old(0)
{ }
void init()
{
*getDdrPort(pin_a) &= ~getMaske(pin_a);
*getOutPort(pin_a) |= getMaske(pin_a);
*getDdrPort(pin_b) &= ~getMaske(pin_b);
*getOutPort(pin_b) |= getMaske(pin_b);
last = getPhases(); // power on state
enc_delta = 0;
}
void encode()
{
int n = getPhases();
int diff = last - n;
if ( diff & 1 ) { // bit 0 = value (1)
last = n; // store new as next last
enc_delta = (diff & 2) - 1; // bit 1 = direction (+/-), Zähler
abs_counter += (long) enc_delta;
direction = enc_delta; // Richtungsanzeige (+1 / -1)
}
update_RelativCounter();
}
int getDirection() {return direction; } // Richtungsabfrage
long getRelCounter() {return rel_counter; } // relativen Zählwert abfragen, ist schon angepasst
long getAbsCounter() {return abs_counter >> shift; } // absoluten Zählwert abfragen
int getA() { return phase_a; }
int getB() { return phase_a; }
};
// ---------------------------------------------------------------------------------------
GrayEncoder <40, 41, 0> Hengstler; // Pins Phase A,B / Raster
int Hengstler_Direction;
int Hengstler_AbsCounter;
void setup() {
Serial.begin(250000);
Hengstler.init();
}
void loop() {
update_Encoder();
serieller_Monitor();
}
// ****** Funktionen ******
void update_Encoder ()
{
Hengstler.encode();
Hengstler_Direction = Hengstler.getDirection();
Hengstler_AbsCounter = Hengstler.getAbsCounter();
}
/*
void Ausgabe()
{
static long Enc1_old_abs = 0;
if (Hengstler_AbsCounter != Enc1_old_abs) {
serieller_Monitor();
Enc1_old_abs = Hengstler_AbsCounter;
}
}
*/
void serieller_Monitor ()
{
const unsigned int INTERVAL = 999;
static unsigned long last_ms = 0;
if (millis() - last_ms < INTERVAL) return; // Zeit noch nicht erreicht, Funktion abbrechen
last_ms += INTERVAL;
Ueberschriftszeile();
Serial.print(Hengstler_Direction); Serial.print('\t');
Serial.print(Hengstler_AbsCounter);
Serial.println();
}
void Ueberschriftszeile ()
{
static int counter = 33;
counter++;
if (counter < 30) return; // Zeilen noch nicht erreicht, Funktion abbrechen
counter = 0;
Serial.print(F("DIR")); Serial.print('\t');
Serial.print(F("abs"));
Serial.println();
}