AttachedInterrupt() related questions

Hi,

I am using digital pin 2&3 of Arduino Uno as my interrupts.
I have externally pull up this two pins. So when button pressed, they will become LOW.
When the pin 2 or 3 is low, Arduino will so something. Else when no interrupt(no button pressed), it will do something else by default.

My problem is, the interrupt doesn’t works at all when my button is pressed. Arduino keep looping at the main default loop even the button was pressed(or interrupt happenned).

Below is my full code:

#include <CytronWiFiShield.h>
#include <CytronWiFiClient.h>
#include <CytronWiFiServer.h>
#include <SoftwareSerial.h>

const char *ssid = "TDE Office";
const char *pass = "tde257a698n";
IPAddress ip(192, 168, 1 ,242);
ESP8266Server server(80);
ESP8266Client client;
const byte ledPin1 = 5;
const byte ledPin2 = 6;
const byte interruptPin1 = 2;
const byte interruptPin2 = 3;

//ip wifi
const char destServer[] = "192.168.1.69";
char httpRequest = "";
String buttonstate;
const char htmlHeader[] = "HTTP/1.1 200 OK\r\n"
                        "Content-Type: text/html\r\n"
                        "Connection: close\r\n\r\n"
                        "<!DOCTYPE HTML>\r\n"
                        "<html>\r\n";
                          
void setup() {
  
  // put your setup code here, to run once:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
 
  if(!wifi.begin(10, 11))
  {
    Serial.println(F("Error talking to shield"));
    while(1);
  }
  Serial.println(wifi.firmwareVersion());
  Serial.print(F("Mode: "));Serial.println(wifi.getMode());// 1- station mode, 2- softap mode, 3- both
  Serial.println(F("Setup wifi config"));
  wifi.config(ip);
  Serial.println(F("Start wifi connection"));
  if(!wifi.connectAP(ssid, pass))
  {
    Serial.println(F("Error connecting to WiFi"));
    while(1);
  } 
  Serial.print(F("Connected to "));
  Serial.println(wifi.SSID());
  Serial.println(F("IP address: "));
  Serial.println(wifi.localIP());
  wifi.updateStatus();
  Serial.println(wifi.status()); //2- wifi connected with ip, 3- got connection with servers or clients, 4- disconnect with clients or servers, 5- no wifi
  espblink(100);
  server.begin();
  
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  digitalWrite(ledPin1, LOW);
  digitalWrite(ledPin2, LOW);
  pinMode(interruptPin1, INPUT);
  pinMode(interruptPin2, INPUT);
  attachInterrupt(digitalPinToInterrupt(interruptPin1), station1, FALLING);
  attachInterrupt(digitalPinToInterrupt(interruptPin2), station2, FALLING);

//LED indicator to notify operator button successfully pressed
 pinMode(14, OUTPUT);
 pinMode(15, OUTPUT);

}

void loop() {
//when no button was pressed, meaning no interrupt

httpRequest = '/';

if (!client.connect(destServer, 81))
  {
    Serial.println(F("Failed to connect to server."));
    client.stop();
    return;
  }
                              
  if(!client.print(httpRequest))
  {
    Serial.println(F("Sending failed"));
    client.stop();
    return;;
  }

  // set timeout approximately 5s for server reply
  int i=10000;
  while (client.available()<=0&&i--)
  {
    delay(1);
    if(i==1) {
      Serial.println(F("Timeout"));
      return;
      }
  }

  while (client.available()>0 && (httpRequest='/'))
  {
    char c = client.read();
    if(c == 'x') {   
      break;
    }
    
    buttonstate += c;
  }
  
  if(buttonstate.length()>0){
    Serial.println(buttonstate);

    if(buttonstate.indexOf("OFF2")>=0){
      digitalWrite(6, LOW);        
    } 

    if(buttonstate.indexOf("OFF1")>=0){
      digitalWrite(5, LOW); 
    }

    if(buttonstate.indexOf("ON1")>=0){
      digitalWrite(5, HIGH); 
    }

    if(buttonstate.indexOf("ON2")>=0){
      digitalWrite(6, HIGH);  
    }

    buttonstate = "";   
    digitalWrite(14, LOW);
    digitalWrite(15, LOW);
  }
  
  client.stop();    
}



