Interrupts call not working

Post here first, or if you can't find a relevant section!
Post Reply
vas_
Posts: 4
Joined: Mon Mar 07, 2022 3:53 pm

Interrupts call not working

Post by vas_ »

Hello all,

Could anyone explain me what's wrong with this code in a C++ library:

.h file

Code: Select all

class PSM
{
public:
    PSM(uint32_t sensePin, uint32_t mode = RISING);
    
    static void onInterrupt();
    
    unsigned int cps();
    
private:
	void calculateSkip();
    
	volatile unsigned int _a;
};
.cpp file

Code: Select all

static PSM * _thePSM;

PSM::PSM(uint32_t sensePin, uint32_t mode)
{
    _thePSM = this;

    pinMode(sensePin, INPUT_PULLUP);

    attachInterrupt(digitalPinToInterrupt(sensePin), onInterrupt, mode);
}

void PSM::onInterrupt(void)
{    
    _thePSM->calculateSkip();
}

void PSM::calculateSkip(void)
{
    PSM::_a++;
}

unsigned int PSM::cps()
{
    return PSM::_a
}
The point is obviously to count impulses on a sensePin.

This code works on AVR, but doesn't work on STM32F411.

attachInterrupt for the same pin and mode works if placed directly in .ino.

What could be wrong with the code? I'm not a C++ pro, maybe it's something obvious.
User avatar
fpiSTM
Posts: 1746
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: Interrupts call not working

Post by fpiSTM »

Code: Select all

static PSM * _thePSM;
You declare it as as pointer ?
vas_
Posts: 4
Joined: Mon Mar 07, 2022 3:53 pm

Re: Interrupts call not working

Post by vas_ »

Yes, it's a pointer.

I tried to rewrite it the following way but the static method still isn't called

Code: Select all

extern "C" {
void _onInterrupt(void)
{    
    digitalWrite(PC13, LOW);
    //_thePSM->calculateSkip();
}
}

PSM::PSM(uint32_t sensePin, uint32_t mode)
{
    _thePSM = this;

    pinMode(sensePin, INPUT_PULLUP);

    attachInterrupt(digitalPinToInterrupt(sensePin), _onInterrupt, mode);
}
ag123
Posts: 1657
Joined: Thu Dec 19, 2019 5:30 am
Answers: 25

Re: Interrupts call not working

Post by ag123 »

you need

Code: Select all

static PSM g_PSM(pin, mode);
you can omit 'static' if this is a global variable after all.
vas_
Posts: 4
Joined: Mon Mar 07, 2022 3:53 pm

Re: Interrupts call not working

Post by vas_ »

This will effectively make the class static, right? So there will be only one instance possible.
vas_
Posts: 4
Joined: Mon Mar 07, 2022 3:53 pm

Re: Interrupts call not working

Post by vas_ »

UPDATE: The original piece of code works in PlatformIO. Looks like Arduino IDE is a problem here.
davetcc
Posts: 2
Joined: Thu Feb 17, 2022 9:11 am

Re: Interrupts call not working

Post by davetcc »

EDIT - I've gone in a lot more depth now, and evaluated all the libraries that are even potentially included, even if not used. I found that the major difference between the two is the inclusion of stm32duino/STM32Duino FreeRTOS. As soon as I remove this dependency it starts working. I assume it is the overriding of the new operator that is not working because this particular test sketch did not initialize free rtos, even though it was on the build path.

----

I've been trying to track down a very strange issue in attachInterrupt, so strange that I didn't even want to post it until I could reliably recreate it. It seems that in some conditions attachInterrupt does not register and it seems to matter that other classes are present in the sketch. It seems very localized to the build environment. I am also a platformIO user, and have one project where this is a problem, one where it is not.

Problem is, I cannot fully isolate it. I post the code below as the closest I have got to isolating, but I have to say, it does not reliably recreate the issue, it may be there is a particular configuration of compiler / settings that creates this problem. But I can't understand how more people would not have seen this?

Unless you think there's some benefit in investigating further I was going to delete the faulty project and configuration and just start over in the working project (and hope it doesn't come back).

Code: Select all

/**
 * My environment is platformIO (CLion IDE), I've tried this on various versions of the Stm32Duino platform back to 
 * about a year ago. In one project it reliably fails, in the other it works perfectly.
 * 
 * Unfortunately, I cannot run the sketch in Arduino as I'd have to add the board I'm using to the boards file there.
 * I know the board is working properly when the marked line below is commented out.
 *
 */

#include <Arduino.h>

// First we create an interface that we will use later - to create a virtual table.
class MyAbstraction {
public:
    virtual void pinDirection(uint8_t pin, uint8_t mode)=0;
};

// Then we create the implementation that has the pinDirection method implementation.
class MyAbstractionImpl : public MyAbstraction {
public:
    void pinDirection(uint8_t pin, uint8_t mode) override {
        pinMode(pin, mode);
    }
};

volatile int counter;

void interruptCallback() {
    // in the interrupt we just increment the counter
    counter++;
}

void setup() {
    // commenting out this line makes the sketch work in the environment that fails.
    auto* digitalIo = new MyAbstractionImpl();
    Serial.begin(115200);

    pinMode(PC8, INPUT_PULLUP);

    // here we register the interrupt
    ::attachInterrupt(digitalPinToInterrupt(PC8), interruptCallback, CHANGE);
}

void loop() {
    // we just print out the contents of the counter every second.
    Serial.print("Counter is ");
    Serial.println(counter);
    delay(1000);
}
Post Reply

Return to “General discussion”