//calculatesthe angle based on a rotary encoder for teaching purposes
//includes rotary encoder and interrupts HTL Anichstraße
// encoder pins
#define ENCODER_CLK 2 //pin usabele for interrupts
#define ENCODER_DT 4
#define ENCODER_SW 3 //pin usabele for interrupts
// max enconder steps for one rotation based on the wiki of wokwi
#define ROTARY_MAX 20
//variable to save the actual count / position of the encoder
//the actual position of the decoder at startup is definded as 0 deg.
int counter = 0;
//variable to save the old counter value
int prevCounter = counter;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Hello, I'm the encoder king!");
// Initialize encoder pins
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
pinMode(ENCODER_SW, INPUT_PULLUP);
//attach interupt for the detection of encoder changes
attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), readEncoder, FALLING);
//attach interupt for reset the 0 deg. postion
attachInterrupt(digitalPinToInterrupt(ENCODER_SW), resetCounter, FALLING);
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// method to read the encoder (called by interrupt)
void readEncoder() {
int dtValue = digitalRead(ENCODER_DT);
if (dtValue == HIGH) {
counter++; // Clockwise
}
if (dtValue == LOW) { //Counterclockwise
if (counter != 0){
counter--; //decreases the counter
}else {
// avoid to get negative angles if the last counter value
// was zero (0 deg.)
counter = ROTARY_MAX -1;
}
}
//resets the counter to zero if an 360 deg rotation occured
if (counter == ROTARY_MAX){
counter = 0;
}
Serial.println("Actual counter: "+ String(counter));
}
// resets the counter (called by interrupt)
//if the decoder is pressed this sets the angle to 0 deg. at the actual position
void resetCounter() {
//Deactivate the interrupts to prevent the reset of the counter
//from being interrupted by turning the encoder.
noInterrupts();
counter = 0;
Serial.println("Reset to 0 deg.");
interrupts();
}
void loop() {
delay(10); //only for wokwi simulation
//calculate the angle of the encoder based on the actual counter
int angle = abs((360/ROTARY_MAX)*counter);
//print the angle only when changed
if (prevCounter != counter) {
Serial.println("Actual angle: "+ String(angle));
}
prevCounter = counter;
}