Lord Integer
18.10.2020, 14:02
Moin,
ich habe mir einen Arduino MEGA 2560 Pro Micro angeschafft und versuche schon seit einigen Tagen einen Rotary Encoder zu benutzen.
Arduino: https://www.amazon.de/ARCELI-Arduino-Mega-ATmega2560-CH340G-Elektronik/dp/B07MQ1J9MR/ref=sr_1_9?__mk_de_DE=ÅMÅŽÕÑ&dchild=1&keywords=arduino+mega&qid=1603022275&quartzVehicle=1480-1518&replacementKeywords=arduino&sr=8-9
Encoder: https://www.amazon.de/WayinTop-Encoder-Drehgeber-Drehwinkelgeber-Druckknopf/dp/B07T3672VK/ref=sr_1_3?__mk_de_DE=ÅMÅŽÕÑ&dchild=1&keywords=Rotary+encoder&qid=1603022349&sr=8-3
Habe schon endliche Beispiele mit irgendwelchen Libs ausprobiert.
Aber, um es besser zu verstehen , habe ich mir einen Sketch gebastelt der 2 Interrups nimmt. Dieser Sketch funktioniert einwandfrei auf einem Arduino Nano mit Pin 2,3.
Laut Recherche sind die digitalen Interrupt Pins von einem Mega, Mega2560, MegaADK = 2, 3, 18, 19, 20, 21 gültig.
Ich hoffe mir kann jemand weiterhelfen.
Beste Grüße
/************************************************** ************************************************** ************************************/
#define EcButtonPin_SW 8
#define EcPin_CLK 2//A
#define EcPin_DT 3//B
/***********************/
#define MinEncoderPos 0
#define MaxEncoderPos 30
/***********************/
volatile unsigned int encoderPos = 0;
unsigned int lastReportedPos = 1; // change management
static boolean rotating = false; // debounce management
/***********************/
// interrupt service routine variables
boolean A_set = false;
boolean B_set = false;
/************************************************** ************************************************** ************************************/
void setup()
{
Serial.begin(9600);
pinMode (EcButtonPin_SW, INPUT);
pinMode (EcPin_CLK,INPUT);//A
pinMode (EcPin_DT,INPUT);//B
digitalWrite(EcPin_CLK, HIGH); // turn on pullup resistors
digitalWrite(EcPin_DT, HIGH); // turn on pullup resistors
attachInterrupt(0, doEncoderA, CHANGE); // encoder pin on interrupt 0 (pin 2)
attachInterrupt(1, doEncoderB, CHANGE); // encoder pin on interrupt 1 (pin 3)
}
void loop()
{
CheckAndSetEncoderPos();
}
void CheckAndSetEncoderPos()
{
rotating = true; // reset the debouncer
if (lastReportedPos != encoderPos)
{
Serial.print("lastPosition: => ");
Serial.print(lastReportedPos);
Serial.print(" ------------------- ");
lastReportedPos = encoderPos;
Serial.print("newPosition: => ");
Serial.println(lastReportedPos);
}
}
// ------------- Interrupt Service Routines ------------------------------
// ISR Interrupt on A changing state (Increment position counter)
void doEncoderA()
{
if ( rotating ) delay(1); // wait a little until the bouncing is done
if( digitalRead(EcPin_CLK) != A_set ) // debounce once more
{
A_set = !A_set;
if (A_set && !B_set)
if(encoderPos <=(MaxEncoderPos -1))
{
encoderPos += 1; // adjust counter +1 if A leads B
}
rotating = false; // no more debouncing until loop() hits again
}
}// ------------------- doEncoderA ----------------------------------------
// ISR Interrupt on B changing state, same as A above
void doEncoderB()
{
if ( rotating ) delay(1);
if( digitalRead(EcPin_DT) != B_set )
{
B_set = !B_set;
if( B_set && !A_set )
if(encoderPos >=(MinEncoderPos +1) )
{
encoderPos -= 1; //adjust counter -1 if B leads A
}
rotating = false;
}
}// -------------------- doEncoderB --------------------------------------
ich habe mir einen Arduino MEGA 2560 Pro Micro angeschafft und versuche schon seit einigen Tagen einen Rotary Encoder zu benutzen.
Arduino: https://www.amazon.de/ARCELI-Arduino-Mega-ATmega2560-CH340G-Elektronik/dp/B07MQ1J9MR/ref=sr_1_9?__mk_de_DE=ÅMÅŽÕÑ&dchild=1&keywords=arduino+mega&qid=1603022275&quartzVehicle=1480-1518&replacementKeywords=arduino&sr=8-9
Encoder: https://www.amazon.de/WayinTop-Encoder-Drehgeber-Drehwinkelgeber-Druckknopf/dp/B07T3672VK/ref=sr_1_3?__mk_de_DE=ÅMÅŽÕÑ&dchild=1&keywords=Rotary+encoder&qid=1603022349&sr=8-3
Habe schon endliche Beispiele mit irgendwelchen Libs ausprobiert.
Aber, um es besser zu verstehen , habe ich mir einen Sketch gebastelt der 2 Interrups nimmt. Dieser Sketch funktioniert einwandfrei auf einem Arduino Nano mit Pin 2,3.
Laut Recherche sind die digitalen Interrupt Pins von einem Mega, Mega2560, MegaADK = 2, 3, 18, 19, 20, 21 gültig.
Ich hoffe mir kann jemand weiterhelfen.
Beste Grüße
/************************************************** ************************************************** ************************************/
#define EcButtonPin_SW 8
#define EcPin_CLK 2//A
#define EcPin_DT 3//B
/***********************/
#define MinEncoderPos 0
#define MaxEncoderPos 30
/***********************/
volatile unsigned int encoderPos = 0;
unsigned int lastReportedPos = 1; // change management
static boolean rotating = false; // debounce management
/***********************/
// interrupt service routine variables
boolean A_set = false;
boolean B_set = false;
/************************************************** ************************************************** ************************************/
void setup()
{
Serial.begin(9600);
pinMode (EcButtonPin_SW, INPUT);
pinMode (EcPin_CLK,INPUT);//A
pinMode (EcPin_DT,INPUT);//B
digitalWrite(EcPin_CLK, HIGH); // turn on pullup resistors
digitalWrite(EcPin_DT, HIGH); // turn on pullup resistors
attachInterrupt(0, doEncoderA, CHANGE); // encoder pin on interrupt 0 (pin 2)
attachInterrupt(1, doEncoderB, CHANGE); // encoder pin on interrupt 1 (pin 3)
}
void loop()
{
CheckAndSetEncoderPos();
}
void CheckAndSetEncoderPos()
{
rotating = true; // reset the debouncer
if (lastReportedPos != encoderPos)
{
Serial.print("lastPosition: => ");
Serial.print(lastReportedPos);
Serial.print(" ------------------- ");
lastReportedPos = encoderPos;
Serial.print("newPosition: => ");
Serial.println(lastReportedPos);
}
}
// ------------- Interrupt Service Routines ------------------------------
// ISR Interrupt on A changing state (Increment position counter)
void doEncoderA()
{
if ( rotating ) delay(1); // wait a little until the bouncing is done
if( digitalRead(EcPin_CLK) != A_set ) // debounce once more
{
A_set = !A_set;
if (A_set && !B_set)
if(encoderPos <=(MaxEncoderPos -1))
{
encoderPos += 1; // adjust counter +1 if A leads B
}
rotating = false; // no more debouncing until loop() hits again
}
}// ------------------- doEncoderA ----------------------------------------
// ISR Interrupt on B changing state, same as A above
void doEncoderB()
{
if ( rotating ) delay(1);
if( digitalRead(EcPin_DT) != B_set )
{
B_set = !B_set;
if( B_set && !A_set )
if(encoderPos >=(MinEncoderPos +1) )
{
encoderPos -= 1; //adjust counter -1 if B leads A
}
rotating = false;
}
}// -------------------- doEncoderB --------------------------------------