Support Forum

Share your projects and post your questions

Register   or   Sign In
The Forum

Interrupts in C

The IO Pi Plus is a 32 channel MCP23017 GPIO expander for the Raspberry Pi

27/03/2020

Posted by:
Robspalu

Robspalu Avatar

Hi,

I am having problems with interrupts in C.

I have modified the demo-iopiread2 module, to use interrupts, but I dont seem to see them. A previous user also asked about interrupts some time back, and he seemd to use WiringPiISR?, which seemed a bit odd.

Below is the modified demo code:

int main(int argc, char **argv){
char isr1 = 0;
char isr2 = 0;


setvbuf (stdout, NULL, _IONBF, 0); // needed to print to the command line

IOPi_init(0x20); // initialise one of the io pi buses on i2c address 0x20, default address for bus 1

set_port_direction(0x20,0, 0xFF); // set bank 0 to be inputs
set_port_direction(0x20,1, 0xFF); // set bank 1 to be inputs
set_port_pullups(0x20, 0, 0xFF); // enable internal pullups for bank 0
invert_port(0x20,0,0xFF); // invert output so bank will read as 0
set_port_pullups(0x20, 1, 0xFF); // enable internal pullups for bank 0
invert_port(0x20,1,0xFF); // invert output so bank will read as 0
set_interrupt_defaults(0x20,0,0);// Set Interrupt default Port 0
set_interrupt_defaults(0x20,1,0);// Set Interrupt default Port 1
set_interrupt_type(0x20,0,0);// Set Interrupt type to state change Port 0
set_interrupt_type(0x20,1,0);// Set Interrupt type to state change Port 1
set_interrupt_on_port(0x20,0,0);// Enable Interrupts Port 0
set_interrupt_on_port(0x20,1,0);// Enable Interrupts Port 1
//reset_interrupts(0x20);
while (1){
clearscreen();
isr1 = read_interrupt_status(0x20,0); // Read Port 0 Interrupt status
isr2 = read_interrupt_status(0x20,1); // Read Port 1 Interrupt status

printf("ISR Port 0 %x \n", isr1); // Interrupt Status Port 0
printf("Port 0 %x \n", read_port(0x20,0)); // grounding a pins 1 to 8 will change the value
printf("ISR Port 1 %x \n", isr2); // Interrupt Status Port1
printf("Port 1 %x \n", read_port(0x20,1)); // grounding a pins 1 to 8 will change the value
usleep(200000); // sleep 0.2 seconds


}

return (0);

Can anyone spot the problem

Thanks Dave

27/03/2020

Posted by:
andrew

andrew Avatar

Hello Dave

The set_interrupt_on_port needs a value of 0xFF for the third parameter to enable the interrupt for all pins. Where you used a value of 0 you were disabling the interrupts instead of enabling them.

Try changing the two set_interrupt_on_port() lines to the code below.


set_interrupt_on_port(0x20,0,0xFF);// Enable Interrupts Port 0
set_interrupt_on_port(0x20,1,0xFF);// Enable Interrupts Port 1

27/03/2020

Posted by:
Robspalu

Robspalu Avatar

Hi Andrew,

Thanks for the suggestion, unfortunatley still no value for interrupt status reported when input state changes, but read_port correctly shows status.

Any other suggestions ?

Thanks Dave

27/03/2020

Posted by:
andrew

andrew Avatar

Hi Dave

I tried your code and the interrupt is triggering but where your loop is repeating every 0.2 seconds it only flashed up on the screen for a fraction of a second before disappearing again so it was easy to miss.

I have translated the interrupt demo from our python library to C.


#include 
#include
#include
#include

#include "ABE_IoPi.h"

void clearscreen ()
{
printf("\033[2J\033[1;1H");
}

int main(int argc, char **argv)
{
setvbuf(stdout, NULL, _IONBF, 0); // needed to print to the command line

// initialise one of the io pi buses on i2c address 0x20, default address for bus 1
IOPi_init(0x20);

// Set all pins on the IO bus to be inputs with internal pull-ups enabled.

set_port_pullups(0x20, 0, 0xFF);
set_port_pullups(0x20, 1, 0xFF);
set_port_direction(0x20, 0, 0xFF);
set_port_direction(0x20, 1, 0xFF);

// Invert both ports so pins will show 1 when grounded
invert_port(0x20, 0, 0xFF);
invert_port(0x20, 1, 0xFF);

// Set the interrupt polarity to be active high and mirroring disabled, so
// pins 1 to 8 trigger INT A and pins 9 to 16 trigger INT B
set_interrupt_polarity(0x20, 1);
mirror_interrupts(0x20, 0);

// Set the interrupts default value to 0x00 so the interrupt will trigger when any pin registers as true
set_interrupt_defaults(0x20, 0, 0x00);
set_interrupt_defaults(0x20, 1, 0x00);

// Set the interrupt type to be 1 for ports A and B so an interrupt is
// fired when the pin does not match the default value
set_interrupt_type(0x20, 0, 0xFF);
set_interrupt_type(0x20, 1, 0xFF);

// Enable interrupts for all pins
set_interrupt_on_port(0x20, 0, 0xFF);
set_interrupt_on_port(0x20, 1, 0xFF);

while (1){

// read the interrupt status for each port.
// If the status is not 0 then an interrupt has occured on one of the pins
// so read the value from the interrupt capture.

if (read_interrupt_status(0x20, 0) != 0){
printf("Port 0: %x \n", read_interrupt_capture(0x20,0));
}
if (read_interrupt_status(0x20, 1) != 0){
printf("Port 1: %x \n", read_interrupt_capture(0x20,1));
}

usleep(200000); // sleep 0.2 seconds

}
return (0);
}


The difference between this and your code is I changed the interrupt type to be 1 on each pin so it will fire when the pin does not match the default value and I changed the while loop so on each loop the interrupt status for each port is checked and it only prints the result if the interrupt has fired.

I used the read_interrupt_capture() function to get the value of the interrupt when it fired and print that to the display.

When the code runs it will print the status repeatedly when a pin is connected to ground. If you only want it to print when the pin state changes change the set_interrupt_type(0x20, 0, 0xFF); to set_interrupt_type(0x20, 0, 0x00);

I have uploaded a copy of the c code to our GitHub repository at demo-iopiinterrupt.c

27/03/2020

Posted by:
Robspalu

Robspalu Avatar

Hi Andrew,

Thanks for the new demo, just what I needed to help me understand my problem.

I have change the interrupt type so I detect each state change.

My intention now is to create a C library ABE_IoPi and a corresponding Lazarus wrapper so I can access the IoPi board from a Lazarus application I have already written, if successful I will need some more IoPi boards.

Thanks again for your help

Dave.

Sign in to post your reply


Note: documents in Portable Document Format (PDF) require Adobe Acrobat Reader 5.0 or higher to view.
Download Adobe Acrobat Reader or other PDF reading software for your computer or mobile device.

Home

Shop

Learn

Forum

FAQ

Contact

0 item

Your cart is empty

Please browse our shop to order from the wide range of Raspberry Pi boards and accessories.

Subtotal:£0.00
View Basket Continue to Checkout