Interrupts: Converting from Arduino to Particle Photon

Hi! I’m new to the Particle boards and am also new to learning interrupts.
I’m trying to get some code to work that will toggle the D7 LED (as an interrupt) on and off when I toggle a Relay. My Photon is connected to the relay board.
I’m able to toggle the relays and LEDs just fine … but when I try to use interrupts to do this, I get an issue.
Can I get some help?

/*Testing Interrupts on Particle Boards

 * this is just to test out the different ways to do 
 * interrupts with the particle board/ IDE

int i = 0;

int relay4 = D6; // controlling relay 4
int led7 = D7; // status LED

int led7Toggle(String command) {
    * just like the example ... but unused unless we go to the event page to reset LED7 back to LOW
    if (command=="on") {
        return 1;
    else if (command=="off") {
        return 0;
    else {
        return -1;
} //int led7Toggle(String command)
int relay4Toggle(String command) {
    if (command=="open") {
        return 1;
    else if (command=="closed") {
        return 0;
    else {
        return -1;
} //int relay4Toggle(String command)

void setup()
    pinMode(relay4, OUTPUT);
    pinMode(led7, OUTPUT);
    int relay4Toggle(String command);
    attachInterrupt(relay4,relay4Toggle,RISING);  //  function for creating external interrupts at pin6 on Rising (LOW to HIGH)
    int ledToggle(String command);
    Particle.function("relay4Toggle", relay4Toggle);

    digitalWrite(led7, LOW);   //LED 7 OFF
    digitalWrite(relay4, LOW); //Relay OPEN


} //void setup()

void loop()
    //Particle.publish("Count: d%", i, PRIVATE);
} //void loop()

The error I’m getting says

63:47: no matching function for call to 'attachInterrupt(int&, int (&)(String), InterruptMode)'


test_interrupts_d7.ino:63:47: invalid conversion from 'int (*)(String)' to 'raw_interrupt_handler_t {aka void (*)()}' [-fpermissive] '

The function “relay4Toggle” is there … and I thought I had the syntax right for the attachInterrupt statement.

(thank you)

Usually the first place to consult would be the reference docs

Your relay4Toggle does not fit that description.
But that is also the case for Arduino - you couldn’t do that there either.

That’s also what the error message means

no matching function for call to 'attachInterrupt(int&, int (&)(String), InterruptMode)'

In verbal language this would read as: “There is no version of attachInterrupt() that would take a reference of a function that takes a String and returns an int as second parameter but that’s what you provide.”

The second message

invalid conversion from 'int (*)(String)' to 'raw_interrupt_handler_t {aka void (*)()}'

clarifies that further
“You are trying to provide a function pointer to a function taking a String and returning an int where an ISR is expected which should rahter be a function pointer to a function that takes nothing (()) and returns nothing (void).”

A valid ISR would look like this

void r4Toggle() {
  digitalWrite(relay4, !digitalRead(relay4));

You also have int relay4Toggle(String command); and int ledToggle(String command); inside of setup() that’s also not valid there.

thanks! that makes a lot of sense …

as far as that goes though … if I’m trying to use these functions like in this example where they can be toggled from the WebUI/ Tinker how would I modify them?

ie, I’d like to toggle a relay using the UI/ Tinker. I am also going to be counting up (variable i, i++) … when I toggle a relay, that will trip an interrupt/ ISR that toggles LED7/ D7.
that bit, combining the example with the function that takes a String argument and returns an int, I haven’t quite been able to wrap my head around.

Yeah. I realize this is a bit convoluted … but I’m trying to figure out interrupts and work with the hardware I have on hand. :slight_smile:

May I ask why you want that done via interrupts?
It’s nothing time critical AFAICT but that usually is the reason for opting for interrupts.

However, if you only want to toggle a pin whenever you get a interrupt trigger, the ISR I provided above does exactly that.
When you want to add the counting bit to that it the ISR would look like this

const    int pin2Toggle = D7;
volatile uint32_t count = 0;
void toggleAndCount() {
  digitalWrite(pin2Toggle, !digitalRead(pin2Toggle));

Besides learning interrupts? :smiley:

What I’m actually trying to do is set this board up so that I can run a looooong delay but the process be stopped by the ISR.
Process is a ~8hour long thing … where the relay switches open, then closed over the course of that time several times.
Buuuuut, i’d like to be able to monitor (and stop) things during that time.
Screwing around a little, I noticed that I couldn’t immediately stop the routine if I just had the functions … so. Interrupts. At least that’s what I’m thinking is the right way to go.

While learning things (including interrupts) is a good reason for everything, learning when to use what is most suitable is a big lesson too :wink:

For what you describe I’d rather think of FSM where one of the finite states does the waiting and another does the work and each state monitors its input conditions for the transitions to the respective states that can potentially follow from there.

Typically delays of any kind should be considered last resort when nothing else would work (or you can accept unresponsiveness).

But for mission critical uses (e.g. emergency stop) and interrupt would be well warranted.

Do you have a link to an example?
Sounds like that may work best.

Do you mean an example for FSM?

(especially the last post that links to a Hackster article)

If you mean interrupt, then I have given you an example for a toggle and count ISR.

FSM example

Thank you!

If you mean interrupt, then I have given you an example for a toggle and count ISR.

Yes please!

Hey Joe!
I wrote that hackster article about FSMs and ported one FSM lib into Particle libs. I’m a huge fan of FSMs.

FSMs can be a bit intimidating at first but once you get the hang of it you’ll wonder how you lived without them.
Most important will be to draw in a paper (or napkin) what is goal of your firmware, assign bubbles or states to them and implement in code.
If you have questions let me know (perhaps create a new topic).

Good luck!