-1

I have been trying for days to get this code to work, but I cannot find a solution. Can anyone please help me find what I am missing here?

My sketch:

#include <ControlInterrupt.h>

const int commonPin = 2;
const int buttonPins[] = {4,5,6,7,8};

ControlInterrupt controlInterrupt(commonPin, buttonPins);

void setup() {
  // put your setup code here, to run once:
  controlInterrupt.configureCommon(); // Setup pins for  interrupt
  attachInterrupt(digitalPinToInterrupt(commonPin), controlInterrupt.pressInterrupt, FALLING);
  controlInterrupt.begin();
}

void loop() {
  // Empty
}

.h

/*
  ControlInterrupt.h - A library for handling multiple buttons using a single interrupt.
                       This is done by using an interrupt pin effectively as the ground,
                       eliminating the need for additional components.
  Authors: Svizel_pritula 05/05/2019
           TheCodeGeek 01/13/2024
*/
#ifndef ControlInterrupt_h
#define ControlInterrupt_h
#include <Arduino.h>
class ControlInterrupt
{
public:
  ControlInterrupt(int commonPin, int buttonPins[]);
  void begin();
  void pressInterrupt();
  void configureCommon();
  void configureDistinct();
  //void getCommand(int button);

private:
  int _commonPin;
  //int _arrLength;
  int _buttonPins[];
};
#endif

.cpp

/*
  ControlInterrupt.h - A library for handling multiple buttons using a single interrupt.
                       This is done by using an interrupt pin effectively as the ground,
                       eliminating the need for additional components.
  Authors: Svizel_pritula 05/05/2019
           TheCodeGeek 01/13/2024
*/
#include <Arduino.h>
#include <ControlInterrupt.h>

unsigned long lastFire;

ControlInterrupt::ControlInterrupt(int commonPin, int buttonPins[])
//, String commandOrder[]
{
  _commonPin = commonPin;
  _arrLength = sizeof(buttonPins);
  _buttonPins[arrLength] = buttonPins;
  //_commandOrder[arrLength] = commandOrder;

  lastFire = 0;
}


void ControlInterrupt::begin()
{
  Serial.begin(9600);
}

void ControlInterrupt::pressInterrupt()
{ // ISR
  if (millis() - lastFire < 200)
  { // Debounce
    return;
  }
  lastFire = millis();

  configureDistinct(); // Setup  pins for testing individual buttons

  for (int i = 0; i < (sizeof(buttonPins)/sizeof(int)); i++)
  { // Test each button for press
    if (!digitalRead(_buttonPins[i]))
    {
      getCommand(i);
    }
  }

  configureCommon(); // Return to original  state
}

void ControlInterrupt::configureCommon()
{
  pinMode(_commonPin, INPUT_PULLUP);

  for (int i = 0; i < (sizeof(buttonPins)/sizeof(int)); i++)
  {
    pinMode(_buttonPins[i], OUTPUT);
    digitalWrite(_buttonPins[i], LOW);
  }
}

void ControlInterrupt::configureDistinct()
{
  pinMode(_commonPin, OUTPUT);
  digitalWrite(_commonPin, LOW);

  for (int i = 0; i < (sizeof(buttonPins)/sizeof(int)); i++)
  {
    pinMode(_buttonPins[i], INPUT_PULLUP);
  }
}

void ControlInterrupt::getCommand(int button)
//String ControlInterrupt::getCommand(int button)
{               // Our handler
  String label; // This stores the string to print when controls are used

  Serial.print(button + 1);
  Serial.print(": ");
  switch (button)
  {
  case 0:
    // statement
    label = "UP";
    break;
  case 1:
    // statement
    label = "DOWN";
    break;
  case 2:
    // statement
    label = "CLEAR";
    break;
  case 3:
    // statement
    label = "BACK";
    break;
  case 4:
    // statement
    label = "LEFT";
    break;
  case 5:
    // statement
    label = "ENTER";
    break;
  case 6:
    // statement
    label = "RIGHT";
    break;
  default:
    // statement
    break;
  }
  Serial.print(label);
  //return label;
}
2

2 Answers 2

0

The solution is covered in my post here.

However, to avoid link-only answers, the brief explanation is that a class method has a hidden argument "this" which refers to the instance of the class. In your case the instance is controlInterrupt.

If you are only ever going to have one instance of the class you could replace it with a namespace. Otherwise, make yourself a glue routine as described in that post.

0

Member functions (here pressInterrupt) in C++ are special. You cannot use them where normal function is required (atrachInterruot). For explanations refer to any good book on C++.

In this particular case, just strip all C++ specific constructs off. They make your code neither shorter nor understandable. All the data for ISR is global anyway.

2
  • Hi Matt, could you please explain what you mean by "just strip all C++ specific constructs off"? Commented Jan 19 at 22:05
  • @TheCodeGeek Don't use class at all. As an it pro you should be able to figure out how to rewrite the code in plain C, aren't you?
    – Matt
    Commented Jan 20 at 2:56

Not the answer you're looking for? Browse other questions tagged or ask your own question.