Hallo zusammen!
Ich habe gerade etwas Seltsames entdeckt, vielleicht kann mir jemand erklären was hier schief läuft. Ich versuche mal kurz den Kontext zu erklären:
In meinem Projekt verwende ich einen Arduino Mega 2560, eine Adafruit Neotrellis LED/Button Matrix und insgesamt neun Encoder um verschiedene Einstellungen der Matrix zu steuern.
Um die Encoder auszuwerten verwende ich die OneButton.h und EncoderStepCounter.h Bibliotheken.
Mein Projekt besteht im Prinzip aus mehreren Lichtlaufleisten, die von verschiedenen Timing Funktionen gesteuert werden, zwischen denen mit den Encoder umgeschaltet werden kann.
In einem Test-Sketch, der nur die Encoder behandelt, funktionieren diese problemlos. Zusammen mit dem Code, der die LED Matrix steuert, werden die Encoder nicht mehr korrekt ausgelesen.
Soweit so gut - offenbar werden die Encoder im Zusammenspiel mit den Neotrellis nicht mehr schnell genug ausgelesen. Eine Möglichkeit der EncoderStepCounter Bibliothek das Problem zu beheben ist nun mit externen Interrupt Pins zu arbeiten. Der betreffende Encoder soll damit mit jeder Bewegung die Interrupt Funktion aufrufen und wird dadurch flüssig ausgelesen. Das funktioniert für einen einzelnen Encoder auch super. Da das Mega 2560 Board nun jedoch nur sechs externe Interrupt Pins besitzt, habe ich mit verschiedenen Möglichkeiten gespielt alle neun Encoder zu versorgen.
Jetzt zu dem mir nicht erklärbaren seltsamen Verhalten: Bei meinen Versuchen bin ich irgendwann an einen Punkt gekommen, wo ich fälschlicherweise dem attachInterrupt Befehl einen Pin zugewiesen habe, an dem gar kein Encoder (und auch nichts anderes) hängt. Das Erstaunliche daran ist, dass meine Encoder nun aber plötzlich alle funktionieren wie sie sollen. :o
Anbei der Code für die Encoder, der kommt so mit aufsteigender Nummerierung (ENC0-ENC8) mehrfach in meinem Sketch vor. An dem im Code definierten Interrupt Pin 3 hängt wie gesagt gerade nichts. Aufgefallen ist mir die ganze Sache nur, weil ich mehrfach zwischen Pin 3 und Pin 13 für den ersten Encoder gewechselt habe (3 ist ein externer Interrupt Pin, 13 kann man als PinChangeInterrupt verwenden).
Kann jemand erklären warum das funktioniert, obwohl es das eigentlich nicht sollte?
#include "OneButton.h"
#include "EncoderStepCounter.h"
const int CLK0 = 12;
const int DT0 = 13;
const int BTN0 = 11;
int pos0A = 0;
int pos0B = 0;
int btnState0 = 0;
bool btnChanged0 = false;
EncoderStepCounter ENC0(CLK0, DT0);
OneButton button0(BTN0, true);
void setup() {
Serial.begin(115200);
ENC0.begin();
attachInterrupt(3, interrupt, CHANGE); //sorgt dafür, dass die Encoder richtig ausgelesen werden
button0.attachClick(click0);
}
void loop() {
ENC0.tick();
button0.tick();
encoderMenu();
//Neotrellis Zeug
Serial.print(pos0A);
Serial.print("\t");
Serial.println(pos0B);
}
void interrupt()
{
ENC0.tick();
}
void click0()
{ btnState0 = !btnState0;
btnChanged0 = true;
}
void encoderMenu()
{
if (btnState0 == 0)
{ if (btnChanged0 == true)
{ ENC0.setPosition(pos0A);
btnChanged0 = false;
}
pos0A = ENC0.getPosition();
if (pos0A > 14)
{
ENC0.setPosition(15);
}
if (pos0A < 1)
{
ENC0.setPosition(0);
}
}
/* ----- Enc0 Menu 1 -----*/
if (btnState0 == 1)
{ if (btnChanged0 == true)
{ ENC0.setPosition(pos0B);
btnChanged0 = false;
}
pos0B = ENC0.getPosition();
if (pos0B > 14)
{
ENC0.setPosition(15);
}
if (pos0B < 1)
{
ENC0.setPosition(0);
}
}
}