What could make all pins on an Arduino go LOW?

Hi,
I have a someone complex setup. I have 25 switches tied to a 17V AC power supply. I'm trying to track when each switch is opened or closed. I'm using H11AA1 Optocouplers that are AC input and DC output. I'm tying the outputs to input pins on my Arduino Mega.

My program seems to work fine as it waits 200ms for each switch to debounce. What's weird is at seemingly random times, all 25 pins read LOW meaning they were switched on. Any idea what would cause that? Thanks.

It's probably a hardware or software problem.

As #2, supply circuit diagram of how you have everything connected and the code you are using.

There's a third option?

Well, they did mention complexity. That can sometimes cause it.

Hope this helps.
image
I have 25 of these each hooked to an Arduino input pin. The 40 ohm resistors are small 6V AC lamps so closing the switch lights the three lamps.

All the GND lines are tied together in groups and connected to various GND pins on the Arduino.

The Arduino is powered by my laptop USB port.

This:

Floating inputs perhaps? I see no pull-up resistors fitted!

If you're using optos, what is the need of connecting the AC ground to Arduino?

  • Zero crossing pulses.
  • Invisible code.

Here's the code. It's a bingo machine with 25 holes. When a ball drops in a hole the switch is closed and the lights light. I'm trying to detect when the switched is pressed and released. it works most of the time, but then it starts outputting things like:

#16 pin 9 was just pressed
#17 pin 4 was just pressed
#18 pin 14 was just pressed
#19 pin 22 was just pressed
#21 pin 26 was just pressed
#22 pin 6 was just pressed
#23 pin 11 was just pressed
#19 pin 22 was just released
#21 pin 26 was just released
#23 pin 11 was just released
#19 pin 22 was just pressed
#21 pin 26 was just pressed
#23 pin 11 was just pressed

Like something's bouncing. I have each Arduino input pin declared as INPUT_PULLUP.

const byte NUMBERS_IN_GAME = 25;
const byte NUM_MATCHES = 5;
const unsigned long DEBOUNCE = 200;

const byte RELAY_PIN = 17;
const byte MAX_SCORE_PIN = 8;

// Map bingo numbers to input pins on the Arduino.
byte PinMap[] = { 0,
    /*  1-5  */ 49, 46, 47, 44, 45,
    /*  6-10 */ 42, 40, 38, 36, 34,
    /* 11-15 */ 52, 53, 50, 51, 48,
    /* 16-19 */  9,  4, 14, 22,
    /* 20-23 */ 18, 26,  6, 11,
    /* 24-25 */ 16, 43 /* 15 is a spare */
};

const byte NUM_CARDS = 6;

byte LastNumBallsDetected;

// Track if number is currently lit.
byte NumberState[NUMBERS_IN_GAME + 1], NumberIsLit[NUMBERS_IN_GAME + 1];
bool JustPressed[NUMBERS_IN_GAME + 1], JustReleased[NUMBERS_IN_GAME + 1];

// This function checks all the number inputs for any changes.  The routine is called eacch loop in order
// to debounce the switches.
void checkNumbers()
{
  static byte _previousstate[NUMBERS_IN_GAME + 1];
  static byte _currentstate[NUMBERS_IN_GAME + 1];
  static byte _statecount[NUMBERS_IN_GAME + 1];
  static unsigned long _lasttime;
  byte index;

  if (millis() < _lasttime)
  {
    _lasttime = millis();    // we wrapped around, lets just try again
  }

  if ((_lasttime + DEBOUNCE) > millis())
  {
    return;   // Not enough time has passed to debounce
  }

  // We have waited DEBOUNCE milliseconds, lets reset the timer
  _lasttime = millis();

  for (index = 1; index <= NUMBERS_IN_GAME; index++)
  {
    // Clear out the "just" indicators
    JustPressed[index] = false;
    JustReleased[index] = false;

    _currentstate[index] = digitalRead(PinMap[index]);   // read the button
    if (_currentstate[index] == _previousstate[index])
    {
      if (_statecount[index] < NUM_MATCHES)
      {
        _statecount[index]++;
      }
      else
      {
        if ((NumberState[index] == LOW) && (_currentstate[index] == LOW))
        {
          JustPressed[index] = true;
          Serial.println(String("") + "#" + index + " pin " + PinMap[index] + " was just pressed");
          NumberIsLit[index] = 1;
        }
        else if ((NumberState[index] == HIGH) && (_currentstate[index] == HIGH))
        {
          JustReleased[index] = 1;
          Serial.println(String("") + "#" + index + " pin " + PinMap[index] + " was just released");
          NumberIsLit[index] = 0;
        }
        NumberState[index] = !_currentstate[index];  // remember, digital HIGH means NOT lit
      }
    }
    else _statecount[index] = 0;
    _previousstate[index] = _currentstate[index];   // keep a running tally of the switches
  }
}

byte searchForNumbers()
{
  byte numNumbersLit = 0;

  for (byte i = 1; i <= NUMBERS_IN_GAME; i++)
  {
    if (NumberIsLit[i] != 0) numNumbersLit++;
  }
  return numNumbersLit;
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println("Starting");
  for (byte i = 1; i <= NUMBERS_IN_GAME; i++)
  {
    pinMode(PinMap[i], INPUT_PULLUP);
    NumberIsLit[i] = 0;
  }

  pinMode(RELAY_PIN, OUTPUT);
  pinMode(MAX_SCORE_PIN, INPUT_PULLUP);

  // See how many numbers are lit.  Have to wait until they debounce.
  for (byte i = 0; i <= NUM_MATCHES; i++)
  {
    checkNumbers();
    delay(DEBOUNCE);
  }
  LastNumBallsDetected = searchForNumbers();
}

void loop() {
  // put your main code here, to run repeatedly:
  checkNumbers();   // This will keep the NumberIsLit array up-to-date.
}

I'm not connecting AC ground to the Arduino. I'm connecting pin 6 of each opto to the Arduino ground.

I'm defining the input pins on the Arduino to INPUT_PULLUP (see code below).

You chose to ignore best practices on how to time with millis(). I would begin looking there. Also you have ignored several requests to provide a complete wiring diagram.

Just curious - what is the a.c. voltage for the lamps?

Your drawing indicates otherwise.

Since the opto is connected across the switch, having the switch "on" results in the opto allowing the input pin to read HIGH - not LOW.

When the AC waveform crosses zero, the opto will also allow the input pin to read HIGH, so the reading will be exactly the same as the switch being "on" at that brief moment. Is that not what is happening? :thinking:

I'm (obviously) not an electrical engineer so my drawing is probably incorrect, but I show pin 5 of the H11AA1 is tied to the Arduino input and pin 6 is tied to Arduino ground (is there a different way to show one ground vs. another?) The Optocoupler (H11AA1) is tied to AC ground.

Thanks for the info I will search for millis best practices.

I'm not an EE. I'm happy to provide further diagrams if I can. I started this project just trying to learn about microcontrollers (I'm a software guy). Like I said I have 25 of those circuits soldered together on boards each one hooked to a different input pin and all their grounds are tied to Arduino ground. What else are you wanting to see in a diagram? Can you recommend a tool?

I can assure you the input pin is reading LOW when the switch is on and the lights are lit. I can place a ball in the hole closing the switch and the program outputs that the hole switch was just pressed. The debounce code should handle any zero-crossing or the ball settling in the hole.

What's happening is that all works, but then if I let it sit for a few seconds and do nothing, it starts telling me all holes are filled, and then those holes are empty. I don't know electronically what would cause that; all 25 optos can't be bad.

OK so I'm assuming you know at least some of the 25 switches are not in the "LOW" condition.

How do you tell the state of the 25 inputs.

  • Could the power to the 25 switched be interrupted?
  • Could you board be being reset due to noise?