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
#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
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
Thank you for the answer. It was really helpful.
Best wishes,
Andrew
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.