abhängig davon was du insgesamt in deinem Programm machen willstbrauchst du höchstwahrscheinlich keinen Interrupt zu benutzen.
Es gibt eine Menge Demo-Programme zu interrupt die in der Interrupt-function etwas auf die serielle Schnittstelle ausgeben.
Das ist eine - ich bezeichne es mal als - extrem unprofessionelle Art und Weise.
Ein Profi macht in einer Interruptroutine NIEMALS eine Ausgabe auf die serielle Schnittstelle.
Einzige Ausnahme: der Arduino-Core-Code der INTERN aufgerufen wird wenn man "print" aufruft.
Um es mal auf die Realwelt zu übertragen: Mit einem Rennwagen B fährt man nicht im inneren des Rennwagens A herum. Nocht mal mit einem ferngesteuerten Modellauto.
Einem Newcomer kann man das nicht vorwerfen wenn er es dann auch so macht.
Bitte vorsichtig zu Ende lesen das folgende ist neutral gemeint keinesfalls als Vorwurf
Ich habe den Eindruck im Moment schreibst du Code um so eine Art Basisfunktionen zu haben die später für veschiedene Sachen verwendet werden sollen. Das ist vollkommen OK.
In der Interruptroutine wird nur eine flag-variable gesetzt und dann wird diese Flag-Variable in loop() abgefragt
Probiere mal diese Version aus die macht das so.
#include "Arduino.h"
#include "NewEncoder.h"
#define VSPI_MOSI 23
#define VSPI_SCK 18
#define VSPI_SS 5
#define ADR_BITS 0x00 // Adressbits A0 und A1 auf 0 setzen
const byte CLK = 39;
const byte DT = 36;
const int Taster = 27;
const int minVal = 0;
const int maxVal = 255;
const int startVal = 0;
volatile boolean TasterGedrueckt = false;
// Pins 2 and 3 should work for many processors, including Uno. See README for meaning of constructor arguments.
// Use FULL_PULSE for encoders that produce one complete quadrature pulse per detnet, such as: https://www.adafruit.com/product/377
// Use HALF_PULSE for endoders that produce one complete quadrature pulse for every two detents, such as: https://www.mouser.com/ProductDetail/alps/ec11e15244g1/?qs=YMSFtX0bdJDiV4LBO61anw==&countrycode=US¤cycode=USD
NewEncoder myEncoderObject(CLK, DT, minVal, maxVal, startVal, FULL_PULSE);
int16_t currentValue;
int16_t prevEncoderValue;
uint8_t poti_value;
void setup() {
// myEncState is a variable of type EncoderState
// EncoderState is a structured variable that has two "simple" variables
// .currentValue which is type int16_t
// (16 bit signed integer valuerange -36767 to 36767)
// currentValue counts up / down with each pulse created through rotating the encoder
// and
// .currentClick which is of type "EncoderClick"
// the variable type "EncoderClick" can have just 3 values
// NoClick, DownClick, UpClick where "click" means a "pulse" created through rotating the encoder
NewEncoder::EncoderState myEncState;
attachInterrupt(digitalPinToInterrupt(Taster), Interrupt, CHANGE);
pinMode(VSPI_MOSI, OUTPUT); // Master Out - Slave In
pinMode(VSPI_SCK, OUTPUT); // Clock
digitalWrite(VSPI_SCK, LOW); // Clock-Ruhezustand: LOW
pinMode(VSPI_SS, OUTPUT); // SPI-Select (Chip Select)
digitalWrite(VSPI_SS, HIGH); // Slave gesperrt
Serial.begin(115200);
delay(2000);
Serial.println("Starting");
if (!myEncoderObject.begin()) {
Serial.println("Encoder Failed to Start. Check pin assignments and available interrupts. Aborting.");
while (1) {
yield();
}
} else {
// store values of currentValue and EncoderClick into variable myEncState
myEncoderObject.getState(myEncState);
Serial.print("Encoder Successfully Started at value = ");
prevEncoderValue = myEncState.currentValue;
Serial.println(prevEncoderValue);
}
}
void loop() {
if (TasterGedrueckt) {
TasterGedrueckt = false; // auf false setzen damit die Ausgabe nur einmal pro Tastendruck erfolgt
Serial.println("Button gedrückt.");
}
NewEncoder::EncoderState myCurrentEncoderState;
// store actual values into variable myCurrentEncoderState
if (myEncoderObject.getState(myCurrentEncoderState)) {
Serial.print("Encoder: ");
currentValue = myCurrentEncoderState.currentValue;
// if currentValue has REALLY changed print new currentValue
if (currentValue != prevEncoderValue) {
Serial.println(currentValue);
prevEncoderValue = currentValue;
poti_value = prevEncoderValue;
WRITE_POTI(ADR_BITS, poti_value, 10); // 10-Bit-Datenwort für die Wiper-Einstellung an Digitalpoti senden
// if currentValue stayed the same because the number is at upper/lower limit
// check if encoder was rotated by using the UpClick / DownClick-values
} else
switch (myCurrentEncoderState.currentClick) {
case NewEncoder::UpClick:
Serial.println("Obere Einstellgrenze erreicht");
break;
case NewEncoder::DownClick:
Serial.println("Untere Einstellgrenze erreicht.");
break;
default:
break;
}
}
}
void Interrupt() // Beginn des Interrupts. Wenn der Rotary Knopf betätigt wird, springt das Programm automatisch an diese Stelle. Nachdem...
{
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
// If interrupts come faster than 200ms, assume it's a bounce and ignore
if (interrupt_time - last_interrupt_time > 200)
{
//Serial.println("Button gedrückt.");
TasterGedrueckt = true;
}
last_interrupt_time = interrupt_time;
}
vgs
Der Tastendruck kann auch innerhalb von loop() durch "pollen" abgefragt werden. Ob es mit pollen gut funktioniert hängt vom Gesamtprogramm ab.
Meine Meinung: Wenn der Zahlenbereich nur bis 255 geht dann lohnt sich umstellen auf 20er-Schritte nicht.
Da bist du länger mit Umschalten beschäftigt als mit schnell am Encoder drehen.
Umschalten auf 10er reicht da.