OPP
Contents
Open Pinball Project
The Open Pinball Project (OPP) was started in 2012 as a resource for pinball makers to have an inexpensive, fully open sourced project for controlling custom pinball machines. It is currently on a second generation design and has had a successful Kickstarter run of boards and components currently in the hands of makers all over the world.
Hardware
The OPP hardware is made up of three main components:
- The Processor board is a Cypress Semiconductor CY8CKIT-049-42XX PSoC prototyping board that can be purchased from Mouser or Digikey.
- The Interface board allows communications between Processor boards via a custom serial communications protocol.
- The Wing boards allow the control of solenoids, lamps, LEDs or input from switches.
The following is an example of some fully assembled and wired OPP Processors with Wing boards.
Processor Boards
The Processor board can have up to four Wing boards controlling solenoids, incandescent lamps, or allowing input for switches. The Wing boards themselves can be combined in any configuration, so a single Processor board can support up to 16 solenoids (with 16 direct switch inputs), 32 switch inputs or 32 lamps. Each Wing board uses eight pins while the Interface board uses four.
All other pins are unused, except on the first board in the chain where the USB plug from the host controller is connected to the Interface board to provide power and serial connections for the other Processors in the chain.
The Processor itself does not run game rules or other game logic - a Controller like Mission Pinball running on a separate PC is still required to handle scoring and other game logic and to fire coils and light lamps as needed. The Processor simply provides the physical connection to playfield devices. (Coils can automatically be fired using the direct switch input for the coil to allow a "white wood" mode that does not require a controller).
Serial Chain
When needing to control more devices or have more switches than a single Processor board can handle, you can chain multiple Processors together via a Serial Chain using a series of 8-pin ribbon cables connected to IN and OUT connectors on the Interface wing.
The ribbon cable serial link between boards works in a similar fashion to a Token Ring network, where each Processor receives messages via the serial line, looks for commands addressed to its ID, removes that command from the message and then passes the remaining message to the next Processor in the chain. The Processor then performs the requested action such as firing a solenoid or turning on a lamp. Switch events are passed back to the primary board and up to the host controller.
The following image gives a visual idea of how messages flow between the Processors:
Like in the above image, each Processor assigns itself an ID on power-up (starting with 0x20 and increasing with each additional Processor) based on its physical position in the serial chain. IDs are not saved between power cycles.
Note that inserting a new card in the middle of a chain will change the ID of every board after it. This will effect any hard-coded ID numbering in controllers like MPF, for example, but should not pose a big problem once the game is complete and no additional boards are added.
Interface Wing
The Interface wing has no transistors or other electronic parts on it other than connectors. Its purpose is to distribute low voltage power (primarily 5V) and serial signals between each Processor board.
Note: The 12V connection is only necessary if using surface mount incandescent wing boards configured as high side switches. Normally the 12V connector can be left unpopulated.
Solenoid Wing
The Solenoid wing uses FQP13N06L MOSFETs to control up to four individual coils via a ground sink method, where the coils themselves are wired to the positive side of the high voltage power supply and the MOSFET provides a ground path when activated, firing the coil.
Standard coil voltages are 24V to 48V and upwards of 10A of current.
There are two connectors on the Solenoid wing - the larger 6-pin has four pins for the coil connections and two for ground. The 4-pin connector is for direct control switch inputs, for devices like slingshots or pop bumpers that require fast response to switch hits in order to fire coils.
Note that the OPP boards support direct control switch programming, so that such devices can be configured in the firmware itself, and the 4-pin connector can cause some packaging issues, so it is recommended to leave the 4-pin connector out when building the boards unless you need it specifically.
However, using the direct switches allows the game to be tested without a host controller, since pop bumpers, slingshots and flippers will work without it.
Incandescent Wing
The Incandescent wing uses 2N7000 MOSFETs to control up to eight direct wired incandescent lamps via the same ground sink method as the coils.
Lamps require a high current 6.3V power supply as each bulb needs about .25A at full brightness.
Direct wired means that each lamp is wired up and controlled individually via the 8-pin connector, rather than in the Matrix style that most commercial pinball machines used until recently.
The other 2-pin connector is for the Ground connection.
Switch Wing
Switches are wired directly to the Processor board via an 8-pin 2.54mm locking header.
Unlike the Solenoid and Incandescent wings, the Switch wing is set up as High-side, where the switch pins are at 5V and playfield and cabinet switches are tied to Ground, so that when a switch is activated, the pins are grounded and the switch is considered 'closed'. It is set up this way since the Processor pins have a Pull-Up resistor on them that is tied to 5V.
The switches provide a ground path for the normally-high inputs.
Before You Start
Prior to ordering and assembling the OPP boards, a number of tools and materials will need to be on hand, and a number of decisions will be made based on the pinball machine being built
Tools and Materials Required
To build and wire the OPP boards, you will need:
- Wire: Look on eBay for stranded wire in the 22-24AWG size.
- Side Cutters
- Pliers
- Soldering Iron: The Hakko FX888D is a popular, inexpensive brand. A lower-priced option is this iron from DX.
- Solder: Kester 44 is an excellent 63/37 solder. DX also has a less expensive option.
- Crimping Tool: Marco Specialities offers an inexpensive tool. Another option is the SN-28B ratcheting crimp tool - it can be purchased for less than $15 on eBay.
- Pin Extractor: Digikey has the Molex-branded tool for extracting the Mini-Fit Jr. style of square connectors used on the Solenoid wings.
Determine Board Layout
Prior to purchasing the OPP boards and components, you need to know how many solenoids, lamps and switches you need to support, where to put them, and how they will be mounted.
For example, a custom game might require 31 inputs, 10 solenoids (with 10 direct inputs), and 43 incandescent bulbs. This could be accomplished with four Processor boards and four Interface wings, three Solenoid wings, six Incandescent wings and five Switch wings. Technically this is more boards and wings than are strictly required, as the Processor boards could handle a denser wing configuration, but this layout cuts down on the total wiring required by placing Processors close to the devices they are controlling, saving significant time and materials.
Alternatively, consider a Williams Jokerz machine. It has 19 solenoids (including direct inputs), 39 switches and 63 incandescent bulbs (which includes 9 flashers). A possible layout for that is five Processor boards with five Interface wings, four Solenoid wings, eight Incandescent wings and five Switch wings.
You can place Processors near what is being controlled, or put them all together in the head of the machine like a traditional commercial pinball - it is entirely up to the maker as to where to place Processors, but placement will determine the final number of Processors and wings required.
Once the total number of Processor and Wing boards has been determined, and their approximate location in the final machine, parts can be ordered.
Power Supply Needs
When running solenoids and lamps, you'll need three voltages: 5V 3A for logic, 6.3V 10A for lamps and 24V to 48V 10A for solenoids (depending on what coils you use). See the Power Supply section for details of what is available.
An inexpensive option is to use a PC power supply, which provides high current 5V for logic and 12V for lamps. A high power DC-DC step down Buck Converter can be used to convert 12V to 6.3V for incandescents.
High current Buck Converters can be found on eBay using the search terms "buck converter step down" - a 12V to 6.3V 12A Buck Converter is around $4.
You can use a separate 24V to 48V 10A switcher for solenoids.
Getting Blank Boards
The OPP site itself does not sell blank boards and there currently is no one selling fully populated and tested boards. However, given the open source nature of the project, there are multiple ways to get the blanks.
The easiest is to order boards from MezelMods as they offer blanks for a very reasonable $1US per board.
The next option is to create Gerber files from the KiCad files located in the OPP SVN repository. For this you'll need to download KiCad, which is a printed circuit board design tool that was used to create the OPP boards. Once you have the Gerber files, they can be uploaded to a number of low-cost PCB manufacturers such as:
Each PCB maker has plusses and minuses that are too involved to go into in this wiki, but SeeedStudio has good prices and fast shipping.
Getting PCBs made can be a fairly advanced process, so it is recommended to simply purchase the already-made boards via MezelMods. They also offer additional parts that are less expensive than purchasing through Digikey or Mouser such as the FC-8P connectors and the 1x40 2.54 mm headers.
Getting Components
Once you have the bare boards, they will need to be fully populated with components, which are not included - they will need to be sourced separately. The following is a Bill of Materials (BoM) for each Processor and Wing board.
Processor Board
Quantity | Mouser Part # | Description | Price Est. | Mezel Price |
---|---|---|---|---|
1 | 727-CY8CKIT-049-42XX | Cypress Semiconductor PSoC 4200 Prototyping Kit | $3.98/ea | N/A |
1 | 649-68602-108HLF | 2 x 4 position 2.54 mm Header | $0.45/ea | $0.20/ea |
2 | 571-9-146278-0 | 40-pin 2.54 mm Header | $2.51/ea | $0.50/ea |
2 | SX1100-B | 2.54 mm Jumper | $0.10/ea | N/A |
Note: The 40-pin header is available much cheaper in larger quantities from eBay - search for "1x40 2.54mm header". These parts are also available through Mezel Mods.
Solenoid Wing
Quantity | Mouser Part # | Description | Price Est. |
---|---|---|---|
4 | 512-FQP13N06L | FQP13N06L MOSFET | $0.67/ea |
4 | 603-CFR-12JR-5210K | 10K Ohm Resistor (1/6W 5%) | $0.02/ea |
1 | 538-35317-0620 | Molex 6-pin 4.2 mm Mini-Fit Header | $0.28/ea |
6 | 538-39-00-0039 | Molex Crimp-Style 4.2 mm 24-18AWG Female Pins | $0.19/ea |
1 | 538-39-01-2065 | Molex 6-pin 4.2 mm Mini-Fit Housing | $0.52/ea |
Parts Needed ONLY If Adding Direct Switches | |||
1 | 640454-4 | 4-pin Polarized 2.54 mm Header | $0.12/ea |
6 | 538-08-50-0136 | Molex Crimp-Style 2.54 mm KK Pins | $0.13/ea |
1 | 538-22-01-2047 | Molex 4-Pin 2.54 mm Housing | $0.17/ea |
Pin-Compatible Higher Current MOSFET (Flippers, etc.) | |||
4 | 942-IRL540NPBF | N-Channel MOSFET 100V 36A | $1.55/ea |
Note: The total number of crimp-style pins included in the BoM is higher than actually needed to account for re-crimping.
Incandescent Wing
Quantity | Mouser Part # | Description | Price Est. |
---|---|---|---|
8 | 512-2N7000TA | MOSFET 60V N-Channel | $0.33/ea |
1 | 538-35317-0220 | Molex 2-pin 4.2 mm Header | $0.12/ea |
1 | 538-39-01-2025 | Molex 2-pin 4.2 mm Housing | $0.33/ea |
3 | 538-39-00-0039 | Molex Crimp-Style 4.2 mm 24-18AWG Female Pins | $0.19/ea |
1 | 571-6404548 | 8-pin 2.54 mm Polarized Header | $0.45/ea |
1 | 538-22-01-2087 | Molex 8-pin 2.54 mm Housing | $0.32/ea |
10 | 538-08-50-0136 | Molex Crimp-Style 2.54 mm KK Pins | $0.13/ea |
Higher Current alternative MOSFET | |||
8 | 512-BS170 | N-Channel MOSFET 60V 500mA | $0.39/ea |
Switch Wing
Quantity | Mouser Part # | Description | Price Est. |
---|---|---|---|
1 | 571-6404548 | 8-pin 2.54 mm Polarized Header | $0.45/ea |
1 | 538-22-01-2087 | Molex 8-pin 2.54 mm Housing | $0.32/ea |
10 | 538-08-50-0136 | Molex Crimp-Style 2.54 mm KK Pins | $0.13/ea |
Note: The Switch wing is just the 8-pin headers soldered directly to the Processor board with the upright lock facing out from the board.
Interface Wing
Quantity | Mouser Part # | Description | Price Est. | Mezel Price |
---|---|---|---|---|
2 | 649-68602-108HLF | 2 x 4 position 2.54 mm Header | $0.45/ea | $0.20/ea |
1 | 640454-4 | Molex 4-Pin 2.54 mm Polarized Header | $0.12/ea | N/A |
2 | 538-22-01-2047 | Molex 4-Pin 2.54 mm Housing | $0.17/ea | N/A |
10 | 538-08-50-0136 | Molex Crimp-Style 2.54 mm KK Pins | $0.13/ea | N/A |
2 | eBay (search "FC-8P") | FC-8P IDC Socket 2.54 mm | ~ $0.10/ea | $0.20/ea |
~10ft | eBay (search "8 pin IDC cable") | 8-pin IDC Flat cable | ~$1/ft | N/A |
Note: Neither Mouser nor Digikey have FC-8P connectors or flat cable in stock, so eBay is the best source for these parts. Mezel Mods sells FC-8P connectors and 2x4 Pin headers for a lower price.
Assembly
Once all the boards and the components are available, you can begin assembly.
Processor Board Assembly
As delivered, the Cypress PSoC 4200 board needs to have two traces on the USB to Serial portion of the board cut - the TX and RX lines. Use an X-Acto knife to cut the thin traces on both sides of the board and use a Multimeter to test between the two through holes to confirm there is no connectivity. This is important to prevent crosstalk on the serial lines.
After the lines are cut, the headers (or lock connectors if being used for switches) can be soldered in, along with the 2x4 header between the USB-to-Serial interface and the main board.
Interface Wing Assembly
The main parts of the Interface wing are the two 2x4 headers for the serial connection and the 4-pin locking header that is used on the first Processor board to bring the Serial output from the USB-to-Serial card into the Interface wing. The 4-pin header is only required for the first Processor board in the chain, and can be left out when building the wing for subsequent boards.
It is best to start with the smallest components and work up - solder the two termination jumpers (marked as R2 and R3) and the serial connector enable jumper as depicted in the diagram, then the 2x4 headers, and finally the 4-pin header if needed.
Once assembled, the Interface board can be soldered to the Processor board on the last four pins marked 4.0 through 4.3 as per the diagram.
The final step is to connect VDD and GND to the Interface wing by soldering wire from the Processor board to the Interface wing as per the diagram - GND to Pin 1 and 5V to Pin 2. This is required to power all the downstream Processor boards as none of them will be plugged into the USB connector which normally provides power. The 8-pin ribbon cable used for serial communications also provides 5V and ground connections.
Solenoid Wing Assembly
The parts for the Solenoid wing are the four MOSFETs, four 10K Resistors, a 2x3 header and a 4-pin locking header. If you are not using the direct switch capabilities of the Solenoid wing, it is recommended to leave the 4-pin out of the build as it causes some packaging issues when placing wings next to each other, as the 2x3 header sticks off the end of the board slightly and makes contact with the 4-pin header on the adjacent wing.
As with the Interface wing, start with the smallest components and work upwards - resistors, MOSFETs then headers. The 2x3 header should be installed with the locking tab facing "up" as in the above diagram.
After assembly, it can be soldered in the appropriate spot on the Processor board. It is recommended to place Solenoid boards in the Wing 0 and Wing 1 positions as this allows a short jumper to connect the logic (5V) ground wiring for the pulldown, as well as slightly better fitment due to the chip packaging on the Processor boards. However, it is not a requirement - Solenoid wings can be placed in any position, as long as the pulldown ground is properly wired.
After soldering the Solenoid wing to the Processor board, use a solid wire jumper to tie it and the Interface board together on the very end through holes. This is a purely physical connection that helps add stability to the board - there is no electrical connection on those holes. A good source for a jumper wire are the leftover legs from the resistors after they've been soldered in and cut to length.
Incandescent Wing Assembly
The through-hole Incandescent wing parts are eight 2N7000 MOSFETs, an 1x8 locking header for lamp connections and a 2-pin header for the 12V ground connection. No resistors are required, so all resistor spots are left empty.
NOTE: As the board was originally designed for BS170s, the screened artwork reflects the pinout for that part, but the pinout is reversed for the 2N7000, so it is critically important to install the MOSFETs in the REVERSED orientation from the artwork.
The tab for the 2-pin header should face inwards towards the center of the board.
Once assembly is complete and the wing is installed on the Processor, a solid wire jumper should be installed on the end holes to provide stability. As with all wing boards other than the Interface board, the Incandescent wing can be installed in any of the four positions.
Switch Wing Assembly
There is no physical wing board required for the Switch wing - it consists entirely of a single 8-pin 2.54mm locking header connected directly to the Processor board.
Firmware
The OPP boards aren't just about the physical hardware, there's also an operating system - to handle the serial communication with the host, moving messages along the serial chain, activating coils and lamp, and maintaining state for all the above. This software is known as Firmware and it runs on each Processor board. This is what talks to the host computer over USB.
The firmware is available for download via the OPP SVN repo. It must be copied to each Processor individually in order for them to work - it cannot be done while the Processors are connected via the Serial Chain.
RX/TX Jumpers
As part of the initial board setup, the RX/TX traces were cut on the Processor board. In order to copy the firmware to the board, jumpers will need to be put in place to connect the two serial pins on the USB-to-Serial interface to the board itself.
Determine your USB Device
In order to talk to the Processor via the host computer's USB port, a device driver will likely need to be installed. Cypress offers device drivers for Windows, Linux and Mac.
Install the appropriate driver for your host computer following the instructions from the Cypress site.
Once installed, plugging the Processor into a USB port on the host computer should result in a device being mounted on your system, with an associated serial device - a COM port on Windows or a tty
or cu
file in the /dev
directory for Linux and Mac.
To determine the port, check the syslog on Mac/Linux or the System Console on WIndows.
Whatever the device name is, write it down as it will be needed for copying the firmware and all future communication with the Processor boards.
cyflash
cyflash is a Python utility provided by Cypress to copy firmware to the board. It is included as part of the OPP SVN repo under the Python/cyflash
directory.
The instructions for downloading the SVN repo are detailed on the main SVN page. Once downloaded to the local filesystem into a directory called opp
, do a directory listing to confirm the cyflash files are in place.
How the firmware is uploaded depends on which OS you use - Windows, Linux or Mac. Linux and Mac are a bit simpler as they already have the correct version of Python installed by default.
For Windows, download the Latest Version of Python 2.7 and follow the install instructions as listed. It should be in the C:\Python27
directory (the default).
From the command line, change into the opp/Python/cyflash/
directory. The cyflash utility can be envoked with the following parameters:
Linux/Mac
python -m cyflash.__main__ --serial /dev/[serial-device] --serial_baudrate 115200 ../../Creator/Gen2Images/Gen2.rev0.2.0.0.cyacd
Windows
c:\Python27\Python.exe -m cyflash.__main__ --serial COM[serial-device] --serial_baudrate 115200 ..\..\Creator\Gen2Images\Gen2.rev0.2.0.0.cyacd
Before running the command, you must put the Processor into bootloader mode. Plug the board in while holding down the small button at the end of the board, which will cause the blue LED to flash rapidly.
Running cyflash should begin to upload the firmware to the board.
% python -m cyflash.__main__ --serial /dev/cu.usbmodem1411 --serial_baudrate 115200 ../../Creator/Gen2Images/Gen2.rev0.2.0.0.cyacd CyFlash version: 1.07 Initialising bootloader. Silicon ID 0x04c81193, revision 17. Bootloader version: 1.20 Array 0: first row 32, last row 255. Uploading data (128/128) Device checksum verifies OK. Rebooting device.
When it is complete, the board should reboot and the LED stop flashing. The board is now ready for configuring the Wing layout.
Gen2Test
Gen2Test is the OPP utility used to check Processor status, as well as erase, load and save the Wing configuration prior to using it with the host controller. It uses an additional Python script as a config file that you define. Even if you use a framework like MPF that automatically sets up the Processor configs for you on startup, it is a good idea to configure each board and save the configs separately to prevent coil or lamp lock-on due to a wing being defined as a switch or other issues.
Example Configuration Files
Here are some examples of wing config files. They are not included in the SVN repo, but can be copied and used for configuring boards if saved with a .py
extension.
2sol2switch.py: This config sets Wing 0-1 to Solenoid wings, and Wing 2-3 to Switch wings.
testVers = '00.00.01' import rs232Intf # Config inputs as all state inputs wingCfg = [ [ rs232Intf.WING_SOL, rs232Intf.WING_SOL, rs232Intf.WING_INP, rs232Intf.WING_INP ] ] # Config inputs as all state inputs inpCfg = [ [ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE ] ] # solenoid config solCfg = [ [ rs232Intf.CFG_SOL_USE_SWITCH, '\x20', '\x00', rs232Intf.CFG_SOL_USE_SWITCH, '\x20', '\x00', \ rs232Intf.CFG_SOL_USE_SWITCH, '\x20', '\x00', rs232Intf.CFG_SOL_USE_SWITCH, '\x20', '\x00', \ rs232Intf.CFG_SOL_USE_SWITCH, '\x20', '\x00', rs232Intf.CFG_SOL_USE_SWITCH, '\x20', '\x00', \ rs232Intf.CFG_SOL_USE_SWITCH, '\x20', '\x00', rs232Intf.CFG_SOL_USE_SWITCH, '\x20', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00' ] ]
4incand.py: This config sets all four wings to Incandescent.
testVers = '00.00.01' import rs232Intf # Config inputs as all state inputs wingCfg = [ [ rs232Intf.WING_INCAND, rs232Intf.WING_INCAND, rs232Intf.WING_INCAND, rs232Intf.WING_INCAND ] ] # Config inputs as all state inputs inpCfg = [ [ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE ] ] # solenoid config solCfg = [ [ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00' ] ]
2incand2switch.py: This config sets Wing 0-1 as Incandescent and Wing 2-3 as Switch.
testVers = '00.00.01' import rs232Intf # Config inputs as all state inputs wingCfg = [ [ rs232Intf.WING_INCAND, rs232Intf.WING_INCAND, rs232Intf.WING_INP, rs232Intf.WING_INP ] ] # Config inputs as all state inputs inpCfg = [ [ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, \ rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE, rs232Intf.CFG_INP_STATE ] ] # solenoid config solCfg = [ [ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', \ '\x00', '\x00', '\x00', '\x00', '\x00', '\x00' ] ]
The key lines in each file are wingCfg
, which defines the layout, and solCfg
, which sets the default values for each solenoid if a Solenoid wing is used on the Processor. InpCfg
and the rest of the file are the same for each config.
wingCfg
lists each wing type in order of wing position from 0 to 3. solCfg
has three parameters per coil - the type of solenoid (USE_SWITCH, AUTO_CLR, ON_OFF_SOL, or DLY_KICK_SOL), initial kick time in milliseconds ("\x20" equals 32ms), and the last is the PWM duty cycle. "\x00" disables PWM. All values are in hexadecimal notation.
For a detailed explanation of what each value means, you can reference the documentation for the serial protocol (opp/Docs/brdIntf.pdf
) in the SVN repo, as well as see the definitions for each value in the opp/Python/Gen2Test/rs232Intf.py
script.
However, any of the above examples, or the included mdCfg
file, will work as-is without needing a deep understanding of the firmware internals.
Running Gen2Test
From the command line, change into the opp/Python/Gen2Test
directory.
Plug in the Processor with the USB jumpers installed and run the command (with either C:\Python27\Python.exe
or just python
depending on your system):
Gen2Test.py -port=[serial-device]
Where the serial-device
is the appropriate serial port on the host computer saved from earlier. The command should provide an inventory of the Wings as set by the firmware when it was uploaded. The default is all wings set to Switch.
% python Gen2Test.py -port=/dev/cu.usbmodem1411 Sending inventory cmd Found 1 Gen2 brds. Addr = ['0x20'] 0x20 WingCfg = 0x02020202 0x20 INP_WING INP_WING INP_WING INP_WING
Next, erase the current config:
% python Gen2Test.py -port=/dev/cu.usbmodem1411 -eraseCfg Sending inventory cmd Found 1 Gen2 brds. Addr = ['0x20'] 0x20 WingCfg = 0x02020202 0x20 INP_WING INP_WING INP_WING INP_WING Sent erase cfg command.
Followed by saving a new config. Put the name of your config file minus the .py
extension:
% python Gen2Test.py -port=/dev/cu.usbmodem1411 -saveCfg -loadCfg=2sol2switch Sending inventory cmd Found 1 Gen2 brds. Addr = ['0x20'] 0x20 WingCfg = 0x02020202 0x20 INP_WING INP_WING INP_WING INP_WING loadFileName = 2sol2switch Sending wing cfg. Sending input cfg. Sending solenoid cfg. Skipping sending color table. Sending save cfg command. Done save cfg command.
Run Gen2Test again with just the port parameter to check the new configuration.
% python Gen2Test.py -port=/dev/cu.usbmodem1411 Sending inventory cmd Found 1 Gen2 brds. Addr = ['0x20'] 0x20 WingCfg = 0x01010202 0x20 SOL_WING SOL_WING INP_WING INP_WING
This configuration will persist between power cycles, so once this step is complete, Gen2Test will not be needed again except to test the connection between the host computer and the OPP boards. To perform that test, unplug and plug-in the Processor and run Gen2Test again to confirm the configuration is saved as above.
Connecting Multiple Boards
Once each individual board is configured, the next step is to create the serial connection between boards by chaining them together via multiple 8-wire ribbon cables.
Serial Cables
The serial cables consist of standard 8-wire ribbon cable - usually a light grey or sometimes in rainbow colors - with FC-8P connectors on each end. These are IDC connectors, which is an acronym for Insulation Displacement Contact. IDC connectors displace the insulation on a wire to make a connection.
You place the wire flat inside the connector and compress the cover (using pliers or similar) to cut into the insulation and connect the wires. The cover locks and all 8 pins should now be connected. The ends can be trimmed with a side cutter or X-Acto knife. The connector should include a cap, used for extra support for the cable, under which the wire is bent prior to crimping.
Each FC-8P connector will have a positioning tab on the housing, and it is recommended to have the tab facing down towards the cable on one end and facing out on the other, so the tab is the same direction at the top and bottom. It isn't critical but it makes it easier to install cables knowing the tab always faces the same direction.
The finished cable should look similar to this example.
First Processor
The first board in the chain connects to the host controller via USB, and uses the integrated USB-to-Serial interface to connect to the Interface board via a 4-wire cable that must be constructed. This cable consists of two Molex 2.54mm housings and pins, which are part of the BoM for the Interface wing.
It connects 5V and Ground to power the other boards in the chain, as well as the TX and RX serial lines used for communicating between Processors.
If you are not familiar with crimping Molex connectors, you can read a detailed tutorial on the PinRepair site that covers proper connection crimping prior to constructing the cable.
Once both the 4-wire and ribbon cables are done, they can be connected to the Processor per the following diagram:
The Interface wing has two 2 x 4 2.54mm connectors labelled IN and OUT. The ribbon cable is connected to the OUT with the ribbon running down from the wing.
Middle Processor
The ribbon cable from the first board connects to the IN connector on the Interface wing of the middle Processor with the ribbon facing up, and another ribbon cable is connected to the OUT connector to lead to the next Processor. This is repeated for each additional Processor in the chain until the last one, so you will need multiple ribbon cables.
Last Processor
On the last Processor in the Serial Chain, the ribbon cable from the previous Processor is attached to the IN connector and a Jumper is placed between Pins 3-4 on the OUT connector, or the top right two pins, to terminate the chain by looping the serial connection together.
Without the jumper, the serial connection chain will not work and any commands will fail.
Testing the Chain
With the first Processor plugged into USB, all Processors should light up if wired correctly. If not, check the ribbon cables for correct orientation. Plugging them in backwards will not damage the boards but it will prevent them from getting power.
Note on this example of a two board chain, the yellow LEDs are lit on both boards, indicating a successful connection:
Running Gen2Test
with only the port parameter should generate an inventory of all cards:
% python Gen2Test.py -port=/dev/cu.usbmodem1411 Sending inventory cmd Found 2 Gen2 brds. Addr = ['0x20', '0x21'] 0x20 WingCfg = 0x01010202 0x20 SOL_WING SOL_WING INP_WING INP_WING 0x21 WingCfg = 0x02020202 0x21 INP_WING INP_WING INP_WING INP_WING
Wiring Examples
At this point the controller boards are ready to be installed in the game and wired up to all solenoids, lamps and switches.
Solenoids
Solenoids are wired with positive voltage from the high voltage power supply (24V to 70V depending on your game) and the other lug to the Solenoid wing via the 2x6 Molex connector. When the MOSFET is triggered, it connects ground for that solenoid and it activates.
NOTE: a 4004 or similar diode must be placed across the positive and ground connections with the band towards the positive wire. This allows for the flyback voltage that is generated when a coil's magnetic field collapses. Without it, that voltage travels back to the Solenoid wing and will likely destroy the MOSFETs, so it is critical that the diode be in place.
Direct switches are connected via the 1x4 Molex connector and wired to the Logic (5V) ground.
Incandescent Lamps
Lamps are wired with positive voltage from the 6.3V power supply and connected to an Incandescent wing via the 1x8 Molex connector. The ground for the lamps is provided by the 1x2 Molex connector, which should be connected to the 6.3V power supply ground.
Switches
Switches are wired with ground from the logic (5V) power supply and connected to the Switch wing (directly to the Processor) via the 1x8 Molex connector. Power is provided via the Interface card from the USB connection.
Troubleshooting
If after assembling the boards and testing the connections they do not work, see below for some suggestions on next steps.
Python Errors
The most common result when testing boards is the IndexError: string index out of range
error from Python. This error means that the serial communication failed and no results were returned.
- Has the firmware been installed?
- Has the Processor been correctly configured for the wings that are installed?
- Is the yellow power LED on when plugged into USB?
- Are you using the correct serial port?
If the answers to the above questions are Yes, then the issue may be hardware related.
Hardware Checklist
More often than not, due to having to self-assemble the boards, assembly errors can cause issues. Here is a checklist of possible reasons why a Processor may not respond to commands.
- Check 5V at multiple points: Interface wing, USB-to-Serial interface, bottom of Cypress board
- Check ground connections are correct and solid with no breaks in the solder
- Use a multimeter to confirm RX/TX lines are cut
- When testing a single board, confirm both RX and TX lines are correctly jumpered on USB-to-Serial interface
- When testing multiple boards, confirm all cables are correctly oriented
- When testing multiple boards, confirm last board is correctly terminated with a jumper on pins 3-4 of OUT connector
Contact OPP Support
If a reason for the failure cannot be found, the maintainer of the Open Pinball Project offers support via email at:
The maintainer is extremely responsive to questions and can often help find the issue with your setup. However, remember that OPP is run by volunteers, so they may not respond immediately to requests for help.