hello everyone,
I am working on a project using KY40 rotary encoder.
I did my research around the internet, tried several examples, tested my own code, but nothing works. except for this one this code works flawlessly :
// Used for generating interrupts using CLK signal
const int PinA = 3;
// Used for reading DT signal
const int PinB = 4;
// Updated by the ISR (Interrupt Service Routine)
volatile int virtualPosition = 0;
void isr () {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
// If interrupts come faster than 5ms, assume it's a bounce and ignore
if (interruptTime - lastInterruptTime > 5) {
if (digitalRead(PinB) == LOW)
{
virtualPosition-- ;
}
else {
virtualPosition++ ;
}
// Keep track of when we were here last (no more than every 5ms)
lastInterruptTime = interruptTime;
}
}
void setup() {
// Just whilst we debug, view output on serial monitor
Serial.begin(9600);
// Rotary pulses are INPUTs
pinMode(PinA, INPUT);
pinMode(PinB, INPUT);
// Attach the routine to service the interrupts
attachInterrupt(digitalPinToInterrupt(PinA), isr, LOW);
// Ready to go!
Serial.println("Start");
}
void loop() {
Serial.println(virtualPosition);
}
well, the problems are :
- the code above is using LOW level interrupt trigger so it has the possibility to be triggered multiple times if the encoder is rotating super slowly (hasn't happened so far). I think using falling / raising edge triggered interrupt is more appropriate(correct me if I'm wrong). But if I do so, it won't work.
- I'm only using Arduino as a prototype. After I make sure everything is working properly I'll switch to stm32 and stm32 can only do edge triggered interrupt (raising, falling, change).
any solutions? thanks.


