0

Greeting! I am finding it difficult setting up a pin change interrupt on an arm board ( I am using Arduino due). I found a sample online which I have used but I discovered that when ever an interrupt occurs on a particular pin, it tends to pick up noise from other pins (i.e it prints the state of other pins which didn't get an interrupt) even after appropriate de-bouncing of the signal. For that reason it is quite difficult to carry out appropriate decision with the result am getting. Please I need a code example on how to set of pin change interrupt on Arduino Due for me to continue with my final year project. its very urgent, thanks in anticipation. Code as Follows:

#include <ArduinoJson.h>
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>

#define DEBOUNCE_TIME 50L

#define interruptPin3 3 
//#define interruptPin4 4 

byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(172, 168, 1, XXX);
IPAddress server(172, 168, 1, XXX);

EthernetClient ethClient;
PubSubClient mqttClient(ethClient);

char data2[700];
void reconnect() {
  // Loop until we're reconnected
    while (!mqttClient.connected()) 
    {
   SerialUSB.println("Attempting MQTT connection...");

    if (mqttClient.connect("arduinoClient")) {
       SerialUSB.println("Now connected!");    
    } else {
      SerialUSB.println("Failed! Please wait for reconnection ...");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

//ISR Flags
volatile bool ISR_DEACTIVATED = false;
volatile bool display_int_time = false;

bool debounce_started = false;
unsigned long Isr_debounce_pin_timer;

volatile bool initializationFlag = false;
volatile bool pinVoltStatus = HIGH;
volatile bool lastVoltStatus=LOW;
String pinStatusValue="HIGH";

volatile int interruptPinDigitalPin;

void PinsInitialization() {

  pinMode(interruptPin3, INPUT);
  attachInterrupt(digitalPinToInterrupt(interruptPin3), Pin3ChangeInterrupt, CHANGE); 
}

void setup() 
{
  SerialUSB.begin(9600);
  while (!SerialUSB) continue;
  mqttClient.setServer(server, 11883);

  Ethernet.begin(mac, ip);
  // Allow the hardware to sort itself out
  delay(1500);
  reconnect();

  ISR_DEACTIVATED = false;
  display_int_time = false;
  initializationFlag = false;

  PinsInitialization();
}

void getPinStatus()
{
   bool pinStatus;
    pinStatus = digitalRead(interruptPinDigitalPin);
    if(pinStatus == LOW)
    {
      pinStatusValue = "LOW";
      pinVoltStatus = LOW;
    }else{
      pinStatusValue = "HIGH";
      pinVoltStatus = HIGH;
    }
}

void Pin3ChangeInterrupt() 
{
  if(!ISR_DEACTIVATED)
  {
    interruptPinDigitalPin = interruptPin3;
    ISR_DEACTIVATED = true;
    display_int_time = true;
  }
}

//Returns TRUE if pin is stable at desired state, FALSE if bouncing or other state
bool debounce(const int debounce_pin, const bool state, unsigned long &state_latch_start) 
{
  static bool current_state;

  // Read the required pin
  current_state = digitalRead(interruptPinDigitalPin);

  if ((!debounce_started) && (current_state == state)) {

      state_latch_start = millis();
      debounce_started = true;
  }


  if (debounce_started && (current_state != state))

      debounce_started = false;

  if (debounce_started && (current_state == state) && (((unsigned long)(millis() - state_latch_start)) >= DEBOUNCE_TIME)) 
  {
    debounce_started = false;
    // report back that all is goood.
    return(true);
  }

  //Either the pin is at the wrong level, or is still bouncing. Try again later!
  return(false);
}


void messageToPublish(String digitalPinNumber, String voltageStatus)
{
  StaticJsonDocument<200> doc;

    doc["digitalPin"] = digitalPinNumber;
    doc["voltStatus"] = voltageStatus;

    String payload = doc.as<String>();
    payload.toCharArray(data2, (payload.length() + 1));
    mqttClient.publish("interruptTopic", data2);
    SerialUSB.println((String)digitalPinNumber+ ":"+(String) voltageStatus);
}

void loop() 
{
  //This runs every time an interrupt occurs
  if (display_int_time) 
  {  
    detachInterrupt(interruptPinDigitalPin);
    //Done with interrupt stuff. Clear the interrupt flag
    getPinStatus();
  }

   //Debounce for the ISR routine in main loop
    if (ISR_DEACTIVATED)
    {//Wait until the pin settles LOW to reactivate the ISR
      bool debounceStatus = debounce(interruptPinDigitalPin, pinVoltStatus, Isr_debounce_pin_timer);
      if(debounceStatus)
      {  
        if (initializationFlag == false)
        {
          ISR_DEACTIVATED = false;
          initializationFlag = true;
        }else
        {

           if(interruptPinDigitalPin == interruptPin3)
          {
            attachInterrupt(digitalPinToInterrupt(interruptPin3), Pin3ChangeInterrupt, CHANGE);
            messageToPublish("Pin3", pinStatusValue);
          } 
          display_int_time = false;
          ISR_DEACTIVATED = false;
        }
      }

    }
}
  • I haven't worked with the Due yet, but on other Arduinos you can deactivate the pin change interrupt for the pins, that you don't need, by setting a mask register. Please post the code, that is showing this problem – chrisl Sep 22 at 20:41
  • @chrisl Thanks alot for your prompt response, am actually just a beginner with arduino and programming at large. Here is the updated question with my code attached – Justus Blaise Sep 23 at 12:00
  • @chrisl can you kindly share a code example on how to achieve that on other arduino boards (AVR am guessing). – Justus Blaise Sep 27 at 10:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.