0

I am currently working on a project that involves reading the states of 500 buttons using a microcontroller. Each button is placed on separate PCBs, with a 30cm gap between each button PCB. The microcontroller is positioned approximately 300cm away from the first button PCB.

  1. The microcontroller needs to efficiently poll the states of all 500 buttons.
  2. The buttons are arranged in series, and I am seeking an efficient communication method for this series-style configuration without specifying any particular protocol.
  3. Each button has one leg connected to GND, and the other to a signal line.
  4. Simultaneous reading of all button states is the objective; there's no need to address specific buttons individually.
  5. The target is a response time of 2ms or less for reading all button states in series.

Seeking Guidance On:

  1. Efficient methods for reading states of a large number of buttons in a series-style configuration using a microcontroller without specifying a particular communication protocol.
  2. Recommendations for maintaining signal integrity over the long series of buttons and cable lengths.
  3. What kind of IC should I look into?

edit:

  1. adding illustration figure

enter image description here

RoastDuck
  • 23
  • 5
  • 1
    Can you please explain what you mean by "in series" (given that each button is connected to gnd)? – Andy aka Jan 02 '24 at 14:04
  • Just that I understand correctly, you have a cable with 500 signal lines and 1 ground line? And then you have the first button 3 m away from your MCU and then 499 boards 0,3 m apart for a total length of around 153 m? "Simultaneous reading of all button states is the objective; there's no need to address specific buttons individually." But you want the information of each button, not just that one of the buttons was pressed, correct? – Arsenal Jan 02 '24 at 14:05
  • @Andyaka Sorry for not being clear, I have attached a setup figure for your reference. – RoastDuck Jan 02 '24 at 14:24
  • @Arsenal yes, I want to be able to read each button states in one polling cycle. no addressing nor interrupt is needed. – RoastDuck Jan 02 '24 at 14:28
  • 1
    @RoastDuck You can put microcontroller and a CAN transceiver on each button PCB. Then, broadcast a frame when the button is pressed. Data in the frame will identify the address of the button. This will get you down to 4 wires between the daisy chained PCB's: VCC, GND, CAN_H and CAN_L. CAN also supports these speeds and distances. – MOSFET Jan 02 '24 at 14:37
  • 1
    In a project with ~100 latched switches (i.e. not momentary switches e.g. push buttons) I used shift register ICs in daisy chain config. So I was able to load the entire button information to registers. If, in your case, the buttons are latch-type then maybe you can go for a similar thing. If they are momentary switches then may Zeus help you. – Rohat Kılıç Jan 02 '24 at 14:38
  • Does each button have to have its own pcb, or can one pcb host 8 buttons on long and short wires? – AnalogKid Jan 02 '24 at 14:48
  • @RohatKılıç, I have used hc165 chips to read 300 buttons, though they are momentary, I was able to detect button press without problem. But I had all the hc165 on the microcontroller side, which results in lots of cable. – RoastDuck Jan 02 '24 at 14:54
  • @AnalogKid each button will have its own pcb. – RoastDuck Jan 02 '24 at 14:59
  • @MOSFET, cool! So the MCU on each button PCB can also handle debounce logic, and send the button state either on state change, or an interval. However, I am not sure if this will meet the requirement. If all the buttons are trigger at the same time, would like bus be too busy? Also, I try to avoid addressing so I don't need to program each board. – RoastDuck Jan 02 '24 at 15:05
  • @RoastDuck Yes the MCU on each PCB will handle the de-bounce logic (and any other logic for that matter - it's a microcontroller after all). But you wouldn't even have to debounce the switch input if you program the MCU as interrupt/event-driven. CAN works by giving each button a priority (arbitration). So my solution will not meet your requirements if simultaneous button presses need to be managed. What MCU do you plan on using to acquire the switch data? – MOSFET Jan 02 '24 at 15:12
  • @MOSFET ESP32 is the MCU I plan to use. – RoastDuck Jan 02 '24 at 15:53

3 Answers3

2

Since you don't care about any specific protocol, the most simple is to create a distributed, 500-bit shift register. Nothing else will get you 500 reads in less time because there is zero protocol overhead. Each pcb is one button, one flipflop, and two 5-pin connectors: Data-In or Data-Out, Strobe, Clock, Vcc, GND.

This sounds like a cumbersome mess with a zillion connections and questionable reliability, but given your requirements, so will any other approach. The good news is that it is very low cost, relatively low speed, and easy to debug and maintain.

Conceptually, the software to drive this is pretty simple. In real life - switch bounce. The switches can be debounced on the boards, interjecting a short delay between the physical push and the input to the shift register, or in software by processing multiple scans of the 500-bit pile, basically 500 instances of a debug processing routine.

Update:

It might be cheaper to put a small uC on each board instead of standard logic components. With just one resistor and one capacitor, a 6-pin (SMT) or 8-pin (DIP) PIC with 4 GPIOs can implement a switch debouncer and shift register stage for less than $1.

Each board regenerates all four signals to drive the next board. It is tempting to run the strobe and clock lines as parallel signals to all 500 boards, but that is way too much load capacitance for megahertz signals.

With logic IC's - an AC-series CMOS flipflop has a typical propagation delay of around 11 ns. Lets round that up to 100 ns. 500 stages equals 50 microseconds of delay, for a max frame rate of 20 500-bit frames per millisecond. Thus, a frame rate of 1 ms should not be a problem. Two chips per board, one flipflop and one gate package to buffer the clock and strobe. A frustration is that I don't think there is a way to do it all in one standard logic package. A flipflop can be configured to be a simple buffer, so a standard dual flipflop can be one shift stage plus one control signal buffer (Clock or Strobe). The problem is the other control signal. Grrrr.

With a uC, things are slower. The switch and strobe inputs can be polled, but the clock input should be a hardware interrupt for minimum latency. All it does is move the data-in bit to the data-out pin. I'm not PIC wizard, but this smells like a few lines of assembler. Multiplied by 500, a 4 MHZ part might not be fast enough. This forum has some true wizards, and they can chime in here.

AnalogKid
  • 19,998
  • 1
  • 13
  • 32
  • See the update. – AnalogKid Jan 02 '24 at 15:12
  • This is actually close to what I had in mind. I was looking at 74hc164 chip (what are the alternatives? or to just build a flipflop circuit? . I also have concern in signal integrity and is thinking to use 2 rs485 transceiver on each board. – RoastDuck Jan 02 '24 at 15:13
  • Brilliant! To clarify, there is no need for a actually shift register. We use PIC to handle switch debounce(so that the main MCU don't need to worry about it), the PIC can also be the shift register itself (using code) Cool, and if the main MCU is further away from the first button board, I would use rs485 on the first board to ensure signal integrity. – RoastDuck Jan 02 '24 at 15:23
  • Four - Clock, Strobe, Data-in, Data-out. But given that the boards are less than 1 foot apart, and each board regenerates the signals going through it, driving that single-ended could work. See the Update addition. – AnalogKid Jan 02 '24 at 15:23
  • Will standard logic components result in faster data transmission than the PIC approach? How can I calculate one polling cycle time for PIC method. Do you think it will take longer than 2ms for each poll? – RoastDuck Jan 02 '24 at 15:30
  • Is this going to be able to read 500 bits in 2 ms given how slow it will have to be to deal with being spread over 150 m? – The Photon Jan 02 '24 at 16:10
  • @AnalogKid I have an idea, Maybe no clock nor strobe is needed in this case: each uC data-out length is dynamic based on its data-in length. So the data is being accumulated starting at the last uC. (it will require a startup time, but its okay.) – RoastDuck Jan 02 '24 at 16:16
  • Photon - not that slow. See the expanded Update. Prop delay through the wire would be approx. 1.5 ns per board, well within the 89 ns margin I added, not counting the 40x speed difference between my calculated frame time and 2 ms. – AnalogKid Jan 02 '24 at 16:35
  • @AnalogKid with logic ICs, is it important that it is all in one standard logic package? can I use buffer for the clock and strobe? – RoastDuck Jan 03 '24 at 12:09
  • Not important at all if you have the room and budget. – AnalogKid Jan 03 '24 at 14:13
2

Assuming this is a one-off...

Let's compare two cases...

500 buttons in 2ms = 250 kbps

500 daisy chained boards

Implementation would be something like a shift register, either in hardware or with a micro. With a clock buffer and a 1-bit latching shift register on each board there should be no signal integrity issues because signals are only transmitted to the next board, so you could use fast clock speeds. No problem to reach the target update speed.

- 5 wire cables: Latch, Data, Clock, VCC, GND

You need 499 identical cables (998 connectors). So the only practical solutions are either to whip an unpaid intern into making them or buying them pre-made. This restricts the choice to off the shelf cheap with 5 (or more) wires... maybe RJ45 or JST/0.1" jumpers...

- 4 wire cables: Data, Clock, VCC, GND

To have a wider choice of cheap readymade cables, 4 wires would be more practical as it allows using RJ11, maybe even USB cables.

This means the latch signal should be encoded with the clock. No clock for a while means latch in the button data, then pulsing the clock shifts the data bits.

It should be possible to do that with a 74HC74 plus a bunch of passives and careful engineering of the clock signal, or a cheap micro on each switch PCB. The latter can also allow debouncing locally, but you have to whip an unpaid intern into programming 500 mcu's or buy them pre-programmed.

enter image description here

Here's a quick and dirty example. Each button PCB has a buffer (two inverters) and a D flip flop. The switches are filtered by 100nF capacitors.

Initially, all the flip flops are set to 1. First the clock is held high for 250µs, which sends low voltage to the diodes. When the switch is on, it discharges the 100pF cap, which resets the flip flop. Then clock goes low for another 250µs, which brings the reset lines high again through the diodes. Then 500 clock pulses are emitted at 1MHz, which shifts all the data through the flip flops: the result is inverted, closed switches result in a 0 bit. The last flip flop in the chain has its input tied to VCC, so as the whole shift register is read, it is filled with 1's at the same time. Then the cycle repeats.

I used high value resistors because the per-PCB consumption should be kept low.

- 3 wire cables: Data, VCC, GND

With MCUs this is also possible by encoding the data into the length of a pulse. The last MCU in the chain sends its status every 2ms, then each MCU acts as a repeater and adds its own button status as the end of the pulse train. Decoding could will probably require a dedicated bitbanging micro, or a fast micro using oversampling. But you can use 3.5mm jack cables (and their legendary reliability).

63 daisy chained boards

The alternative is to use one "smart" board for every 8 buttons for example. This adds more 2-wire cabling between buttons and board, and it reduces the number of multiwire cables between boards.

This may be an advantageous solution if it is easier and cheaper to find a large number of 2-wire cables, than a large number of 4-5-wire cables.

In this case each board would either use a 74HC165 shift register, or a microcontroller with local debouncing.

In all cases, wires will be long and thin so each board should use minimum power.

bobflux
  • 77,207
  • 3
  • 91
  • 222
  • Thank you for the informative answer! I plan to buy premade cables and consider a 5-wire, 3-wire, or 74HC165 design. Questions: 1. If 74HC74's price is close to 74HC165, and HC165 opens up possibility for scalability, I'm thinking of using one HC165 per PCB to read one button, wasting 7 shifting times for each HC165. How to calculate time for shifting all 500 74HC165? 2. With HC165, how to ensure data integrity? Is a buffer needed for clock and strobe on each pcb? – RoastDuck Jan 03 '24 at 13:06
  • HC165 for each button will require 8x faster clock, ie 2MHz. With a buffer on each board it should work. Since a chip with 2 buffers probably costs the same as 1 buffer you may as well buffer both clock and latch enable. 500m wire on your latch enable may work without buffers but... meh... – bobflux Jan 03 '24 at 14:52
  • With one 74HC74 you can also make a 2-bit shift register, so one board can handle 2 buttons. There is no "latch" input on this chip but it has set/reset inputs, so if you use a quad AND/OR chip as buffer, you can use one of the spare gates to combine the latch signal and the button voltage to set or reset the HC74 when the latch signal is active. So it's the same number of components as the HC165 solution but only 2 bits per board, which means it can run with slower clock and you still have a spare input per board. – bobflux Jan 03 '24 at 14:55
  • So you should not consider the HC74 (dual flop) and HC165 (8 bit shift reg) as completely different solutions, they're quite similar, only difference is the number of bits and how you translate Latch into Set/Reset for HC74 with the extra "free" gates you get in your buffer chip. – bobflux Jan 03 '24 at 14:57
  • Basically these chips are so standardized they all cost the same, about 0.11€ at qty 500, the single flip flop costs the same as the double, and the chip with 4-6 gates/buffers costs the same as the single gate chip... the shift register may be 1 cent extra... besides that you need two 100nF caps (decoupling and button noise filter), a pullup, and a bunch of resistors. So pretty damn cheap. IMO the money saved (or wasted) will be in cables and connectors. – bobflux Jan 03 '24 at 15:02
  • The MCU on the main board is ESP32, I think it will be no problem for the speed. Say the distance between each board with HC165 now increased from 30cm to 300cm, what should I take into account? Do I need RS485 transceiver for the three signals? – RoastDuck Jan 03 '24 at 17:18
  • No need for RS485 for just 3m if you have buffers. But you may want an extra ground wire in your cable: GND Clock GND Data VCC Latch. To prevent crosstalk between clock and data. Maybe ESD protection diodes on your signals. And if you still have 500 boards then... that's going to be a huge length of wires, watch out for voltage drop on your power supply. – bobflux Jan 03 '24 at 20:20
0

You're looking almost 90 meter of wire. That will give you some signal integrity challanges.
A serial method involving "an IC" will probably be too slow for your 2 ms requirement. For example, CAN bus was mentioned.
CAN bus is a slow protocol, at 90 meters you're limited to 500 kBit, then one frame is ~200 us. You can't poll all 500 buttons states within 2 ms.

However, CAN bus could still be feasable if you let buttons only send changes and the number of buttons changing at once is limited.
CAN bus will provide signal integrity and communication robustness with checksum and retries. An 9-bit DIP switch could set the "ID" of each node. This does introduce implicit priorities for buttons due to the way CAN bus does bus arbitration.

However, in my opinion the optimal way to approach this given the requirements:

  • simultaneous reading of all button states
  • 2ms response time

Would be to use a realtime field IO system, for example group buttons together into fieldbus nodes with Ethercat. (eg: Beckhoff).
Ethercat is a realtime ring network protocol based on Ethernet, where a single master can poll data from every node on a fixed interval and can be used to read the states every 2 ms for example.

Yet doing Ethercat master in "an mcu" raises the complexity by a large amount.

I would recommend watching Jeff Geerlings video about the MrBeast game setup. For similar challanges.

Jeroen3
  • 22,972
  • 37
  • 74