Using arduino inputs more reliably

I have an Arduino Nano 33 IoT and a MacBook.

Through a PS/2 connecter, I have the following wiring:

Arduino PS/2 Seat Pads

9 1 Seat1
10 2 Seat2
11 3 Seat3
13 4 Seat4
15 5 Seat5
VIN (5v) 6 Common

Whenever all of the seatpads are "open", the Arduino reads arbitrary values. Sometimes, when one seat is closed, neighboring seats are read as on (digitalRead) which I assume is because the wires are interfering with each other.

Is there a way to make the seats grounded or something so that the readings from the inputs would be reliable? I cannot alter the seat pads, so said fix would have to be within my circuit. I made PCBs, but I don't really know what I'm doing, so I may have to get them redone anyway (only 10 of them.) I am fairly new to Arduino, so constructive criticism would be appreciated.

Am I allowed to post files of my PCB on the forum, or just screen shots?

The end goal is to use digitalInturrpts on each pin instead of digitalRead

How did you initialize the GPIO pins?

Post your complete code as requested in Read this before posting a programming question ...

From what you are describing I am assuming a seat is a switch (never read that term before). Not knowing your circuit I cannot really suggest either a pull up or pull down. When the "seats" are open that tells me you have an open line. That would explain what you are seeing. My way of doing it would be to put a pull up resistor on the switch and use ground on the other side so when the switch is closed the line to the Arduino is grounded. That will invert your logic but that is an easy fix in software. Maybe ~500 Ohm would work OK.

You need to use pullup or pulldown resistors with any switch, otherwise the voltage is undefined when the switch is open (aka "floating" input).

CMOS logic takes such low current (*) that the voltage on an input is affected by nearby wiring and leakage if not explicitly connected to some defined voltage through a resistor.

(*) can be less than 1 picoamp

"Floating" inputs on the are undefined and they might read high or low. They are also very-high impedance which makes open/floating inputs very sensitive to electro-magnetic noise pick-up and that can make them switch randomly between high & low.

When the switch is closed, is it low or high?

If closed is low (switch wired to ground) you can simply enable the internal pull-up resistors.

Otherwise, you might have to add pull-down resistors, or reverse your connections and your software logic so you can use the internal pull-ups.

...A pull-up resistor holds the input high by default. Then when the input is grounded by closing the switch, the resistor is "overpowered", current flows through the pull-up, and the input is low.

Pull downs work the same way... The resistor is "overpowered" and current flows through the resistor when forced to the opposite state.

Clarification: Seat pads are effectively momentary switches that are normally closed, and open when the person sits. When the switch is closed, the corresponding Arduino pin is connected to +5v, so High?

Also: it is basically impossible for me to modify the pads themselves. Not because I’m unable, but because they are quite expensive, and I want to be able to buy more and use them with out modification.

Ok, pull-up/pull-down resistors…

You just connect pins 1-5 to ground each with a pull-down, and then it shouldn't stay floating?

@DVDdoug I am very interested in a software only approach if possible. Could you elaborate on:

@SteveMann This is a hardware question, but I did forget to state the pinMode: all pins relevant to the seats are set to input

Why? Interrupts are seldom appropriate for reading manual switches (which is what a seatpad is, basically).

Also, since you have a PCB, I assume you must have a schematic. Please post it.

Ok, I'm all ears. I'm new to this, and saw interrupts as a way to not have to constantly check if someone had jumped.

I just got a new laptop, so I'll have to get the schematic off the old one. I'll post that tonight.

Here's what happens:
Someone wants to do two things at once.
Aha, I can do that by making one thing an interrupt.
Oh, but wait a minute, nothing works.
I find out it's because interrupts are disabled during an interrupt service routine.
I realize (or I'm told) I can set a flag in the interrupt and poll it in the main program.
I then realize that the polling is as slow as the loop() is.
I then realize I could have just polled the switch in the first place. :slight_smile:


Yes, in your case a PULL down resistor from each input pin to gnd, 10K should be fine.
Where on the 33 is the D1 pin?

It is better that you configure the seat switches to pull down when closed, it is just a case of how you connect to the controller, not changing anything physical with the switch.

There is nothing wrong with polling, when you consider the controller speed, even at 16Mhz of a UNO.
Avoid using the delay() function.

Did you make a breadboard prototype before going to PCB?
Can you please post a copy of your schematic?

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

First picture is just the Arduino and PS/2 connector, second is the entire pcb. Not sure the best way to upload the whole file. If that's needed, a link on how to do it would be nice.

I don't think the rest of it is relevant, but it's there. Each of the ICs are Shift Registers with resistors next to them. Each of the Sets of 4 through holes are 5mm RGB LEDs. The Sets of 3 through-holes are sliding switches. If I have to order new PCBs, does anyone know of an actual LED driver with resitors and/or brightness regulation that has 7 RGB outputs, or can be run in series? Not a necessity, but I'm sure there's a better way to do it.

Pins of PS/2:

3 1 2 4
5 ----- 6

D1 is the 2nd pin from the left on the bottom row of pins.

Yes, I did, but I didn't throughly test the bread board.... whoops... 33 Nano's "+5v" pin isn't 5v, despite trying different input voltages through the VIN... my 5V rail is connected straight to the VIN which is regulated to 5V.

If I were to get the PCB remade (sounds like I will), how might I get the components already soldered on? I saw SMD Service on JLC where I got the last PCBs, but I don't know how to add SMD components using Diptrace. Do I need a new program, or can I keep using Diptrace?

Thank you all for your help!!!

A proper schematic would be best, a net diagram for a PCB is almost as bad as a Fritzy image.
Please label all components and used pins on your schematic please.

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

pinMode(pin, INPUT_PULLUP);

Read this for a reference.

@SteveMann Ok... You win.

Assuming I set each of the 5 seats to "INPUT_PULLUP", there aren't any obvious issues that I should have, are there? I'll have to switch the "common" pin on the PS/2 to GND instead of 5V, but I can just break the trace and connect to the GND rail.

Thank you for your help!!

A schematic or even a block diagram would add a lot to this conversation.

I thought the PS/2 port was a 2- channel serial interface for mouse and keyboard. Will it work with contact closure only?

The PS/2 port isn't up to any kind of standard, just a physical connection between the arduino and "SeatPads".

We would already know that if you had posted the requested diagram.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.