phantom interrupt changes?

I checked the faq and did some searching and didn't get anywhere. I hope this is close to the right place to post. It's not a "project" problem per se, but seems like it's probably something about electronics or the arduino that I don't understand.

I'm using a mega2650 on a project where the object is to count pulses from three devices. The three devices provide a 120v pulse that I need to count. I have three relays in place (120v coils) and the switching on these ties pins 2,3 or 21 to ground. I have the internal pull-ups turned on.

int pbInApin = 2;
int pbInBpin = 3;
int pbInCpin = 21;

volatile int countA = 0;
volatile int countB = 0;
volatile int countC = 0;

...

// turn on internal pull ups
  digitalWrite(pbInApin,HIGH);
  digitalWrite(pbInBpin,HIGH);
  digitalWrite(pbInCpin,HIGH);

I attach the interrupt like so (change for HIGH only, but similar results with ANY)

  attachInterrupt(pbInAint, stateChangeA, HIGH);
  attachInterrupt(pbInBint, stateChangeB, HIGH);
  attachInterrupt(pbInCint, stateChangeC, HIGH);

and then the three counters, which are the same thing three times...

void stateChangeA()
{
  //debounce
  if (millis()-lastPulseA>minPulseGap)
  {
    countA++;
    lastPulseA=millis();
    apulse=true;
  }
}

void stateChangeB()
{
  //debounce
  if (millis()-lastPulseB>minPulseGap)
  {
    countB++;
    lastPulseB=millis();
    bpulse=true;
  }
}

void stateChangeC()
{
  //debounce
  if (millis()-lastPulseC>minPulseGap)
  {
    countC++;
    lastPulseC=millis();
    cpulse=true;
  }
}

Here's the problem.

I was watching a counter via the arduino yesterday afternoon and noticed that for every 2 pulses on B there would be 1 pulse appearing to happen on A and 1 pulse on C, even though the A and C relays were not switching. (they are mounted next to each other, but you can put your hand on the cases and tell which one(s) are switching.)

When A was pulsing, about every 2nd one would add a count to B.

More odd-- later on yesterday evening, I checked it again, and the ratio was one-to-four. For every four pulses on B, A and C would each count 1 pulse that didn't happen as far as I could see.

Also, throughout testing, I would notice that when the B relay is switching on and off, sometimes the C count was not affected at all, while other times it was every fourth B pulse or every two B pulse. (the 1:2 only happened during the day and the 1:4 only happened at night.)

I don't know if day-vs-night had anything at all to do with it (this thing is outside, so the temperature was probably 15 degrees of difference, which is the only reason I think it might make some kind of difference) but I'm at a loss as to what to try next.

Something else that may be relevant: there is a POE Ethernet shield involved. The shield and the mega are both less than two months old. (In case you're wondering what revision of either they are... that's really all I know for sure.)

Can enough noise from a 5v wire jump onto another with 20k pullups in place? (I think I read somewhere that the internal pullups are 20k)

How fast does the switching occur, you ask? there is a minimum of about 1 second between ON and OFF. so the relays go "click on--one mississippi--click off--two mississippi--click on--one mississippi--click off"

Why I am using the interrupts at all instead of just watching in the loop? Because the loop has some HTTP requests which tend to be long-winded (in comparison) and I absolutely can't miss a pulse. But I also can't be counting extra pulses that didn't really happen! (it's measuring liquid moving through three pumps)

Thanks for any ideas you might have.

Jeremy

  attachInterrupt(pbInAint, stateChangeA, HIGH);
  attachInterrupt(pbInBint, stateChangeB, HIGH);
  attachInterrupt(pbInCint, stateChangeC, HIGH);

http://www.arduino.cc/en/Reference/AttachInterrupt

mode defines when the interrupt should be triggered. Four contstants are predefined as valid values:

LOW to trigger the interrupt whenever the pin is low, CHANGE to trigger the interrupt whenever the pin changes value RISING to trigger when the pin goes from low to high, FALLING for when the pin goes from high to low.

HIGH is not in the list.

Jeremy: I have the internal pull-ups turned on.

Try a lower resistance (external) pull-up resistor. 10K or 4.7K or 1K.

  if (millis()-lastPulseC>minPulseGap)

Do you have some objection to hitting the space bar?

[quote author=Coding Badly link=topic=130276.msg980144#msg980144 date=1351830626]

Jeremy: I have the internal pull-ups turned on.

Try a lower resistance (external) pull-up resistor. 10K or 4.7K or 1K.

[/quote]

maybe a Capacitor should also work. The problem seems to be the "bounce" effect that also is suffered by buttons, take a look a debounce library to have some clue how to workaround this problem

Finally made progress and wanted to help with all of the input.

HIGH vs RISING -- I completely missed that. I guess the constant HIGH is equivalent to one of the correct four choices, since the compiler never complained. This has been corrected to RISING!

Space bar -- I laughed at that one. Thanks for pointing out the difficulty in badly-formed-crammed-together code. Obviously, that entire line except for the "C" was copied and pasted from an example found somewhere in the ether, so I didn't type it. But if I find the original author I'll pass along the spanking!

All the rest:

I took the thing apart and got to looking at my work under a good light. Probably better than the one I used during the original soldering work. As it turned out, the simplest and most obvious answer is the correct one- just a bad soldering job. There were some tiny stray strands or wire that were loose and moving around and sometimes connecting the thing to ground and sometimes connecting the pins to each other. In any case, I've removed a header, cleaned out the original solder in the holes and properly connected the wires to the mega. I'm going to look into header-less versions next time. (I'm not into full assembly, but I'm also not into dis-assembly!)

Thanks again for the replies, sorry it took so long to get back on, and sorry for giving up on replies too soon. ;)

Jeremy

void stateChangeA()
{
  //debounce
  if (millis()-lastPulseA>minPulseGap)
  {
    countA++;
    lastPulseA=millis();
    apulse=true;
  }
}

be aware that you call millis() twice and that the value could have changed. Might or might not be a problem...

void stateChangeA()
{
  //debounce
  unsigned long now = millis();
  if (now - lastPulseA > minPulseGap)
  {
    countA++;
    lastPulseA=now;
    apulse=true;
  }
}

and apulse and lastPulseA should be volatile too ...