D0-Schnittstellen-Projekt

Part 3, Drehencoder.h

// Quelle: https://miscsolutions.wordpress.com/2011/10/16/five-things-i-never-use-in-arduino-projects/

// bisher klappt die Erkennung super - kein Verzählen festgestellt

// Class to interface Arduino to rotary encoders
// D Crocker, Escher Technologies Limited, October 2011.
// This code may be freely used for any purpose
// but is supplied without warranty.
//
// Declare a rotary encoder like this:
//
// RotaryEncoder encoder(leftPin, rightPin, pulsesPerClick);
//
// where pulsesPerClick is normally 4.
// Every 1 millisecond or so, call:
//
// encoder.poll();
//
// To find how much the encoder has moved since you last asked, do this:
//
// int movement = encoder.getChange();

class RotaryEncoder
{
    byte state;
    byte pin0, pin1;
    byte ppc;
    char change;

  public:
    byte readState()
    {
      return (digitalRead(pin0) == HIGH ? 1u : 0u)
             | (digitalRead(pin1) == HIGH ? 2u : 0u);
    }

    //public:
    RotaryEncoder(byte p0, byte p1, byte pulsesPerClick) :
      pin0(p0), pin1(p1), ppc(pulsesPerClick), change(0), state(0) {}

    void init();
    void poll();
    int getChange();
};

void RotaryEncoder::init()
{
  pinMode(pin0, INPUT_PULLUP);
  pinMode(pin1, INPUT_PULLUP);
  //digitalWrite(pin0, 1);  // enable internal pullup
  //digitalWrite(pin1, 1);  // enable internal pullup
  change = 0;
  state = readState();
}

void RotaryEncoder::poll()
{
  // State transition table
  static char tbl[16] =
  { 0, +1, -1, 0,
    // position 3 = 00 to 11, can't really do anythin, so 0
    -1, 0, -2, +1,
    // position 2 = 01 to 10, assume a bounce, should be 01 -> 00 -> 10
    +1, +2, 0, -1,
    // position 1 = 10 to 01, assume a bounce, should be 10 -> 00 -> 01
    0, -1, +1, 0
    // position 0 = 11 to 10, can't really do anything
  };

  unsigned int t = readState();
  int movement = tbl[(state << 2) | t];
  if (movement != 0)
  {
    change += movement;
    state = t;
  }
}

int RotaryEncoder::getChange()
{
  int r;
  noInterrupts();
  if (change >= ppc - 1)
  {
    r = (change + 1) / ppc;
  }
  else if (change <= 1 - ppc)
  {
    r = -((1 - change) / ppc);
  }
  else
  {
    r = 0;
  }
  change -= (r * ppc);
  interrupts();
  return r;
}

Denke, an diesem Code kann man noch eine ganze Menge verbessern - wenn ich damit die benötigten Kennzahlen meiner Zähler ausgelesen bekomme, soll mir Das aber schon reichen.

Da stecke ich dann lieber die Zeit in den folgenden Sketch, statt Den hier von 'läuft' auf 'läuft und sieht gut aus' umzubauen.

Vll. kann's ja Wer gebrauchen (oder Seinen Nutzen aus dem Konvolut an Try & Error ziehen)

MfG