Controlling a Pinball Machine Using Linux
Not everything in the pinball machine control system has to execute as frequently as the low-level hardware I/O operations. Game play itself—how the machine responds to switch detections, lighting different lamps and incrementing the player scores—operates just fine as an ordinary user process. In a sense, it is really a supervisory controller of the low-level I/O processing.
The kernel module should work for every game based on the AS2518 MPU. You can download the source code from the Pinball Machine Reverse-Engineering Kit Project on SourceForge.net and compile it for your kernel. It will then be up to you to write the supervisory control software to play the particular game you are hacking. Table 1 lists other source code files in this package.
Table 1. Source Code for the Pinball Machine Reverse-Engineering Kit
|Source Code File||Purpose|
|analyze_testbed_output.php||Analyzes a game using the parsed text file output of user_pmrek.exe and the saved system activity records.|
|common_functions.php||Functions shared by PHP programs.|
|Makefile_pmrek||GNU Make command file to compile kernel module and executables.|
|pmrek_bash_profile||Appended to auto-login user's bash profile; calls start_testbed.|
|pmrek.c||Linux 2.6 kernel module for hardware control process.|
|pmrek.h||Header file containing definitions and data structures.|
|pmrek.sql||MySQL script to create database, tables and access permissions.|
|start_testbed||Shell script for running standalone testbed system; runs testbed.exe and restarts if terminated for upgrade.|
|testbed.c||Supervisory process for controlling kernel module, playing Evel Knievel, logging and analyzing process data; compiles into the executable testbed.exe.|
|testbed_performance.php||Creates summary statistics of all games analyzed.|
|user_pmrek.c||Utility program for parsing output of testbed.exe, displaying data structure sizes and simulating operation of the kernel module; compiles into the executable user_pmrek.exe.|
You are free to modify the C program testbed.c I wrote for Evel Knievel. It uses the ncurses screen handling package to provide a console color display and user input. A diagnostic display shows the disposition of the switch matrix, the lamps and the most recently fired solenoid. It also shows the player scores, as well as run-time statistics such as the average cycle frequency and execution time of the kernel workqueue process. Keyboard commands can be entered to turn the continuous solenoid on or off, fire momentary solenoids, turn feature lamps on or off and adjust the workqueue delay. Figure 6 shows a game in progress. Note the closed switches; these are drop targets that have been struck.
The supervisory program receives events passed from the kernel module by reading /dev/pmrek, which it has opened using the system call open(), just like any other file. Commands are then sent back to the module by writing to it. I tried to make the main functions correspond to my impression of the key events in a game of pinball. They are listed in Table 2.
Table 2. Supervisory Control Program Functions
|game_add_player()||Called when the credit button is pressed (and there are credits) to start a new game or add more players.|
|game_ball_end()||Called when the outhole switch is detected while a ball is in play to initiate the bonus countdown, advance to the next ball, the next player or end the game.|
|game_collect_bonus()||Called after a ball ends to count down the current player's bonus.|
|game_segment_display()||Emulation of a seven-segment digital display on the computer screen for player scores, match count, credits and ball in play.|
|game_lamp_update()||Called after processing switch detections to update the disposition of all the feature lamps at once.|
|game_play_tune()||Plays various tunes by firing the chime momentary solenoids in predefined sequences.|
|game_switch_response()||Called for each valid switch detection retrieved from the kernel module; initiates all other events related to normal game operation.|
|game_watchdog()||Called every second to detect game faults, including missed switch detections, and either reprocesses the switch response or terminates the program.|
|process_output_file()||Called by the forked child process after a game is completed to analyze the log file recorded during the game play.|
|termination_handler()||Signal handler for cleanly ending the program; closes data log file and puts the kernel module into an idle state.|
|main()||Main program initializes kernel module data structures, computer screen and loops until a termination signal is caught; main loop processes user keyboard input, reads events from kernel module, calls game process functions, writes log file to disk and updates computer screen display.|
You should be able to adapt this code to your particular game by tweaking the functions game_switch_response() and game_lamp_update(). How do you write the program without peeking at the original manufacturer's source code? There are plenty of clues painted on the play field itself, telling you what each switch scores and so on. Of course, you also can create your own rules, perhaps improving on weaknesses in the original design.
The diagnostic display is great for testing, but the player scores are too small. By default, the console simulates the large digital displays on the original back box, as shown in Figure 7. You can get to the diagnostic display by pressing the Self Test switch inside the pinball machine coin door.
We took the game to Pinball at the Zoo in Kalamazoo, Michigan in April 2005. Hundreds of people played the game, which collected statistical data that I used in my Master's thesis. After each game completes, a PHP program reads through the log file created by the game program. It generates an HTML document summarizing the event history of the game and statistics about its real-time performance. These results are then stored in a MySQL database to facilitate analysis of overall performance. Figure 8 is a block diagram of the setup. Figure 9 shows the game in action.
|Dynamic DNS—an Object Lesson in Problem Solving||May 21, 2013|
|Using Salt Stack and Vagrant for Drupal Development||May 20, 2013|
|Making Linux and Android Get Along (It's Not as Hard as It Sounds)||May 16, 2013|
|Drupal Is a Framework: Why Everyone Needs to Understand This||May 15, 2013|
|Home, My Backup Data Center||May 13, 2013|
|Non-Linux FOSS: Seashore||May 10, 2013|
- Dynamic DNS—an Object Lesson in Problem Solving
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Using Salt Stack and Vagrant for Drupal Development
- New Products
- Drupal Is a Framework: Why Everyone Needs to Understand This
- New Products
- Download the Free Red Hat White Paper "Using an Open Source Framework to Catch the Bad Guy"
- Validate an E-Mail Address with PHP, the Right Way
- A Topic for Discussion - Open Source Feature-Richness?
- The Secret Password Is...
2 hours 49 min ago
- Keeping track of IP address
4 hours 40 min ago
- Roll your own dynamic dns
9 hours 53 min ago
- Please correct the URL for Salt Stack's web site
13 hours 5 min ago
- Android is Linux -- why no better inter-operation
15 hours 20 min ago
- Connecting Android device to desktop Linux via USB
15 hours 48 min ago
- Find new cell phone and tablet pc
16 hours 46 min ago
18 hours 15 min ago
- Automatically updating Guest Additions
19 hours 24 min ago
- I like your topic on android
20 hours 10 min ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi
It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?