Support Forum

Share your projects and post your questions

Register   or   Sign In
The Forum

Interrupts doesn't work in C

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

16/08/2019

Posted by:
Androw96

Androw96 Avatar

Hello Guys! I am writing to you because we have a problem with Programming and using IO Pi Plus in C. I have read a lot of discussions about this topic, but we couldn't manage to solve our problem yet.Our problem is that we would like to connect a lot of buttons to the IO Pi Plus and use their signal as interrupts.(We are using a RPI 3B+) We want the pins 1-8 of port0 of the bus2 to trigger the IA of the bus2. The IA port is connected to one of the GPIOs of the Raspberry Pi 3B+ which is initialized as an interrupt. Our problem is, that we can't get any feedback from the buttons. In the wiring we don't use a level-shifter, but voltage divider(an 1k Ohm resistor and an 1,8k Ohm resistor) and so we get 3,22 Volt. There was a one time occasion,that we got a printout from the read_interrupt_capture function as we were constantly pushing our button. It was something like that: Port 0 7f Port 0 7f Port 0 7f Port 0 fe Port 0 fe It was a pretty random answer.. We had one wired button on the pin1 of the port0 of the bus1. Since then we checked all wireings. This is our code:




#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "signal.h"
#include "unistd.h"

#include
#include "ABE_IoPi.h"

#include
#include
#include


#define BUTTON 25





void callBut()
{

printf("Port 0 %x \n",read_interrupt_capture(0x21, 0));

}



int main(int argc, char* argv[])
{


IOPi_init(0x21); // initialise one of the io pi buses on i2c address 0x20

set_port_pullups( 0x21, 0, 0x00); //set the internal 100K pull-up resistors for the selected IO port

set_port_direction(0x21, 0, 0xFF); // set the direction for bank 0 to be outputs

invert_port(0x21, 0, 0xFF); //invert the polarity of the pins on a selected port

set_interrupt_polarity(0x21, 0); //This sets the polarity of the char output pins.

mirror_interrupts( 0x21, 1); // Set the interrupt pins to be mirrored or for separate ports

set_interrupt_defaults( 0x21, 0, 0xFF);

set_interrupt_type( 0x21, 0, 0xFF); //Sets the type of interrupt for each pin on the selected port

set_interrupt_on_port( 0x21, 0, 0xFF);

reset_interrupts( 0x21);

wiringPiSetupGpio();

pinMode(BUTTON,INPUT);

pullUpDnControl(BUTTON,PUD_UP);

wiringPiISR(BUTTON,INT_EDGE_FALLING,&callBut);

while(1)
{

}

}


Can anyone help us solve this problem? Any advice and/or help is welcomed!

Best regards,

Andrew

16/08/2019

Posted by:
andrew

andrew Avatar

Hello Andrew

The code below should work for your project.

In the callback function, I added a while loop which keeps reading the port value until the state changes which means a button has been released. Without this, the code will only run once and not reset the interrupts.

The port did not need to be inverted as the internal pull-ups are disabled so the pin would go high when a button is pressed. You will need to make sure you have a pull-down resistor on each button so they drop back to 0V when the button is released otherwise they will sit in a floating state which can cause unwanted interrupt triggers.

I changed the interrupt polarity to 1 as the voltage divider will pull the output low when the interrupt resets so it will work better with triggering high.

The wiringPiISR now triggers on a rising edge instead of a falling edge and I disabled the GPIO pull-up as you already have a pull-down resistor on the voltage divider.

I have tested the code with a button connected to the 5V pin on the Raspberry Pi and the same voltage divider values as you have used and it appears to be working correctly but if you have any problems please let me know.


#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "signal.h"
#include "unistd.h"

#include
#include "ABE_IoPi.h"

#include
#include
#include


#define BUTTON 25





void callBut()
{
int intval = read_interrupt_capture(0x21,0); // read the capture value

printf("Port 0 %x \n",intval);

while (intval == read_port(0x21,0)){ // keep reading the port until the button is released
usleep(100000);
}
}



int main(int argc, char* argv[])
{


IOPi_init(0x21); // initialise one of the io pi buses on i2c address 0x20

set_port_pullups( 0x21, 0, 0x00); //turn off the internal 100K pull-up resistors for the selected IO port

set_port_direction(0x21, 0, 0xFF); // set the direction for bank 0 to be inputs

invert_port(0x21, 0, 0x00); //set the polarity of the pins on the port to be normal

set_interrupt_polarity(0x21, 1); // Set the polarity of the interrupt pin to go high.

mirror_interrupts( 0x21, 1); // Set the interrupt pins to be mirrored or for separate ports

set_interrupt_defaults( 0x21, 0, 0x00); // Set the default value to be off for all pins

set_interrupt_type( 0x21, 0, 0xFF); // Sets the type of interrupt to trigger when the pin matches the default value

set_interrupt_on_port( 0x21, 0, 0xFF); // Enable interrupts for all pins on port 0

reset_interrupts( 0x21);

wiringPiSetupGpio();

pinMode(BUTTON,INPUT);

pullUpDnControl(BUTTON,PUD_OFF);

wiringPiISR(BUTTON,INT_EDGE_RISING,&callBut);

while(1)
{

}

}

22/08/2019

Posted by:
Androw96

Androw96 Avatar

Hi Andrew,

Thank you for the answer. It was really helpful.

Best wishes,

Andrew

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