Problem with interrupt inside a class

Hey everyone,

I am having an issue with my code. I'm not a programming nor C++ expert by any stretch of imagination so please be patient :smiley:

My goal is to create a class that can handle an interrupt on an Arduino Nano. By researching this on the internet, I found out, that I would need to create an interrupt handler as a static method of the class.

My main.cpp looks like this:

#include <Arduino.h>
#include "interruptClass.h"

static const int interrupt_pin = 2;

interruptClass myInterruptClass(interrupt_pin);

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println(myInterruptClass.getCounter());
}

My interruptClass header file looks like this:

#pragma once

#include <Arduino.h>

class interruptClass
{
    public:
        interruptClass(int interrupt_pin);
        unsigned long getCounter();
    private:
        static void interruptHandler();
        void increment();
        int m_interrupt_pin;
        volatile unsigned long m_counter = 0;
};

My interruptClass.cpp looks like this:

#include "interruptClass.h"

interruptClass::interruptClass(int interrupt_pin):
m_interrupt_pin(interrupt_pin)
{
    pinMode(m_interrupt_pin, INPUT);
    attachInterrupt(digitalPinToInterrupt(m_interrupt_pin), interruptClass::interruptHandler, RISING);
}

void interruptClass::interruptHandler()
{
    static interruptClass *instance = nullptr;
    if (instance)
    {
        instance->increment();
    }
}

void interruptClass::increment()
{
    m_counter++;
}

unsigned long interruptClass::getCounter()
{
    return m_counter;
}

However, the interrupt does not trigger. What am I doing wrong?

Thank you very much!

I not seen where you assign anything to your instance pointer.

You should not do hardware related stuff in your constructor. Add a begin method to the class where you set the pinMode and attach the interrupt.

@b707 How would I do it correctly? I have never before worked with something like this and the code from the interruptHandler is right out of ChatGPT :smiley:

@sterretje Thank you for your hint! I created a public begin function that is being called in the setup part of the main.cpp. However this didn't resolve the issue.

I would move the instanse variable to the class definition instead the method and add

instance = this;

to the constructor.

I added the following to the private members of the class:

static interruptClass *instance;

Then, I added the line

instance = this;

to the constructor in between the braces.

The content of the interruptHandler method is now reduced to:

instance->increment();

However, if I want to compile, I get the following error:

C:\Users\User\AppData\Local\Temp\ccbcijcg.ltrans0.ltrans.o: In function interruptClass::interruptHandler()': <artificial>:(.text+0x21e): undefined reference to interruptClass::instance'
:(.text+0x222): undefined reference to interruptClass::instance' C:\Users\User\AppData\Local\Temp\ccbcijcg.ltrans0.ltrans.o: In function global constructors keyed to 65535_0_interruptClass.cpp.o.1788':
:(.text.startup+0x6e): undefined reference to interruptClass::instance' <artificial>:(.text.startup+0x72): undefined reference to interruptClass::instance'
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\nanoatmega328\firmware.elf] Error 1

You need to start with the understanding that any code you get from ChatGPT (or instructables.com) is going to be crap.

For a more general method of handling interrupts in classes, see Post #44 in this Thread.

Why did you decided to make it private?

I followed this approach, which is pretty similar and now it works fine! Thank you guys very much for your help!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.