//station1
void station1() {

  httpRequest = '?';
  digitalWrite(14, HIGH);
  
if (!client.connect(destServer, 81))
  {
    Serial.println(F("Failed to connect to server."));
    client.stop();
    return;
  }
                              
  if(!client.print(httpRequest))
  {
    Serial.println(F("Sending failed"));
    client.stop();
    return;;
  }

  // set timeout approximately 5s for server reply
  int i=10000;
  while (client.available()<=0&&i--)
  {
    delay(1);
    if(i==1) {
      Serial.println(F("Timeout"));
      return;
      }
  }

  while (client.available()>0 && (httpRequest='?'))
  {
    char c = client.read();
    if(c == 'x') {   
      break;
    }
    
    buttonstate += c;
  }
  
  if(buttonstate.length()>0){
    Serial.println(buttonstate);

    if(buttonstate.indexOf("ON")>=0){
      digitalWrite(5, HIGH);   
      buttonstate = "";  
    } 
  }
  
  client.stop();   
} 


//station2
void station2() {

  httpRequest = ';';
  digitalWrite(15, HIGH);
  
if (!client.connect(destServer, 81))
  {
    Serial.println(F("Failed to connect to server."));
    client.stop();
    return;
  }
                              
  if(!client.print(httpRequest))
  {
    Serial.println(F("Sending failed"));
    client.stop();
    return;;
  }

  // set timeout approximately 5s for server reply
  int i=10000;
  while (client.available()<=0&&i--)
  {
    delay(1);
    if(i==1) {
      Serial.println(F("Timeout"));
      return;
      }
  }

  while (client.available()>0 && (httpRequest=';'))
  {
    char c = client.read();
    if(c == 'x') {   
      break;
    }
    
    buttonstate += c;
  }
  
  if(buttonstate.length()>0){
    Serial.println(buttonstate);

    if(buttonstate.indexOf("ON2")>=0){
      digitalWrite(6, HIGH);   
      buttonstate = "";  
    } 
  }
  
  client.stop();   
}


void espblink(int time)
{
  for(int i = 0;i<12;i++)
  {
    wifi.digitalWrite(2,wifi.digitalRead(2)^1);
    delay(time);
  }
}

Can anyone please advise on this? Thank you.

Those ISRs are way too long and slow and they call code that won't work in an interrupt. Button presses are slow slow things. You don't need an interrupt for that. But if you insist, then just let the ISR set a flag and let loop respond to that with the code you have in the ISR now.

Delta_G:
Those ISRs are way too long and slow and they call code that won’t work in an interrupt. Button presses are slow slow things. You don’t need an interrupt for that. But if you insist, then just let the ISR set a flag and let loop respond to that with the code you have in the ISR now.

Hi Delta_G,

I used timer for my application before i consider to use interrupt. However it takes too long to response. Timer couldn’t give immediate response once the button is pressed. (My button is momentary button)
Below is my code with timer:

