0

I'm trying to solve a nagging issue with external interrupts - this is for a slot car track lap count controller. It uses the Mega's 6 external interrupt lines connected to photo diodes. The HW itself works fine - yes, trust me, it's fantastic.

I have observed the following. The code in the loop() is surrounded with:

detachAllInterrupts();
delay(10);
...
... process any interrupts and/or button presses
...
delay(10);
attachAllInterrupts();

If I omit or reduce the delay amount the random firing gets worse.

The ISR is lean and mean:

void lapDetected1() {
  lane1.lapDetected();
}

calling the method of class Lane:

    void lapDetected() { // called by ISR, short and sweet
      now = millis();
      if ((now - finish) < laneProtectionTime) {
        return;
      }
      start = finish;
      finish = now;
      count++;
      reported = false;
    }

all the variables used are declared volatile.

I don't like to use delay and I'm seeking advice on how to correctly implement ISRs and their handling.

here's the link to the entire code on GitHub: https://github.com/gabe2001/PCLapCounterWithArduino/

Thanks for any advice I can get here! -gabe

  • Not related with your problem - but it'd be way shorter with arrays and for each loops. Like for (auto & lane : lanes) lane.reset(); and so on... – KIIV Mar 3 '17 at 20:22
  • Wow. You will need to provide something more. When I opened the github space, I only found some hardware diagram of the wiring. Therefore. Please provide the full code here in Stacktrace, or, in a form where I would not have to sit and guess where you have stuffed the code :-)... I am very experienced in interrupt softwares and such stuff, so I guess that I can help you if you provide me with the complete code you have and explain why it is like it is. FIRST of all, I would guess that you have hardware noise. You could decouple that one nicely, however, you would then first have to provide a d – David Svarrer May 27 '17 at 21:49
  • Continuing David's comment: iagram for me, not a hardwire-picture like the one on GITHUB. We electronic engineers use diagrams and then I can tell you what you may have to do, to avoid hardware noise. Untied inputs can produce noise in certain environments. If that is not the case, we will look into other possibilities - but then you will have to provide the entire code block. – Avamander May 28 '17 at 12:19
  • If you are IN DOUBT of if the input produces noise, then again - give me the diagram, then I will go through your wiring to reveal if there are places which are actually prone to making noise. IF we are in doubt then we can actually probe into it, but that would require that we build some more electronics on to the construction. – Avamander May 28 '17 at 12:19
  • first - many many thanks for your reactions! second - apologies for the delay (and counting...) - I will provide more details the coming months. What I can say now is this: it's most likely an environmental issue. After the guys grounded most of the track the stray interrupts have become less. The more people are in the room, the more likely we see stray interrupts. The track is surrounded by a synthetic curtain to hide the posts and other stuff under the track. The floor is covered with carpet tiles. The combination is a perfect source for static charges all around. more to come... – gabe Aug 15 '17 at 11:10
1

Now, you write the following:

detachAllInterrupts();
delay(10);
...
... process any interrupts and/or button presses
...
delay(10);
attachAllInterrupts();

I understand that you put this stuff into the loop, such that the loop in effect looks like this:

void loop() {
    detachAllInterrupts();
    delay(10);
    ...
    ... process any interrupts and/or button presses
    ...
    delay(10);
    attachAllInterrupts();
}

Assuming that the above is correct, then you will be enabling and disabling your interrupts in one long stream. You would often NOT disable your interrupts, because you don't know when the are available or not, then.

You should typically ENABLE the interrupts in the startup code, and then in the loop() you can have any Other processing you want, but not any processing referring to the interrupt processing.

The interrupt processing would take care of the button pressed etc. So - in the lane.lapdetected1() algorithm, you would take care of reading buttons pressed etc., and, you would have to attach the interrupt itself directly to your algorithm. I cannot see that you have told that when an interrupt has been happening, then the code execution goes to the ISR lane.lapdetected1() algorithm?

What you would want to do, is to setup an interrupt in the setup(), which is run once upon start of the program in the arduino, and then, providing that you want the interrupt on pin 2 (external pin), and the algorithm to run while you receive falling signals on the pin 2 is lapdetected1, then you could use the following:

void setup() {
  attachInterrupt(digitalPinToInterrupt(2), lapdetected1, FALLING);
}

Thereby you would remove the detachAllInterrupts(), and all the way down to attachAllInterrupts() from the loop construction and thereby you would be able now to process interrupts within the lapdetected1-algorithm and run what ever you would want to run, normally, from within the loop-construction.

0

The code in the loop() is surrounded with:

it doesn't make much sense for you to "process the interrupts" in the loop(). Use ISR instead.

Your Answer

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

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