Photon and interrupts on multiple pins is giving strange results


#1

Hello everyone,

Currently I want to use a particle photon in combination with Blynk to setup a simple action-reaction logger on a machine. My intention is to use two interrupts, one on a button and one on an output of the machine, I’ve piggybacked the signals via 2 relays to the photon.

My debugging code is as follows:

#include <Particle.h>
#include <blynk.h>

STARTUP(WiFi.selectAntenna(ANT_EXTERNAL)); // selects the u.FL antenna

char auth[] = "xxx";

BlynkTimer timer;

int buttonPresses = 0;
int machineCounter = 0;

volatile bool buttonChanged = false;
volatile bool machineChanged = false;

//--------- Interrupts ----------

void operatorButton()
{
    buttonChanged = true;
}

void machineFeedback()
{
    machineChanged = true;
}

//-------------------------------

void myTimerEvent()
{
  if(buttonChanged == true)
  {
      buttonPresses += 1;
      Blynk.virtualWrite(V3,buttonPresses);
      buttonChanged = false;
  }
  if(machineChanged == true)
  {
      machineCounter += 1;
      Blynk.virtualWrite(V4,machineCounter);
      machineChanged = false;
  }
}

void setup()
{
  // Debug console
  Serial.begin(9600);
  delay(5000);
  Blynk.begin(auth);

  // Setup a function to be called every second
  timer.setInterval(1000L, myTimerEvent);
  
  pinMode(D5, INPUT_PULLUP);
  pinMode(D6, INPUT_PULLUP);

  attachInterrupt(D5, operatorButton, CHANGE);
  attachInterrupt(D6, machineFeedback, CHANGE);
}

void loop()
{
  Blynk.run();
  timer.run(); // Initiates BlynkTimer
}

If I run this code and use the blynk app to track the value of buttonPresses and machineCounter, I get a very strange effect where both values increment every second, even if I disconnect the input from the relay I know I shouldn’t be getting an interrupt on… On the other input pin I have a 2Hz signal.

According to the pin documentation I should be able to use pins D5 and D6 as separate interrupts right? I’m thinking this might be a Blynk related problem?

Hopefully someone can help me out.


#2

One thing, when you opt for CHANGE you will usually get at least two triggers with one button press/release.
Also if you are actually using buttons, you may see button bounce producing many contacts with one press.
Next, how long are your wires? You may be picking up EMI.
You could also try moving the xxxChanged = false; statements further up in your if() branches (particularly before the Blynk calls).

BTW, what is the advantage of using BlynkTimer instead of Particle’s Timer object?
The latter won’t require a call in loop()


#3

It doesn’t seem to matter if I choose CHANGE or FALLING/RISING, the code checks once a second whether the interrupt flags are true and then increments and sends the value.

Button bounce is most likely a thing, but shouldn’t be a problem because the flag was already set to true the first time and is only checked once a second.

Wires to the relay are only 8cm long, from the button to the relay is probably 3m, EMI could very well be an issue here as the photon is mounted inside the machines cabinet.

As far as I’m aware, the way the program is build up now, is how it should be in conjunction with Blynk.
A timer which periodically calls a function which actually turns in the classic “loop()”, this is done to not spam the Blynk Cloud with messages. The void myTimerEvent() is sort of the void loop()

**Just put the photon on my desk to test the code, functions excatly as it should, no false hits…
EMI seems to be the most logical culprit, any idea’s on how to eliminate this issue or atleast shield the photon from the effecs? shielded wires to the relay perhaps?


#4

Yes, shielded wires and stronger external pull-resistors would be a start.
On the relay side you could consider increasing the voltage (if the relay allows).

You could also provide a schematic with annotations about the voltages and lengths used to get a better understanding of your setup.


#5

I don’t think it should be necessary to increase the relay voltage, the relays I’m using are industrial din rail mounted version, so should be up for the task, as are the rest of the machine components.I will try a shielded cable first, external pullup or pulldown resistors will have to wait till monday.


It shouldn’t be a problem that I use the relay to separate the circuits right? or should I connect the grounds to be certain?


#6

@jacarbro, your circuit is fine as-is. However, like @ScruffR mentioned, you should:

  • Use stronger external pull-up resistors (eg. 4.7K or 2.2K)
  • Use shielded cabling (cat5 cable is great for that since it’s also twisted pairs)
  • Include debouncing in your ISR. Buttons and relays are noisy.
  • You can also add a small cap (eg. 0.1uF) to Photon GND on D5 and D6 to decouple high frequency noise picked up by the wires

#7

In addition to the great suggestions by @peekay123 you could add some debug code to your ISRs that could either trigger the D7 LED when it fires and/or add a trigger counter to get a feeling how much noise you find yourself up against.
The frequency may also provide clues about the actual source for the false triggers.

Or directly check the signal with an oscilloscope.