void setup() {
  
  pinMode(8, INPUT);
  pinMode(9, INPUT);
  pinMode(10, INPUT);
  //LED indicator to notify operator button successfully pressed
  pinMode(14, OUTPUT);
  pinMode(15, OUTPUT);
  pinMode(16, OUTPUT);
  //Pin 5&6 control relay to on/off tower light 1&2
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  
  digitalWrite(14, LOW);
  digitalWrite(15, LOW);
  digitalWrite(16, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
}

void loop() {

//if Start1 Buttton were pressed, send "?" to LabVIEW
if (digitalRead(8) == LOW) {

  httpRequest = '?';
  digitalWrite(14, HIGH);
  
if (!client.connect(destServer, 81))
  {
    Serial.println(F("Failed to connect to server."));
    client.stop();
    return;
  }
                              
  if(!client.print(httpRequest))
  {
    Serial.println(F("Sending failed"));
    client.stop();
    return;;
  }

  // set timeout approximately 5s for server reply
  int i=10000;
  while (client.available()<=0&&i--)
  {
    delay(1);
    if(i==1) {
      Serial.println(F("Timeout"));
      return;
      }
  }

  while (client.available()>0 && (httpRequest='?'))
  {
    char c = client.read();
    if(c == 'x') {   
      break;
    }
    
    buttonstate += c;
  }
  
  if(buttonstate.length()>0){
    Serial.println(buttonstate);

    if(buttonstate.indexOf("ON")>=0){
      digitalWrite(5, HIGH);   
      buttonstate = "";  
    } 
  }
  
  client.stop();   
} 

//if Start1 Buttton2 were pressed, send ";" to LabVIEW
else if (digitalRead(9) == LOW) {

  httpRequest = ';';
  digitalWrite(15, HIGH);
  
if (!client.connect(destServer, 81))
  {
    Serial.println(F("Failed to connect to server."));
    client.stop();
    return;
  }
                              
  if(!client.print(httpRequest))
  {
    Serial.println(F("Sending failed"));
    client.stop();
    return;;
  }

  // set timeout approximately 5s for server reply
  int i=10000;
  while (client.available()<=0&&i--)
  {
    delay(1);
    if(i==1) {
      Serial.println(F("Timeout"));
      return;
      }
  }

  while (client.available()>0 && (httpRequest='?'))
  {
    char c = client.read();
    if(c == 'x') {   
      break;
    }
    
    buttonstate += c;
  }
  
  if(buttonstate.length()>0){
    Serial.println(buttonstate);

    if(buttonstate.indexOf("ON2")>=0){
      digitalWrite(6, HIGH);   
      buttonstate = "";  
    } 
  }
  
  client.stop();   
}

//to turn LED off
else if (digitalRead(8) && digitalRead(9) == HIGH) {
  timer.run();
}
}   

void espblink(int time)
{
  for(int i = 0;i<12;i++)
  {
    wifi.digitalWrite(2,wifi.digitalRead(2)^1);
    delay(time);
  }
}


//timer
void repeatMe() {
  //if Reset Button were pressed, send "/" to LabVIEW

   httpRequest = '/';

if (!client.connect(destServer, 81))
  {
    Serial.println(F("Failed to connect to server."));
    client.stop();
    return;
  }
                              
  if(!client.print(httpRequest))
  {
    Serial.println(F("Sending failed"));
    client.stop();
    return;;
  }

  // set timeout approximately 5s for server reply
  int i=10000;
  while (client.available()<=0&&i--)
  {
    delay(1);
    if(i==1) {
      Serial.println(F("Timeout"));
      return;
      }
  }

  while (client.available()>0 && (httpRequest='/'))
  {
    char c = client.read();
    if(c == 'x') {   
      break;
    }
    
    buttonstate += c;
  }
  
  if(buttonstate.length()>0){
    Serial.println(buttonstate);

    if(buttonstate.indexOf("OFF2")>=0){
      digitalWrite(6, LOW);        
      //buttonstate = "";  
    } 

    if(buttonstate.indexOf("OFF1")>=0){
      digitalWrite(5, LOW); 
      //buttonstate = "";   
    }

    if(buttonstate.indexOf("ON1")>=0){
      digitalWrite(5, HIGH); 
      //buttonstate = "";   
    }

    if(buttonstate.indexOf("ON2")>=0){
      digitalWrite(6, HIGH); 
      //buttonstate = "";   
    }

    buttonstate = "";   
    digitalWrite(14, LOW);
    digitalWrite(15, LOW);
  }
  
  client.stop();    
}

Other than that, i have modified my code using flag but it doesn’t works too. Could you please see what’s wrong with my sketch?

void setup() {
  
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  digitalWrite(ledPin1, LOW);
  digitalWrite(ledPin2, LOW);
  pinMode(interruptPin1, INPUT);
  pinMode(interruptPin2, INPUT);
  attachInterrupt(digitalPinToInterrupt(interruptPin1), station1, LOW);
  attachInterrupt(digitalPinToInterrupt(interruptPin2), station2, LOW);

//LED indicator to notify operator button successfully pressed
 pinMode(14, OUTPUT);
 pinMode(15, OUTPUT);
 flag1 = 0;
 flag2 = 0;
}

void loop() {
//when no button was pressed, meaning no interrupt

if ((flag1 = 0)&&(flag2 = 0)) {
httpRequest = '/';

if (!client.connect(destServer, 82))
  {
    Serial.println(F("Failed to connect to server."));
    client.stop();
    return;
  }
                              
  if(!client.print(httpRequest))
  {
    Serial.println(F("Sending failed"));
    client.stop();
    return;;
  }

  // set timeout approximately 5s for server reply
  int i=10000;
  while (client.available()<=0&&i--)
  {
    delay(1);
    if(i==1) {
      Serial.println(F("Timeout"));
      return;
      }
  }

  while (client.available()>0 && (httpRequest='/'))
  {
    char c = client.read();
    if(c == 'x') {   
      break;
    }
    
    buttonstate += c;
  }
  
  if(buttonstate.length()>0){
    Serial.println(buttonstate);

    if(buttonstate.indexOf("OFF2")>=0){
      digitalWrite(6, LOW);        
    } 

    if(buttonstate.indexOf("OFF1")>=0){
      digitalWrite(5, LOW); 
    }

    if(buttonstate.indexOf("ON1")>=0){
      digitalWrite(5, HIGH); 
    }

    if(buttonstate.indexOf("ON2")>=0){
      digitalWrite(6, HIGH);  
    }

    buttonstate = "";   
    digitalWrite(14, LOW);
    digitalWrite(15, LOW);
  }
  
  client.stop();    
}


if (flag1 = 1) {
  
httpRequest = '?';

  digitalWrite(14, HIGH);
  
if (!client.connect(destServer, 82))
  {
    Serial.println(F("Failed to connect to server."));
    client.stop();
    return;
  }
                              
  if(!client.print(httpRequest))
  {
    Serial.println(F("Sending failed"));
    client.stop();
    return;;
  }

  // set timeout approximately 5s for server reply
  int i=10000;
  while (client.available()<=0&&i--)
  {
    delay(1);
    if(i==1) {
      Serial.println(F("Timeout"));
      return;
      }
  }

  while (client.available()>0 && (httpRequest='?'))
  {
    char c = client.read();
    if(c == 'x') {   
      break;
    }
    
    buttonstate += c;
  }
  
  if(buttonstate.length()>0){
    Serial.println(buttonstate);

    if(buttonstate.indexOf("ON")>=0){
      digitalWrite(5, HIGH);   
      buttonstate = "";  
    } 
  }
  flag1 = 0;
  client.stop();     
}


if (flag2 = 1) {
 httpRequest = ';';
  digitalWrite(15, HIGH);
  
if (!client.connect(destServer, 81))
  {
    Serial.println(F("Failed to connect to server."));
    client.stop();
    return;
  }
                              
  if(!client.print(httpRequest))
  {
    Serial.println(F("Sending failed"));
    client.stop();
    return;;
  }

  // set timeout approximately 5s for server reply
  int i=10000;
  while (client.available()<=0&&i--)
  {
    delay(1);
    if(i==1) {
      Serial.println(F("Timeout"));
      return;
      }
  }

  while (client.available()>0 && (httpRequest=';'))
  {
    char c = client.read();
    if(c == 'x') {   
      break;
    }
    
    buttonstate += c;
  }
  
  if(buttonstate.length()>0){
    Serial.println(buttonstate);

    if(buttonstate.indexOf("ON2")>=0){
      digitalWrite(6, HIGH);   
      buttonstate = "";  
    } 
  }
  
  client.stop();  
  flag2 = 0; 
}
}


//station1
void station1() {
flag1 = 1;
} 

//station2
void station2() {
flag2 = 1; 
}

The basic rules are don't call delay() in an interrupt, don't call Serial functions in an interrupt, both will cause the system to hang waiting for interrupts that are masked off.

In general if you spend longer than a few 100 microseconds in an ISR, you are mis-using them.

If all you need to do is detect a human pressing a button there is no need for interrupts or hardware timers. Have a look at the demo Several Things at a Time

  • what @MarkT has said.

...R

i have modified my code using flag but it doesn't works too. Could you please see what's wrong with my sketch?

if ((flag1 = 0)&&(flag2 = 0))
if (flag1 = 1) 
if (flag2 = 1)

== for comparison.

MarkT: The basic rules are don't call delay() in an interrupt, don't call Serial functions in an interrupt, both will cause the system to hang waiting for interrupts that are masked off.

In general if you spend longer than a few 100 microseconds in an ISR, you are mis-using them.

Hi MarkT,

Thanks for the remind. I will modify my sketch. I am sorry because i am still new in programming. Again, thanks so much.

cattledog: if ((flag1 = 0)&&(flag2 = 0)) if (flag1 = 1) if (flag2 = 1)

== for comparison.

Hi cattledog,

Oh ya thanks for pointing out my mistake :)