Hardware - padraigfl/awesome-arcade-coder GitHub Wiki
This page covers details around how the hardware itself operates; please add details relating to the specific components, optimal timings and how the hardware operates here.
TODO:
- circuit diagrams: you can find KiCad sketches available at https://github.com/ColdFerrin/twsu-arcade-coder-pcb
- details on specifics for optimisations (e.g. brightness control, how many buttons can be pressed at once)
- a full breakdown of the input tracking process: @jake-walker has some great work done on this for single button input tracking at https://jake-walker.github.io/rs-arcade-coder/hardware/buttons/
- how to connect to a computer (see this page for some details currently
- 144 RGB individually addressable LEDs
- 144 membrane buttons
- Accelerometer
- ESP32-WROOM-32D microcontroller (capable of bluetooth and wifi; if you don't know this microcontroller it's worth looking up what it can do)
- 1 digital button
- 2 rear status LEDs
- LiPo battery (charged via USB-C port)
- 1x ESP32-WROOM-32D
- 9x 74HC595 Shift Registers: for controlling LEDs
- 1x ICN2012 (similar to 74LS138) for multiplexing LED channels and processing membrane button inputs
- 1x SC7A20 Accelerometer
Only 24 buttons / RGB LEDs can be controlled at a time, via multiplexing across 6 channels we are able to track the full range of buttons and LEDs.
The groupings of both are the same and consist of 0+n
-> 0+n+12
and 60+n
-> 60+n+12
where n is one of [0, 12, 24, 36, 48, 60]
Here is a rough approximation of the board layout following a format of ChannelNum_RGBNum (e.g. 2_13 will refer to the 2nd LED/button on the second row of the 3rd channel):
O | 0_00 | 0_01 | 0_02 | 0_03 | 0_04 | 0_05 | 0_06 | 0_07 | 0_08 | 0_09 | 0_10 | 0_11 | X |
1_00 | 1_01 | 1_02 | 1_03 | 1_04 | 1_05 | 1_06 | 1_07 | 1_08 | 1_09 | 1_10 | 1_11 | ||
2_00 | 2_01 | 2_02 | 2_03 | 2_04 | 2_05 | 2_06 | 2_07 | 2_08 | 2_09 | 2_10 | 2_11 | ||
3_00 | 3_01 | 3_02 | 3_03 | 3_04 | 3_05 | 3_06 | 3_07 | 3_08 | 3_09 | 3_10 | 3_11 | ||
4_00 | 4_01 | 4_02 | 4_03 | 4_04 | 4_05 | 4_06 | 4_07 | 4_08 | 4_09 | 4_10 | 4_11 | ||
5_00 | 5_01 | 5_02 | 5_03 | 5_04 | 5_05 | 5_06 | 5_07 | 5_08 | 5_09 | 5_10 | 5_11 | ||
0_12 | 0_13 | 0_14 | 0_15 | 0_16 | 0_17 | 0_18 | 0_19 | 0_20 | 0_21 | 0_22 | 0_23 | ||
1_12 | 1_13 | 1_14 | 1_15 | 1_16 | 1_17 | 1_18 | 1_19 | 1_20 | 1_21 | 1_22 | 1_23 | ||
2_12 | 2_13 | 2_14 | 2_15 | 2_16 | 2_17 | 2_18 | 2_19 | 2_20 | 2_21 | 2_22 | 2_23 | ||
3_12 | 3_13 | 3_14 | 3_15 | 3_16 | 3_17 | 3_18 | 3_19 | 3_20 | 3_21 | 3_22 | 3_23 | ||
4_12 | 4_13 | 4_14 | 4_15 | 4_16 | 4_17 | 4_18 | 4_19 | 4_20 | 4_21 | 4_22 | 4_23 | ||
5_12 | 5_13 | 5_14 | 5_15 | 5_16 | 5_17 | 5_18 | 5_19 | 5_20 | 5_21 | 5_22 | 5_23 | ||
Home Button |
GPIO | Component / Function |
---|---|
0 | exposed, required for bootloader mode |
1 | UART TX |
2 | Home button |
3 | UART RX |
4 | HC595 OE |
5 | HC595 Data |
16 | HC595 Latch |
17 | HC595 Clock |
18 | ICN2012 A1 |
19 | ICN2012 A0 |
21 | ICN2012 A2 |
22 | LED1 |
23 | LED2 |
25 | Unknown (possibly battery) |
26 | SC7A20: SDA |
27 | SC7A20: SCL |
32 | Analog button data for rows 6 and 12 |
33 | Analog button data for rows 5 and 11 |
34 | Analog button data for rows 4 and 10 |
35 | Analog button data for rows 3 and 9 |
36 | Analog button data for rows 2 and 8 |
39 | Analog button data for rows 1 and 7 |
LEDs 12-15 appear to be unused so could be utilised if you want to add extra functionality. Pins 26 and 27 could be used for multiple i2c devices as well.
LED data is passed in in batches of 9 bytes at a time for each multiplexed channel. The data is passed into the daisy chained shift registers in the following format:
This 9 byte array being passed through the shift registers would result in LED 11 being green and all other LEDs remaining off
0b01111111,
0b11111111,
0b11111111,
0b11111111,
0b11111111,
0b11111111,
0b11111111,
0b11111111,
0b11111111
Brightness can be handled via PWM, this has not been thoroughly investigated yet but shouldn't be anything out of the ordinary
Button inputs are logged via the 6 input pins and some kind of circuit logic with resistors.
Via the 6 input pins it's possible to derive how many buttons in a group are pressed; combining this with a scan of a row with a single red pixel it's possible to spot pressed buttons via a deviation in the voltage logic. This was figured out somewhat flukily but can be seen in action via the isButtonPressed
function here.
It's significantly simpler to determine button presses if you assume only one button is pushed at a time.
The accelerometer uses a 2 pin I2C interface and can be seen implemented here