/* * Speed measurement with optical encoder * On every rising edge the time delta to the last rising edge is printed to the serial port. * Additionaly LED_BUILTIN output shows the trigger point. * * 2024-06-27 Christoph M. */ // pin change interrupt base code: // https://wolles-elektronikkiste.de/en/interrupts-part-2-pin-change-interrupts const int interruptPin = 6; volatile bool event = false; volatile uint32_t TimeDelta = 0; volatile byte changedPin = 0; const byte interruptPinMask = 0b11111100; volatile byte lastInterruptPinsStatus = 0b01010100; volatile bool risingEdge = false; // PCINT2_vect: interrupt vector for PORTD ISR (PCINT2_vect) { uint32_t nowTime; static uint32_t oldTime; byte currentInterruptPinsStatus = PIND & interruptPinMask; if (currentInterruptPinsStatus > lastInterruptPinsStatus) { risingEdge = true; nowTime = micros(); TimeDelta = nowTime - oldTime; oldTime = nowTime; event = true; } else { risingEdge = false; } byte statusCopy = currentInterruptPinsStatus; currentInterruptPinsStatus ^= lastInterruptPinsStatus; lastInterruptPinsStatus = statusCopy; if (currentInterruptPinsStatus) { changedPin = 0; while (!(currentInterruptPinsStatus & 1)) { changedPin++; currentInterruptPinsStatus = (currentInterruptPinsStatus >> 1); } } } void setup() { Serial.begin(115200); pinMode(interruptPin, INPUT_PULLUP); PCICR = (1 << PCIE2); // enable PCINT[23:16] interrupts PCMSK2 = (1 << PCINT22); // D6 = PCINT22 pinMode(LED_BUILTIN,OUTPUT); } void loop() { if (event) { digitalWrite(LED_BUILTIN,HIGH); // debug trigger correctness Serial.println(TimeDelta); digitalWrite(LED_BUILTIN,LOW); event = false; } }