Pin Change Interrupts


for a project i need to respond to keypresses from a common type keypad. The project is going to go on battery, so just busy waiting in the loop() is not a good question. So what I need are 12 Interrupts. But on the sanguino I'm going to use are only two external Interrupts. So I found these Pin change Interrupts. My question is:

What exactly are they? Has anyone some code or similar for me?


Pin change interrupts are a build in hardware function of the AVR chip such that any pin can generate an interrupt. However the Arduino platform does not support or provide any software library to utilize this feature directly. The Arduino only supports the user interrupt pins, 2 for 168/328 boards and 5 for the mega boards. Arduino doesn't directly support the Sanguino boad and requires modified files from the Sanquino people and I forget how many user pin interrupts they support or provide for.

As far as battery usage Vs interrupts, there is no direct connection. The processor chip is always running regardless if it is in a waiting loop for an interrupt or polling input pins looking for change. Only by using the various chip sleep mode features can one put the chip into a low power usage mode. However again the Arduino provides no direct support for sleep mode and you would have to write your own or find a user contributed library or code fragment.


AWOL: That's only for the two interrupts, not the pin change interrupts.

retrolefty: The sanguino (atmega644) has 3 external interrupts, and I have already downloaded the modified files.

I have read the datasheet of the 644 and it doesn't look like you save to much power when sleeping, but I don't need the analog inputs, so I should be able to disable them, does anyone know how you do what?


[edit]What looks good, but what do I need to change to work with the Sanguino?:[/edit]

Why not try a simpler approach? Get some diodes and make a Wired AND interrupt.
If you search for “simple remote for granny” you will see the basic mechanism.
If you have 4x3 keypad, then you can do it like I did here instead.
This uses a 4x4 keypad, keypress pulls the diode low causing an interrupt, which wakes the promini from sleeping and transmits the keypress, then goes back into deep power down mode.

I was never able to get PCINTs working, adding the diodes into a regular interrupt pin was very straightforward.

To make it work, you need to write the column pins Low before going into sleep mode, then write them High again as one of the first things you do from waking up.
This collection of libraries worked great for doing this (via wireless)
#include <VirtualWire.h> // Wireless transmitter/receiver library
#include <Keypad.h> // Matrix Keypad library
#include <avr/sleep.h> // powerdown library
#include <avr/interrupt.h> // interrupts library

I don't need the analog inputs, so I should be able to disable them, does anyone know how you do what?

You don't disable them as such but just use them as digital. With 'genuine' Arduino, digital 14 is the same as analogue 0, etc. So to use analogue 0, you'd say pinMode(14,INPUT); and digitalWrite(14,HIGH) to connect the pull-ups.

Expanding interrupts

In principle, you just need to set some bits in the appropriate registers to achieve what you want. In practice, this means you have to read the datasheet a little bit.

For anything like this, I make a really simple sketch where I read the register and Serial.print it bit-by-bit. I then change the bits (OR with 1 to switch on; AND with 0 to switch off) and print again to make sure I've only changed what I really want to change.