### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Writing three interrupts on a ATmega328p for a rotary encoder.  (Read 456 times)

#### pascalbythree

• Sr. Member
• Posts: 255
##### Writing three interrupts on a ATmega328p for a rotary encoder.
« on: December 08, 2023, 06:37:57 pm »
Hello Brothers in FPC World,

Is it possible to code a interrupt for the ATMega328P on PD3 and  PD4 and on PD5

As soon the pin changes to HIGH i need to fire a procedure. In total 3 of them.

Does anybody got example code? As simple as possible ? How to init them. How to formulate the procedures ?

PS: It is to make my rotary encoder work fine.  Still working on the digital side of my LI-ION Charger project i etched.

Greets, Wouter van Wegen

#### ccrause

• Hero Member
• Posts: 841
##### Re: Writing three interrupts on a ATmega328p for a rotary encoder.
« Reply #1 on: December 09, 2023, 06:59:09 am »
Is it possible to code a interrupt for the ATMega328P on PD3 and  PD4 and on PD5
Yes, read about external interrupts (chapter 13) in the atmega328p datasheet, specifically pin change interrupts.
Note the pins are grouped into three groups for interrupts:
PCIE0 for port B, PB0 ... PB7 -> PCINT0 ... PCINT7
PCIE1 for port C, PC0 .. PC6 -> PCINT8 ... PCINT14
PCIE2 for port D, PD0 ... PD7 -> PCINT16 ... PCINT23

Since you are using pins in port D, you need to write an interrupt handler for PCIE2.
Then set bit PCIE2 in register PCICR
Then set bits PCINT19, PCINT20, PCINT21 in register PCMSK2.

Now you should get an interrupt if any of PD3/4/5 pins change state.  To determine which pin changed, you have to store the initial state of the pins you want to monitor, then read the pins when the PCINT2 interrupt fires, then compare this state against the previous state.

Quote
As soon the pin changes to HIGH i need to fire a procedure. In total 3 of them.
The pin change mechanism will fire on any change of pin state, so you need to handle this check in code. It may be more convenient to enable the internal pullup resistors, then connect the external encoder and button pins to ground - no need for other external resistors.

Quote
Does anybody got example code? As simple as possible ? How to init them. How to formulate the procedures ?
Start by creating a table with all the pins on the port and all possible states of the pins you want to monitor.  The values and states from this table is the logic that you should program in the interrupt code.

#### avra

• Hero Member
• Posts: 2511
##### Re: Writing three interrupts on a ATmega328p for a rotary encoder.
« Reply #2 on: December 09, 2023, 07:29:30 am »
As ccrause has specified, MEGA328P capabilities are described in it's datasheet. You can see there how many external interrupts are possible, how to set raising/falling edge or both, and what exact pins can be used for triggering. Datasheet is embedded developer's best friend.

I do not have AVR FP encoder code, but you can get inspiration from Arduino MEGA328P example found at https://www.allaboutcircuits.com/projects/how-to-use-a-rotary-encoder-in-a-mcu-based-project/, and implement hardware debouncing as explained there to avoid false triggering. For easier conversion of Arduino code you can use FP lib https://github.com/afriess/Laz_AVR_Lib.
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib