Page 1 of 1

problems with interrupts

Posted: Thu Jan 21, 2021 8:19 am
by attila666
Hello everyone, sorry but I have a problem and I have not been able to get out of it for months, I am trying to manage the lights, and I would like to control 8 relays with 8 buttons, the system works but, using the interrupts, I cannot stabilize the program, so if I repeatedly press the buttons the Sketch stops, maybe the problem is my wrong way to use IRAM, the configuration is the following ESP32, mcp23017 and under the Sketch, could someone tell me what am I wrong? thank you very much p.s. sorry my english, i use google translator

Code: Select all

#include <Wire.h>
#include "Adafruit_MCP23017.h"
#include <SPI.h>
byte IntPin = 23; // collegare entrata interrupt mcp A------------------------
volatile boolean awakenByInterrupt = false;
static uint16_t ledState = 0;
boolean led_state[8];
byte pinLed[] = {7, 6, 5, 4, 3, 2, 1, 0};
byte buttons[] = {8, 9, 10, 11, 12, 13, 14, 15};
int i ;
int test;
Adafruit_MCP23017 mcp;

void setup() {

  Serial.begin(115200);
  mcp.begin();
  pinMode(IntPin, INPUT);
  for (i = 0; i < (8); i++) {
    mcp.pinMode(buttons[i], INPUT);
    mcp.pinMode(pinLed[i], OUTPUT);

    mcp.digitalWrite(pinLed[i], LOW);
    led_state[i] = false;
    mcp.setupInterruptPin(buttons[i], RISING);
  }

  mcp.readGPIOAB();
  mcp.setupInterrupts(true, false, LOW);
  attachInterrupt(digitalPinToInterrupt(IntPin), intCallBack, FALLING);
}

ICACHE_RAM_ATTR void intCallBack() {
  awakenByInterrupt = true;
}


void handleInterrupt() { // gestione pulsanti da interrupt************************************************************************************
  noInterrupts();

  uint8_t pin = mcp.getLastInterruptPin();
  //uint8_t val = mcp.getLastInterruptPinValue();
  led_state[pin - 8] = ! led_state[pin - 8];
  if (led_state[pin - 8]) mcp.digitalWrite(pinLed[pin - 8], HIGH);
  else mcp.digitalWrite(pinLed[pin - 8], LOW);
  delay(35);
  //mcp.readGPIOAB();
  while ( !(!mcp.digitalRead(buttons[0]) && ! mcp.digitalRead(buttons[1]) &&  !mcp.digitalRead(buttons[2]) && !mcp.digitalRead(buttons[3]) && !mcp.digitalRead(buttons[4]) && !mcp.digitalRead(buttons[5]) && !mcp.digitalRead(buttons[6]) && !mcp.digitalRead(buttons[7])));
  awakenByInterrupt = false;
  interrupts();
}

void loop() {
  if (awakenByInterrupt) handleInterrupt();
}

Re: problems with interrupts

Posted: Sat Jan 23, 2021 5:23 pm
by attila666
Now I remember why I had left this forum, 94 visits and not even a reply, even if it was "forget it", p.s. is it because I don't speak english ??

Re: problems with interrupts

Posted: Sun Jan 24, 2021 3:57 am
by ESP_Sprite
Possibly, your use of Google Translate certainly does not help. Furthermore, I imagine 94 people just like me went over your code and went 'dunno, looks good to me, hope he finds his problem'.

Re: problems with interrupts

Posted: Sun Jan 24, 2021 3:35 pm
by lbernstone
Put a delay(150); in your loop. This will act to debounce your button interrupt (I assume you are not The Flash), as well as prevent the tight looping that can starve your cpu.

Re: problems with interrupts

Posted: Mon Jan 25, 2021 7:49 pm
by Michalpu
I had used while in while to check if button is pressed this prevent from sending pressed singal all the time

Re: problems with interrupts

Posted: Thu Jan 28, 2021 11:26 pm
by attila666
thanks for the answers, I didn't check before because I didn't think you answered :) anyway for info I have a hardware debounce and that I checked with an oscilloscope and that works correctly by eliminating the bounces, in the following code I have centered the problem, in the attached photo l last message of the serial is when the ESP32 is blocked. - I don't want to insert delays if I can solve it from code
https://www.dropbox.com/s/680o5ag84uex6 ... e.JPG?dl=0

Code: Select all

#include <Wire.h>
#include "Adafruit_MCP23017.h"
#include <SPI.h>
byte IntPin = 23; // collegare entrata interrupt mcp A------------------------
volatile boolean awakenByInterrupt = false;
boolean ledState = 0;
boolean led_state[8];
boolean Ccheck = 1;
byte pinLed[] = {7, 6, 5, 4, 3, 2, 1, 0};
byte buttons[] = {8, 9, 10, 11, 12, 13, 14, 15};
int i ;

//ICACHE_RAM_ATTR
void IRAM_ATTR intCallBack() {
  Serial.println("puntoIRAM");
  if (Ccheck == 1) {
    Serial.println("punto4");
    awakenByInterrupt = true;
  }
}
Adafruit_MCP23017 mcp;
void setup() {
  Serial.begin(115200);
  mcp.begin();
  pinMode(IntPin, INPUT);

  for (i = 0; i < (8); i++) {
    mcp.pinMode(buttons[i], INPUT);
    mcp.pinMode(pinLed[i], OUTPUT);
    mcp.pullUp(buttons[i], HIGH); //------------------- da valutare
    mcp.digitalWrite(pinLed[i], LOW);
    led_state[i] = false;
    mcp.setupInterruptPin(buttons[i], RISING);
  }
  mcp.readGPIOAB();
  mcp.setupInterrupts(true, false, LOW);
  attachInterrupt(digitalPinToInterrupt(IntPin), intCallBack, FALLING);
}

void handleInterrupt() { // gestione pulsanti da interrupt************************************************************************************
  Ccheck = 0;
  Serial.println("punto5");
  uint8_t pin = mcp.getLastInterruptPin();
  uint8_t val = mcp.getLastInterruptPinValue();
  led_state[pin - 8] = ! led_state[pin - 8];
  if (led_state[pin - 8]) mcp.digitalWrite(pinLed[pin - 8], HIGH);
  else mcp.digitalWrite(pinLed[pin - 8], LOW);

  while (mcp.digitalRead(buttons[0]));
  Serial.println("puntoW1");
  while (mcp.digitalRead(buttons[1]));
  while (mcp.digitalRead(buttons[2]));
  while (mcp.digitalRead(buttons[3]));
  while (mcp.digitalRead(buttons[4]));
  while (mcp.digitalRead(buttons[5]));
  while (mcp.digitalRead(buttons[6]));
  while (mcp.digitalRead(buttons[7]));
  Serial.println("punto6");
  mcp.readGPIOAB();
  awakenByInterrupt = false;
  Serial.println("punto7");
  Ccheck = 1;
  Serial.print("awakenByInterrupt > "); Serial.println(awakenByInterrupt);
  Serial.println("------------------");
  Serial.print("buttons 1 > "); Serial.println(mcp.digitalRead(buttons[0]));
  Serial.print("buttons 2 > "); Serial.println(mcp.digitalRead(buttons[1]));
  Serial.print("buttons 3 > "); Serial.println(mcp.digitalRead(buttons[2]));
  Serial.print("buttons 4 > "); Serial.println(mcp.digitalRead(buttons[3]));
  Serial.print("buttons 5 > "); Serial.println(mcp.digitalRead(buttons[4]));
  Serial.print("buttons 6 > "); Serial.println(mcp.digitalRead(buttons[5]));
  Serial.print("buttons 7 > "); Serial.println(mcp.digitalRead(buttons[6]));
  Serial.print("buttons 8 > "); Serial.println(mcp.digitalRead(buttons[7]));
  Serial.print("IntPin > "); Serial.println(digitalRead(IntPin));
  Serial.print("val > "); Serial.println(digitalRead(val));
  Serial.println("------------------");
}




void loop() {

  if (awakenByInterrupt) handleInterrupt();
 
}

Re: problems with interrupts

Posted: Thu Jan 28, 2021 11:33 pm
by attila666
@ lbernstone
is correct what you say, even so without delay if you press not fast, it works, but I would like to understand how to optimize it :D

Re: problems with interrupts

Posted: Thu Jan 28, 2021 11:34 pm
by attila666
@Michalpu
I'm sorry I did not understand