├── APC.ino ├── BaseCode.ino ├── BlackKnight.ino ├── DOC ├── APC_board.md ├── BlackKnight.md ├── Changes.md ├── Comet.md ├── Frames.md ├── GameCodeTutorial.md ├── Hardware │ ├── APC_FabricationFiles_SOIC │ │ ├── APC_BOM.csv │ │ ├── APC_Gerber.zip │ │ └── APC_cpl_top.csv │ ├── APC_FabricationFiles_SSOP │ │ ├── APC_BOM.csv │ │ ├── APC_Gerber.zip │ │ └── APC_cpl_top.csv │ ├── APC_LED_exp │ │ ├── APC_LED_exp-B.Cu.svg │ │ ├── APC_LED_exp.ino │ │ ├── APC_LED_exp.pdf │ │ └── LED_Gerber.zip │ ├── APC_Solenoid_exp │ │ ├── APC_Solenoid_exp-drl_map.pdf │ │ ├── APC_Solenoid_exp_Comp.pdf │ │ ├── APC_Solenoid_exp_schematic.pdf │ │ └── Solenoid_exp_Gerber.zip │ ├── APC_schematics.pdf │ ├── Assembly │ │ ├── APC_BOMnonSMD.pdf │ │ ├── APC_BOMselfSolder.pdf │ │ └── APC_components.pdf │ ├── InstallationFrames │ │ ├── System11_stl.zip │ │ ├── System11c_stl.zip │ │ ├── System7_stl.zip │ │ └── System9_stl.zip │ ├── Sys11a_Display │ │ └── Sys11_Gerber.zip │ ├── Sys7Alpha │ │ ├── AlphaDisp_Gerber.zip │ │ ├── AlphaDisp_v12-Bottom.svg │ │ ├── Credit_Gerber.zip │ │ ├── Credit_v11_-Bottom.svg │ │ ├── Credit_v11_-PTH-drl_map.pdf │ │ ├── Driver-PTH-drl_map.pdf │ │ ├── Driver.pdf │ │ ├── DriverBOM.pdf │ │ ├── Driver_Bottom_comp.pdf │ │ ├── Driver_Gerber.zip │ │ └── Driver_Top_comp.pdf │ └── Sys7_Display │ │ ├── S7Driver20p_BOM.csv │ │ ├── S7Driver_Gerber.zip │ │ ├── S7Player_Gerber.zip │ │ ├── Sys7_Driver.pdf │ │ └── Sys7_OldBoard.JPG ├── InitialTests.md ├── LEDexpBoard.md ├── LisyDebug.md ├── PICS │ ├── APC.JPG │ ├── APC_Connectors.png │ ├── APC_Pinbot.JPG │ ├── APC_Rollergames.JPG │ ├── Audacity.png │ ├── BK.jpg │ ├── BKopen.JPG │ ├── Buck.jpg │ ├── Comet.jpg │ ├── CometLED.jpg │ ├── FrameExample.JPG │ ├── FrameSys11a.JPG │ ├── FrameSys11c.JPG │ ├── FrameSys7.JPG │ ├── FrameSys7_2.jpg │ ├── FrameSys9.JPG │ ├── GI_LEDs.jpg │ ├── LED_ExpBoard.jpg │ ├── LampFix.jpg │ ├── LisyJumper.png │ ├── MiniLisy.png │ ├── PinMame.jpg │ ├── Pinbot.JPG │ ├── PlayerDisplay.png │ ├── RG_Sol.JPG │ ├── RG_Sw.JPG │ ├── Ringbuffer.png │ ├── SDadapter.JPG │ ├── SDonBoard.JPG │ ├── SolExpBoard.JPG │ ├── Sys11cKabel.jpg │ ├── Sys7DispCable.JPG │ ├── Sys7SoundCable.jpg │ ├── Sys7_Alpha.jpg │ ├── Sys7_Alpha2.jpg │ └── U1wrongPol.jpg ├── PinMame.md ├── PinMameExceptions.md ├── PinMameSound_11.md ├── PinMameSound_3_7.md ├── PinMameSound_9.md ├── PinMameSounds.md ├── Pinbot.md ├── Prepare.md ├── Problems.md ├── RunGame.md ├── SetUpBC.md ├── Settings.md ├── Software │ ├── APC_SW_reference.pdf │ ├── APC_SoundCheck │ │ ├── APC_SoundCheck.ino │ │ └── Sound.h │ ├── AudioSave.pl │ ├── AudioSaveFolder.pl │ ├── DisplayAlphaLower.pl │ ├── DisplayAlphaUpper.pl │ ├── DisplayNumLower.pl │ └── MPF │ │ └── Rollergames │ │ ├── config │ │ └── config.yaml │ │ ├── data │ │ ├── audits.yaml │ │ └── machine_vars.yaml │ │ └── modes │ │ ├── LeftOrbit │ │ └── config │ │ │ └── LeftOrbit.yaml │ │ ├── Lock1 │ │ └── config │ │ │ └── Lock1.yaml │ │ ├── attract │ │ ├── config │ │ │ └── attract.yaml │ │ └── shows │ │ │ ├── attract_display_loop.yaml │ │ │ └── attract_light_show.yaml │ │ └── base │ │ └── config │ │ └── base.yaml ├── SolExpBoard.md ├── Specialties.md ├── Sys7Alpha.md ├── Upload_SW.md ├── UsefulSWtools.md └── lisyminigames.csv ├── LICENSE ├── PinMameExceptions.ino ├── Pinbot.ino ├── README.md ├── Sound.h ├── Tutorial.ino ├── USBcontrol.ino └── _config.yml /DOC/APC_board.md: -------------------------------------------------------------------------------- 1 | # The APC board 2 | 3 | First you should know what you're dealing with, so take a look at the [APC schematics](https://github.com/AmokSolderer/APC/blob/master/DOC/Hardware/APC_schematics.pdf). I have tried to design the hardware simple and straightforward, that means with a bit of hardware knowledge it shouldn't be a problem for you to understand how it works. 4 | 5 | In the schematics the names of the connectors are given for System7 and System11, but the System7 names are also valid for System3 - 6 and the System11 names match to System9. The following picture should help you to determine where the various connectors belong. The direction of the Molex connectors is printed on the boards and also visible in the picture below: the friction lock belongs to the side where the additional thin line is drawn. 6 | The solenoid GND connector of Sys11 games (1J13) has only 4 pins, in the picture it is marked as a black rectangle. The X symbols indicate which pins have to be removed. 7 | 8 | ![APC connectors](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/APC_Connectors.png) 9 | 10 | However, the APC is only suited for you if you have some basic knowledge of electronics, because you can easily damage your precious pinball machine when you don't do things right. 11 | 12 | ## Order a board 13 | 14 | I recommend to use [JLCPCB](https://jlcpcb.com) as your board manufacturer, because the assembly files are tailored to their specifications. You need to order at least five boards, so you might want to ask in the forum first whether someone from your country has a board for sale. 15 | If you want to place an order, the manufacturer will need the APC_Gerber.zip file to build the boards. You also have to select 'PCB Assembly' and choose the top side for assembly. In the next step you have to provide the APC_BOM.csv and APC_cpl_top.csv files to make them populate the parts. All required files are located [here](https://github.com/AmokSolderer/APC/tree/V01.01/DOC/Hardware/APC_FabricationFiles_SOIC). 16 | 17 | However, it has become increasingly difficult to get all the required parts. In this case JLCPCB would state an 'Inventory shortage' in the parts list. You can either try to select another part with the same package or you could pre-order the part. Go to the 'Parts Manager' to do so. If the pre-ordering was successful you can use these parts for your boards. 18 | 19 | Note that JLCPCB will populate the Molex connectors, but they wont remove the key pins. This can be done easiliy by heating them up with a soldering iron and pulling them out with a pair of pliers. 20 | 21 | ## The Components 22 | 23 | Most of the components can be populated by the board manufacturer. They can do all SMD and most of the other stuff as well. Hence, there're only a few components left for you to assemble. You can find a list of these components with their respective order number from [Mouser](http://www.mouser.com) and [Reichelt](http://www.reichelt.de) in the [Bill of Materials](https://github.com/AmokSolderer/APC/blob/master/DOC/Hardware/Assembly/APC_BOMselfSolder.pdf) 24 | 25 | The german electronics retailer Reichelt doesn't sell all required components, but some (especially connectors) are much cheaper compared to Mouser, so for people in Europe it might still make sense to order them separately. 26 | 27 | ### TDA7496 availability 28 | 29 | I got a notification from Mouser that the TDA7496 audio amplifier IC won't be produced any longer. 30 | 31 | You can use the TDA7495 instead which is a pin compatible replacement. It's also discontinued, but at the moment the TDA7495 is available on eBay for a reasonable price. In China there are still large quantities of both ICs available for very low prices. 32 | However, this might change in the future so you should be sure to get these ICs before you order any boards. 33 | 34 | ## The assembly 35 | 36 | As the boards have the component names printed at the corresponding locations, you can just use the [Bill of Materials](https://github.com/AmokSolderer/APC/blob/master/DOC/Hardware/Assembly/APC_BOMselfSolder.pdf) to identify the right component to put there. 37 | The resistor network RR8 has to be populated in the correct orientation. There's a marking for pin 1 printed on the APC boards. On the resistor networks pin 1 is usually marked with a dot. 38 | 39 | ## Getting your board started 40 | 41 | Plug the Arduino DUE on your APC board, but don't populate the Pi yet. I recommend to do the basic tests before assembling the Pi. 42 | The next step is to [Upload the SW](https://github.com/AmokSolderer/APC/blob/master/DOC/Upload_SW.md). I'd do this before you put the APC board into your pinball machine, because if this works you know, that your 5V supply has no short and is working properly. 43 | -------------------------------------------------------------------------------- /DOC/BlackKnight.md: -------------------------------------------------------------------------------- 1 | # The APC Black Knight 2 | 3 | This page is about the BlackKnight.ino game SW which is part of the APC SW. Note that you have to have the Black Knight sound files for this game to work. 4 | Some features like the High Score table are only available when my [4 Alpha+Credit](https://github.com/AmokSolderer/APC/blob/master/DOC/Sys7Alpha.md) display is used. 5 | 6 | ![APC Black Knight](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/BK.jpg) 7 | 8 | This is a view inside the backbox. 9 | 10 | ![APC open BK](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/BKopen.JPG) 11 | 12 | I'm using an APC 2 prototype board for this. As I'm running the code natively on the Arduino I don't need Lisy/PinMame and therefore no Raspberry Pi. 13 | 14 | The LED_exp board which is connected here is also not needed. 15 | 16 | ## Features 17 | 18 | * Timed Magna Saves -> When activated, the Magna Saves behave like in games like Jungle Lord, for the magnets are active as long as the corresponding button is being held and you still have Magna Save Time left. Clearing a drop target bank adds one second to the Magna Save Time. The Black Knight is lacking the playfield lamps to indicate the remaining Magna Save Time, so this is done by letting the Magna Save lamps blink. The slower the blinking frequency the more Magna Save Time is left until the lamps stay on permanently when the Magna Save Time has reached 5 seconds. 19 | * Multi Ball Jackpot -> When activated a music score is played after Multiball has started. After all balls are released a music score starts and the lamp of the lower eject hole starts blinking. A shot to this hole enables the upper lock for Jackpot. After the Jackpot has been scored, the lower hole starts blinking and the Jackpot can be enabled again. 20 | * Improved ball release -> In System7 games it sometimes happens that a ball ejected into the plunger lane bounces back from the side rail and into the trunk again. If it gets back into the trunk completely the SW will recognize this and eject the ball again. But sometimes the ball doesn't really get back into the trunk. Instead it gets stuck above the shooter lane feeder and there isn't much to do about it except of opening the coin door and operating the feeder manually to push the ball into the shooter lane. The APC Black Knight SW offers a settings to adjust the strength of the ball feeder. When properly adjusted this avoids that the ball is bouncing back. 21 | * Ball search -> The SW features a ball search mode which is started when no playfield switch has been triggered for 30 seconds. The SW will recheck the locks and the ball through and will activate certain solenoids if a ball is missing. 22 | * High Score table -> This feature is only available if '4 Alpha+Credit' is selected as the Display Type for it doesn't make much sense to enter initials no one is able to see. However, with the correct display installed you can enter you initials by using the Magna Save buttons. 23 | 24 | ## How to set up this game 25 | 26 | You need to have the audio files for this game. [Contact me](https://github.com/AmokSolderer/APC/tree/master#feedback) to get the corresponding sound file package. 27 | 28 | If you want to use the Multiball Jackpot feature you need to pick a music track to be played during Multi Ball. Take a track of your choice, convert it to the APC sound format and rename it to BK_M01.snd. 29 | The same needs to be done for the High Score table feature. In this case the name of the music track has to be BK_M02.snd. As already mentioned, the High Score table is only available when alphanumeric displays are used. 30 | 31 | ## BK Game Settings 32 | 33 | | Number | Text | Item Nr | Item Text | Default | Comment | 34 | |--|--|--|--|--|--| 35 | | 0 | Timed Magna | - | - | No | Bool setting - see features description | 36 | | 1 | Replay Score | 0 | 1000000 | X | Set 1 million as replay score | 37 | | 1 | | 1 | 1500000 | - | Set 1.5 million as replay score | 38 | | 1 | | 2 | 2000000 | - | Set 2 million as replay score | 39 | | 1 | | 3 | 2500000 | - | Set 2.5 million as replay score | 40 | | 2 | Multiball Jackpot | 0 | Off | X | Turn the multiball jackpot off | 41 | | 2 | | 1 | 500000 | - | Set 500K as multiball jackpot | 42 | | 2 | | 2 | 750000 | - | Set 750K as multiball jackpot | 43 | | 2 | | 3 | 1000000 | - | Set 1 million as multiball jackpot | 44 | | 3 | Multiball volume | - | - | 0 | Numerical setting - range 0 - 30 / can be used to increase the volume during multiball. Does only work when the digital volume control of the APC is used and not the old volume pot | 45 | | 4 | High Score volume | - | - | 0 | Numerical setting - range 0 - 30 / can be used to increase the volume during high score entry. Does only work when the digital volume control of the APC is used and not the old volume pot | 46 | | 5 | Ball eject strength | - | - | 30 | Numerical setting - range 0 - 30 / activation time of the ball ramp thrower (solenoid 6) in ms. Adjust this to avoid that the ball is bouncing back into the trunk 47 | | 6 | Reset High | - | - | - | No setting - resets the high scores for this game | 48 | | 7 | Restore Default | - | - | - | No setting - restores the default settings | 49 | | 8 | Exit Settings | - | - | - | No setting - exits the settings mode and writes the new setting to an SD card if present | 50 | 51 | Check the [settings page](https://github.com/AmokSolderer/APC/blob/master/DOC/Settings.md#using-the-settings-menu) if you're not sure how to use these game settings. 52 | ## Things to do 53 | 54 | * The Jackpot still needs some sound effects. 55 | -------------------------------------------------------------------------------- /DOC/Comet.md: -------------------------------------------------------------------------------- 1 | # The APC Comet 2 | 3 | The basic game runs in PinMame as described in the [PinMame Section](https://github.com/AmokSolderer/APC/blob/master/DOC/PinMame.md). 4 | This page is about the PinMameExtensions I did for my Comet. You need to install the SW from the AmokPrivate branch on GitHub to run my special extensions. 5 | 6 | As you can see, my Comet is using my [4 Alpha+Credit](https://github.com/AmokSolderer/APC/blob/master/DOC/Sys7Alpha.md) displays. All extensions will also work with the original numerical displays except the custom text feature of course. 7 | The blue shine on the playfield is from the LED effects I added to my GI. 8 | 9 | ![APC Comet](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/Comet.jpg) 10 | 11 | This is a view inside the backbox. 12 | 13 | ![APC open Comet](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/CometLED.jpg) 14 | 15 | You can see the [LED expansion board](https://github.com/AmokSolderer/APC/blob/master/DOC/LEDexpBoard.md) which is needed for the LED effects. 16 | 17 | ## Features 18 | 19 | * Ball saver -> Comet's outlanes are special. Alas, this leads to lots of balls falling from the bumper area into the left outlane without any way for the player to prevent this. Therefore I added an optional ball saver to my PinMameExtensions which gives back any ball which is lost through an outlane when the last active switch before was in the bumper area. 20 | Watch [this video](https://youtu.be/JbgMa_pn0Lo) to see how the ball saver works. 21 | * LED GI -> I'm using the [LED expansion board](https://github.com/AmokSolderer/APC/blob/master/DOC/LEDexpBoard.md) with some RGB-LED chain instead of the old GI lightbulbs. You can choose your GI color in the Game Settings. 22 | * GI gameplay animations -> During normal gameplay the GI LEDs behave like the normal GI, but in some occasions when the game shows some fireworks animation with the backbox flashers the GI does the same on the playfield, which makes this effect much stronger. 23 | * GI attract animations -> I also use the GI LEDs to play some colorful animations every now and then during attract mode. There's a video showing my [GI LEDs](https://youtu.be/kLWVUdhSwfo) in action 24 | * Custom Text Message -> As my game has alphanumeric displays I'm showing a custom text message when the GI LEDs are showing their animations during attract mode. The text is retrieved from the file Custom.txt which has to be present on the SD card. 25 | * Custom game music -> Comet's original music is ... basic. So to hear a song of your choice during gameplay, name it MUSIC.SND, store it on the SD card and select 'Music bin' in the game settings. 26 | 27 | ## How to set up this game 28 | 29 | * You need to have the audio files for this game. [Contact me](https://github.com/AmokSolderer/APC/tree/master#feedback) to get the corresponding sound file package. 30 | * Use the 'AmokPrivate' branch of GitHub to get the additional features. The normal 'master' branch just supports Comet without any special features. 31 | * For the GI LED animations you need to install the necessary HW of course, but the other features work without it. The same applies for the alphanumeric displays. 32 | 33 | ## Comet Game Settings 34 | 35 | | Number | Text | Item Nr | Item Text | Default | Comment | 36 | |--|--|--|--|--|--| 37 | | 0 | USB watchdog | - | - | No | Bool setting - disables all solenoids when no watchdog reset command is received for 1s | 38 | | 1 | Debug Mode | 0 | Off | X | No debugging | 39 | | 1 | | 1 | USB | - | Shows the received commands in the displays | 40 | | 1 | | 2 | Audio | - | Audio debug mode for PinMame Sounds | 41 | | 2 | PinMame Sound | 0 | APC | X | PinMame sounds are played on the APC sound HW | 42 | | 2 | | 1 | Board | - | PinMame sounds are played on an external audio board | 43 | | 3 | PinMame game | - | - | 0 | Numerical setting - PinMame game number | 44 | | 4 | Lisy Debug | - | - | 0 | Numerical setting according to the [Controlling Lisy](https://github.com/AmokSolderer/APC/blob/master/DOC/LisyDebug.md) page | 45 | | 5 | Ball Saver | 0 | Off | X | No ball saver | 46 | | 5 | | 1 | Right Outlane | - | Ball saver only active for the right outlane | 47 | | 5 | | 2 | Left Outlane | - | Ball saver only active for the left outlane | 48 | | 5 | | 3 | Both Outlane | - | Ball saver active for both outlanes | 49 | | 6 | LED GI red | - | - | 255 | Numerical setting (0-255) -> GI color setting red | 50 | | 7 | LED GI green | - | - | 255 | Numerical setting (0-255) -> GI color setting green | 51 | | 8 | LED GI blue | - | - | 255 | Numerical setting (0-255) -> GI color setting blue | 52 | | 9 | BG Music | 0 | PinMame default | X | Normal Comet BG music | 53 | | 9 | | 1 | Music snd | - | Uses the MUSIC.snd file as BG music | 54 | | 10 | Custom Text | - | - | No | Bool setting - Shows the custom text sometimes during attract mode | 55 | | 11 | Restore Default | - | - | - | No setting - restores the default settings | 56 | | 12 | Exit Settings | - | - | - | No setting - exits the settings mode and writes the new setting to an SD card if present | 57 | 58 | ## GI LEDs 59 | 60 | These are the GI LEDs I've used. They match exactly into the holes for the normal lightbulbs. 61 | 62 | ![GI_LEDs](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/GI_LEDs.jpg) 63 | -------------------------------------------------------------------------------- /DOC/Frames.md: -------------------------------------------------------------------------------- 1 | # Installation frames 2 | 3 | The APC board is a lot smaller than the boards it replaces. That means you cannot use the fixtures of the original boards to attach the APC to, which makes affixing an APC board in your backbox a bit cumbersome. 4 | 5 | The installation frames on this page offer a solution to overcome this problem. Depending on the game generation they consist of two to four parts to build a frame and four legs. The legs are mounted below the attachment holes of the APC. They have a double purpose as they are mainly hollow but the hole has a cross like shape and can therefore be used as a thread for a 2mm woodscrew. 6 | 7 | ![SD slot](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/FrameExample.JPG) 8 | 9 | ## System 3 - 7 10 | 11 | The left side of the System 7 frame is split into two parts to be also suited for smaller printers. 12 | The lower rail which holds the original CPU board must be removed for this to fit. 13 | 14 | ![SD slot](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/FrameSys7.JPG) 15 | 16 | ![SD slot](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/FrameSys7_2.jpg) 17 | 18 | The STL files for printing can be found [here](https://github.com/AmokSolderer/APC/blob/master/DOC/Hardware/InstallationFrames/System7_stl.zip) 19 | 20 | ## System 9 21 | 22 | Note that the two parts of the System 9 frame are not identical as the APC board must be shifted a bit to the right to avoid a metal mounting post of the backbox. 23 | 24 | ![SD slot](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/FrameSys9.JPG) 25 | 26 | ![SD slot](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/CometLED.jpg) 27 | 28 | The STL files for printing can be found [here](https://github.com/AmokSolderer/APC/blob/master/DOC/Hardware/InstallationFrames/System9_stl.zip) 29 | 30 | ## System 11 without interconnect board 31 | 32 | This frame is for the early System11 games without an interconnect board. It consists of four parts as the right side is split into two parts to be also suited for smaller printers. 33 | 34 | ![SD slot](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/FrameSys11a.JPG) 35 | 36 | ![SD slot](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/APC_Pinbot.JPG) 37 | 38 | The STL files for printing can be found [here](https://github.com/AmokSolderer/APC/blob/master/DOC/Hardware/InstallationFrames/System11_stl.zip) 39 | 40 | ## System 11 with interconnect board 41 | 42 | This frame is for the later System11 games with an interconnect board. It consists of four parts as the lower side is split into two parts to be also suited for smaller printers. 43 | 44 | ![SD slot](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/FrameSys11c.JPG) 45 | 46 | ![SD slot](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/APC_Rollergames.JPG) 47 | 48 | The STL files for printing can be found [here](https://github.com/AmokSolderer/APC/blob/master/DOC/Hardware/InstallationFrames/System11c_stl.zip) 49 | -------------------------------------------------------------------------------- /DOC/Hardware/APC_FabricationFiles_SOIC/APC_BOM.csv: -------------------------------------------------------------------------------- 1 | Comment,Designator,Footprint,JLCPCB Part #(optional) 2 | 2.2u,"C1,C6",Capacitors_SMD:C_0603,C23630 3 | 22u,C14,Capacitors_SMD:C_0805,C782176 4 | 100n,"C25,C4,C28,C15,C22,C26,C23,C27,C19,C12,C10,C20,C29",Capacitors_SMD:C_0603,C14663 5 | 680p,"C3,C7",Capacitors_SMD:C_0603,C1630 6 | 68n,"C31,C30,C24,C21,C18,C17,C16,C13",Capacitors_SMD:C_0603,C31658 7 | 470n,"C33,C32",Capacitors_SMD:C_0603,C1623 8 | 150p,"C5,C8",Capacitors_SMD:C_0603,C1594 9 | IRF7316,"Q1,Q2,Q3,Q4",MeineLibs:SO8E,C55887 10 | MMBT3904,"Q5,Q7",TO_SOT_Packages_SMD:SOT-23,C20526 11 | S9015,Q8,TO_SOT_Packages_SMD:SOT-23,C2149 12 | IRF7341,"Q9,Q10,Q11,Q12",MeineLibs:SO8E,C21791 13 | 10K,"R21,R20,R22",Resistors_SMD:R_1206,C17902 14 | 10K,R68,Resistors_SMD:R_0603,C25804 15 | 27K,"R69,R67,R65,R90,R87,R74",Resistors_SMD:R_0603,C22967 16 | 300K,"R70,R76",Resistors_SMD:R_0603,C23024 17 | 15K,"R71,R66",Resistors_SMD:R_0603,C22809 18 | 1K,"R73,R2,R6,R10,R14,R4,R8,R12,R16",Resistors_SMD:R_1206,C4410 19 | 4.7K,R86 R72 R17 R19 R18 R1 R5 R9 R13 R3 R7 R11 R15 R77 R82 R78 R83 R79 R84 R81 R85,Resistors_SMD:R_1206,C17936 20 | 47K,R88,Resistors_SMD:R_0603,C25819 21 | 4.7K,R89,Resistors_SMD:R_0603,C23162 22 | 74HCT573,"U1,U2,U4",Housings_SOIC:SOIC-20_7.5x12.8mm_Pitch1.27mm,C5209384 23 | 74HC154,U14,MeineLibs:SOIC-24_7.5x15.4mm_Pitch1.27mm,C13758 24 | IRL540,Q13 Q19 Q25 Q31 Q14 Q20 Q26 Q32 Q15 Q21 Q27 Q33 Q16 Q22 Q28 Q34 Q17 Q23 Q29 Q35 Q18 Q30 Q24 Q36,MeineLibs:TO220_GDS_BP,C111607 25 | LM358,U20,MeineLibs:SO8E,C7950 26 | ULN2803A,U3,Housings_SOIC:SOIC-18_7.5x11.6mm_Pitch1.27mm,C845537 27 | 74HCT273,"U5,U6,U16,U17,U18,U8,U11,U12,U15,U23",Package_SO:SOIC-20W_7.5x12.8mm_P1.27mm,C2652822 28 | SD_adapter,P14,MeineLibs:uSD_TF-01,C91145 29 | 2x40 pin header,J1,"2,54mm",C2834348 30 | CH3.96-9A,"1J6,1J7,2J12,2J13,sys11_1J10,sys11_1J11,sys11_1J12,sys11_1J6,sys11_1J7,sys11_1J8,sys7_1J2,sys7_2J10,sys7_2J11,sys7_2J2,sys7_2J3,sys7_2J4,sys7_2J5,sys7_2J6,sys7_2J7,sys7_2J9",CONN-TH_CH3.96-9A,C10586 31 | CH3.96-4A,"10J2,10J4,1J4",CONN-TH_CH3.96-4A,C10379 32 | CH3.96-12A,1J5,CONN-TH_CH3.96-12A,C10589 33 | B-2100S36P-B110,P4,CONN_36_2x18,C168945 34 | B-2100S12P-B110,P12,Lisy_Jumper_2x6,C124388 35 | MTP125-1213S1,1J8,Display Segments 2_2x13,C358701 36 | C68234,P11,Sys11_J21_2x8,C68234 37 | B-2200S06P-B120,P7,CONN_3X2(Female),C124421 38 | B-2200S06P-A120,P8,SD_card_1x6(Female),C124415 39 | B-2100S04P-A110,P9,Ardu_pwr_1x4,C124378 40 | PZ254V-11-02P,"P6,P13","CONN_2,1x2",C492401 41 | A2541WV-6P,P1,"CONN_6,1x6",C225481 42 | X6511WV-07H-C30D60,P2,"CONN_7,1x7",C706879 43 | Z-211-0811-0021-001,P5,"CONN_8,1x8",C190820 44 | Tacticle Switch,SW1,KEY-TH_4P,C273473 45 | A09-472JP,"RR1,RR7",Array SIP-9 4.7K,C9112 46 | 1000uF 16V,C9,"Radial,10X16mm",C88751 47 | 100uF 25V,C2,"Radial,6.3X11mm",C106598 48 | 470uF 35V,C11,"Radial,10X12.5mm",C127917 49 | LED red,D1,3mm,C2286 50 | LED yellow,D2,3mm,C72038 51 | LED green,D3,3mm,C72043 52 | -------------------------------------------------------------------------------- /DOC/Hardware/APC_FabricationFiles_SOIC/APC_Gerber.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/Hardware/APC_FabricationFiles_SOIC/APC_Gerber.zip -------------------------------------------------------------------------------- /DOC/Hardware/APC_FabricationFiles_SOIC/APC_cpl_top.csv: -------------------------------------------------------------------------------- 1 | Designator,Val,Package,MidX,MidY,Rotation,Layer 2 | 1J4,Diag Sw,Molex4,78.3336mm,-247.015mm,180.000000,top 3 | 1J5,Display Segments 1,Molex12,21.59mm,-211.98mm,-90.000000,top 4 | 1J6,Display Strobes 2,Molex9,21.59mm,-126.3904mm,-90.000000,top 5 | 1J7,Display Strobes 1,Molex9,21.59mm,-85.7504mm,-90.000000,top 6 | 1J8,Display Segments 2,pin_array_13x2_big_pads,22.860000,-166.370000,90.000000,top 7 | 2J12,Special Sol Drivers,Molex9,212.725mm,-43.7896mm,90.000000,top 8 | 2J13,Special Sol Triggers,Molex9,109.1946mm,-247.015mm,180.000000,top 9 | 10J2,Speakers,Molex4,201.5236mm,-247.015mm,180.000000,top 10 | 10J4,Volume,Molex4,180.5686mm,-247.015mm,180.000000,top 11 | C1,2.2u,C_0603,171.450000,-220.345000,90.000000,top 12 | C2,100u,C_Radial_D5_L11_P2.5,192.659000,-223.012000,90.000000,top 13 | C3,680p,C_0603,179.070000,-225.425000,-90.000000,top 14 | C4,100n,C_0603,180.340000,-168.910000,90.000000,top 15 | C5,150p,C_0603,184.785000,-222.250000,180.000000,top 16 | C6,2.2u,C_0603,171.450000,-227.965000,90.000000,top 17 | C7,680p,C_0603,180.340000,-238.760000,-90.000000,top 18 | C8,150p,C_0603,182.995000,-234.315000,180.000000,top 19 | C9,1000u,C_Radial_D8_L13_P3.8,193.675000,-235.585000,180.000000,top 20 | C10,100n,C_0603,204.470000,-224.790000,0.000000,top 21 | C11,470u,C_Radial_D8_L13_P3.8,203.835000,-229.870000,180.000000,top 22 | C12,100n,C_0603,186.055000,-233.160000,90.000000,top 23 | C13,68n,C_0603,146.050000,-215.265000,0.000000,top 24 | C14,10u,C_0805,149.225000,-183.515000,180.000000,top 25 | C15,100n,C_0603,90.170000,-182.880000,180.000000,top 26 | C16,68n,C_0603,147.955000,-217.170000,180.000000,top 27 | C17,68n,C_0603,152.400000,-217.170000,0.000000,top 28 | C18,68n,C_0603,154.305000,-215.265000,180.000000,top 29 | C19,100n,C_0603,68.580000,-115.570000,90.000000,top 30 | C20,100n,C_0603,113.030000,-214.630000,90.000000,top 31 | C21,68n,C_0603,158.750000,-217.170000,0.000000,top 32 | C22,100n,C_0603,46.990000,-82.550000,90.000000,top 33 | C23,100n,C_0603,41.275000,-221.615000,0.000000,top 34 | C24,68n,C_0603,160.655000,-215.265000,180.000000,top 35 | C25,100n,C_0603,68.580000,-66.040000,-90.000000,top 36 | C26,100n,C_0603,43.815000,-196.215000,90.000000,top 37 | C27,100n,C_0603,43.815000,-151.765000,90.000000,top 38 | C28,100n,C_0603,116.840000,-140.970000,180.000000,top 39 | C29,100n,C_0603_1608Metric,203.200000,-170.180000,-90.000000,top 40 | C30,68n,C_0603,165.100000,-217.170000,0.000000,top 41 | C31,68n,C_0603,167.005000,-215.265000,180.000000,top 42 | C32,470n,C_0603,197.485000,-224.790000,180.000000,top 43 | C33,470n,C_0603,197.485000,-221.615000,180.000000,top 44 | D1,LED_Red,LED_0603_1608Metric,175.260000,-68.882500,90.000000,top 45 | D2,LED_Yellow,LED_0603_1608Metric,175.260000,-62.230000,90.000000,top 46 | D3,LED_Green,LED_0603_1608Metric,175.260000,-55.547500,90.000000,top 47 | J1,Raspberry_Pi,Raspi,162.560000,-104.140000,90.000000,top 48 | P3,CONN_1,1pin,29.845000,-190.500000,0.000000,top 49 | P4,CONN_36,pin_array_18x2_mirror_bp,118.745mm,-175.895mm,90.000000,top 50 | P7,CONN_3X2,pin_array_3x2_mirror_big_pads,149.225000,-177.165000,90.000000,top 51 | P11,Sys11_J21,pin_array_8x2_big_pads,92.710000,-146.685000,180.000000,top 52 | P12,Lisy_Jumper,pin_array_6x2_big_pads,172.720000,-39.370000,-90.000000,top 53 | P14,SD_ADAPTER,TF01A,207.5236mm,-157.855mm,90.000000,top 54 | Q1,IRF7316,SO8E,60.198000,-38.862000,0.000000,top 55 | Q2,IRF7316,SO8E,50.800000,-38.862000,0.000000,top 56 | Q3,IRF7316,SO8E,41.148000,-38.862000,0.000000,top 57 | Q4,IRF7316,SO8E,31.750000,-38.862000,0.000000,top 58 | Q5,MMBT3904,SOT-23,179.705000,-161.290000,90.000000,top 59 | Q7,MMBT3904,SOT-23,125.730000,-178.798220,-90.000000,top 60 | Q8,S9015,SOT-23,35.560000,-191.770000,-90.000000,top 61 | Q9,IRF7341,SO8E,100.330000,-38.735000,0.000000,top 62 | Q10,IRF7341,SO8E,91.440000,-38.735000,0.000000,top 63 | Q11,IRF7341,SO8E,81.280000,-38.735000,0.000000,top 64 | Q12,IRF7341,SO8E,73.025000,-38.735000,0.000000,top 65 | Q13,IRL540,TO220_GDS_BP,176.530000,-75.565000,90.000000,top 66 | Q14,IRL540,TO220_GDS_BP,191.135000,-67.818000,90.000000,top 67 | Q15,IRL540,TO220_GDS_BP,176.530000,-116.840000,90.000000,top 68 | Q16,IRL540,TO220_GDS_BP,191.135000,-109.982000,90.000000,top 69 | Q17,IRL540,TO220_GDS_BP,201.295000,-35.687000,90.000000,top 70 | Q18,IRL540,TO220_GDS_BP,187.325000,-51.435000,90.000000,top 71 | Q19,IRL540,TO220_GDS_BP,176.530000,-84.455000,90.000000,top 72 | Q20,IRL540,TO220_GDS_BP,191.135000,-78.867000,90.000000,top 73 | Q21,IRL540,TO220_GDS_BP,176.530000,-125.984000,90.000000,top 74 | Q22,IRL540,TO220_GDS_BP,191.135000,-119.380000,90.000000,top 75 | Q23,IRL540,TO220_GDS_BP,201.295000,-46.609000,90.000000,top 76 | Q24,IRL540,TO220_GDS_BP,187.325000,-31.877000,90.000000,top 77 | Q25,IRL540,TO220_GDS_BP,176.530000,-93.980000,90.000000,top 78 | Q26,IRL540,TO220_GDS_BP,191.135000,-87.503000,90.000000,top 79 | Q27,IRL540,TO220_GDS_BP,176.530000,-134.112000,90.000000,top 80 | Q28,IRL540,TO220_GDS_BP,191.135000,-129.413000,90.000000,top 81 | Q29,IRL540,TO220_GDS_BP,187.325000,-59.055000,90.000000,top 82 | Q30,IRL540,TO220_GDS_BP,201.295000,-55.245000,90.000000,top 83 | Q31,IRL540,TO220_GDS_BP,176.530000,-101.600000,90.000000,top 84 | Q32,IRL540,TO220_GDS_BP,191.135000,-96.520000,90.000000,top 85 | Q33,IRL540,TO220_GDS_BP,176.530000,-141.986000,90.000000,top 86 | Q34,IRL540,TO220_GDS_BP,191.135000,-141.986000,90.000000,top 87 | Q35,IRL540,TO220_GDS_BP,187.325000,-40.005000,90.000000,top 88 | Q36,IRL540,TO220_GDS_BP,201.295000,-27.051000,90.000000,top 89 | R1,4.7K,R_1206,59.690000,-45.720000,180.000000,top 90 | R2,1K,R_1206,58.420000,-50.165000,-90.000000,top 91 | R3,4.7K,R_1206,63.500000,-48.895000,0.000000,top 92 | R4,1K,R_1206,63.500000,-52.070000,180.000000,top 93 | R5,4.7K,R_1206,50.165000,-45.720000,180.000000,top 94 | R6,1K,R_1206,48.260000,-50.165000,-90.000000,top 95 | R7,4.7K,R_1206,53.340000,-48.895000,0.000000,top 96 | R8,1K,R_1206,53.340000,-52.070000,180.000000,top 97 | R9,4.7K,R_1206,40.005000,-45.720000,180.000000,top 98 | R10,1K,R_1206,38.735000,-50.165000,-90.000000,top 99 | R11,4.7K,R_1206,43.180000,-48.895000,0.000000,top 100 | R12,1K,R_1206,43.180000,-52.070000,180.000000,top 101 | R13,4.7K,R_1206,30.480000,-45.720000,180.000000,top 102 | R14,1K,R_1206,29.210000,-50.165000,-90.000000,top 103 | R15,4.7K,R_1206,33.655000,-48.895000,0.000000,top 104 | R16,1K,R_1206,33.655000,-52.070000,180.000000,top 105 | R17,4.7K,R_1206,172.085000,-69.215000,90.000000,top 106 | R18,4.7K,R_1206,171.450000,-55.880000,90.000000,top 107 | R19,4.7K,R_1206,171.450000,-62.230000,90.000000,top 108 | R20,10K,R_1206,154.305000,-106.680000,90.000000,top 109 | R21,10K,R_1206,124.460000,-173.810000,90.000000,top 110 | R22,10K,R_1206_3216Metric,155.575000,-159.385000,-90.000000,top 111 | R65,27K,R_0603,177.165000,-221.615000,0.000000,top 112 | R66,15K,R_0603,189.230000,-227.965000,90.000000,top 113 | R67,27K,R_0603,188.595000,-220.345000,90.000000,top 114 | R68,10K,R_0603,184.150000,-160.020000,0.000000,top 115 | R69,27K,R_0603,181.610000,-220.345000,-90.000000,top 116 | R70,300K,R_0603,177.800000,-168.910000,90.000000,top 117 | R71,15K,R_0603,179.705000,-229.870000,180.000000,top 118 | R72,4.7K,R_1206,125.550000,-169.545000,0.000000,top 119 | R73,1K,R_1206,173.990000,-163.830000,0.000000,top 120 | R74,27K,R_0603,174.625000,-233.680000,-90.000000,top 121 | R76,300K,R_0603,204.470000,-222.885000,0.000000,top 122 | R77,4.7K,R_1206,167.640000,-220.980000,-90.000000,top 123 | R78,4.7K,R_1206,161.290000,-220.980000,-90.000000,top 124 | R79,4.7K,R_1206,154.940000,-220.980000,-90.000000,top 125 | R81,4.7K,R_1206,148.590000,-220.980000,-90.000000,top 126 | R82,4.7K,R_1206,164.465000,-220.980000,-90.000000,top 127 | R83,4.7K,R_1206,158.115000,-220.980000,-90.000000,top 128 | R84,4.7K,R_1206,151.765000,-220.980000,-90.000000,top 129 | R85,4.7K,R_1206,145.415000,-220.980000,-90.000000,top 130 | R86,4.7K,R_1206,118.110000,-207.010000,180.000000,top 131 | R87,27K,R_0603,180.340000,-233.680000,90.000000,top 132 | R88,47K,R_0603,22.225000,-185.420000,0.000000,top 133 | R89,4.7K,R_0603,127.000000,-165.100000,-90.000000,top 134 | R90,27K,R_0603,182.880000,-236.728000,180.000000,top 135 | RR1,"4,7K",SIP9_Housing_BigPads,111.125000,-236.855000,180.000000,top 136 | RR7,"4,7K",SIP9_Housing_BigPads,156.845000,-227.330000,180.000000,top 137 | RR8,18K,SIP9_Housing_BigPads,153.035000,-210.185000,0.000000,top 138 | SW1,Shutdown,Taster3301,203.200000,-21.590000,0.000000,top 139 | U1,74HCT573,SOIC-20_7.5x12.8mm_Pitch1.27mm,88.900000,-173.990000,-90.00,top 140 | U2,74HCT573,SOIC-20_7.5x12.8mm_Pitch1.27mm,72.390000,-184.150000,0.000000,top 141 | U3,ULN2803A,SOIC-18_7.5x11.6mm_Pitch1.27mm,50.165000,-71.120000,90.000000,top 142 | U4,74HCT573,SOIC-20_7.5x12.8mm_Pitch1.27mm,102.870000,-161.290000,90.000000,top 143 | U5,74HCT273,SOIC-20W_7.5x12.8mm_P1.27mm,76.835000,-86.360000,0.000000,top 144 | U6,74HCT273,SOIC-20W_7.5x12.8mm_P1.27mm,76.835000,-50.800000,0.000000,top 145 | U8,74HCT273,SOIC-20W_7.5x12.8mm_P1.27mm,52.070000,-140.970000,0.000000,top 146 | U11,74HCT273,SOIC-20W_7.5x12.8mm_P1.27mm,52.070000,-158.750000,0.000000,top 147 | U12,74HCT273,SOIC-20W_7.5x12.8mm_P1.27mm,52.070000,-203.200000,0.000000,top 148 | U14,74HC154,SOIC-24_7.5x15.4mm_Pitch1.27mm,38.100000,-92.075000,-90.00,top 149 | U15,74HCT273,SOIC-20W_7.5x12.8mm_P1.27mm,52.070000,-184.150000,0.000000,top 150 | U16,74HCT273,SOIC-20W_7.5x12.8mm_P1.27mm,76.835000,-104.140000,0.000000,top 151 | U17,74HCT273,SOIC-20W_7.5x12.8mm_P1.27mm,76.835000,-121.920000,0.000000,top 152 | U18,74HCT273,SOIC-20W_7.5x12.8mm_P1.27mm,76.835000,-68.580000,0.000000,top 153 | U19,74BCT760,DIP-20__300_ELL,124.460000,-222.250000,0.000000,top 154 | U20,LM358,SO8E,184.150000,-227.330000,180.000000,top 155 | U21,TDA7496,Multiwatt15V,210.820000,-230.505000,-90.000000,top 156 | U23,74HCT273,SOIC-20W_7.5x12.8mm_P1.27mm,52.070000,-219.710000,0.000000,top 157 | sys7_1J2,Logic PWR/GND,Molex9,193.0146mm,-211.455mm,180.000000,top 158 | sys7_2J2,Switch Drivers,Molex9,47.5996mm,-247.015mm,180.000000,top 159 | sys7_2J3,Switch Inputs,Molex9,149.8346mm,-247.015mm,180.000000,top 160 | sys7_2J4,Lamp B+,Molex9,21.59mm,-45.1104mm,-90.000000,top 161 | sys7_2J5,Lamp Strobes,Molex9,45.7454mm,-19.685mm,0.000000,top 162 | sys7_2J6,Lamp GND,Molex9,127.0254mm,-19.685mm,0.000000,top 163 | sys7_2J7,Lamp Rows,Molex9,86.3854mm,-19.685mm,0.000000,top 164 | sys7_2J9,Solenoid Drivers 2,Molex9,212.725mm,-128.8796mm,90.000000,top 165 | sys7_2J10,Solenoid GND,Molex9,167.6654mm,-19.685mm,0.000000,top 166 | sys7_2J11,Solenoid Drivers 1,Molex9,212.725mm,-86.3346mm,90.000000,top 167 | sys11_1J6,Lamp Rows,Molex9,86.3854mm,-29.845mm,0.000000,top 168 | sys11_1J7,Lamp Strobes,Molex9,45.7454mm,-29.845mm,0.000000,top 169 | sys11_1J8,Switch Drivers,Molex9,47.5996mm,-236.855mm,180.000000,top 170 | sys11_1J10,Switch Inputs,Molex9,149.8346mm,-236.855mm,180.000000,top 171 | sys11_1J11,Solenoid Drivers 1,Molex9,201.93mm,-86.3346mm,90.000000,top 172 | sys11_1J12,Solenoid Drivers 2,Molex9,201.93mm,-128.8796mm,90.000000,top 173 | P13,,,144.145mm,-154.305mm,0.000000,top 174 | P1,,,161.925mm,-154.305mm,0.000000,top 175 | P2,,,179.959mm,-154.305mm,0.000000,top 176 | P5,,,154.305mm,-202.565mm,0.000000,top 177 | P6,,,128.905mm,-202.565mm,0.000000,top 178 | P8,,,116.84mm,-144.78mm,0.000000,top 179 | P9,,,174.625mm,-202.565mm,0.000000,top 180 | -------------------------------------------------------------------------------- /DOC/Hardware/APC_FabricationFiles_SSOP/APC_BOM.csv: -------------------------------------------------------------------------------- 1 | Comment,Designator,Footprint,JLCPCB Part #(optional) 2 | 2.2u,"C1,C6",Capacitors_SMD:C_0603,C23630 3 | 22u,C14,Capacitors_SMD:C_0805,C782176 4 | 100n,"C25,C4,C28,C15,C22,C26,C23,C27,C19,C12,C10,C20,C29",Capacitors_SMD:C_0603,C14663 5 | 680p,"C3,C7",Capacitors_SMD:C_0603,C1630 6 | 68n,"C31,C30,C24,C21,C18,C17,C16,C13",Capacitors_SMD:C_0603,C31658 7 | 470n,"C33,C32",Capacitors_SMD:C_0603,C1623 8 | 150p,"C5,C8",Capacitors_SMD:C_0603,C1594 9 | IRF7316,"Q1,Q2,Q3,Q4",MeineLibs:SO8E,C55887 10 | MMBT3904,"Q5,Q7",TO_SOT_Packages_SMD:SOT-23,C20526 11 | S9015,Q8,TO_SOT_Packages_SMD:SOT-23,C2149 12 | IRF7341,"Q9,Q10,Q11,Q12",MeineLibs:SO8E,C21791 13 | 10K,"R21,R20,R22",Resistors_SMD:R_1206,C17902 14 | 10K,R68,Resistors_SMD:R_0603,C25804 15 | 27K,"R69,R67,R65,R90,R87,R74",Resistors_SMD:R_0603,C22967 16 | 300K,"R70,R76",Resistors_SMD:R_0603,C23024 17 | 15K,"R71,R66",Resistors_SMD:R_0603,C22809 18 | 1K,"R73,R2,R6,R10,R14,R4,R8,R12,R16",Resistors_SMD:R_1206,C4410 19 | 4.7K,R86 R72 R17 R19 R18 R1 R5 R9 R13 R3 R7 R11 R15 R77 R82 R78 R83 R79 R84 R81 R85,Resistors_SMD:R_1206,C17936 20 | 47K,R88,Resistors_SMD:R_0603,C25819 21 | 4.7K,R89,Resistors_SMD:R_0603,C23162 22 | 74HCT573,"U1,U2,U4",Housings_SOIC:SOIC-20_7.5x12.8mm_Pitch1.27mm,C547792 23 | 74HC154,U14,MeineLibs:SOIC-24_7.5x15.4mm_Pitch1.27mm,C13758 24 | IRL540,Q13 Q19 Q25 Q31 Q14 Q20 Q26 Q32 Q15 Q21 Q27 Q33 Q16 Q22 Q28 Q34 Q17 Q23 Q29 Q35 Q18 Q30 Q24 Q36,MeineLibs:TO220_GDS_BP,C111607 25 | LM358,U20,MeineLibs:SO8E,C7950 26 | ULN2803A,U3,Housings_SOIC:SOIC-18_7.5x11.6mm_Pitch1.27mm,C9683 27 | 74HCT273,"U5,U6,U8,U11,U12,U15,U16,U17,U18,U23",Housings_SSOP:SSOP-20_4.4x6.5mm_Pitch0.65mm,C6780 28 | SD_adapter,P14,MeineLibs:uSD_TF-01,C91145 29 | 2x40 pin header,J1,"2,54mm",C2834348 30 | CH3.96-9A,"1J6,1J7,2J12,2J13,sys11_1J10,sys11_1J11,sys11_1J12,sys11_1J6,sys11_1J7,sys11_1J8,sys7_1J2,sys7_2J10,sys7_2J11,sys7_2J2,sys7_2J3,sys7_2J4,sys7_2J5,sys7_2J6,sys7_2J7,sys7_2J9",CONN-TH_CH3.96-9A,C10586 31 | CH3.96-4A,"10J2,10J4,1J4",CONN-TH_CH3.96-4A,C10379 32 | CH3.96-12A,1J5,CONN-TH_CH3.96-12A,C10589 33 | B-2100S36P-B110,P4,CONN_36_2x18,C168945 34 | B-2100S12P-B110,P12,Lisy_Jumper_2x6,C124388 35 | MTP125-1213S1,1J8,Display Segments 2_2x13,C358701 36 | C68234,P11,Sys11_J21_2x8,C68234 37 | B-2200S06P-B120,P7,CONN_3X2(Female),C124421 38 | B-2200S06P-A120,P8,SD_card_1x6(Female),C124415 39 | B-2100S04P-A110,P9,Ardu_pwr_1x4,C124378 40 | PZ254V-11-02P,"P6,P13","CONN_2,1x2",C492401 41 | A2541WV-6P,P1,"CONN_6,1x6",C225481 42 | X6511WV-07H-C30D60,P2,"CONN_7,1x7",C706879 43 | Z-211-0811-0021-001,P5,"CONN_8,1x8",C190820 44 | Tacticle Switch,SW1,KEY-TH_4P,C273473 45 | A09-472JP,"RR1,RR7",Array SIP-9 4.7K,C9112 46 | 1000uF 16V,C9,"Radial,10X16mm",C88751 47 | 100uF 25V,C2,"Radial,6.3X11mm",C106598 48 | 470uF 35V,C11,"Radial,10X12.5mm",C127917 49 | LED red,D1,3mm,C2286 50 | LED yellow,D2,3mm,C72038 51 | LED green,D3,3mm,C72043 52 | -------------------------------------------------------------------------------- /DOC/Hardware/APC_FabricationFiles_SSOP/APC_Gerber.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/Hardware/APC_FabricationFiles_SSOP/APC_Gerber.zip -------------------------------------------------------------------------------- /DOC/Hardware/APC_FabricationFiles_SSOP/APC_cpl_top.csv: -------------------------------------------------------------------------------- 1 | Designator,Mid X,Mid Y,Layer,Rotation 2 | P14,207.5236mm,-157.855mm,top,90.0 3 | P4,118.745mm,-175.895mm,top,90.0 4 | 10J2,201.5236mm,-247.015mm,top,180.0 5 | 10J4,180.5686mm,-247.015mm,top,180.0 6 | 1J4,78.3336mm,-247.015mm,top,180.0 7 | sys11_1J8,47.5996mm,-236.855mm,top,180.0 8 | sys7_2J5,45.7454mm,-19.685mm,top,0.0 9 | sys7_1J2,193.0146mm,-211.455mm,top,180.0 10 | sys7_2J2,47.5996mm,-247.015mm,top,180.0 11 | sys7_2J3,149.8346mm,-247.015mm,top,180.0 12 | sys7_2J4,21.59mm,-45.1104mm,top,270.0 13 | sys7_2J6,127.0254mm,-19.685mm,top,0.0 14 | sys7_2J7,86.3854mm,-19.685mm,top,0.0 15 | sys7_2J9,212.725mm,-128.8796mm,top,90.0 16 | sys7_2J10,167.6654mm,-19.685mm,top,0.0 17 | sys7_2J11,212.725mm,-86.3346mm,top,90.0 18 | sys11_1J6,86.3854mm,-29.845mm,top,0.0 19 | sys11_1J7,45.7454mm,-29.845mm,top,0.0 20 | sys11_1J10,149.8346mm,-236.855mm,top,180.0 21 | sys11_1J11,201.93mm,-86.3346mm,top,90.0 22 | sys11_1J12,201.93mm,-128.8796mm,top,90.0 23 | 1J6,21.59mm,-126.3904mm,top,270.0 24 | 1J7,21.59mm,-85.7504mm,top,270.0 25 | 2J13,109.1946mm,-247.015mm,top,180.0 26 | 2J12,212.725mm,-43.7896mm,top,90.0 27 | 1J5,21.59mm,-211.98mm,top,270.0 28 | SW1,199.95mm,-19.7mm,top,0.0 29 | J1,162.56mm,-104.14mm,top,90.0 30 | P13,144.145mm,-154.305mm,top,0.0 31 | P2,179.959mm,-154.305mm,top,0.0 32 | C9,193.548mm,-235.966mm,top,180.0 33 | R21,124.46mm,-173.81mm,top,90.0 34 | U14,38.1mm,-92.075mm,top,270.0 35 | U21,210.82mm,-230.505mm,top,270.0 36 | C11,203.835mm,-229.87mm,top,180.0 37 | C2,192.659mm,-223.012mm,top,90.0 38 | P7,149.225mm,-177.165mm,top,90.0 39 | Q5,179.705mm,-161.29mm,top,90.0 40 | RR1,111.125mm,-236.855mm,top,180.0 41 | RR7,156.845mm,-227.33mm,top,180.0 42 | P11,92.71mm,-146.685mm,top,180.0 43 | U19,124.46mm,-222.25mm,top,0.0 44 | Q7,125.73mm,-178.79822mm,top,270.0 45 | Q8,35.56mm,-191.77mm,top,270.0 46 | P3,29.845mm,-190.5mm,top,0.0 47 | P12,172.72mm,-39.37mm,top,270.0 48 | 1J8,22.86mm,-166.37mm,top,90.0 49 | P1,161.925mm,-154.305mm,top,0.0 50 | P5,154.305mm,-202.565mm,top,180.0 51 | P6,128.905mm,-202.565mm,top,180.0 52 | P8,116.84mm,-144.78mm,top,180.0 53 | P9,174.625mm,-202.565mm,top,180.0 54 | Q1,60.198mm,-38.862mm,top,0.0 55 | Q2,50.8mm,-38.862mm,top,0.0 56 | Q3,41.148mm,-38.862mm,top,0.0 57 | Q4,31.75mm,-38.862mm,top,0.0 58 | Q9,100.33mm,-38.735mm,top,0.0 59 | Q10,91.44mm,-38.735mm,top,0.0 60 | Q11,81.28mm,-38.735mm,top,0.0 61 | Q12,73.025mm,-38.735mm,top,0.0 62 | RR8,153.035mm,-210.185mm,top,0.0 63 | U20,184.15mm,-227.33mm,top,180.0 64 | C1,171.45mm,-220.345mm,top,90.0 65 | C3,179.07mm,-225.425mm,top,270.0 66 | C4,180.34mm,-166.37mm,top,90.0 67 | C5,184.785mm,-222.25mm,top,180.0 68 | C6,171.45mm,-227.965mm,top,90.0 69 | C7,180.34mm,-238.76mm,top,270.0 70 | C8,182.995mm,-234.315mm,top,180.0 71 | C10,204.47mm,-224.79mm,top,0.0 72 | C12,186.055mm,-233.16mm,top,90.0 73 | C13,146.05mm,-215.265mm,top,0.0 74 | C14,149.225mm,-183.515mm,top,180.0 75 | C16,147.955mm,-217.17mm,top,180.0 76 | C17,152.4mm,-217.17mm,top,0.0 77 | C18,154.305mm,-215.265mm,top,180.0 78 | C19,68.58mm,-115.57mm,top,90.0 79 | C21,158.75mm,-217.17mm,top,0.0 80 | C22,46.99mm,-82.55mm,top,90.0 81 | C23,41.275mm,-221.615mm,top,0.0 82 | C24,160.655mm,-215.265mm,top,180.0 83 | C25,68.58mm,-66.04mm,top,270.0 84 | C27,43.815mm,-147.32mm,top,90.0 85 | C28,116.84mm,-140.97mm,top,180.0 86 | C30,165.1mm,-217.17mm,top,0.0 87 | C31,167.005mm,-215.265mm,top,180.0 88 | C32,197.485mm,-224.79mm,top,180.0 89 | C33,197.485mm,-221.615mm,top,180.0 90 | R65,177.165mm,-221.615mm,top,0.0 91 | R66,189.23mm,-227.965mm,top,90.0 92 | R67,188.595mm,-220.345mm,top,90.0 93 | R68,184.15mm,-160.02mm,top,0.0 94 | R69,181.61mm,-220.345mm,top,270.0 95 | R71,179.705mm,-229.87mm,top,180.0 96 | R74,174.625mm,-233.68mm,top,270.0 97 | R76,204.47mm,-222.885mm,top,0.0 98 | R87,180.34mm,-233.68mm,top,90.0 99 | R88,22.225mm,-185.42mm,top,0.0 100 | R90,182.88mm,-236.728mm,top,180.0 101 | U3,50.165mm,-71.12mm,top,90.0 102 | R77,167.64mm,-220.98mm,top,270.0 103 | R78,161.29mm,-220.98mm,top,270.0 104 | R79,154.94mm,-220.98mm,top,270.0 105 | R81,148.59mm,-220.98mm,top,270.0 106 | R82,164.465mm,-220.98mm,top,270.0 107 | R83,158.115mm,-220.98mm,top,270.0 108 | R84,151.765mm,-220.98mm,top,270.0 109 | R85,145.415mm,-220.98mm,top,270.0 110 | R86,118.11mm,-207.01mm,top,180.0 111 | C26,43.815mm,-200.152mm,top,90.0 112 | R1,59.69mm,-45.72mm,top,180.0 113 | R2,58.42mm,-50.165mm,top,270.0 114 | R3,63.5mm,-48.895mm,top,0.0 115 | R4,63.5mm,-52.07mm,top,180.0 116 | R5,50.165mm,-45.72mm,top,180.0 117 | R6,48.26mm,-50.165mm,top,270.0 118 | R7,53.34mm,-48.895mm,top,0.0 119 | R8,53.34mm,-52.07mm,top,180.0 120 | R9,40.005mm,-45.72mm,top,180.0 121 | R10,38.735mm,-50.165mm,top,270.0 122 | R11,43.18mm,-48.895mm,top,0.0 123 | R12,43.18mm,-52.07mm,top,180.0 124 | R13,30.48mm,-45.72mm,top,180.0 125 | R14,29.21mm,-50.165mm,top,270.0 126 | R15,33.655mm,-48.895mm,top,0.0 127 | R16,33.655mm,-52.07mm,top,180.0 128 | R17,172.085mm,-69.215mm,top,90.0 129 | R18,171.45mm,-55.88mm,top,90.0 130 | R19,171.45mm,-62.23mm,top,90.0 131 | R73,173.99mm,-163.83mm,top,0.0 132 | U1,88.9mm,-173.99mm,top,270.0 133 | U2,72.39mm,-184.15mm,top,0.0 134 | Q13,176.53mm,-75.565mm,top,90.0 135 | Q14,191.135mm,-67.818mm,top,90.0 136 | Q15,176.53mm,-116.84mm,top,90.0 137 | Q16,191.135mm,-109.982mm,top,90.0 138 | Q17,201.295mm,-35.687mm,top,90.0 139 | Q18,187.325mm,-51.435mm,top,90.0 140 | Q19,176.53mm,-84.455mm,top,90.0 141 | Q20,191.135mm,-78.867mm,top,90.0 142 | Q21,176.53mm,-125.984mm,top,90.0 143 | Q22,191.135mm,-119.38mm,top,90.0 144 | Q23,201.295mm,-46.609mm,top,90.0 145 | Q24,187.325mm,-31.877mm,top,90.0 146 | Q25,176.53mm,-93.98mm,top,90.0 147 | Q26,191.135mm,-87.503mm,top,90.0 148 | Q27,176.53mm,-134.112mm,top,90.0 149 | Q28,191.135mm,-129.413mm,top,90.0 150 | Q29,187.325mm,-59.055mm,top,90.0 151 | Q30,201.295mm,-55.245mm,top,90.0 152 | Q31,176.53mm,-101.6mm,top,90.0 153 | Q32,191.135mm,-96.52mm,top,90.0 154 | Q33,176.53mm,-141.986mm,top,90.0 155 | Q34,191.135mm,-141.986mm,top,90.0 156 | Q35,187.325mm,-40.005mm,top,90.0 157 | Q36,201.295mm,-27.051mm,top,90.0 158 | C15,90.17mm,-182.88mm,top,180.0 159 | C20,113.03mm,-214.63mm,top,90.0 160 | R20,154.305mm,-106.68mm,top,90.0 161 | U4,102.87mm,-161.29mm,top,90.0 162 | R89,127mm,-165.1mm,top,270.0 163 | R70,177.8mm,-166.37mm,top,90.0 164 | R72,125.55mm,-169.545mm,top,0.0 165 | U5,76.835mm,-87.63mm,top,0.0 166 | U6,76.835mm,-48.26mm,top,0.0 167 | U8,52.07mm,-138.43mm,top,0.0 168 | U11,52.07mm,-151.765mm,top,0.0 169 | U12,52.07mm,-205.74mm,top,0.0 170 | U15,52.07mm,-187.325mm,top,0.0 171 | U16,76.835mm,-102.362mm,top,0.0 172 | U17,76.835mm,-121.666mm,top,0.0 173 | U18,76.835mm,-66.04mm,top,0.0 174 | U23,52.07mm,-220.98mm,top,0.0 175 | R22,155.575mm,-158.75mm,top,270.0 176 | C29,203.2mm,-170.18mm,top,270.0 177 | D1,175.26mm,-68.8825mm,top,90.0 178 | D2,175.26mm,-62.23mm,top,90.0 179 | D3,175.26mm,-55.5475mm,top,90.0 180 | -------------------------------------------------------------------------------- /DOC/Hardware/APC_LED_exp/APC_LED_exp.ino: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include 3 | #ifdef __AVR__ 4 | #include 5 | #endif 6 | #define PIN 12 7 | 8 | byte RecByte = 0; // received byte 9 | bool RecFlag; 10 | byte LampStatus[24]; // current status of each lamp 11 | byte LampMax[192][3]; // current max color values of each lamp 12 | byte LampMaxSel[3] = {200, 200, 200}; // selected max color values 13 | byte Sync = 8; // ms after last Sync 14 | byte Mode = 0; // Mode 0 -> lamps being lit get the ColorSelect color / Mode 1 -> lamps keep their color / Mode 2 -> lamps set in the following frame get the new color immediately 15 | byte Command = 0; // LED command currently being processed 16 | byte CommandCount = 0; // counts the bytes received by the color select command 17 | byte SystemFlags = 0; // to indicate special system states 18 | byte OwnCommands = 0; // indicate active own LED commands 19 | byte OwnCommandStep = 0; // needed for own LED commands 20 | byte NumOfLEDbytes = 8; // stores the length of the transferred LED pattern 21 | byte TurnOn[6][24]; // the list of the lamps currently being turned on 22 | byte TurnOff[6][24]; // the list of the lamps currently being turned off 23 | Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NumOfLEDbytes*8, PIN, NEO_GRB + NEO_KHZ800); 24 | const byte OwnPattern[6][3] = {{0,0,0},{0,50,0},{0,100,0},{0,150,0},{0,200,0},{0,250,0}}; 25 | 26 | void setup() { 27 | pixels.begin(); 28 | for (byte i=0;i<9;i++) { 29 | pinMode(i, INPUT_PULLUP);} 30 | pinMode(12, OUTPUT); 31 | pinMode(13, OUTPUT); 32 | pinMode(10, OUTPUT); 33 | digitalWrite(12, LOW); 34 | for (byte i=0;i<64;i++) { 35 | for (byte c=0;c<3;c++) { 36 | LampMax[i][c] = 255;}} 37 | RecFlag = PINB && 1;} 38 | 39 | void loop() { 40 | if ((PINB && 1) != RecFlag) { // get byte 41 | RecByte = PIND; // store it 42 | RecFlag = !RecFlag; 43 | if (Sync < NumOfLEDbytes) { // still LED pattern bytes to transfer? 44 | if (Mode < 2) { // LEDs fade on and off 45 | for (byte c=0;c<5;c++) { // for 5 brightness levels 46 | if (TurnOn[c][Sync]) { // anything to do in this byte? 47 | byte Mask = 1; // initialize bitmask 48 | for (byte i=0;i<8;i++) { // for the 8 lamps currently being processed 49 | if (TurnOn[c][Sync] & Mask) { 50 | if (c) { 51 | pixels.setPixelColor(Sync*8+i, pixels.Color(LampMax[Sync*8+i][0]/5*(5-c),LampMax[Sync*8+i][1]/5*(5-c),LampMax[Sync*8+i][2]/5*(5-c)));} 52 | else { // for the last level turn it fully on 53 | pixels.setPixelColor(Sync*8+i, pixels.Color(LampMax[Sync*8+i][0],LampMax[Sync*8+i][1],LampMax[Sync*8+i][2]));}} 54 | Mask = Mask << 1;}} 55 | TurnOn[c][Sync] = TurnOn[c+1][Sync]; 56 | if (TurnOff[c][Sync]) { 57 | byte Mask = 1; // initialize bitmask 58 | for (byte i=0;i<8;i++) { // for the 8 lamps currently being processed 59 | if (TurnOff[c][Sync] & Mask) { 60 | if (c) { 61 | pixels.setPixelColor(Sync*8+i, pixels.Color(LampMax[Sync*8+i][0]/5*(c),LampMax[Sync*8+i][1]/5*(c),LampMax[Sync*8+i][2]/5*(c)));} 62 | else { // for the last level turn it completely off 63 | pixels.setPixelColor(Sync*8+i,pixels.Color(0,0,0));}} 64 | Mask = Mask << 1;}} 65 | TurnOff[c][Sync] = TurnOff[c+1][Sync];} 66 | if (RecByte != LampStatus[Sync]) { // any status changes? 67 | byte Mask = 1; // initialize bitmask 68 | for (byte i=0;i<8;i++) { 69 | if ((RecByte & Mask) && !(LampStatus[Sync] & Mask)) { // lamp turned on 70 | if (Mode == 0) { // New lit lamps get a new color 71 | for (byte c=0;c<3;c++) { // set max brightness of lamp to selected max value 72 | LampMax[Sync*8+i][c] = LampMaxSel[c];}} 73 | LampStatus[Sync] |= Mask; 74 | TurnOn[5][Sync] |= Mask;} 75 | else { 76 | TurnOn[5][Sync] &= (255 - Mask);} 77 | if (!(RecByte & Mask) && (LampStatus[Sync] & Mask)) { // lamp turned off 78 | LampStatus[Sync] &= (255 - Mask); 79 | TurnOff[5][Sync] |= Mask;} 80 | else { 81 | TurnOff[5][Sync] &= (255 - Mask);} 82 | Mask = Mask << 1;}} 83 | else { 84 | TurnOn[5][Sync] = 0; 85 | TurnOff[5][Sync] = 0;}} 86 | else { // Mode > 1 87 | if (Mode < 4) { // selected lamps get the selected color immediately 88 | if (RecByte) { // any lamps set? 89 | byte Mask = 1; 90 | for (byte i=0;i<8;i++) { // for the 8 lamps currently being processed 91 | if (RecByte & Mask) { // lamp set in RecByte? 92 | if (Mode == 2) { // selected LEDs are also turned on 93 | for (byte c=0;c<5;c++) { // and 5 brightness levels 94 | TurnOn[c][Sync] &= (255 - Mask); // stop lamp from TurningOn - Off 95 | TurnOff[c][Sync] &= (255 - Mask);} 96 | LampStatus[Sync] |= Mask; // turn on lamp 97 | pixels.setPixelColor(Sync*8+i, pixels.Color(LampMaxSel[0],LampMaxSel[1],LampMaxSel[2]));} 98 | else { // Mode = 3 99 | if (LampStatus[Sync] & Mask) { // LED on? 100 | pixels.setPixelColor(Sync*8+i, pixels.Color(LampMaxSel[0],LampMaxSel[1],LampMaxSel[2]));}} 101 | for (byte c=0;c<3;c++) { // set max brightness of lamp to selected max value 102 | LampMax[Sync*8+i][c] = LampMaxSel[c];}} 103 | Mask = Mask << 1;}}}} 104 | if (!Sync && OwnCommands) { // a good place to let an own command run once per refresh cycle 105 | if (OwnCommands & 1) { // check which command is meant 106 | if (!(OwnCommandStep % 5)) { // only be active every 5th refresh cycle 107 | byte Step = OwnCommandStep / 5; // calculate the current step 108 | for (byte i=0;i<6;i++) { // pattern has 6 fading grades 109 | if (Step+i < 12) { // it's for 12 LEDs 110 | pixels.setPixelColor(Step+i,OwnPattern[i][0],OwnPattern[i][1],OwnPattern[i][2]);} 111 | else { 112 | pixels.setPixelColor(Step+i-12,OwnPattern[i][0],OwnPattern[i][1],OwnPattern[i][2]);}}} 113 | OwnCommandStep++; 114 | if (OwnCommandStep > 59) { 115 | OwnCommandStep = 0;}}} 116 | Sync++;} // increase the counter 117 | else { // LED patterns are done 118 | if (CommandCount) { // still bytes to read for this command 119 | CommandCount--; 120 | switch (Command) { 121 | case 192: // color select command 122 | LampMaxSel[2-CommandCount] = RecByte; 123 | break; 124 | case 193: // configure number of LED bytes 125 | OwnCommands = RecByte; // store new number of LEDs 126 | SystemFlags = 1; // indicate special treatment at sync 127 | break; 128 | case 195: // set color for LED 129 | LampMax[RecByte][0] = LampMaxSel[0]; 130 | LampMax[RecByte][1] = LampMaxSel[1]; 131 | LampMax[RecByte][2] = LampMaxSel[2]; 132 | if (LampStatus[RecByte / 8] &= 255-(1<<(RecByte % 8))) { // LED on? 133 | pixels.setPixelColor(RecByte, pixels.Color(LampMaxSel[0],LampMaxSel[1],LampMaxSel[2]));} 134 | break; 135 | default: // unknown command 136 | CommandCount = 0;} 137 | if (!CommandCount) { // command processed 138 | Command = 0;}} 139 | else { 140 | switch (RecByte) { // treat it as a command 141 | case 64: // Mode 0 -> lamps being lit get the ColorSelect color 142 | Mode = 0; 143 | break; 144 | case 65: // Mode 1 -> lamps keep their color 145 | Mode = 1; 146 | break; 147 | case 66: // Mode 2 -> lamps set in the following frame get the new color immediately 148 | Mode = 2; 149 | break; 150 | case 67: // Mode 3 -> only the color of the LEDs is changed, but they're not turned on 151 | Mode = 3; 152 | break; 153 | case 68: // Mode 4 -> LED state is frozen 154 | Mode = 4; 155 | break; 156 | case 100: // execute OwnCommand 157 | OwnCommands |= 1; // activate OwnCommand number 1 158 | break; 159 | case 101: 160 | OwnCommands &= 254; // deactivate OwnCommand number 1 161 | for (byte i=0;i<12;i++) { // for all affected LEDs 162 | pixels.setPixelColor(i, pixels.Color(0,0,0)); // turn them off 163 | LampStatus[i / 8] &= 255-(1<<(i % 8));} // and change the status to off 164 | break; 165 | case 170: // sync command 166 | Sync = 0; // the next four cycles (8 bytes) represent a lamp pattern 167 | pixels.show(); // update the LEDs 168 | if (SystemFlags) { // number of LEDs has changed 169 | SystemFlags = 0; 170 | NumOfLEDbytes = OwnCommands; 171 | OwnCommands = 0; 172 | pixels.updateLength(NumOfLEDbytes*8);} // set new strip length 173 | break; 174 | case 192: // color select command 175 | Command = 192; 176 | CommandCount = 3; // 3 bytes to read for this command 177 | break; 178 | case 193: // configure number of LED bytes 179 | Command = 193; 180 | CommandCount = 1; 181 | break; 182 | case 195: // set color for LED 183 | Command = 195; 184 | CommandCount = 1; 185 | break; 186 | case 196: // turn off all LEDs 187 | for (byte i=0;i 59) { 156 | OwnCommandStep = 0;}}} 157 | 158 | The first line waits for the Sync counter becoming zero and OwnCommands being different from zero. That means if any of the bits in OwnCommands is set then the following code is executed after each Sync which is once per refresh cycle. 159 | At first the player checks the LSB of OwnCommands and proceeds if it's set. In order not to play the pattern too fast the player checks next if OwnCommandStep can be divided by 5 without rest and skips the other 4 cycles. The desired effect is some kind of green radar animation for an LED ring with 12 LEDs. Basically it's always the same pattern going round and round, a bright spot which fades in 6 steps. 160 | 161 | const byte OwnPattern[6][3] = {{0,0,0},{0,50,0},{0,100,0},{0,150,0},{0,200,0},{0,250,0}}; 162 | 163 | That means for the player that it has to write always the same LED data, but the start LED changes from cycle to cycle. Therefore OwnCommandStep divided by 5 is also the internal counter of this command which determines the actual LED to start from. The pixels.set command writes the color values in the corresponding LEDs. This data is then sent to the LEDs on the next Sync. 164 | At the end OwnCommandStep is increased by one and after 60 cycles it starts all over again. 165 | 166 | Now that we have added the command to the LED_ExpBoard SW, we still have to issue it from the program running on the APC board itself. This can be done with the LEDhandling command. For our single byte command this would be 167 | 168 | LEDhandling(6, 100); // write 100 to the command buffer 169 | LEDhandling(7, 1); // send 1 byte to the LED_ExpBoard 170 | 171 | The first line adds our command (number 100) to the command buffer and the second line sends 1 byte of this buffer. If your command has more than one byte they all need to be send with LEDhandling(6,byte) and executed with LEDhandling(7, number of bytes). 172 | Let's use LEDsetColor as an example. This command has 4 bytes (command and 3 color values) which leads to 173 | 174 | void LEDsetColor(byte Red, byte Green, byte Blue) { // set a new color 175 | LEDhandling(6, 192); 176 | LEDhandling(6, Red); 177 | LEDhandling(6, Green); 178 | LEDhandling(6, Blue); 179 | LEDhandling(7, 4);} 180 | 181 | -------------------------------------------------------------------------------- /DOC/LisyDebug.md: -------------------------------------------------------------------------------- 1 | # Controlling Lisy 2 | 3 | This page covers just the APC relevant basics. In some cases it might be necessary to read the corresponding chapters in the [Lisy manual](https://lisy.dev/documentation.html). 4 | 5 | Note that the following debug features are only available while using the normal Lisy version. Lisy Embedded does not include these features. 6 | 7 | The basic mode of Lisy is selected by the Lisy_Jumpers P12 which are depicted below. 8 | 9 | ![Lisy Jumper](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/LisyJumper.png) 10 | 11 | |Jumper|Function|Comment| 12 | |--|--|--| 13 | |1|No Autostart|Lisy won't start PinMame after booting up| 14 | |2|Hotspot Mode|Lisy will start a WiFi hotspot instead of using the local Wifi| 15 | |3|Debug Mode|Writes a debug log| 16 | |4|Lisy Control|Starts the Lisy Webserver| 17 | |5|Not used|| 18 | |6|Not used|| 19 | 20 | ## Setting up WiFi 21 | 22 | All the features described below do require a working WiFi which means you have to put a WiFi capable Raspberry Pi (Zero or Pi3) on your APC board. 23 | 24 | To set up WiFi you have to find the following file on your Lisy SD-card 25 | 26 | /lisy/lisy/ wpa_supplicant.conf 27 | 28 | and change the settings for 'country', 'ssid' and 'psk' to those of your wireless network. 29 | 30 | For more information about Lisy and WiFi, please read the 'Wireless config' section in the Lisy manual. 31 | 32 | ## Updating Lisy 33 | 34 | With WiFi working you can use the incremental update function for minor updates instead of having to write a new Lisy-image to the SD card. 35 | 36 | With WiFi set-up and the system being switched off, connect the jumper 4 (Lisy Control) and power up your machine. 37 | After booting up, Lisy will try to connect to your WiFi. If the connection is successful, the obtained IP address is shown in the pinball displays. 38 | Enter this IP address into your browser to connect to the LisyControl webpage where you can initiate an update. 39 | 40 | ## Lisy Debug Mode 41 | 42 | Lisy comes with a build-in Debug Mode which writes a debug log to the SD card of the Raspberry Pi when activated. 43 | Before you start the Debug mode you have to specify what kind of debug information you want to have logged. To do this, enter the 'Game Settings' of the 'Remote Control' Mode and change the 'Lisy Debug' setting accordingly. 44 | The value for 'Lisy Debug' can be derived from the following table. 45 | 46 | |Debug Option|Value| 47 | |--|--| 48 | |Displays|1| 49 | |Switches|2| 50 | |Lamps|4| 51 | |Solenoids|8| 52 | |Sound|16| 53 | 54 | If you want to log more than one option you have to add the respective values. For example, if you want to log the events for switches and solenoids you have to select 10 here. 55 | Don't forget to select 'Exit Settings' to store your changes to the APC's SD card. 56 | 57 | To start the Debug Mode, turn off your machine and set Lisy jumper 3 before turning it back on. The system will now log the selected debug information, but this doesn't mean that it is immediately stored on Lisy's SD card. You should therefore not just turn your pinball machine off after your debug session, but press the Shutdown Switch SW1 which will initiate a controlled shutdown of Lisy. After that you can turn off your machine and remove the SD card of the Raspberry Pi. 58 | 59 | The log file is located in the /lisy/lisy_m/debug folder. 60 | 61 | ## Remote debug Mode 62 | 63 | Lisy can also be controlled remotely via WiFi. In this mode it'll just print all information directly into your shell, including the debug log. Hence, you don't have to bother with removing the SD card any more, since all the required information is already on your screen. 64 | 65 | If you have set-up the WiFi configuration of your Lisy system, you can use the Remote Debug Mode as follows: 66 | 67 | With your pinball machine switched off, connect the jumpers 1 (No Autostart) and 3 (Debug Mode). 68 | After you've turned on the power, wait for the yellow LED to light up. Now Lisy has booted and is waiting for instructions. 69 | First you have to obtain the IP address of Lisy in your WiFi network. Then open up a shell on your PC and use this address to connect to Lisy via ssh: 70 | 71 | ssh pi@IP-address 72 | 73 | Log into the system by using lisy80 as the password. 74 | Now it depends whether you're using the Pi on an APC 3 or on a Lisy_Mini board. In case of the APC 3 you have to use 75 | 76 | ./run_lisy_apc 77 | 78 | to start PinMame and with a Lisy_Mini board it's 79 | 80 | ./run_lisy_mini 81 | 82 | These commands will run Lisy and print a complete log into your shell. 83 | 84 | ### Remote mode and Lisy updates 85 | 86 | The run_lisy_apc and run_lisy_mini commands are not automatically updated with your Lisy system when the update is done via Lisy Control. That means you have to change these scripts manually. 87 | Let's use the run_lisy_apc script as an example. Normally it looks as follows: 88 | 89 | sudo ./lisy/xpinmame.vid_lisy -nosound -skip_disclaimer -skip_gameinfo -nvram_directory /pinmame/nvram -rp /boot/lisy/lisy_m/roms lisy_apc 90 | #sudo /usr/local/bin/lisy -nosound -skip_disclaimer -skip_gameinfo -nvram_directory /pinmame/nvram -rp /boot/lisy/lisy_m/roms lisy_apc 91 | 92 | To activate the Lisy update you just have to move the comment sign from the second to the first line and you're done. 93 | Note that you have to issue an rw command first in order to set Lisy into read/write mode. 94 | -------------------------------------------------------------------------------- /DOC/PICS/APC.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/APC.JPG -------------------------------------------------------------------------------- /DOC/PICS/APC_Connectors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/APC_Connectors.png -------------------------------------------------------------------------------- /DOC/PICS/APC_Pinbot.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/APC_Pinbot.JPG -------------------------------------------------------------------------------- /DOC/PICS/APC_Rollergames.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/APC_Rollergames.JPG -------------------------------------------------------------------------------- /DOC/PICS/Audacity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/Audacity.png -------------------------------------------------------------------------------- /DOC/PICS/BK.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/BK.jpg -------------------------------------------------------------------------------- /DOC/PICS/BKopen.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/BKopen.JPG -------------------------------------------------------------------------------- /DOC/PICS/Buck.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/Buck.jpg -------------------------------------------------------------------------------- /DOC/PICS/Comet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/Comet.jpg -------------------------------------------------------------------------------- /DOC/PICS/CometLED.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/CometLED.jpg -------------------------------------------------------------------------------- /DOC/PICS/FrameExample.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/FrameExample.JPG -------------------------------------------------------------------------------- /DOC/PICS/FrameSys11a.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/FrameSys11a.JPG -------------------------------------------------------------------------------- /DOC/PICS/FrameSys11c.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/FrameSys11c.JPG -------------------------------------------------------------------------------- /DOC/PICS/FrameSys7.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/FrameSys7.JPG -------------------------------------------------------------------------------- /DOC/PICS/FrameSys7_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/FrameSys7_2.jpg -------------------------------------------------------------------------------- /DOC/PICS/FrameSys9.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/FrameSys9.JPG -------------------------------------------------------------------------------- /DOC/PICS/GI_LEDs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/GI_LEDs.jpg -------------------------------------------------------------------------------- /DOC/PICS/LED_ExpBoard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/LED_ExpBoard.jpg -------------------------------------------------------------------------------- /DOC/PICS/LampFix.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/LampFix.jpg -------------------------------------------------------------------------------- /DOC/PICS/LisyJumper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/LisyJumper.png -------------------------------------------------------------------------------- /DOC/PICS/MiniLisy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/MiniLisy.png -------------------------------------------------------------------------------- /DOC/PICS/PinMame.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/PinMame.jpg -------------------------------------------------------------------------------- /DOC/PICS/Pinbot.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/Pinbot.JPG -------------------------------------------------------------------------------- /DOC/PICS/PlayerDisplay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/PlayerDisplay.png -------------------------------------------------------------------------------- /DOC/PICS/RG_Sol.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/RG_Sol.JPG -------------------------------------------------------------------------------- /DOC/PICS/RG_Sw.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/RG_Sw.JPG -------------------------------------------------------------------------------- /DOC/PICS/Ringbuffer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/Ringbuffer.png -------------------------------------------------------------------------------- /DOC/PICS/SDadapter.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/SDadapter.JPG -------------------------------------------------------------------------------- /DOC/PICS/SDonBoard.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/SDonBoard.JPG -------------------------------------------------------------------------------- /DOC/PICS/SolExpBoard.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/SolExpBoard.JPG -------------------------------------------------------------------------------- /DOC/PICS/Sys11cKabel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/Sys11cKabel.jpg -------------------------------------------------------------------------------- /DOC/PICS/Sys7DispCable.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/Sys7DispCable.JPG -------------------------------------------------------------------------------- /DOC/PICS/Sys7SoundCable.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/Sys7SoundCable.jpg -------------------------------------------------------------------------------- /DOC/PICS/Sys7_Alpha.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/Sys7_Alpha.jpg -------------------------------------------------------------------------------- /DOC/PICS/Sys7_Alpha2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/Sys7_Alpha2.jpg -------------------------------------------------------------------------------- /DOC/PICS/U1wrongPol.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/PICS/U1wrongPol.jpg -------------------------------------------------------------------------------- /DOC/PinMame.md: -------------------------------------------------------------------------------- 1 | # PinMame Sound 2 | 3 | This page is to guide you through the process of enabling the APC to generate the original sound and music for your pinball machine. 4 | If you're lucky then your machine is listed below which means that someone else has done the work for you. If not then I'm afraid that you have to read the rest of this page also. 5 | 6 | # Available Sounds 7 | 8 | At the moment the list of available sound packages is still quite short, but we hope that some of you will do this for their machines also. Of course it would be great if you'd share your sound package with the rest of us. Up to now we haven't found some server space to store the files on, so send me a PM via Pinside or Flippertreff (see the feedback section on the main page) if you want to have one of the sound packages listed below. 9 | 10 | |System|Game| Sound Files |Comments| 11 | |--|--|--|--| 12 | |3|Disco Fever| available on request| PinMameExceptions might still need some finetuning | 13 | |4|Flash| available on request| Ball saver and alternate music mode implemented for this machine | 14 | |6|Time Warp| available on request | Ball saver and alternate music mode implemented for this machine | 15 | |6|Gorgar| available on request | Ball saver and alternate music mode implemented for this machine | 16 | |6|Firepower| available on request thanks to Matiou | PinMameExceptions also done by Matiou / Ball saver and alternate music mode implemented for this machine / [Throttle value](https://github.com/AmokSolderer/APC/blob/master/DOC/RunGame.md#emulation-speed) needs to be changed to 110| 17 | |6|Alien Poker| available on request | Ball saver and alternate music mode implemented for this machine | 18 | |7|Barracora| available on request | Ball saver and alternate music mode implemented for this machine | 19 | |7|Black Knight| available on request| Ball saver and alternate music mode implemented for this machine | 20 | |7|Jungle Lord| available on request| Ball saver and alternate music mode implemented for this machine | 21 | |7|Pharaoh| available on request| PinMameExceptions done by Grangeomatic / Ball saver and alternate music mode implemented for this machine| 22 | |9|Comet|available on request| Ball saver and alternate music mode implemented for this machine | 23 | |11a|Pinbot| available on request| Ball saver implemented for this machine | 24 | |11a|F-14 Tomcat| available on request thanks to Snux | PinMameExceptions also done by Snux / Ball saver implemented for this machine| 25 | |11b|Space Station| available on request| Ball saver implemented for this machine | 26 | |11c|Rollergames| available on request| There're problem with this game. For some reason PinMame restarts random music tracks all 5 seconds. The issue doesn't seem to affect the Windows version of PinMame. Please contact me if you have any idea what the root cause might be. | 27 | 28 | # What needs to be done 29 | 30 | The fact that you're reading this probably means that your machine is not yet supported. So let's first summarize what you have to do to change that: 31 | 32 | * Get the sounds. This can be done from the internet, PinMame or by self recording. 33 | * Adjust the amplitude, DC offset and sampling rate if necessary. You need a mono WAV file with 44.1KHz sampling rate 34 | * Ensure the filenames are correct to help the APC find the correct audio file 35 | * Convert them to the APC sound file format 36 | * Put them on the SD card of the APC 37 | * Do the necessary PinMameExceptions to incorporate the special functions of the respective audio board 38 | 39 | Click on the generation of your game to get to the corresponding how-to page: 40 | 41 | [System 3 - 7 sound how-to](https://github.com/AmokSolderer/APC/blob/master/DOC/PinMameSound_3_7.md) 42 | 43 | [System 9 sound how-to](https://github.com/AmokSolderer/APC/blob/master/DOC/PinMameSound_9.md) 44 | 45 | [System 11 sound how-to](https://github.com/AmokSolderer/APC/blob/master/DOC/PinMameSound_11.md) 46 | -------------------------------------------------------------------------------- /DOC/PinMameSounds.md: -------------------------------------------------------------------------------- 1 | # Instructions for extracting sound files from pinball ROMs 2 | 3 | Thanks to Mokopin for these instructions 4 | 5 | There are several ways to extract sounds from pinball ROMs: 6 | 1) 'F5' method using [PINMAME and M1 music extractor](https://www.vpforums.org/index.php?app=tutorials&article=54) 7 | 2) 'F6' method using [PINMAME with patch by lucky1](https://vpuniverse.com/forums/topic/4489-pinmame-altsound-editor/) 8 | 9 | Method 2) seems preferable because it delivers a list of files automatically, but does not work for everybody (OS Win7, Win10) 10 | It seems that pinmame version >dec 2020 is required. With WIN10 It doesn't work with the pinmame32.exe from sourceforge which is version 3.3 (july 29th,2020). It works flawlessly with version 3.3b from Toxie (https://www.vpforums.org/index.php?app=downloads&showfile=11571) 11 | Method 1) has the drawback that the F5 key is not reliably polled and thus requires good nerves for many files... 12 | 13 | Both methods have in common, that both music and sound board of the pinball control system are triggered with machine specific commands (eg. 0x0101 means play song1 on musicboard, 0x0001 means play sound1 on soundboard) . With method 1) a number of files will be available in the 'wave' folder of the pinmame folder (eg. 'rdkn0001.wav'). These files are sampled with 48kHz which is the default pinmame sample rate and which needs to be converted to the APC samplerate of 44.1kHz later. 14 | 15 | Before that, renaming and postprocessing of the files is required. This could be performed with an automatic renaming tool ( eg. Bulk Rename Utility https://www.bulkrenameutility.co.uk). The sound files need to be changed to '00_XX.wav' with XX in hexadecimal format, and the music files to '01_XX.wav' accordingly. 16 | 17 | The next step is postprocessing in an audio tool like e.g. audacity (http://www.audacity.com). With audacity nearly every operation can be batch processed. This is very handy to change the relative volume of music files or/and sound files with a single mouse click. 18 | It also can be used to automize a time series of 'F5' exported soundfiles. Eg. if the 'F5' method is used to record the sounds 0x00-0x0F into a single sound file, the sounds can be threshold-level detected by audacity and saved automatically. 19 | This can be achieved by inserting the following commands into the macro queue: 20 | 21 | 1) Mark all 22 | 2) Highpass filter 10Hz /6dB 23 | 3) noisefinder (-)28db, 0.1 , 0.1 , 0 ( dB value might need adaption, if resulting selection is unsatisfactory) 24 | 25 | After executing the macro, check if the text markers are set correctly. Then use CTRL-Shift-L to export single files defined by the text markers (use prefix '0_'). 26 | 27 | The next recommended step is to mix the stereo track down to mono (use Tracks->mix->downmix to mono in audacity) and change the volume (either use 'normalize' oder 'amplify' function in audacity). Experiment a bit with the amplification, because the synthetically generated peak values (by pinmame) are sometimes misleading. Try it out on the real machine. 28 | 29 | After this step, you can either convert each file to 44.1kHz manually in audacity (for this there is no macro function yet ). Or use a different tool like OCENAUDIO (https://www.ocenaudio.com) which can batch convert sample rates. With OCENAUDIO you can pull a folder in the left column of the program screen, mark all with CTRL-A and use the right mouse button to 'change samplerate' and set this to 44100Hz. After this, close all files and confirm 'save files' with ok and wait for automatic conversion. 30 | 31 | The last step is to convert the 16Bit WAV files to the 12Bit APC format. This can be done with a PERL script which takes all (mono) wav files within the current directory and converts them to *.snd files. This script can be executed with a perl interpreter, e.g. for windows available from http://strawberryperl.com 32 | 33 | The resulting snd Files need to be copied to the APC SD-CARD. Please use a SD-card formatter utility (eg https://www.sdcardformatter.com/) and not the operating system function. FAT file systems do not sort or index files so open does a sequential search for the file. Opening a file normally takes about 15ms but can take up to 50ms. In addition to that, the SD card controller might be doing some 'housekeeping', further prolonging access times. As a result, a sound file may not be found by the APC, even if it is available on the SD card (with a larger number of files stored on it). 34 | -------------------------------------------------------------------------------- /DOC/Pinbot.md: -------------------------------------------------------------------------------- 1 | # The APC Pinbot 2 | 3 | This page is about the Pinbot.ino game SW which is part of the APC SW. Note that you have to have the Pinbot sound files for this game to work. 4 | 5 | ![APC Pinbot](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/Pinbot.JPG) 6 | 7 | This is a view inside the backbox. 8 | 9 | ![APC open PB](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/APC_Pinbot.JPG) 10 | 11 | I'm using an APC 2 prototype board for this. As I'm running the code natively on the Arduino I don't need Lisy/PinMame and therefore no Raspberry Pi. 12 | 13 | ## Features 14 | 15 | * Ball Saver -> Pinbot is an outlane monster and when a ball drains in an outlane right after it was launched then I'm really getting furious. Hence there's an optional Ball Saver which saves any ball draining in an outlane before any flipper buttons had been pressed. 16 | * 3 ball Multiball -> Pinbot's multiball is kind of lame IMHO. That's why there's a 3 ball multiball option in my SW. Activate the option, add a third ball and enjoy a different ruleset introducing an unlimited million Jackpot. 17 | 18 | ## 3 ball Multiball 19 | 20 | Switching the 'Multiball' game setting to '3 ball' (and adding a third ball) switches to a different ruleset. 21 | 22 | The the 3 ball mode keeps Pinbot's basic rules, which means that opening the visor, extra balls and so on work exactly as before. The main differences are: 23 | 24 | * The skill shot multiplier (Vortex) does not increase with every new launch but stays 1 25 | * When the visor has been opened and two balls have been locked in the eyes, the visor closes and a third ball is put into play. This ball must be shot into the eject hole left of the visor to start multiball 26 | * As long as 3 ball multiball is running, the ramp is lit for jackpots. The first jackpot is worth 200,000 points, the second 400,000 and so on. At 1,000,000 points it won't increase any more, but can be scored as long as 3 balls are in play. 27 | * During 3 ball multiball, the eyes and the eject hole hold balls for an adjustable hold time (10s by default) 28 | * If a ball goes from the ramp to the shooter lane, no jackpots can be scored until the ball has been launched 29 | * After one ball has drained, the visor won't close and the remaining two balls can be locked in the eyes again to re-lite the eject hole. 30 | * If a second ball drains, the visor closes and needs to be re-opened with the chest lamps 31 | 32 | Like the original Pinbot, the APC SW also explains the rules if the machine is in attract mode for a while. Depending on which multiball mode is selected in the game settings, it will explain the original 2 ball or the 3 ball rules as shown [here](https://youtu.be/IGrUnbhkijU). 33 | 34 | ## How to set up this game 35 | 36 | You need to have the audio files for this game. [Contact me](https://github.com/AmokSolderer/APC/tree/master#feedback) to get the corresponding sound file package. 37 | 38 | If you want to use the 3 ball Multiball you have to add a third ball apparently. Don't forget to remove it when you switch back to 2 ball mode. 39 | 40 | You might have to adjust the 'Eject Strength' setting. It should be selected for the outhole kicker to be strong enough to put one ball into the trunk, but not two. The default value should be OK for most machines, but if your outhole kicker is somewhat special you might have to change this setting. 41 | The reason for this is that Pinbot's ball through is lacking a switch to detect a third ball. Therefore it's difficult to detect a double drain of the last two balls. The SW tries to detect whether one or two balls are in the outhole by limiting the strength of the outhole kicker. If the first kick was not successfull, the second one is done much stronger and the SW assumes this to be a double drain. 42 | 43 | ## Pinbot Game Settings 44 | 45 | | Number | Text | Item Nr | Item Text | Default | Comment | 46 | |--|--|--|--|--|--| 47 | | 0 | Drop TG Time | - | - | 15 | Down time of the drop targets | 48 | | 1 | Reach Planet | 0 | Pluto | - | Planet to reach for Extra Ball | 49 | | 1 | | 1 | Neptune | - | | 50 | | 1 | | 2 | Uranus | - | | 51 | | 1 | | 3 | Saturn | - | | 52 | | 1 | | 4 | Jupiter | - | | 53 | | 1 | | 5 | Mars | - | | 54 | | 1 | | 6 | Earth | X | | 55 | | 1 | | 7 | Venus | - | | 56 | | 1 | | 8 | Mercury | - | | 57 | | 2 | Energy Timer | - | - | 15 | Time to collect energy | 58 | | 3 | Multiball | 0 | 2 Ball | - | 2 ball multiball (Normal Pinbot) gameplay - see features description| 59 | | 3 | | 1 | 3 Ball | - | 3 ball multiball gameplay | 60 | | 4 | Ball Saver | - | - | No | Bool setting - see features description | 61 | | 5 | Eject Strength | - | - | 30 | Strength of the outhole kicker (debug option)| 62 | | 6 | Hold Time | - | - | 10 | Time to hold balls in locks during 3 ball multiball | 63 | | 7 | Reset High | - | - | - | No setting - resets the high scores for this game | 64 | | 8 | Restore Default | - | - | - | No setting - restores the default settings | 65 | | 9 | Exit Settings | - | - | - | No setting - exits the settings mode and writes the new setting to an SD card if present | 66 | 67 | Check the [settings page](https://github.com/AmokSolderer/APC/blob/master/DOC/Settings.md#using-the-settings-menu) if you're not sure how to use these game settings. 68 | 69 | -------------------------------------------------------------------------------- /DOC/Prepare.md: -------------------------------------------------------------------------------- 1 | # Basic Preparation 2 | 3 | ## SD cards 4 | 5 | The APC needs an SD card for it's settings as well as for the audio files. 6 | 7 | From HW version 3.1 onwards the APC has an on-board SD-Card slot which is located below the Arduino. 8 | 9 | ![SD slot](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/SDonBoard.JPG) 10 | 11 | If you want to let the APC generate the sound then you should reformat your SD Card befort using it, preferably with the tool provided from the SD Association (sdcard.org). This can improve the file access time of the card which is crucial for the sound system to work properly. 12 | 13 | ### Self made SD adapter 14 | 15 | Depending on your pinbal machine the on-board SD-Card slot might be cumbersome to access. You might therefore want to built a simple adapter which can be plugged into connector P8 and can be accessed comfortably. 16 | 17 | ![SD adapter](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/SDadapter.JPG) 18 | 19 | This adapter can be build very easily by just using a micro SD adapter and soldering a pin row beneath it. It must then be plugged into the SD card connector P8 of the APC. The orientation must be to make the adapter point away from the Arduino. Look at the photo below if you're unsure about the orientation. 20 | 21 | Of course you cannot use the SD-Card slot and the self made adapter simultaneously, as the APC can only use one SD-Card at a time. 22 | 23 | ### Installation frames 24 | 25 | There're [installation frames](https://github.com/AmokSolderer/APC/blob/master/DOC/Frames.md) available which can be 3D printed and help you install the APC board in your backbox. 26 | 27 | # Machine specific preparation 28 | 29 | This page is divided in different sections, depending on which generation your pinball machine is from. 30 | 31 | ## System 3 - 6 32 | 33 | ### System 3 - 7 display blanking cable 34 | 35 | Sys3 - 7 games need a single wire for the display blanking. On the APC you can either use pin 12 of Display Segments 1 (1J5) or P3 which is a single pin located right next to 1J5 and labeled Blank_N. This signal must be connected to pin 4 of 1P3 (the connector which was plugged on 1J3 of your old CPU board). For this being the only functional pin on 1P3, one easy way to do the connection is to just turn 1P3 by 90 degree and plug it on pin 12 of 1J5 on the APC. The picture below shows this setup in a System7 Jungle Lord. 36 | 37 | ![Sys7DispCable](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/Sys7DispCable.JPG) 38 | 39 | ### System 7 display comma cables 40 | 41 | The picture above does also show the two additional connections that have to be done for the commas of Sys7 displays to work. The APC has them on pin 10 (comma 1+2) and 11 (comma 3+4) of 1J5 and on pin 3 (comma 1+2) and pin 4 (comma 3+4) of 1J8. Either one of those have to be connected to pin 2 (comma 1+2) and pin 1 (comma 3+4) of the old 1P8. 42 | In the picture 1J8 of the APC has been used to provide the signals. 43 | 44 | ### System 7 audio cable 45 | 46 | You can use a simple 5 wire cable to use System7 audio boards with the APC 3.0 (older APCs need additional HW). This cable needs to connect the pins 3 - 7 of the HW extensions interface (P11) of the APC 3.0 to the audio board. One easy way to do this is to connect them to the pins 12 to 8 of 1P8 (the plug belonging to 1J8 of your Sys7 CPU board). 47 | 48 | |APC pin (P11)| 1P8 pin | 49 | |--|--| 50 | |3|12| 51 | |4|11| 52 | |5|10| 53 | |6|9| 54 | |7|8| 55 | 56 | A cable like this is shown below. 57 | 58 | ![Sys7SoundCable](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/Sys7SoundCable.jpg) 59 | 60 | To make the APC use this interface, you have to set the 'PinMame Sound' setting to 'Board'. The setting can be found in the 'Game Settings' menu in 'Remote Control' mode. 61 | 62 | ## System 9 - 11 63 | 64 | For System 9, 11 and 11a machines the APC fits in quite well, you might have to cut some cable ties though. 65 | Using the old audio boards is not possible for these machines. 66 | 67 | ### Cable extensions for System11b + c 68 | 69 | For some System11 games you'll need to extend some cables to make them fit to the APC. For System11a boards this is not necessary, but you'll have to cut some cable ties to open the cable tree a bit. If you don't want to do this you can use cable extensions instead. 70 | 71 | For later games featuring auxiliary power and interconnect boards there is no way to prevent this. For a System11c machine like Rollergames you have to extend the cables to the power connector 1J17, the lamp strobe connector 1J7 and one of the solenoid drivers 1J19. For the flipper drivers (second part of 1J19) it's enough to cut one cable tie. The result looks like this: 72 | 73 | ![APC_Rollergames](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/APC_Rollergames.JPG) 74 | 75 | # Ready for testing 76 | 77 | The next step is to [do the tests](https://github.com/AmokSolderer/APC/blob/master/DOC/InitialTests.md). 78 | -------------------------------------------------------------------------------- /DOC/Problems.md: -------------------------------------------------------------------------------- 1 | # If things don't work 2 | 3 | ## APC doesn't boot 4 | 5 | On some System 9 and 11 machines the APC doesn't boot sometimes. Usually it is enough to powercycle your machine to make it work. 6 | If it happens frequently then you could swap C14 from a 10µF to a 22µF capacitor. 7 | 8 | ## Sound stuttering 9 | 10 | If your sound has unregular lags and stutters sometimes then it's most probably an issue with your SD card. 11 | 12 | The first thing to try is to format your card with a special SD-card formatting tool like the one from the SD Association (sdcard.org) which can improve the time your SD card needs to open a file. This can be crucial especially for pre System11 machines as their sound sequences usually consist of lot's of single sounds. Each of these sounds requires a new file on the card to be opened and if your card cannot open the files fast enough than the sounds just start to stutter. 13 | 14 | If this doesn't work then try a different SD card. I had several SD cards of the same brand, but for some reason one of these cards just produced sound lags on my Pinbot, even though I had it formatted with the formatting tool. After I replaced the card with one of it's siblings everything worked fine. 15 | 16 | However, some sound sequences might just be too challenging for your SD cards. 17 | The solution is to record the whole sequence into one single sound file and to play this with a high priority. This requires only one file to be opened for the whole sequence and the high priority blocks all subsequent sound commands from PinMame as long as the file is being played. 18 | 19 | ## Unknown Command error message 20 | 21 | If you're using the APC with Lisy/PinMame and the 'Unknown Command' error message followed by a number pops up on your lower displays then you have a problem with your serial communication. 22 | 23 | This usually happens when Lisy/PinMame is playing sound files from the SD card. The reason is that an SD-card needs several ms to open a file. During this time the APC SW cannot process any commands coming in on the serial interface which means they have to be stored in the receive buffer. 24 | The standard size of the DUE's serial buffer is 128 bytes which was sufficient for the SD-cards I did my tests with. Even though these were cheap and ordinary cards it still might be that your card is even slower. 25 | Of course you can try another SD-card and hope that this one is faster, but you can also increase the size of the serial buffer. The problem is that this setting is part of the Arduino libraries which makes it a bit cumbersome to find at least with the Arduino IDE. 26 | 27 | If you're using Sloeber, the Arduino plugin for Eclipse you can simply take a look into your 'Project Explorer' and look for the file RingBuffer.h as shown below: 28 | 29 | ![Ringbuffer](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/Ringbuffer.png) 30 | 31 | For the Arduino IDE this is a bit more complicated. 32 | In the preferences window of your Arduino IDE you should see a link to some preferences.txt file in the lower left corner. We don't care about the file, but the path is important. It should look somehow like this: 33 | 34 | C:\Users\user\AppData\Local\Arduino15 35 | 36 | Follow the path and then proceed to 37 | 38 | C:\Users\user\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.12\cores\arduino 39 | 40 | where you should find the RingBuffer.h file. 41 | 42 | In the file there's the line 43 | 44 | #define SERIAL_BUFFER_SIZE 128 45 | 46 | which sets the buffer size to 128 bytes. 47 | Set the size to 256 bytes and your 'Unknown Command' errors should be gone. 48 | 49 | ## Damaged Arduino clone 50 | 51 | If you're using a chinese clone of the Arduino DUE which just stopped working and draws a huge current instead, then it's most probably a blown buck converter IC. 52 | You can check this by supplying your DUE on the bench (without the APC board) with 5V. Then check the temperature of the marked IC. 53 | 54 | ![Buck](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/Buck.jpg) 55 | 56 | If the IC gets hot then it's damaged. The good thing is that you don't need this IC when using the DUE with the APC, so you can just remove it and your system should run fine again. 57 | -------------------------------------------------------------------------------- /DOC/RunGame.md: -------------------------------------------------------------------------------- 1 | # Run a game 2 | 3 | So you've done the tests and you have the Base Code running. If you've also [adjusted the Base Code](https://github.com/AmokSolderer/APC/blob/master/DOC/SetUpBC.md) to your machine then you can already press the Game Start button and play a very basic game. 4 | 5 | After you've had enough fun with the Base Code you have the following options: 6 | 7 | * Use Lisy/PinMame to run the original game code on a Raspberry Pi 8 | * Create your game in MPF and let it control the APC 9 | * Do your own game code in C and use the APC SW framework 10 | 11 | ## PinMame 12 | 13 | The APC by itself cannot run the original Williams EPROM software, but you can use PinMame to emulate the pinball's hardware. By this you can run the old game SW on the APC. The easiest way to do this is to plug a Raspberry Pi on the APC board and install Lisy on it. 14 | Here's what to do: 15 | 16 | 1. Enter the [System Settings](https://github.com/AmokSolderer/APC/blob/master/DOC/Settings.md#system-settings) 17 | 1.1. Select 'Remote Control' as the Active Game 18 | 1.2. Check that 'On Board' is selected in the 'Connect Type' setting 19 | 2. Enter the [Game Settings of the Remote Control Mode](https://github.com/AmokSolderer/APC/blob/master/DOC/Settings.md#game-settings-in-remote-control-mode) 20 | 2.1. Select the corresponding [PinMame game number](https://github.com/AmokSolderer/APC/blob/master/DOC/lisyminigames.csv) in the Game Settings 21 | 2.2. If you want to let the APC generate the audio then the Game Setting 'PinMame Sound' has to be APC, 'Board' means that an old audio board is used which is possible for System 3 - 7 machines. System 7 machines need an additional cable for this to work 22 | 2.3. Exit the settings and switch off your machine 23 | 3. Go to the [Lisy project page](https://lisy.dev/apc.html) and download a Lisy image file. Note that only the Raspberry Pi Zero, Zero W, Pi 2W, 3A+, 3B+ as well as the Banana PI M2 Zero models are currently supported by Lisy. 24 | 3.1. Install the image file on an SD card and put it in your Raspberry Pi 25 | 3.2. Install the Pi on your APC board 26 | 4. Turn on your pinball machine 27 | 4.1. The 'Booting Lisy' message should appear in your displays 28 | 4.2. After a while the yellow on board LED will be lit and the name of the selected game will appear in the displays as well as a countdown 29 | 4.3. The green LED will be lit and the game should start 30 | 31 | Most Williams games go into 'Factory Settings' mode when started for the first time. That means if the game doesn't start, use the Advance and Up/Down Buttons to navigate and quit the Williams settings. Note that as you're now in the original Williams settings you can navigate them as usual with one exception: 32 | You must not keep Advance pressed for more than 1 second with Up/Down in up position as this will trigger the APC settings. If you want to browse the Williams Settings quickly, just do it backwards with Up/Down in down position. 33 | 34 | ## PinMame sound 35 | 36 | ### Using old audio boards 37 | 38 | For some game generations you could install the original audio board. In this case you cannot do any sound related changes of course. 39 | For System 3 - 6, the sound board is controlled by some reserved solenoid drivers, so it will work out of the box. System 7 needs an [adapter](https://github.com/AmokSolderer/APC/blob/master/DOC/Prepare.md#system-7-audio-cable) for connecting the audio board to the HW extension interface of the APC. 40 | For the APC to control the external audio board you have to enter the [game settings](https://github.com/AmokSolderer/APC/blob/master/DOC/Settings.md#game-settings-in-remote-control-mode) while in Remote Control Mode and set setting 2 (PinMame Sound) from 0 (APC) to 1 (Board). 41 | 42 | System 9 and 11 audio boards are not supported, you have to let the APC generate the sound instead. 43 | 44 | ### Using the APC to generate audio 45 | 46 | Letting the APC generate the sounds has several benefits. 47 | 48 | The audio quality of the APC is quite good. It is also better in noise suppression than the old audio boards, so if you have a hum in your sound due to worn out capacitors, the chances are that it is much weaker with the APC. 49 | You can also change your sounds as you wish. This can be as simple as replacing certain sound files, but you could also add a music track to your old System 3 - 7 game. Let your Flash play Queen as background music if you like. 50 | 51 | The drawback of this is that someone has to extract the music files from PinMame and if your game is not already supported then this someone is probably you. 52 | 53 | Check the table on the [PinMame Sound](https://github.com/AmokSolderer/APC/blob/master/DOC/PinMame.md) page to see whether your game is already supported and the audio files are available. If your game is listet there, you can simply request the files and put them on the SD card on the APC board (not the one of the Pi). That's it, have fun. 54 | If your game is not yet supported then you should also read this page to find out how to proceed. 55 | 56 | ### Emulation speed 57 | 58 | It might be that your game is not running at the correct speed, e.g. if your bonus sound is running out but your game is still counting. In this case you can change PinMame's emulation speed. To do this you have to remove the SD card from your Raspberry Pi and access the file 59 | boot/lisy/lisy_m/cfg/lisyminigames.csv 60 | There's a throttle value specified for each game, the default for most games is 120. Changing this value to a lower value will make the game run faster and vice versa. 61 | 62 | ## MPF 63 | 64 | If you want to do your own rules without having to program in C, the [Mission Pinball Framework](http://missionpinball.org/) might be your method of choice. It can run on a PC which then controls the APC via USB. You'd have to select 'Remote Control' as the Active Game and 'Connect Type' to 'USB' in the [System Settings](https://github.com/AmokSolderer/APC/blob/master/DOC/Settings.md#system-settings). 65 | 66 | Most of the switch numbering and so on is quite straightforward but there're some [APC specialties](https://github.com/AmokSolderer/APC/blob/master/DOC/Specialties.md) you should be aware of when doing your own game. 67 | 68 | We can also let Lisy run MPF which would then work without a PC, but we'd do this only on request. 69 | 70 | Here you can find my basic [MPF setup](https://github.com/AmokSolderer/APC/tree/master/DOC/Software/MPF) 71 | 72 | ## C code 73 | 74 | If you're familiar with C you can also program the APC directly. This SW would then run on the Arduino itself with no need for an additional PC or Raspberry Pi. 75 | For this the APC software offers an [API](https://github.com/AmokSolderer/APC/tree/master/DOC/Software/APC_SW_reference.pdf) providing the necessary commands to control a pinball machine. It's still a lot of effort to program a game completely from scratch, but you could even run your game in PinMame and only use the API to do changes or extensions to the original rules. 76 | 77 | The APC software itself consists of two parts: the operating system APC.ino and the game specific code. The former controls the hardware and offers an application interface (API) for the game specific software to use. For an overview of the available API variables and commands please take a look at the 78 | [APC software reference](https://github.com/AmokSolderer/APC/blob/master/DOC/Software/APC_SW_reference.pdf). 79 | 80 | I have written game codes for my Black Knight and Pinbot. They are still not final, but good enough to have fun with and to use as a reference when writing own code. Additionally there's a [Base Code](https://github.com/AmokSolderer/APC/blob/master/BaseCode.ino) which should serve as a starting point for you to do your own game. It contains the very basics of a pinball game and it can be easily adapted to your machine. As a startup guide how to start writing game code I have written a short [tutorial](https://github.com/AmokSolderer/APC/blob/master/DOC/GameCodeTutorial.md). 81 | 82 | Most of the switch numbering and so on is quite straightforward but there're some [APC specialties](https://github.com/AmokSolderer/APC/blob/master/DOC/Specialties.md) you should be aware of when doing your own game. 83 | 84 | Please note that I have equipped my Black Knight with a [special alphanumerical display](https://github.com/AmokSolderer/APC/blob/master/DOC/Sys7Alpha.md) for pre System11 machines and that advanced APC commands like scrolling are currently not usable with numerical only displays. This is because I think that these displays are not suited for homebrew machines. If you do all the work needed to do your own game code, you'd for sure want to have a display with letters, otherwise you wouldn't be able to even have a decent high score list. Additionally it would be quite cumbersome to debug some game software without the display being able to show letters. Therfore I recommend to use an early System11 display which has at least one row with alphanumeric displays (or build my [System7Alpha](https://github.com/AmokSolderer/APC/tree/master/DOC/Hardware/Sys7Alpha)). However, the basic software support is implemented, which means you can use the old displays without any restrictions you just have to do a bit more coding to get all the features. And if you just want to use them with PinMame to replace your old boards these displays will work perfectly well. 85 | -------------------------------------------------------------------------------- /DOC/SetUpBC.md: -------------------------------------------------------------------------------- 1 | # Setting up the Base Code 2 | 3 | To switch to the Base Code you have to select the Base Code in the System Settings (Setting 1 'Active Game' should be set to 0 'Base Code'). Look at the [Settings page](https://github.com/AmokSolderer/APC/blob/master/DOC/Settings.md) to learn how to do this. 4 | 5 | In order for the Base Code to work properly, you have to set it up with the properties of your machine. Usually you would do this in the code itself, but for the Base Code this has been implemented in the 'Game Settings'. 6 | To get there press the Advance button while running the Base Code, then enter the 'Game Settings' which are shown below: 7 | 8 | | Number | Text | Item Nr | Item Text | Default | Comment | 9 | |--|--|--|--|--|--| 10 | | 0 | Outhole Switch | - | - | 9 | Numerical setting - Number of the Outhole Switch | 11 | | 1 | Ball Thru 1 | - | - | 13 | Numerical setting - Number of the 1st Ball Through Switch | 12 | | 2 | Ball Thru 2 | - | - | 12 | Numerical setting - Number of the 2nd Ball Through Switch, if there is any | 13 | | 3 | Ball Thru 3 | - | - | 11 | Numerical setting - Number of the 3rd Ball Through Switch, if there is any | 14 | | 4 | Plunger Ln Sw | - | - | 20 | Numerical setting - Number of the Plunger Lane Switch | 15 | | 5 | AC Sel Relay | - | - | 12 | Numerical setting - Number of the A/C relay solenoid, set to zero for pre System11 games | 16 | | 6 | Outhole Kicker | - | - | 1 | Numerical setting - Number of the Outhole Kicker solenoid | 17 | | 7 | Shooter Ln Feed | - | - | 2 | Numerical setting - Number of the Shooter Lane Feeder solenoid | 18 | | 8 | Instald Balls | - | - | 3 | Numerical setting - Number of balls installed | 19 | | 9 | RestoreDefault | - | - | - | No setting - restores the default settings | 20 | | 10 | Exit Settngs | - | - | - | No setting - exits the settings mode and writes the new setting to an SD card if present | 21 | 22 | You have to get the required values from the manual of your pinball machine. Alas, the names of the switches and solenoids have changed over the years. 23 | The default values are valid for a System11c Rollergames and I have added the corresponding manual pages below to make it easier for you to identify the right parts. 24 | 25 | For single ball games set the 'Installed Balls' setting to 1. The shooter lane feeder should be set to your Outhole Kicker solenoid. 26 | 27 | ![RollergamesSwitches](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/RG_Sw.JPG) 28 | 29 | ![RollergamesSolenoids](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/RG_Sol.JPG) 30 | -------------------------------------------------------------------------------- /DOC/Settings.md: -------------------------------------------------------------------------------- 1 | # APC settings 2 | 3 | ## Selecting the correct display 4 | 5 | The preselected display setting is set for early System11 displays. That means if you have a pre System11 (numbers only) display or a Black Knight 2000 (BK2K / 2 x 16 alphanumeric) you have to adjust the display setting first. In order to get there blindly, the display setting is the very first one. 6 | To get there you have to keep the Advance key pressed for more than 1s with the Up/Down key being in up position. Wait 4s and then press the Game Start button slowly but repeatedly until you can read the display contents. Pre Sys11 displays cannot show any text, so for the 6 digit displays (Sys3 - 6) a single 7 is shown on the player 4 display. For 7 digit displays (Sys7 and 9) it's an 8. 7 | After the correct display is selected, press Up/Down to get it down and Game Start to go back one setting to 'Exit Settings'. Now release the Up/Down button and press Game Start again to save the settings and return to the attract mode. 8 | 9 | The complete re-initialization of the display is done when you EXIT the system settings. That means your lower row might still look a bit odd even though you've selected the correct display until you exit the settings. 10 | 11 | I did two videos to show what I've described above: 12 | 13 | [How to use numerical displays](https://www.youtube.com/watch?v=2A5Tt9FQ2as) 14 | 15 | [Adjusting the display settings for 2x16 segment System11 displays](https://www.youtube.com/watch?v=XqPWbm-HWM8) 16 | 17 | Note that the menus have changed since these videos have been made. So use them only to see how it works in general, but use the tables below as a reference for the settings. 18 | 19 | ## Using the settings menu 20 | 21 | To enter the APC settings you have to press the Advance button at the coin door with the Up/Down switch in 'up' position. If you're in Remote Control mode you have to keep it pressed for more than 1s. 22 | 23 | After that you have to select whether you want to enter the system or game settings. 24 | 25 | * The System Settings are valid for all selected active games 26 | * The Game Settings are game specific. They change depending on which 'Active Game' is selected in the System Settings. This is not identical to the game you might want to run in PinMame, but you have to set your 'Active Game' to [Remote Control mode](https://github.com/AmokSolderer/APC/blob/master/DOC/RunGame.md#pinmame) in order to run PinMame. 27 | 28 | Games with a credit display show 00 for System Settings and 01 for Game Settings in the left two digits. The number of the setting currently being shown appears in the right two digits of the credit display. This is important for pre System11 displays as they can show only numbers and no menu text. 29 | 30 | For pre Sys11 displays all text settings are represented by their item number as shown in the tables. For example, if a pre Sys11 display is selected and the credit display shows 00 01 you have selected the System Settings and the 'Active Game' setting is currently being shown. An early System11 display (upper display row alphanumerical and lower row numerical) will still try to show the name of the currently selected game as a text which is not perfect, but good enough. A pre System11 display will show the item number instead and if there is a 3 stated in the player 4 display then you're in Remote Control mode. 31 | 32 | In settings mode use Advance to select the setting and the Game Start button to change it's value. If the Up/Down button is in down position then you're moving backwards. 33 | 34 | If an SD card is present the settings are stored when you choose 'Exit Settings'. 35 | 36 | ## Using PinMame settings 37 | 38 | While you're running PinMame you can adjust the original Williams System 4 - 11 adjustments as usual with one exception: 39 | You must not keep Advance pressed for more than 1 second with Up/Down in up position as this will trigger the APC settings. If you want to browse the Williams Settings quickly, just do it backwards with Up/Down in down position. 40 | 41 | ### System 3 game adjustments 42 | 43 | Doing game adjustments on a System 3 game is done with DIP switches. The procedure is quite cumbersome and error prone which is why we're using the APC's settings menu instead. 44 | The following description works only for System 3 games being controlled by Lisy/PinMame, for all other generations the adjustment process hasn't changed from the original. 45 | 46 | Keep the Advance switch pressed for more than one second with the Up/Down switch in up position. This will end PinMame and enter the settings menu of the APC. The content of the 18 System 3 adjustments is now stored in the 'Game Settings' 46 to 63 as shown in the table below (Game Settings in Remote Control mode). 47 | Enter the game settings and do your changes. When you're done, just select menu entry 65 (Exit Settings) and press the start button. After a few seconds PinMame will restart with the new settings applied. 48 | 49 | ## System Settings 50 | 51 | | Number | Text | Item Nr | Item Text | Default | Comment | 52 | |--|--|--|--|--|--| 53 | | 0 | Display Type | 0 | 4 Alpha+Credit | X | 4x 7 digit alphanumeric + credit | 54 | | 0 | | 1 | Sys11 Pinbot | - | 2x 7 digit alphanumeric + 2x 7 digit numeric + credit | 55 | | 0 | | 2 | Sys11 F-14 | - | 2x 7 digit alphanumeric + 2x 7 digit numeric | 56 | | 0 | | 3 | Sys11 BK2K | - | 2x 16 digit alphanumeric (inverted segments)| 57 | | 0 | | 4 | Sys11 Taxi | - | 2x 16 digit alphanumeric + 1x 7 digit numeric (non inverted segments)| 58 | | 0 | | 5 | Sys11 Riverboat | - | 2x 16 digit alphanumeric + 2x 7 digit numeric (inverted segments)| 59 | | 0 | | 6 | Data East 2x16 | - | 2x 16 digit alphanumeric (non inverted segments)| 60 | | 0 | | 7 | 7 | - | 4x 6 digit numeric + credit (System 3 - 6)| 61 | | 0 | | 8 | 8 | - | 4x 7 digit numeric + credit (System 7 + 9)| 62 | | 1 | Active Game | 0 | Base Code | - | The very basics of a game SW | 63 | | 1 | | 1 | Black Knight | - | My own Black Knight game SW | 64 | | 1 | | 2 | Pinbot | - | My own Pinbot game SW | 65 | | 1 | | 3 | Remote Control | X | For controlling the APC remotely via USB or an onboard Raspberry Pi| 66 | | 1 | | 4 | Tutorial | - | The corresponding game SW to the game code tutorial Wiki| 67 | | 2 | No of balls | - | - | 3 | Numerical setting - range 1 -5 | 68 | | 3 | Free game | - | - | Yes | Bool setting | 69 | | 4 | Connect Type | 0| Off | - | No remote control during Remote Control mode | 70 | | 4 | | 1 | On board | - | APC is controlled by the Pi on board | 71 | | 4 | | 2 | USB | X | APC is controlled via USB | 72 | | 5 | Dim inserts | - | - | No | Bool setting - brightness of playfield lamps is set to 50% when on | 73 | | 6 | Speaker volume | - | - | 0 | Numerical setting - range 1 - 255 / must be set to 0 when volume pot is connected at 10J4 / 1J16 | 74 | | 7 | LED lamps | 0 | No LEDs | X | The APC_LED_exp board is not used | 75 | | 7 | | 1 | Additional | - | The APC_LED_exp board is used for the lamps 65+ | 76 | | 7 | | 2 | Playfld only | - | The APC_LED_exp board is only used for the lamps 9 - 64 | 77 | | 7 | | 3 | PlayfldBackbox | - | The APC_LED_exp board is used for the lamps 1 - 64 | 78 | | 8 | No of LEDs | - | - | 64 | Numerical setting - range 1 - 192 / The length of the LED stripe. Setting is only effective when 'Additional' is selected as 'LED lamps' setting| 79 | | 9 | Sol Exp Board | - | - | No | Bool setting - will use the solenoid expander board for solenoids 26 - 33 if set 80 | | 10 | Debug Mode | - | - | No | Bool setting - Active debug mode will show the number of active timers in the credit display and will stop the game on error | 81 | | 11 | Backbox Lamps | 0| Column 1 | X | Backbox lamps are in lamp column 1 | 82 | | 11 | | 1 | Column 8 | - | Backbox lamps are in lamp column 8 | 83 | | 11 | | 2 | None | - | game has no controlled backbox lamps | 84 | | 12 | Connect Startup | - | - | No | Bool setting - If active, then the connection type is not set by setting 4 (Connect Type) but by the state of the Up/Down switch during startup (and when leaving the settings). Switch in Up state selects the onboard Pi, otherwise the USB programming port | 85 | | 13 | Restore Default | - | - | - | No setting - restores the default settings | 86 | | 14 | Exit Settings | - | - | - | No setting - exits the settings mode and writes the new setting to an SD card if present | 87 | 88 | ## Game Settings in Remote Control mode 89 | 90 | These game settings are only visible if 'Remote Control' is selected as the 'Active Game' in the 'System Settings'. 91 | 92 | | Number | Text | Item Nr | Item Text | Default | Comment | 93 | |--|--|--|--|--|--| 94 | | 0 | USB watchdog | - | - | No | Bool settings - disables all solenoids when no watchdog reset command is received for 1s | 95 | | 1 | Debug Mode | 0 | Off | X | No debugging | 96 | | 1 | | 1 | USB | - | Shows the received commands in the displays | 97 | | 1 | | 2 | Audio | - | Audio debug mode for PinMame Sounds | 98 | | 2 | PinMame Sound | 0 | APC | X | PinMame sounds are played on the APC sound HW | 99 | | 2 | | 1 | Board | - | PinMame sounds are played on an external audio board | 100 | | 3 | PinMame game | - | - | 0 | Numerical setting - [PinMame game number](https://github.com/AmokSolderer/APC/blob/master/DOC/lisyminigames.csv) | 101 | | 4 | Lisy Debug | - | - | 0 | Numerical setting according to the [Controlling Lisy](https://github.com/AmokSolderer/APC/blob/master/DOC/LisyDebug.md) page | 102 | | 5 | Ball Saver | 0 | Off | X | The optional ball saver is not active | 103 | | 5 | | 1 | On | - | The ball saver is active for all drained balls | 104 | | 6 | Ball Saver Time | - | - | 20 | Numerical setting - range 5 - 250 / Active time of the Ball Saver | 105 | | 7 | BG Music | 0 | PinMame default | X | Normal BG music | 106 | | 7 | | 1 | Music snd | - | Uses the MUSIC.SND file as BG music | 107 | | 8 - 45 | Setting Unused | - | – | - | They behave like boolean settings, but they have no effect | 108 | | 46 | System3 Set 1 | - | - | - | Use this to change the 1st setting of system 3 games | 109 | | 47 | System3 Set 2 | - | - | - | Use this to change the 2nd setting of system 3 games | 110 | | 48 | System3 Set 3 | - | - | - | Use this to change the 3rd setting of system 3 games | 111 | | 49 | System3 Set 4 | - | - | - | Use this to change the 4th setting of system 3 games | 112 | | 50 | System3 Set 5 | - | - | - | Use this to change the 5th setting of system 3 games | 113 | | 51 | System3 Set 6 | - | - | - | Use this to change the 6th setting of system 3 games | 114 | | 52 | System3 Set 7 | - | - | - | Use this to change the 7th setting of system 3 games | 115 | | 53 | System3 Set 8 | - | - | - | Use this to change the 8th setting of system 3 games | 116 | | 54 | System3 Set 9 | - | - | - | Use this to change the 9th setting of system 3 games | 117 | | 55 | System3 Set 10 | - | - | - | Use this to change the 10th setting of system 3 games | 118 | | 56 | System3 Set 11 | - | - | - | Use this to change the 11th setting of system 3 games | 119 | | 57 | System3 Set 12 | - | - | - | Use this to change the 12th setting of system 3 games | 120 | | 58 | System3 Set 13 | - | - | - | Use this to change the 13th setting of system 3 games | 121 | | 59 | System3 Set 14 | - | - | - | Use this to change the 14th setting of system 3 games | 122 | | 60 | System3 Set 15 | - | - | - | Use this to change the 15th setting of system 3 games | 123 | | 61 | System3 Set 16 | - | - | - | Use this to change the 16th setting of system 3 games | 124 | | 62 | System3 Set 17 | - | - | - | Use this to change the 17th setting of system 3 games | 125 | | 63 | System3 Set 18 | - | - | - | Use this to change the 18th setting of system 3 games | 126 | | 64 | Restore Default | - | - | - | No setting - restores the default settings | 127 | | 65 | Exit Settings | - | - | - | No setting - exits the settings mode and writes the new setting to an SD card if present | 128 | -------------------------------------------------------------------------------- /DOC/Software/APC_SW_reference.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmokSolderer/APC/8d49233fe9b3faf5cc0d1fa02a01c4c93a265038/DOC/Software/APC_SW_reference.pdf -------------------------------------------------------------------------------- /DOC/Software/APC_SoundCheck/Sound.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Sound ////////////////////////////////////////////////////////////////////// 3 | /////////////////////////////////////////////////////////////////////////////// 4 | /* 5 | * Copyright (c) 2012 Arduino LLC. All right reserved. 6 | * Audio library for Arduino Due. 7 | * 8 | * This file is free software; you can redistribute it and/or modify 9 | * it under the terms of either the GNU General Public License version 2 10 | * or the GNU Lesser General Public License version 2.1, both as 11 | * published by the Free Software Foundation. 12 | */ 13 | 14 | #ifndef SOUND_INCLUDED 15 | #define SOUND_INCLUDED 16 | 17 | #include "Print.h" 18 | #define UNUSED(x) (void)(x) 19 | 20 | /////////////////////////////////////////////////////////////////////////////// 21 | 22 | typedef void (*OnTransmitEnd_CB)(void *data); 23 | 24 | /////////////////////////////////////////////////////////////////////////////// 25 | // DAC //////////////////////////////////////////////////////////////////////// 26 | /////////////////////////////////////////////////////////////////////////////// 27 | 28 | class CDAC 29 | { 30 | public: 31 | CDAC(Dacc *_dac, uint32_t _dacId, IRQn_Type _isrId) : m_dac(_dac), m_dacId(_dacId), m_isrId(_isrId), m_cb(NULL) { m_cbData = NULL; }; 32 | 33 | void begin(uint32_t period) { 34 | // Enable clock for DAC 35 | pmc_enable_periph_clk(m_dacId); 36 | 37 | dacc_reset(m_dac); 38 | 39 | // Set transfer mode to double word 40 | dacc_set_transfer_mode(m_dac, 1); 41 | 42 | // Power save: 43 | // sleep mode - 0 (disabled) 44 | // fast wakeup - 0 (disabled) 45 | dacc_set_power_save(m_dac, 0, 0); 46 | 47 | // DAC refresh/startup timings: 48 | // refresh - 0x08 (1024*8 dacc clocks) 49 | // max speed mode - 0 (disabled) 50 | // startup time - 0x10 (1024 dacc clocks) 51 | dacc_set_timing(m_dac, 0x08, 0, DACC_MR_STARTUP_1024); 52 | 53 | // Flexible channel selection with tags 54 | dacc_enable_flexible_selection(m_dac); 55 | //dacc_set_channel_selection(m_dac, 0); 56 | 57 | // Set up analog current 58 | dacc_set_analog_control(m_dac, 59 | DACC_ACR_IBCTLCH0(0x02) | 60 | DACC_ACR_IBCTLCH1(0x02) | 61 | DACC_ACR_IBCTLDACCORE(0x01)); 62 | 63 | // Enable output channels 64 | dacc_enable_channel(m_dac, 0); 65 | dacc_enable_channel(m_dac, 1); 66 | 67 | // Configure Timer Counter to trigger DAC 68 | // -------------------------------------- 69 | pmc_enable_periph_clk(ID_TC1); 70 | TC_Configure(TC0, 1, 71 | TC_CMR_TCCLKS_TIMER_CLOCK2 | // Clock at MCR/8 72 | TC_CMR_WAVE | // Waveform mode 73 | TC_CMR_WAVSEL_UP_RC | // Counter running up and reset when equals to RC 74 | TC_CMR_ACPA_SET | TC_CMR_ACPC_CLEAR); 75 | const uint32_t TC = period / 8; 76 | TC_SetRA(TC0, 1, TC / 2); 77 | TC_SetRC(TC0, 1, TC); 78 | TC_Start(TC0, 1); 79 | 80 | // Configure clock source for DAC (2 = TC0 Output Chan. 1) 81 | dacc_set_trigger(m_dac, 2); 82 | 83 | // Configure pins 84 | PIO_Configure(g_APinDescription[DAC0].pPort, 85 | g_APinDescription[DAC0].ulPinType, 86 | g_APinDescription[DAC0].ulPin, 87 | g_APinDescription[DAC0].ulPinConfiguration); 88 | PIO_Configure(g_APinDescription[DAC1].pPort, 89 | g_APinDescription[DAC1].ulPinType, 90 | g_APinDescription[DAC1].ulPin, 91 | g_APinDescription[DAC1].ulPinConfiguration); 92 | 93 | // Enable interrupt controller for DAC 94 | dacc_disable_interrupt(m_dac, 0xFFFFFFFF); 95 | NVIC_DisableIRQ(m_isrId); 96 | NVIC_ClearPendingIRQ(m_isrId); 97 | NVIC_SetPriority(m_isrId, 0); 98 | NVIC_EnableIRQ(m_isrId); 99 | } 100 | 101 | void end() { 102 | TC_Stop(TC0, 1); 103 | NVIC_DisableIRQ(m_isrId); 104 | dacc_disable_channel(m_dac, 0); 105 | dacc_disable_channel(m_dac, 1); 106 | } 107 | 108 | bool canQueue() { 109 | return (m_dac->DACC_TNCR == 0); 110 | } 111 | 112 | size_t queueBuffer(const uint32_t *buffer, size_t size) { 113 | // Try the first PDC buffer 114 | if ((m_dac->DACC_TCR == 0) && (m_dac->DACC_TNCR == 0)) { 115 | m_dac->DACC_TPR = (uint32_t) buffer; 116 | m_dac->DACC_TCR = size; 117 | m_dac->DACC_PTCR = DACC_PTCR_TXTEN; 118 | if (m_cb) 119 | dacc_enable_interrupt(m_dac, DACC_IER_ENDTX); 120 | return size; 121 | } 122 | 123 | // Try the second PDC buffer 124 | if (m_dac->DACC_TNCR == 0) { 125 | m_dac->DACC_TNPR = (uint32_t) buffer; 126 | m_dac->DACC_TNCR = size; 127 | m_dac->DACC_PTCR = DACC_PTCR_TXTEN; 128 | if (m_cb) 129 | dacc_enable_interrupt(m_dac, DACC_IER_ENDTX); 130 | return size; 131 | } 132 | 133 | // PDC buffers full, try again later... 134 | return 0; 135 | } 136 | 137 | void setOnTransmitEnd_CB(OnTransmitEnd_CB _cb, void *_data) { 138 | m_cb = _cb; 139 | m_cbData = _data; 140 | if (!m_cb) 141 | dacc_disable_interrupt(m_dac, DACC_IDR_ENDTX); 142 | } 143 | 144 | void onService() { 145 | uint32_t sr = m_dac->DACC_ISR; 146 | if (sr & DACC_ISR_ENDTX) { 147 | // There is a free slot, enqueue data 148 | dacc_disable_interrupt(m_dac, DACC_IDR_ENDTX); 149 | if (m_cb) 150 | m_cb(m_cbData); 151 | } 152 | } 153 | 154 | void enableInterrupts() { NVIC_EnableIRQ(m_isrId); }; 155 | 156 | void disableInterrupts() { NVIC_DisableIRQ(m_isrId); }; 157 | 158 | private: 159 | Dacc *m_dac; 160 | uint32_t m_dacId; 161 | IRQn_Type m_isrId; 162 | OnTransmitEnd_CB m_cb; 163 | void *m_cbData; 164 | }; 165 | 166 | /////////////////////////////////////////////////////////////////////////////// 167 | 168 | CDAC g_DAC(DACC_INTERFACE, DACC_INTERFACE_ID, DACC_ISR_ID); 169 | 170 | void DACC_ISR_HANDLER(void) { g_DAC.onService(); } 171 | 172 | /////////////////////////////////////////////////////////////////////////////// 173 | // ~DAC /////////////////////////////////////////////////////////////////////// 174 | /////////////////////////////////////////////////////////////////////////////// 175 | 176 | class CSound : public Print { 177 | public: 178 | CSound(CDAC &_dac) : m_dac(&_dac) { bufferSize = 0; buffer = half = last = running = next = NULL; }; 179 | virtual ~CSound(void) {}; 180 | 181 | void begin (uint32_t sampleRate, uint32_t msPreBuffer); 182 | 183 | void end (); 184 | 185 | size_t write(uint8_t c) { 186 | UNUSED(c); 187 | return 0; /* not implemented */ 188 | }; 189 | size_t write(const uint16_t *data, size_t size) { return write(reinterpret_cast(data), size/2) * 2; }; 190 | size_t write(const uint32_t *data, size_t size); 191 | 192 | uint32_t bufferSize; 193 | uint32_t *buffer; 194 | uint32_t *half; 195 | uint32_t *last; 196 | uint32_t *volatile running; 197 | uint32_t *volatile next; 198 | void enqueue(); 199 | 200 | private: 201 | static void onTransmitEnd(void *me); 202 | //void enqueue(); 203 | uint32_t *cook(const uint32_t *buffer, size_t size); 204 | 205 | CDAC *m_dac; 206 | }; 207 | 208 | /////////////////////////////////////////////////////////////////////////////// 209 | 210 | void CSound::onTransmitEnd(void *_me) { 211 | CSound *me = reinterpret_cast (_me); 212 | if (me->running == me->buffer) 213 | me->running = me->half; 214 | else 215 | me->running = me->buffer; 216 | } 217 | 218 | /////////////////////////////////////////////////////////////////////////////// 219 | 220 | void CSound::begin(uint32_t sampleRate, uint32_t msPreBuffer) { 221 | UNUSED(msPreBuffer); 222 | // Allocate a buffer to keep msPreBuffer milliseconds of audio 223 | bufferSize = 128; 224 | // if (bufferSize < 1024) 225 | // bufferSize = 1024; 226 | buffer = (uint32_t *) malloc(bufferSize * sizeof(uint32_t)); 227 | half = buffer + bufferSize / 2; 228 | last = buffer + bufferSize; 229 | 230 | // Buffering starts from the beginning 231 | running = buffer; 232 | next = buffer; 233 | 234 | // Start DAC 235 | m_dac->begin(VARIANT_MCK / sampleRate); 236 | 237 | m_dac->setOnTransmitEnd_CB(onTransmitEnd,this); 238 | } 239 | 240 | /////////////////////////////////////////////////////////////////////////////// 241 | 242 | void CSound::end() { 243 | m_dac->end(); 244 | free( buffer); 245 | } 246 | 247 | /////////////////////////////////////////////////////////////////////////////// 248 | 249 | //size_t CSound::write(const uint32_t *data, size_t size) { 250 | //const uint32_t TAG = 0x10000000; 251 | //Serial.println(size); 252 | // size_t i; 253 | // for (i = 0; i < size; i++) { 254 | // *next = data[i]; //| TAG; 255 | // next++;} 256 | // enqueue(); 257 | // 258 | // if (next == half || next == last) { 259 | // enqueue(); 260 | // while (next == running) 261 | // ; 262 | // } 263 | // } 264 | //return i; 265 | //} 266 | 267 | /////////////////////////////////////////////////////////////////////////////// 268 | 269 | void CSound::enqueue() { 270 | if (!m_dac->canQueue()) { 271 | // DMA queue full 272 | return; 273 | } 274 | 275 | if (next == half) { 276 | // Enqueue the first half 277 | m_dac->queueBuffer(buffer, bufferSize / 2); 278 | } else { 279 | // Enqueue the second half 280 | m_dac->queueBuffer(half, bufferSize / 2); 281 | next = buffer; // wrap around 282 | } 283 | } 284 | 285 | /////////////////////////////////////////////////////////////////////////////// 286 | /////////////////////////////////////////////////////////////////////////////// 287 | 288 | CSound g_Sound(g_DAC); 289 | 290 | #endif 291 | 292 | /////////////////////////////////////////////////////////////////////////////// 293 | // ~Sound ///////////////////////////////////////////////////////////////////// 294 | /////////////////////////////////////////////////////////////////////////////// 295 | -------------------------------------------------------------------------------- /DOC/Software/AudioSave.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | $buf1 = 0; 4 | $buf2 = 0; 5 | $i = 0; 6 | $size = 0; 7 | @data = ('d','a','t','a'); # 'data' is indicating the beginning of the data chunk 8 | 9 | open(FH, "< Data.wav"); 10 | binmode(FH); 11 | open(FOUT, "> Data.snd"); 12 | binmode(FOUT); 13 | 14 | do { # search for the 'data' keyword 15 | read(FH, $buf1, 1); # read charakter 16 | if ($buf1 eq $data[$i]) { # does it belong to the keyword? 17 | $i++;} # increase hit counter 18 | else { 19 | $i = 0;} # reset hit counter 20 | } until ($i > 3); # all four characters found? 21 | read(FH, $buf1, 1); # read LSByte of the data chunk size 22 | $size = ord($buf1); 23 | read(FH, $buf1, 1); 24 | $size = $size | (ord($buf1) << 8); 25 | read(FH, $buf1, 1); 26 | $size = $size | (ord($buf1) << 16); 27 | read(FH, $buf1, 1); # read MSByte of the data chunk size 28 | $size = $size | (ord($buf1) << 24); 29 | $i = 0; 30 | do { # read all bytes of the data chunk 31 | read(FH, $buf1, 1); # the read uses chars 32 | $i++; 33 | read(FH, $buf2, 1); # get two two have a 16 bit value 34 | $i++; 35 | #read(FH, $buf1, 1); # uncomment these four lines when using 36 | #$i++; 37 | #read(FH, $buf2, 1); # stereo input files to skip one channel 38 | #$i++; 39 | $buf1 = ord($buf1); # convert to numbers 40 | $buf2 = ord($buf2); 41 | $buf = ($buf2 << 8) | $buf1; # and to 16 bit 42 | $buf = $buf >> 4; # reduce to 12 bit 43 | if ($buf < 2048) { # move the zero to 2048 44 | $buf = $buf + 2048;} 45 | else { 46 | $buf = $buf - 2048;} 47 | syswrite (FOUT, pack("v", $buf), 2); # and fumble it into the output file 48 | } while ($i < $size); # all byte of the data chunk read? 49 | close(FH); 50 | close(FOUT); 51 | 52 | -------------------------------------------------------------------------------- /DOC/Software/AudioSaveFolder.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | my @files = <*.wav>; # grab all wav files and convert to *.snd 4 | for $file (@files) { 5 | $outfile= $file; 6 | substr($outfile, -3, 3,"snd"); 7 | print $outfile."\n"; 8 | 9 | $buf1 = 0; 10 | $buf2 = 0; 11 | $i = 0; 12 | $size = 0; 13 | @data = ('d','a','t','a'); # 'data' is indicating the beginning of the data chunk 14 | 15 | open(FH, "< ".$file) 16 | or die "Can't open inputfile"; 17 | binmode(FH); 18 | open(FOUT, "> ".$outfile) 19 | or die "Can't open outfile"; 20 | binmode(FOUT); 21 | 22 | do { # search for the 'data' keyword 23 | read(FH, $buf1, 1); # read charakter 24 | if ($buf1 eq $data[$i]) { # does it belong to the keyword? 25 | $i++;} # increase hit counter 26 | else { 27 | $i = 0;} # reset hit counter 28 | } until ($i > 3); # all four characters found? 29 | read(FH, $buf1, 1); # read LSByte of the data chunk size 30 | $size = ord($buf1); 31 | read(FH, $buf1, 1); 32 | $size = $size | (ord($buf1) << 8); 33 | read(FH, $buf1, 1); 34 | $size = $size | (ord($buf1) << 16); 35 | read(FH, $buf1, 1); # read MSByte of the data chunk size 36 | $size = $size | (ord($buf1) << 24); 37 | $i = 0; 38 | do { # read all bytes of the data chunk 39 | read(FH, $buf1, 1); # the read uses chars 40 | $i++; 41 | read(FH, $buf2, 1); # get two two have a 16 bit value 42 | $i++; 43 | #read(FH, $buf1, 1); # uncomment these four lines when using 44 | #$i++; 45 | #read(FH, $buf2, 1); # stereo input files to skip one channel 46 | #$i++; 47 | $buf1 = ord($buf1); # convert to numbers 48 | $buf2 = ord($buf2); 49 | $buf = ($buf2 << 8) | $buf1; # and to 16 bit 50 | $buf = $buf >> 4; # reduce to 12 bit 51 | if ($buf < 2048) { # move the zero to 2048 52 | $buf = $buf + 2048;} 53 | else { 54 | $buf = $buf - 2048;} 55 | syswrite (FOUT, pack("v", $buf), 2); # and fumble it into the output file 56 | } while ($i < $size); # all byte of the data chunk read? 57 | close(FH); 58 | close(FOUT);} # do loop end 59 | -------------------------------------------------------------------------------- /DOC/Software/DisplayAlphaLower.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | $PatX = 9; # X dimension of segment pattern 4 | $PatY = 9; # Y dimension of segment pattern 5 | @Pattern = qw( 6 | .aaaaaaa. 7 | fh..j..kb 8 | f.h.j.k.b 9 | f..hjk..b 10 | .ggg.mmm. 11 | e..rpn..c 12 | e.r.p.n.c 13 | er..p..nc 14 | .ddddddd.); # segment pattern 15 | $Segments = 14 ; # number of segments present in this display type 16 | #@PinDefine = ('d','c','b','a','e','f','g','.','j','h','m','k','p','r','.','n'); # segments to APC pins (upper line Alphanumeric) 17 | @PinDefine = ('.','g','f','b','a','d','e','c','j','m','n','.','r','p','k','h'); # segments to APC pins (lower line Alphanumeric) 18 | #@PinDefine = ('.','g','f','b','a','d','e','c');# segments to APC pins (lower line Big Guns) 19 | @Segment = ('a','b','c','d','e','f','g','h','j','k','m','n','p','r'); # list of segments present in this display type (upper line Big Guns) 20 | #@Segment = ('a','b','c','d','e','f','g'); # list of segments present in this display type (lower line Big Guns) 21 | @Present = (0,0,0,0,0,0,0,0,0,0,0,0,0,0); # stores which segments are active 22 | 23 | do { 24 | $Puffer = ; # read keyboard 25 | chomp($Puffer); # remove linefeed 26 | for ($i=0; $i<$Segments; $i++) { # for all segments 27 | if ($Puffer eq $Segment[$i]) { # check if segment is chosen 28 | $Present[$i] = !$Present[$i];}} # if yes negate its state 29 | for (my $y=0; $y<$PatY; $y++) { # for all lines of the pattern 30 | print(" "); # start with a few blanks 31 | for (my $x=0; $x<$PatX; $x++) { # for all columns of the pattern 32 | $Seg = substr($Pattern[$y], $x, 1); # get the selected pattern position 33 | if ($Seg eq '.') { # does it belong to a segment? 34 | print(" ");} # if no print a blank 35 | else { # if yes 36 | for ($i=0; $i<$Segments; $i++) { # cycle through all segments 37 | if ($Seg eq $Segment[$i]) { # if its the right one 38 | if ($Present[$i]) { # check if segments is enabled 39 | print("*");} # if yes print a star 40 | else { 41 | print(" ");}}}}} # if not print a blank 42 | print("\n");} # print a linefeed at the end of each line 43 | print("\n"); 44 | $Result1 = 0; # First result byte 45 | $Result2 = 0; # Second result byte 46 | for (my $x=0; $x<$Segments; $x++) { # for all segments 47 | if ($Present[$x]) { # segment active? 48 | $Mask = 1; # set bit mask 49 | $i = 0; # reset counter 50 | until ($Segment[$x] eq $PinDefine[$i]) { # search for segment in PinDefine 51 | $i++; # returns the position of the segment in PinDefine 52 | $Mask = $Mask << 1;} # and the bit mask shifted to the corresponding position 53 | if ($i > 7) { # position in second result byte? 54 | $Result2 = $Result2 | ($Mask >> 8);} # set the bit for the pin 55 | else { # position in first result byte 56 | $Result1 = $Result1 | $Mask;}}} # set the bit for the pin 57 | print("\n","\n",$Result1,", ",$Result2,"\n");} 58 | while($Puffer ne 'q'); # leave the program on q 59 | 60 | -------------------------------------------------------------------------------- /DOC/Software/DisplayAlphaUpper.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | $PatX = 9; # X dimension of segment pattern 4 | $PatY = 9; # Y dimension of segment pattern 5 | @Pattern = qw( 6 | .aaaaaaa. 7 | fh..j..kb 8 | f.h.j.k.b 9 | f..hjk..b 10 | .ggg.mmm. 11 | e..rpn..c 12 | e.r.p.n.c 13 | er..p..nc 14 | .ddddddd.); # segment pattern 15 | $Segments = 14 ; # number of segments present in this display type 16 | @PinDefine = ('d','c','b','a','e','f','g','.','j','h','m','k','p','r','.','n'); # segments to APC pins (upper line Alphanumeric) 17 | #@PinDefine = ('.','g','f','b','a','d','e','c','j','m','n','.','r','p','k','h'); # segments to APC pins (lower line Alphanumeric) 18 | #@PinDefine = ('.','g','f','b','a','d','e','c');# segments to APC pins (lower line Big Guns) 19 | @Segment = ('a','b','c','d','e','f','g','h','j','k','m','n','p','r'); # list of segments present in this display type (upper line Big Guns) 20 | #@Segment = ('a','b','c','d','e','f','g'); # list of segments present in this display type (lower line Big Guns) 21 | @Present = (0,0,0,0,0,0,0,0,0,0,0,0,0,0); # stores which segments are active 22 | 23 | do { 24 | $Puffer = ; # read keyboard 25 | chomp($Puffer); # remove linefeed 26 | for ($i=0; $i<$Segments; $i++) { # for all segments 27 | if ($Puffer eq $Segment[$i]) { # check if segment is chosen 28 | $Present[$i] = !$Present[$i];}} # if yes negate its state 29 | for (my $y=0; $y<$PatY; $y++) { # for all lines of the pattern 30 | print(" "); # start with a few blanks 31 | for (my $x=0; $x<$PatX; $x++) { # for all columns of the pattern 32 | $Seg = substr($Pattern[$y], $x, 1); # get the selected pattern position 33 | if ($Seg eq '.') { # does it belong to a segment? 34 | print(" ");} # if no print a blank 35 | else { # if yes 36 | for ($i=0; $i<$Segments; $i++) { # cycle through all segments 37 | if ($Seg eq $Segment[$i]) { # if its the right one 38 | if ($Present[$i]) { # check if segments is enabled 39 | print("*");} # if yes print a star 40 | else { 41 | print(" ");}}}}} # if not print a blank 42 | print("\n");} # print a linefeed at the end of each line 43 | print("\n"); 44 | $Result1 = 0; # First result byte 45 | $Result2 = 0; # Second result byte 46 | for (my $x=0; $x<$Segments; $x++) { # for all segments 47 | if ($Present[$x]) { # segment active? 48 | $Mask = 1; # set bit mask 49 | $i = 0; # reset counter 50 | until ($Segment[$x] eq $PinDefine[$i]) { # search for segment in PinDefine 51 | $i++; # returns the position of the segment in PinDefine 52 | $Mask = $Mask << 1;} # and the bit mask shifted to the corresponding position 53 | if ($i > 7) { # position in second result byte? 54 | $Result2 = $Result2 | ($Mask >> 8);} # set the bit for the pin 55 | else { # position in first result byte 56 | $Result1 = $Result1 | $Mask;}}} # set the bit for the pin 57 | print("\n","\n",$Result1,", ",$Result2,"\n");} 58 | while($Puffer ne 'q'); # leave the program on q 59 | 60 | -------------------------------------------------------------------------------- /DOC/Software/DisplayNumLower.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | $PatX = 9; # X dimension of segment pattern 4 | $PatY = 9; # Y dimension of segment pattern 5 | @Pattern = qw( 6 | .aaaaaaa. 7 | f.......b 8 | f.......b 9 | f.......b 10 | .ggggggg. 11 | e.......c 12 | e.......c 13 | e.......c 14 | .ddddddd.); # segment pattern 15 | $Segments = 7 ; # number of segments present in this display type 16 | #@PinDefine = ('d','c','b','a','e','f','g','.','j','h','m','k','p','r','.','n'); # segments to APC pins (upper line Alphanumeric) 17 | #@PinDefine = ('.','g','f','b','a','d','e','c','j','m','n','.','r','p','k','h'); # segments to APC pins (lower line Alphanumeric) 18 | @PinDefine = ('.','g','f','b','a','d','e','c');# segments to APC pins (lower line Big Guns) 19 | #@Segment = ('a','b','c','d','e','f','g','h','j','k','m','n','p','r'); # list of segments present in this display type (upper line Big Guns) 20 | @Segment = ('a','b','c','d','e','f','g'); # list of segments present in this display type (lower line Big Guns) 21 | @Present = (0,0,0,0,0,0,0,0,0,0,0,0,0,0); # stores which segments are active 22 | 23 | do { 24 | $Puffer = ; # read keyboard 25 | chomp($Puffer); # remove linefeed 26 | for ($i=0; $i<$Segments; $i++) { # for all segments 27 | if ($Puffer eq $Segment[$i]) { # check if segment is chosen 28 | $Present[$i] = !$Present[$i];}} # if yes negate its state 29 | for (my $y=0; $y<$PatY; $y++) { # for all lines of the pattern 30 | print(" "); # start with a few blanks 31 | for (my $x=0; $x<$PatX; $x++) { # for all columns of the pattern 32 | $Seg = substr($Pattern[$y], $x, 1); # get the selected pattern position 33 | if ($Seg eq '.') { # does it belong to a segment? 34 | print(" ");} # if no print a blank 35 | else { # if yes 36 | for ($i=0; $i<$Segments; $i++) { # cycle through all segments 37 | if ($Seg eq $Segment[$i]) { # if its the right one 38 | if ($Present[$i]) { # check if segments is enabled 39 | print("*");} # if yes print a star 40 | else { 41 | print(" ");}}}}} # if not print a blank 42 | print("\n");} # print a linefeed at the end of each line 43 | print("\n"); 44 | $Result1 = 0; # First result byte 45 | $Result2 = 0; # Second result byte 46 | for (my $x=0; $x<$Segments; $x++) { # for all segments 47 | if ($Present[$x]) { # segment active? 48 | $Mask = 1; # set bit mask 49 | $i = 0; # reset counter 50 | until ($Segment[$x] eq $PinDefine[$i]) { # search for segment in PinDefine 51 | $i++; # returns the position of the segment in PinDefine 52 | $Mask = $Mask << 1;} # and the bit mask shifted to the corresponding position 53 | if ($i > 7) { # position in second result byte? 54 | $Result2 = $Result2 | ($Mask >> 8);} # set the bit for the pin 55 | else { # position in first result byte 56 | $Result1 = $Result1 | $Mask;}}} # set the bit for the pin 57 | print("\n","\n",$Result1,", ",$Result2,"\n");} 58 | while($Puffer ne 'q'); # leave the program on q 59 | 60 | -------------------------------------------------------------------------------- /DOC/Software/MPF/Rollergames/data/audits.yaml: -------------------------------------------------------------------------------- 1 | events: 2 | game_ended: 99 3 | game_started: 249 4 | player: 5 | score: 6 | average: 1162.6262626262626 7 | top: 8 | - 13700 9 | - 10200 10 | - 7500 11 | - 5900 12 | - 5300 13 | - 4800 14 | - 4200 15 | - 3800 16 | - 3700 17 | - 3300 18 | total: 99 19 | shots: 20 | lock1_shot: 199 21 | my_first_shot: 159 22 | my_first_shot_mode2: 4 23 | sh_Right_Inlane: 2 24 | sh_a_drop_target: 173 25 | sh_abc_a: 13 26 | sh_abc_b: 10 27 | sh_abc_c: 11 28 | sh_lane_e: 26 29 | sh_lane_j: 24 30 | sh_lane_t: 16 31 | sh_left_orbit: 181 32 | sh_r_drop_target: 169 33 | sh_right_inlane: 58 34 | sh_s_skate_a: 56 35 | sh_s_skate_e: 41 36 | sh_s_skate_k: 53 37 | sh_s_skate_s: 73 38 | sh_s_skate_t: 45 39 | sh_w_drop_target: 170 40 | switches: 41 | s_5bank_A: 106 42 | s_5bank_E: 73 43 | s_5bank_K: 75 44 | s_5bank_S: 93 45 | s_5bank_T: 64 46 | s_ac_relay: 0 47 | s_ball_popper: 200 48 | s_center_coin_chute: 0 49 | s_center_drop_target: 176 50 | s_extra_ball: 59 51 | s_high_score_reset: 0 52 | s_lane_rollover_E: 36 53 | s_lane_rollover_J: 51 54 | s_lane_rollover_T: 20 55 | s_left_coin_chute: 0 56 | s_left_drop_target: 172 57 | s_left_inlane: 133 58 | s_left_jet_bumper: 202 59 | s_left_jetway_top: 101 60 | s_left_lane_change: 963 61 | s_left_sling: 166 62 | s_left_spinner: 1449 63 | s_lock_1: 220 64 | s_lock_2: 439 65 | s_lock_ramp_entry: 246 66 | s_lower_jet_bumper: 106 67 | s_ouhole: 530 68 | s_oulane_kickback: 144 69 | s_outlane_kickback: 57 70 | s_plunger_lane: 760 71 | s_ramp_diverter_1: 394 72 | s_ramp_diverter_2: 307 73 | s_right_coin_chute: 0 74 | s_right_drop_target: 171 75 | s_right_inlane: 392 76 | s_right_jet_bumper: 107 77 | s_right_jetway_top: 135 78 | s_right_lane_change: 1413 79 | s_right_oulane: 42 80 | s_right_sling: 60 81 | s_right_spinner: 365 82 | s_slam_tilt: 0 83 | s_standup_A: 57 84 | s_standup_B: 39 85 | s_standup_C: 29 86 | s_start: 0 87 | s_tilt: 0 88 | s_top_standup_1: 14 89 | s_top_standup_2: 17 90 | s_top_standup_3: 13 91 | s_trough1: 789 92 | s_trough2: 1203 93 | s_trough3: 652 94 | s_upper_kickback: 80 95 | -------------------------------------------------------------------------------- /DOC/Software/MPF/Rollergames/data/machine_vars.yaml: -------------------------------------------------------------------------------- 1 | player1_score: 2 | expire: null 3 | value: 0 4 | -------------------------------------------------------------------------------- /DOC/Software/MPF/Rollergames/modes/LeftOrbit/config/LeftOrbit.yaml: -------------------------------------------------------------------------------- 1 | #config_version=5 2 | # mode2 config file 3 | 4 | mode: 5 | start_events: Right_Inlane_start 6 | stop_events: Right_Inlane_stop 7 | priority: 200 8 | 9 | # widgets: 10 | # mode2_start_banner: 11 | # type: text 12 | # text: MODE 2 STARTED 13 | # font_size: 50 14 | # color: lime 15 | # y: 80% 16 | # expire: 1s 17 | 18 | # widget_player: 19 | # mode_mode2_started: mode2_start_banner 20 | 21 | variable_player: 22 | sh_LeftOrbit_flashing_hit: 23 | score: 10000 24 | sh_LeftOrbit_lit_hit: 25 | score: 100 26 | 27 | # shots: 28 | # sh_Right_Inlane: 29 | # switch: s_right_inlane 30 | # profile: Right_Inlane 31 | 32 | shot_profiles: 33 | Right_Inlane: 34 | states: 35 | - name: flashing 36 | show: flash 37 | speed: 5 38 | - name: lit 39 | show: on 40 | loop: no 41 | block: yes 42 | -------------------------------------------------------------------------------- /DOC/Software/MPF/Rollergames/modes/Lock1/config/Lock1.yaml: -------------------------------------------------------------------------------- 1 | #config_version=5 2 | 3 | mode: 4 | start_events: drop_target_bank_war_drop_targets_down 5 | stop_events: multiball_normal_multiball_ended 6 | priority: 200 7 | 8 | shots: 9 | lock1_shot: 10 | switch: s_lock_ramp_entry 11 | show_tokens: 12 | light: l_lock 13 | profile: flash_profile 14 | 15 | multiball_locks: 16 | lock: 17 | balls_to_lock: 2 18 | balls_to_replace: 2 19 | lock_devices: bd_lock 20 | reset_count_for_current_player_events: multiball_normal_multiball_ended 21 | disable_events: multiball_normal_multiball_started 22 | #debug: yes 23 | 24 | multiballs: 25 | normal_multiball: 26 | ball_count: 3 27 | ball_locks: bd_lock 28 | #reset_events: multiball_normal_multiball_ended 29 | enable_events: multiball_lock_lock_full 30 | start_events: s_lock_ramp_entry_active 31 | shoot_again: 5s 32 | #debug: yes 33 | -------------------------------------------------------------------------------- /DOC/Software/MPF/Rollergames/modes/attract/config/attract.yaml: -------------------------------------------------------------------------------- 1 | #config_version=5 2 | 3 | show_player: 4 | mode_attract_started: attract_display_loop 5 | mode_attract_started.1: attract_light_show -------------------------------------------------------------------------------- /DOC/Software/MPF/Rollergames/modes/attract/shows/attract_display_loop.yaml: -------------------------------------------------------------------------------- 1 | #show_version=5 2 | 3 | - duration: 0.05 4 | segment_displays: 5 | display1: 6 | text: " T" 7 | - duration: 0.05 8 | segment_displays: 9 | display1: 10 | text: " Th" 11 | - duration: 0.05 12 | segment_displays: 13 | display1: 14 | text: " Thi" 15 | - duration: 0.05 16 | segment_displays: 17 | display1: 18 | text: " This" 19 | - duration: 0.05 20 | segment_displays: 21 | display1: 22 | text: " This " 23 | - duration: 0.05 24 | segment_displays: 25 | display1: 26 | text: " This i" 27 | - duration: 0.05 28 | segment_displays: 29 | display1: 30 | text: " This is" 31 | - duration: 0.05 32 | segment_displays: 33 | display1: 34 | text: " This is " 35 | - duration: 0.05 36 | segment_displays: 37 | display1: 38 | text: " This is a" 39 | - duration: 0.05 40 | segment_displays: 41 | display1: 42 | text: " This is a " 43 | - duration: 0.05 44 | segment_displays: 45 | display1: 46 | text: " This is a t" 47 | - duration: 0.05 48 | segment_displays: 49 | display1: 50 | text: " This is a te" 51 | - duration: 0.05 52 | segment_displays: 53 | display1: 54 | text: " This is a tes" 55 | - duration: 0.05 56 | segment_displays: 57 | display1: 58 | text: " This is a test" 59 | - duration: 0.05 60 | segment_displays: 61 | display1: 62 | text: " This is a test " 63 | - duration: 0.05 64 | segment_displays: 65 | display2: 66 | text: " M" 67 | - duration: 0.05 68 | segment_displays: 69 | display2: 70 | text: " MP" 71 | - duration: 0.05 72 | segment_displays: 73 | display2: 74 | text: " MPF" 75 | - duration: 0.05 76 | segment_displays: 77 | display2: 78 | text: " MPF " 79 | - duration: 0.05 80 | segment_displays: 81 | display2: 82 | text: " MPF r" 83 | - duration: 0.05 84 | segment_displays: 85 | display2: 86 | text: " MPF ru" 87 | - duration: 0.05 88 | segment_displays: 89 | display2: 90 | text: " MPF run" 91 | - duration: 0.05 92 | segment_displays: 93 | display2: 94 | text: " MPF runs" 95 | - duration: 0.05 96 | segment_displays: 97 | display2: 98 | text: " MPF runs " 99 | - duration: 0.05 100 | segment_displays: 101 | display2: 102 | text: " MPF runs A" 103 | - duration: 0.05 104 | segment_displays: 105 | display2: 106 | text: " MPF runs AP" 107 | - duration: 0.05 108 | segment_displays: 109 | display2: 110 | text: " MPF runs APC" 111 | - duration: 0.05 112 | segment_displays: 113 | display2: 114 | text: " MPF runs APC " 115 | - duration: 2 116 | segment_displays: 117 | display2: 118 | text: " MPF runs APC " 119 | - duration: 0.05 120 | segment_displays: 121 | display1: 122 | text: "This is a test " 123 | - duration: 0.05 124 | segment_displays: 125 | display1: 126 | text: "his is a test " 127 | - duration: 0.05 128 | segment_displays: 129 | display1: 130 | text: "is is a test " 131 | - duration: 0.05 132 | segment_displays: 133 | display1: 134 | text: "s is a test " 135 | - duration: 0.05 136 | segment_displays: 137 | display1: 138 | text: " is a test " 139 | - duration: 0.05 140 | segment_displays: 141 | display1: 142 | text: "is a test " 143 | - duration: 0.05 144 | segment_displays: 145 | display1: 146 | text: "s a test " 147 | - duration: 0.05 148 | segment_displays: 149 | display1: 150 | text: " a test " 151 | - duration: 0.05 152 | segment_displays: 153 | display1: 154 | text: "a test " 155 | - duration: 0.05 156 | segment_displays: 157 | display1: 158 | text: " test " 159 | - duration: 0.05 160 | segment_displays: 161 | display1: 162 | text: "test " 163 | - duration: 0.05 164 | segment_displays: 165 | display1: 166 | text: "est " 167 | - duration: 0.05 168 | segment_displays: 169 | display1: 170 | text: "st " 171 | - duration: 0.05 172 | segment_displays: 173 | display1: 174 | text: "t " 175 | - duration: 0.05 176 | segment_displays: 177 | display1: 178 | text: " " 179 | - duration: 0.05 180 | segment_displays: 181 | display2: 182 | text: " MPF runs APC " 183 | - duration: 0.05 184 | segment_displays: 185 | display2: 186 | text: "MPF runs APC " 187 | - duration: 0.05 188 | segment_displays: 189 | display2: 190 | text: "PF runs APC " 191 | - duration: 0.05 192 | segment_displays: 193 | display2: 194 | text: "F runs APC " 195 | - duration: 0.05 196 | segment_displays: 197 | display2: 198 | text: " runs APC " 199 | - duration: 0.05 200 | segment_displays: 201 | display2: 202 | text: "runs APC " 203 | - duration: 0.05 204 | segment_displays: 205 | display2: 206 | text: "uns APC " 207 | - duration: 0.05 208 | segment_displays: 209 | display2: 210 | text: "ns APC " 211 | - duration: 0.05 212 | segment_displays: 213 | display2: 214 | text: "s APC " 215 | - duration: 0.05 216 | segment_displays: 217 | display2: 218 | text: " APC " 219 | - duration: 0.05 220 | segment_displays: 221 | display2: 222 | text: "APC " 223 | - duration: 0.05 224 | segment_displays: 225 | display2: 226 | text: "PC " 227 | - duration: 0.05 228 | segment_displays: 229 | display2: 230 | text: "C " 231 | - duration: 0.1 232 | segment_displays: 233 | display2: 234 | text: " " 235 | -------------------------------------------------------------------------------- /DOC/Software/MPF/Rollergames/modes/attract/shows/attract_light_show.yaml: -------------------------------------------------------------------------------- 1 | #show_version=5 2 | 3 | - duration: 1 4 | lights: 5 | l_track_10: 0 6 | l_track_13: ff 7 | - duration: 1 8 | lights: 9 | l_track_13: 0 10 | l_track_6: ff 11 | - duration: 1 12 | lights: 13 | l_track_6: 0 14 | l_track_4: ff 15 | - duration: 1 16 | lights: 17 | l_track_4: 0 18 | l_track_1: ff 19 | - duration: 1 20 | lights: 21 | l_track_1: 0 22 | l_track_2: ff 23 | - duration: 1 24 | lights: 25 | l_track_2: 0 26 | l_track_3: ff 27 | - duration: 1 28 | lights: 29 | l_track_3: 0 30 | l_track_5: ff 31 | - duration: 1 32 | lights: 33 | l_track_5: 0 34 | l_track_7: ff 35 | - duration: 1 36 | lights: 37 | l_track_7: 0 38 | l_track_9: ff 39 | - duration: 1 40 | lights: 41 | l_track_9: 0 42 | l_track_10: ff 43 | - duration: 1 44 | lights: 45 | l_track_10: 0 46 | l_track_11: ff 47 | - duration: 1 48 | lights: 49 | l_track_11: 0 50 | l_track_8: ff 51 | - duration: 1 52 | lights: 53 | l_track_8: 0 54 | l_track_15: ff 55 | - duration: 1 56 | lights: 57 | l_track_15: 0 58 | l_track_17: ff 59 | - duration: 1 60 | lights: 61 | l_track_17: 0 62 | l_track_16: ff 63 | - duration: 1 64 | lights: 65 | l_track_16: 0 66 | l_track_14: ff 67 | - duration: 1 68 | lights: 69 | l_track_14: 0 70 | l_track_12: ff 71 | - duration: 1 72 | lights: 73 | l_track_12: 0 74 | l_track_10: ff 75 | -------------------------------------------------------------------------------- /DOC/Software/MPF/Rollergames/modes/base/config/base.yaml: -------------------------------------------------------------------------------- 1 | #config_version=5 2 | mode: 3 | start_events: ball_starting 4 | priority: 100 5 | 6 | segment_display_player: 7 | mode_base_started: 8 | display1: 9 | text: "{players[0].score:d}" 10 | 11 | hardware_sound_player: 12 | skate_targets_unlit_hit: 13 | "SOUND.BIN": 14 | track: 2 15 | action: play_file 16 | # sh_s_skate_k_hit: 17 | # "SOUND.BIN": 18 | # track: 2 19 | # action: play_file 20 | # sh_s_skate_a_hit: 21 | # "SOUND.BIN": 22 | # track: 2 23 | # action: play_file 24 | # sh_s_skate_t_hit: 25 | # "SOUND.BIN": 26 | # track: 2 27 | # action: play_file 28 | # sh_s_skate_e_hit: 29 | # "SOUND.BIN": 30 | # track: 2 31 | # action: play_file 32 | 33 | variable_player: 34 | skate_targets_unlit_hit: 35 | score: 100 36 | # sh_s_skate_k_hit: 37 | # score: 200 38 | # sh_s_skate_a_hit: 39 | # score: 300 40 | # sh_s_skate_t_hit: 41 | # score: 400 42 | # sh_s_skate_e_hit: 43 | # score: 500 44 | # my_first_shot_my_first_profile_unlit_hit: 45 | # score: 100 46 | # my_first_shot_my_first_profile_flashing_hit: 47 | # score: 1000 48 | 49 | lock1_shot_hit: 50 | v_balls_locked: 1 51 | #multiball_normal_multiball_ended: 52 | # v_balls_locked: 53 | # int: 0 54 | # action: set 55 | # lock_locked_balls: 56 | # int: 0 57 | # action: set 58 | 59 | 60 | shots: 61 | sh_w_drop_target: 62 | switch: s_left_drop_target 63 | reset_events: drop_target_bank_war_drop_targets_down, ball_will_end 64 | show_tokens: 65 | light: l_drop_target_W 66 | sh_a_drop_target: 67 | switch: s_center_drop_target 68 | reset_events: drop_target_bank_war_drop_targets_down, ball_will_end 69 | show_tokens: 70 | light: l_drop_target_A 71 | sh_r_drop_target: 72 | switch: s_right_drop_target 73 | reset_events: drop_target_bank_war_drop_targets_down, ball_will_end 74 | show_tokens: 75 | light: l_drop_target_R 76 | sh_s_skate_s: 77 | switch: s_5bank_S 78 | show_tokens: 79 | light: l_5bank_S 80 | sh_s_skate_k: 81 | switch: s_5bank_K 82 | show_tokens: 83 | light: l_5bank_K 84 | sh_s_skate_a: 85 | switch: s_5bank_A 86 | show_tokens: 87 | light: l_5bank_A 88 | sh_s_skate_t: 89 | switch: s_5bank_T 90 | show_tokens: 91 | light: l_5bank_T 92 | sh_s_skate_e: 93 | switch: s_5bank_E 94 | show_tokens: 95 | light: l_5bank_E 96 | sh_lane_j: 97 | switch: s_lane_rollover_J 98 | show_tokens: 99 | light: l_lane_J 100 | sh_lane_e: 101 | switch: s_lane_rollover_E 102 | show_tokens: 103 | light: l_lane_E 104 | sh_lane_t: 105 | switch: s_lane_rollover_T 106 | show_tokens: 107 | light: l_lane_T 108 | sh_abc_a: 109 | switch: s_standup_A 110 | show_tokens: 111 | light: l_standup_A 112 | sh_abc_b: 113 | switch: s_standup_B 114 | show_tokens: 115 | light: l_standup_B 116 | sh_abc_c: 117 | switch: s_standup_C 118 | show_tokens: 119 | light: l_standup_C 120 | 121 | sequence_shots: 122 | sh_left_orbit: 123 | switch_sequence: s_right_inlane, s_left_spinner 124 | sequence_timeout: 5s 125 | sh_right_orbit: 126 | switch_sequence: s_left_inlane, s_right_spinner 127 | sequence_timeout: 5s 128 | 129 | shot_groups: 130 | jet_lanes: 131 | shots: sh_lane_j, sh_lane_e, sh_lane_t 132 | rotate_left_events: s_left_lane_change_active 133 | rotate_right_events: s_right_lane_change_active 134 | reset_events: jet_lanes_complete 135 | # enable_events: ball_starting 136 | # disable_events: ball_ending 137 | skate_targets: 138 | shots: sh_s_skate_s, sh_s_skate_k, sh_s_skate_a, sh_s_skate_t, sh_s_skate_e 139 | reset_events: skate_targets_complete 140 | # enable_events: ball_starting 141 | # disable_events: ball_ending 142 | abc_targets: 143 | shots: sh_abc_a, sh_abc_b, sh_abc_c 144 | reset_events: abc_targets_complete 145 | # enable_events: ball_starting 146 | # disable_events: ball_ending 147 | 148 | show_player: 149 | s_right_inlane_active: 150 | lane_flash: 151 | show_tokens: 152 | light: l_left_orbit 153 | speed: 5 154 | sh_left_orbit_timeout: 155 | lane_flash: 156 | show_tokens: 157 | light: l_left_orbit 158 | action: stop 159 | sh_left_orbit_hit: 160 | lane_flash: 161 | show_tokens: 162 | light: l_left_orbit 163 | action: stop 164 | s_left_inlane_active: 165 | lane_flash: 166 | show_tokens: 167 | light: l_right_orbit 168 | speed: 5 169 | sh_right_orbit_timeout: 170 | lane_flash: 171 | show_tokens: 172 | light: l_right_orbit 173 | action: stop 174 | sh_right_orbit_hit: 175 | lane_flash: 176 | show_tokens: 177 | light: l_right_orbit 178 | action: stop 179 | ball_started{is_extra_ball}: 180 | lane_flash: 181 | show_tokens: 182 | light: l_skate_again 183 | speed: 5 184 | 185 | shows: 186 | lane_flash: 187 | - time: 0 188 | lights: 189 | (light): 0 190 | - time: +1 191 | lights: 192 | (light): ff 193 | 194 | state_machines: 195 | teams: 196 | states: 197 | start: 198 | label: state_start 199 | show_when_active: 200 | show: flash 201 | speed: 5 202 | show_tokens: 203 | light: l_team_1 204 | events_when_started: state_start_start 205 | events_when_stopped: state_start_stopped 206 | team2: 207 | label: state_team2 208 | show_when_active: 209 | show: flash 210 | speed: 5 211 | show_tokens: 212 | light: l_team_2 213 | events_when_started: state_team2_start 214 | events_when_stopped: state_team2_stopped 215 | team3: 216 | label: state_team3 217 | show_when_active: 218 | show: flash 219 | speed: 5 220 | show_tokens: 221 | light: l_team_3 222 | events_when_started: state_team3_start 223 | events_when_stopped: state_team3_stopped 224 | team4: 225 | label: state_team4 226 | show_when_active: 227 | show: flash 228 | speed: 5 229 | show_tokens: 230 | light: l_team_4 231 | events_when_started: state_team4_start 232 | events_when_stopped: state_team4_stopped 233 | team5: 234 | label: state_team5 235 | show_when_active: 236 | show: flash 237 | speed: 5 238 | show_tokens: 239 | light: l_team_5 240 | events_when_started: state_team5_start 241 | events_when_stopped: state_team5_stopped 242 | team6: 243 | label: state_team6 244 | show_when_active: 245 | show: flash 246 | speed: 5 247 | show_tokens: 248 | light: l_team_6 249 | events_when_started: state_team6_start 250 | events_when_stopped: state_team6_stopped 251 | team6_complete: 252 | label: state_team6_complete 253 | show_when_active: 254 | show: flash 255 | speed: 5 256 | show_tokens: 257 | light: l_extra_ball 258 | events_when_started: state_team6_complete 259 | events_when_stopped: state_team_reset 260 | transitions: 261 | - source: start 262 | target: team3 263 | events: ball_started{current_player.ball==1 and not is_extra_ball} 264 | - source: start 265 | target: team2 266 | events: sh_left_orbit_hit, sh_right_orbit_hit 267 | - source: team2 268 | target: team3 269 | events: sh_left_orbit_hit, sh_right_orbit_hit 270 | - source: team3 271 | target: team4 272 | events: sh_left_orbit_hit, sh_right_orbit_hit 273 | - source: team4 274 | target: team5 275 | events: sh_left_orbit_hit, sh_right_orbit_hit 276 | - source: team5 277 | target: team6 278 | events: sh_left_orbit_hit, sh_right_orbit_hit 279 | - source: team6 280 | target: team6_complete 281 | events: sh_left_orbit_hit, sh_right_orbit_hit 282 | - source: team6_complete 283 | target: start 284 | events: s_extra_ball_active 285 | 286 | extra_balls: 287 | teams_extra_ball: 288 | award_events: state_team_reset 289 | debug: yes 290 | -------------------------------------------------------------------------------- /DOC/SolExpBoard.md: -------------------------------------------------------------------------------- 1 | # APC solenoid expansion board (for use with loads having an additional power supply) 2 | 3 | This board can be connected to the Hardware Extensions Interface of the APC and increases the number of controlled solenoids by 8. 4 | Note that this is a simple board without ground separation. This means you can only use this board with an own power supply. A typical application would be a shaker motor which usually needs 24V and therefore comes with an own 24V power supply. Connect the ground of this power supply to the Sol_GND connector of the Solenoid Expansion Board and not to the Solenoid Ground connector of the APC. 5 | 6 | The prototype of the Solenoid Expansion Board looks like this. The final board looks slightly different. 7 | 8 | ![SolExpBoard](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/SolExpBoard.JPG) 9 | 10 | Currently the use of only one board is supported by the SW, but this could be changed if needed. 11 | 12 | This board must be activated by setting the 'Sol Exp Board' setting in the 'System Settings' menu to 'yes'. 13 | Solenoids connected to the pins 1 to 8 of the P2 connector of the expander board are then mapped to the APC solenoid numbers 26 - 33. 14 | 15 | ## Hardware 16 | 17 | The hardware just consists of a latch and some power MOSFET drivers. The latch is controlled by the Sel7 signal of the APC and is automatically reset when the blanking signal is active. The board is only suited for use with an own power supply. Connect the ground of this supply to P3 (Sol_GND). 18 | 19 | The schematic, Gerber (and drilling) are located in the [APC_Solenoid_exp](https://github.com/AmokSolderer/APC/tree/master/DOC/Hardware/APC_Solenoid_exp) folder. 20 | 21 | # APC solenoid expansion board with separated grounds (for use with loads using the pinball's power supply) 22 | 23 | Still to come. -------------------------------------------------------------------------------- /DOC/Specialties.md: -------------------------------------------------------------------------------- 1 | # APC specialties 2 | 3 | Usually the APC handles the pinball hardware quite straightforward. That means the lamp, switch and solenoid numbers used by the APC are the same as printed in the manual of your pinball machine, no matter whether you use MPF, Lisy/PinMame or write your own C code. 4 | However, there're some specialties which are handled in this section. 5 | 6 | ## Special switches 7 | 8 | Williams assigned numbers only to Switches which belong to the switch matrix. 9 | The APC assigns numbers > 64 to the rest of them, so they can be used as normal switches: 10 | 11 | | APC switch number | Williams equivalent | 12 | |--|--| 13 | | 65 | Activation switch for special solenoid 1 | 14 | | 66 | Activation switch for special solenoid 2 | 15 | | 67 | Activation switch for special solenoid 3 | 16 | | 68 | Activation switch for special solenoid 4 | 17 | | 69 | Activation switch for special solenoid 5 | 18 | | 70 | Activation switch for special solenoid 6 | 19 | | 71 | Memory Protect switch | 20 | | 72 | Advance switch | 21 | | 73 | Up/Down switch (active when the switch is in Up position) | 22 | 23 | Additional information about these switches is provided below: 24 | 25 | ### Special solenoids and their switch numbers 26 | 27 | Williams machines from System3 to System 11a have so called special solenoids. Each of these solenoids is connected to a special switch which will fire the solenoid immediately without any involvement of the CPU. This means that those special switches are not part of the switch matrix (which is CPU controlled). They are handled by a dedicated logic, are not visible for the CPU and therefore have no numbers. 28 | If your switch matrix has a switch for a special solenoid anyway, then it's because the CPU needs to know when it is triggered (e.g. for scoring). It's a second switch additional to the special solenoid switch. For example: in case of a pop bumper, the plastic disc to trigger the bumper is usually connected to the special solenoid switch and the scoring switch is triggered by the bumper ring being pulled down by the solenoid. 29 | This means that you have to select the special solenoid switch as the activation switch for your pop bumper, because the scoring switch is only activated when the solenoid is already moving. 30 | 31 | The APC handles special solenoid switches as normal switches, but their numbers start with 65 which is the trigger switch for special solenoid 1. 32 | 33 | Williams dropped the special solenoid switches with the start of System 11b. After that the activation switches were part of the switch matrix and controlled by the CPU. 34 | 35 | ### The Advance, Memory Protect and Up/Down switch 36 | 37 | Similar to the special solenoid switches, the Advance, Memory Protect and Up/Down switch are also not part of the switch matrix. The APC assignes the numbers > 70 to them. Note that the Up/Down switch is low active, which means that it's active when NOT pressed. 38 | 39 | ## The flipper relay 40 | 41 | In the original Williams HW the flipper relay switches both flipper fingers at once and has no solenoid number. 42 | The APC doesn't use a relay but switching transistors. There's one for the left and one for the right flippers, so it is possible to activate the sides individually. 43 | Their solenoid numbers are 23 and 24, but any (de-)activation command sent to solenoid 25 will affect both flipper fingers. 44 | -------------------------------------------------------------------------------- /DOC/Sys7Alpha.md: -------------------------------------------------------------------------------- 1 | # Alphanumeric displays for System7 - 11 machines 2 | 3 | Beginning with System7 Williams changed their display setup to 4 player displays with 7 characters each and one credit display with 4 characters. In System7 and 9 machines all of these displays were 7-segment numerical only. With System11 the basic setup was kept, but the displays for player 1 and 2 were changed to alphanumerical ones. 4 | 5 | This display set replaces all 4 player displays by 14-segment alphanumeric ones, just the credit display stays numerical. It is made for System 7 and System9. It can however also be used in System11 machines up to Taxi (which was the first to use two 16 character alphanumeric displays AFAIK) but there the drilling holes of the board won't fit those of the original board. 6 | 7 | Note that this display can only be used with APC boards, it won't work with the original CPU boards. 8 | It works with the APC and PinMame, but will behave like an old numerical display set then, because PinMame won't ask for anything but numbers. 9 | That means it makes only sense for you to build this if you want to use the APC API or MPF to write the corresponding code to use it. 10 | 11 | I have used this display in my [Black Knight game code](https://github.com/AmokSolderer/APC/blob/master/DOC/BlackKnight.md). 12 | 13 | ![APC Black Knight](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/BK.jpg) 14 | 15 | The picture below shows 2 versions of the driver board. The lower (older) one is equipped with Molex connectors and has System 9 display cables attached. The upper one is the updated version which can also be used with System7 display cables. It can also use Molex connectors for System 9 and 11, but in this case they have not been populated. 16 | 17 | ![Sys7Alpha](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/Sys7_Alpha.jpg) 18 | 19 | The next shot shows the upper board in my System7 Black Knight with all the cables for the actual display boards connected. 20 | 21 | ![Sys7AlphaBK](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/Sys7_Alpha2.jpg) 22 | 23 | For the display to work properly you have to select 'Alpha+Credit' in the display settings. 24 | 25 | The alphanumeric player displays use Kingbright's PSA08-11SRWA LED display components, the credit display has four SA08-11SRWA. Alas, these components are a bit too wide, but you can use a bench- or belt-grinder until they fit on the boards. 26 | 27 | The Gerber files, BOM and schematics can be found [here](https://github.com/AmokSolderer/APC/tree/master/DOC/Hardware/Sys7Alpha). 28 | 29 | As the display boards are only single sided there're four wire connections needed on each player board. In the picture below they're shown as red lines right below the display elemets. 30 | 31 | ![PlayerDisplay](https://github.com/AmokSolderer/APC/blob/master/DOC/PICS/PlayerDisplay.png) 32 | -------------------------------------------------------------------------------- /DOC/Upload_SW.md: -------------------------------------------------------------------------------- 1 | # Upload the Software 2 | 3 | ## Installing the Arduino IDE 4 | 5 | The APC uses an Arduino DUE which needs to be programmed with the APC Software. 6 | Go to the [Arduino DUE](https://docs.arduino.cc/hardware/due) page and use the 'Quickstart Guide' to learn how to do this. 7 | 8 | The next step is to install the SPI and the SdFat libraries. There is a tutorial on the [Arduino page](https://docs.arduino.cc/software/ide-v2/tutorials/ide-v2-installing-a-library) about that. 9 | 10 | ## Download the APC software from GitHub 11 | 12 | If you don't want to use Git to access the GitHub repository, you can download a ZIP package instead. 13 | To do that go to the main [GitHub page](https://github.com/AmokSolderer/APC) and click the green <> Code button at the top right of the page. A small pull down menu appears with 'Download ZIP' as the lowest entry. Click on it to download the complete repository. 14 | Unzip the file and rename the APC-master folder to APC. The folder must contain all .ino files and the Sound.h from the APC repository. 15 | 16 | ## Uploading the APC software 17 | 18 | Enter the APC folder and open the Arduino.ino sketch in the Arduino IDE. The other .ino files should open up as seperate register cards. 19 | 20 | I recommend to initially program the Arduino before installing the APC into your pinball machine. The APC's power consumption is quite low so the USB connection to yor PC is enough to supply it. 21 | Connect the 'Programming Port' of the DUE to your PC and press 'Upload' in your Arduino IDE. The SW should be compiled and uploaded automatically. 22 | 23 | You're now ready for the [basic preparation](https://github.com/AmokSolderer/APC/blob/master/DOC/Prepare.md) that might be necessary for your machine to work with the APC. 24 | 25 | ## Updating the SW 26 | 27 | Once you have the APC installed in your machine, you don't have to remove it to upload a new SW version. However, I'd recommend to press the 'High Score Reset' button before uploading as this disables the lamps, coils and displays. 28 | After the upload is completed, the APC will restart and come up with the new SW. If you're using a Raspberry Pi with Lisy you might have to restart your machine anyway, to make the Pi and the Arduino sync again. 29 | -------------------------------------------------------------------------------- /DOC/UsefulSWtools.md: -------------------------------------------------------------------------------- 1 | # Usefull SW tools 2 | 3 | I have written some perl scripts to do certain APC related work. 4 | All these scripts can be executed with a perl interpreter e.g. for Windows available from http://strawberryperl.com 5 | 6 | ## Audio data converter 7 | 8 | [AudioSave.pl](https://github.com/AmokSolderer/APC/blob/master/DOC/Software/AudioSave.pl) is a data converter that must be used to convert WAV files to a format that can directly be handled by the Arduino. The sampling rate of this WAV file has to be 44.1KHz. 9 | The tool looks for a 16bit WAV mono file named Data.wav and generates a file Data.snd from it. Basically it skips the header and converts the 16bit signed values of the WAV file to 12bit unsigned for the DAC of the DUE. 10 | I recommend to use tools like Audacity to generate the mono WAV, but the tool can also be used to convert stereo files. For this you just have to uncomment the two `read(FH, $buf1, 1);` lines which makes the tool skip every second value. The drawback is that this will not generate a real mono file but just throw away one channel. 11 | 12 | Rename Data.snd and put it on the SD Card. Use only capital letters for the filename, because only then the pinball display is able to show it correctly in case an error message is shown. 13 | 14 | There's also an [AudioSaveFolder.pl](https://github.com/AmokSolderer/APC/blob/master/DOC/Software/AudioSaveFolder.pl) version of this tool available (thanks to Mokopin). This tool converts all .wav files in the current folder to .snd files automatically. 15 | 16 | ## Display segment code calculator 17 | 18 | The following tool generates the numerical definition of the display segment patterns (2 bytes for each character). In other words the numbers tell the APC which display segments to switch on for which character. In the code these numbers can be found at the beginning of APC.ino. They are stored in arrays named AlphaUpper, AlphaLower and NumLower depending on where you want this character to appear. 19 | 20 | For normal letters and numbers there should be no need for you to bother with these definitions as they're already defined. However if you want special characters or graphical effects you have to determine the corresponding numbers. To make it easier I have generated three versions of this tool for the various occasions. 21 | 22 | * [DisplayAlphaUpper.pl](https://github.com/AmokSolderer/APC/blob/master/DOC/Software/DisplayAlphaUpper.pl) 23 | * [DisplayAlphaLower.pl](https://github.com/AmokSolderer/APC/blob/master/DOC/Software/DisplayAlphaLower.pl) 24 | * [DisplayNumLower.pl](https://github.com/AmokSolderer/APC/blob/master/DOC/Software/DisplayNumLower.pl) 25 | 26 | Let's assume you have a Black Knight 2000 which has alphanumerical displays in both rows and you want to know the pattern definition numbers for the character 'A' in the upper display row. Take a look into your pinball manual or open the code of the tool to determine which segments have to be lit for an 'A'. You can see that an 'A' consists of the segments a, b, c ,e ,f, g and m. Now execute DisplayAlphaUpper.pl in a shell and type each of these segment characters followed by _Enter_. The tool will print a simple sketch of the selected segments as well as the two definition bytes. If your 'A' is complete you should end up with 126, 4 and when you look at the third line of AlphaUpper in the APC.ino you will find these values to define an 'A'. 27 | 28 | If you want to have the values for an 'A' in the lower row you have to use DisplayAlphaLower.pl and DisplayNumLower.pl for numbers in the lower row (like in Big Guns). 29 | 30 | *** 31 | -------------------------------------------------------------------------------- /DOC/lisyminigames.csv: -------------------------------------------------------------------------------- 1 | No,Mame Name,Long Name,Type,throttle,comment 2 | 0,httip_l1,Hot Tip ,SYS3,120, 3 | 1,lucky_l1,Lucky Seven ,SYS3,120, 4 | 2,wldcp_l1,World Cup ,SYS3,120, 5 | 3,cntct_l1,Contact ,SYS3,120, 6 | 4,disco_l1,Disco Fever ,SYS3,120, 7 | 5,phnix_l1,Phoenix ,SYS4,120, 8 | 6,flash_l1,Flash ,SYS4,120, 9 | 7,flash_l2,Flash ,SYS4,120, 10 | 8,trizn_l1,Tri Zone ,SYS4,120, 11 | 9,pkrno_l1,Pokerino ,SYS4,120, 12 | 10,tmwrp_l2,Time Warp ,SYS4,120, 13 | 11,stlwr_l2,Stellar Wars ,SYS4,120, 14 | 12,lzbal_l2,Laser Ball ,SYS6,120, 15 | 13,scrpn_l1,Scorpion ,SYS6,120, 16 | 14,blkou_l1,Blackout ,SYS6,120, 17 | 15,grgar_l1,Gorgar ,SYS6,120, 18 | 16,frpwr_l6,Firepower ,SYS6,120, 19 | 17,algar_l1,Algar ,SYS6A,120, 20 | 18,alpok_l6.zip,Alien Poker ,SYS6A,120, 21 | 19,csmic_l1,Cosmic Gunfight ,SYS7,120, 22 | 20,jngld_l2,Jungle Lord ,SYS7,120, 23 | 21,pharo_l2,Pharaoh ,SYS7,120, 24 | 22,solar_l2,Solar Fire ,SYS7,120, 25 | 23,prototy,Thunderball,SYS7,120, 26 | 24,hypbl_l6,Hyperball ,SYS7,120, 27 | 25,barra_l1,Barracora ,SYS7,120, 28 | 26,vrkon_l1,Varkon ,SYS7,120, 29 | 27,wrlok_l3,Warlok ,SYS7,120, 30 | 28,dfndr_l4,Defender ,SYS7,120, 31 | 29,jst_l2,Joust ,SYS7,120, 32 | 30,lsrcu_l2,Laser Cue ,SYS7,120, 33 | 31,fpwr2_l2,Firepower II ,SYS7,120, 34 | 32,ratrc_l1,Rat Race,SYS7,120, 35 | 33,strlt_l1,Star Light ,SYS7,120, 36 | 34,bk_l4,Black Knight ,SYS7,120, 37 | 35,tmfnt_l5,Time Fantasy ,SYS7,120, 38 | 36,pfevr_l2,Pennant Fever ,SYS8,120, 39 | 37,sshtl_l7.zip,Space Shuttle ,SYS9,120, 40 | 38,sorcr_l2,Sorcerer ,SYS9,120, 41 | 39,comet_l5,Comet ,SYS9,120, 42 | 40,hs_l4,High Speed ,SYS11,120, 43 | 41,grand_l4,Grand Lizard ,SYS11,120, 44 | 42,rdkng_l4,Road Kings ,SYS11RK,120, 45 | 43,pb_l5,Pinbot ,SYS11A_,120, 46 | 44,f14_l1,F-14 Tomcat ,SYS11A_,120, 47 | 45,fire_l3,Fire! ,SYS11A,120, 48 | 46,milln_l3,Millionaire ,SYS11A,120, 49 | 47,bguns_l8,Big Guns ,SYS11B,120, 50 | 48,spstn_l5,Space Station ,SYS11B,120, 51 | 49,gmine_l2,Gold Mine ,SYS11B,120, 52 | 50,cycln_l5,Cyclone ,SYS11B,120, 53 | 51,bnzai_l3,Banzai Run ,SYS11B,120, 54 | 52,swrds_l2,Swords of Fury ,SYS11B,120, 55 | 53,taxi_l4,Taxi ,SYS11B,120, 56 | 54,tdawg_l1,Top Dawg ,SYS11B,120, 57 | 55,jokrz_l6,Jokerz! ,SYS11B,120, 58 | 56,esha_la3,Earthshaker ,SYS11B,120, 59 | 57,bk2k_l4,Black Knight 2000 ,SYS11B,120, 60 | 58,tsptr_l3,Transporter the Rescue ,SYS11B,120, 61 | 59,polic_l4,Police Force ,SYS11B,120, 62 | 60,shfin_l1,Shuffle Inn ,SYS11B,120, 63 | 61,afm_11b,Elvira and the Party Monsters ,SYS11B,120, 64 | 62,bcats_l5,Bad Cats ,SYS11B,120, 65 | 63,mousn_l1,Mousin' Around! ,SYS11B,120, 66 | 64,whirl_l3,Whirlwind,SYS11B,120, 67 | 65,gs_l4,The Bally Game Show ,SYS11C,120, 68 | 66,pool_l7,Pool Sharks ,SYS11C,120, 69 | 67,rollr_l3,Rollergames ,SYS11C,120, 70 | 68,diner_l4,Diner ,SYS11C,120, 71 | 69,radcl_l1,Radical! ,SYS11C,120, 72 | 70,dd_l2,Dr. Dude ,SYS11C,120, 73 | 71,rvrbt_l3,Riverboat Gambler ,SYS11RG,120, 74 | 72,bbnny_l2,Bugs Bunny's Birthday Ball ,SYS11C,120, 75 | 73,lwar_a83,Laser War,DE_A1,120, 76 | 74,ssvc_a26,Secret Service,DE_A2,120, 77 | 75,torp_e21,Torpedo Alley,DE_A2,120, 78 | 76,tmac_a24,Time Machine,DE_A2,120, 79 | 77,play_a24,Playboy 35th Anniversary ,DE_A2,120, 80 | 78,mnfb_c27,Monday Night Football,DE_A2,120, 81 | 79,robo_a34,Robocop,DE_A2,120, 82 | 80,poto_a32,Phantom of the Opera,DE_A2,120, 83 | 81,bttf_a28,Back to the Future,DE_A2,120, 84 | 82,simp_a27,The Simpsons,DE_A3,120, 85 | -------------------------------------------------------------------------------- /Sound.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // Sound ////////////////////////////////////////////////////////////////////// 3 | /////////////////////////////////////////////////////////////////////////////// 4 | /* 5 | * Copyright (c) 2012 Arduino LLC. All right reserved. 6 | * Audio library for Arduino Due. 7 | * 8 | * This file is free software; you can redistribute it and/or modify 9 | * it under the terms of either the GNU General Public License version 2 10 | * or the GNU Lesser General Public License version 2.1, both as 11 | * published by the Free Software Foundation. 12 | */ 13 | 14 | #ifndef SOUND_INCLUDED 15 | #define SOUND_INCLUDED 16 | 17 | #include "Print.h" 18 | #define UNUSED(x) (void)(x) 19 | 20 | /////////////////////////////////////////////////////////////////////////////// 21 | 22 | typedef void (*OnTransmitEnd_CB)(void *data); 23 | 24 | /////////////////////////////////////////////////////////////////////////////// 25 | // DAC //////////////////////////////////////////////////////////////////////// 26 | /////////////////////////////////////////////////////////////////////////////// 27 | 28 | class CDAC 29 | { 30 | public: 31 | CDAC(Dacc *_dac, uint32_t _dacId, IRQn_Type _isrId) : m_dac(_dac), m_dacId(_dacId), m_isrId(_isrId), m_cb(NULL) { m_cbData = NULL; }; 32 | 33 | void begin(uint32_t period) { 34 | // Enable clock for DAC 35 | pmc_enable_periph_clk(m_dacId); 36 | 37 | dacc_reset(m_dac); 38 | 39 | // Set transfer mode to double word 40 | dacc_set_transfer_mode(m_dac, 1); 41 | 42 | // Power save: 43 | // sleep mode - 0 (disabled) 44 | // fast wakeup - 0 (disabled) 45 | dacc_set_power_save(m_dac, 0, 0); 46 | 47 | // DAC refresh/startup timings: 48 | // refresh - 0x08 (1024*8 dacc clocks) 49 | // max speed mode - 0 (disabled) 50 | // startup time - 0x10 (1024 dacc clocks) 51 | dacc_set_timing(m_dac, 0x08, 0, DACC_MR_STARTUP_1024); 52 | 53 | // Flexible channel selection with tags 54 | dacc_enable_flexible_selection(m_dac); 55 | //dacc_set_channel_selection(m_dac, 0); 56 | 57 | // Set up analog current 58 | dacc_set_analog_control(m_dac, 59 | DACC_ACR_IBCTLCH0(0x02) | 60 | DACC_ACR_IBCTLCH1(0x02) | 61 | DACC_ACR_IBCTLDACCORE(0x01)); 62 | 63 | // Enable output channels 64 | dacc_enable_channel(m_dac, 0); 65 | dacc_enable_channel(m_dac, 1); 66 | 67 | // Configure Timer Counter to trigger DAC 68 | // -------------------------------------- 69 | pmc_enable_periph_clk(ID_TC1); 70 | TC_Configure(TC0, 1, 71 | TC_CMR_TCCLKS_TIMER_CLOCK2 | // Clock at MCR/8 72 | TC_CMR_WAVE | // Waveform mode 73 | TC_CMR_WAVSEL_UP_RC | // Counter running up and reset when equals to RC 74 | TC_CMR_ACPA_SET | TC_CMR_ACPC_CLEAR); 75 | const uint32_t TC = period / 8; 76 | TC_SetRA(TC0, 1, TC / 2); 77 | TC_SetRC(TC0, 1, TC); 78 | TC_Start(TC0, 1); 79 | 80 | // Configure clock source for DAC (2 = TC0 Output Chan. 1) 81 | dacc_set_trigger(m_dac, 2); 82 | 83 | // Configure pins 84 | PIO_Configure(g_APinDescription[DAC0].pPort, 85 | g_APinDescription[DAC0].ulPinType, 86 | g_APinDescription[DAC0].ulPin, 87 | g_APinDescription[DAC0].ulPinConfiguration); 88 | PIO_Configure(g_APinDescription[DAC1].pPort, 89 | g_APinDescription[DAC1].ulPinType, 90 | g_APinDescription[DAC1].ulPin, 91 | g_APinDescription[DAC1].ulPinConfiguration); 92 | 93 | // Enable interrupt controller for DAC 94 | dacc_disable_interrupt(m_dac, 0xFFFFFFFF); 95 | NVIC_DisableIRQ(m_isrId); 96 | NVIC_ClearPendingIRQ(m_isrId); 97 | NVIC_SetPriority(m_isrId, 0); 98 | NVIC_EnableIRQ(m_isrId); 99 | } 100 | 101 | void end() { 102 | TC_Stop(TC0, 1); 103 | NVIC_DisableIRQ(m_isrId); 104 | dacc_disable_channel(m_dac, 0); 105 | dacc_disable_channel(m_dac, 1); 106 | } 107 | 108 | bool canQueue() { 109 | return (m_dac->DACC_TNCR == 0); 110 | } 111 | 112 | size_t queueBuffer(const uint32_t *buffer, size_t size) { 113 | // Try the first PDC buffer 114 | if ((m_dac->DACC_TCR == 0) && (m_dac->DACC_TNCR == 0)) { 115 | m_dac->DACC_TPR = (uint32_t) buffer; 116 | m_dac->DACC_TCR = size; 117 | m_dac->DACC_PTCR = DACC_PTCR_TXTEN; 118 | if (m_cb) 119 | dacc_enable_interrupt(m_dac, DACC_IER_ENDTX); 120 | return size; 121 | } 122 | 123 | // Try the second PDC buffer 124 | if (m_dac->DACC_TNCR == 0) { 125 | m_dac->DACC_TNPR = (uint32_t) buffer; 126 | m_dac->DACC_TNCR = size; 127 | m_dac->DACC_PTCR = DACC_PTCR_TXTEN; 128 | if (m_cb) 129 | dacc_enable_interrupt(m_dac, DACC_IER_ENDTX); 130 | return size; 131 | } 132 | 133 | // PDC buffers full, try again later... 134 | return 0; 135 | } 136 | 137 | void setOnTransmitEnd_CB(OnTransmitEnd_CB _cb, void *_data) { 138 | m_cb = _cb; 139 | m_cbData = _data; 140 | if (!m_cb) 141 | dacc_disable_interrupt(m_dac, DACC_IDR_ENDTX); 142 | } 143 | 144 | void onService() { 145 | uint32_t sr = m_dac->DACC_ISR; 146 | if (sr & DACC_ISR_ENDTX) { 147 | // There is a free slot, enqueue data 148 | dacc_disable_interrupt(m_dac, DACC_IDR_ENDTX); 149 | if (m_cb) 150 | m_cb(m_cbData); 151 | } 152 | } 153 | 154 | void enableInterrupts() { NVIC_EnableIRQ(m_isrId); }; 155 | 156 | void disableInterrupts() { NVIC_DisableIRQ(m_isrId); }; 157 | 158 | private: 159 | Dacc *m_dac; 160 | uint32_t m_dacId; 161 | IRQn_Type m_isrId; 162 | OnTransmitEnd_CB m_cb; 163 | void *m_cbData; 164 | }; 165 | 166 | /////////////////////////////////////////////////////////////////////////////// 167 | 168 | CDAC g_DAC(DACC_INTERFACE, DACC_INTERFACE_ID, DACC_ISR_ID); 169 | 170 | void DACC_ISR_HANDLER(void) { g_DAC.onService(); } 171 | 172 | /////////////////////////////////////////////////////////////////////////////// 173 | // ~DAC /////////////////////////////////////////////////////////////////////// 174 | /////////////////////////////////////////////////////////////////////////////// 175 | 176 | class CSound : public Print { 177 | public: 178 | CSound(CDAC &_dac) : m_dac(&_dac) { bufferSize = 0; buffer = half = last = running = next = NULL; }; 179 | virtual ~CSound(void) {}; 180 | 181 | void begin (uint32_t sampleRate, uint32_t msPreBuffer); 182 | 183 | void end (); 184 | 185 | size_t write(uint8_t c) { 186 | UNUSED(c); 187 | return 0; /* not implemented */ 188 | }; 189 | size_t write(const uint16_t *data, size_t size) { return write(reinterpret_cast(data), size/2) * 2; }; 190 | size_t write(const uint32_t *data, size_t size); 191 | 192 | uint32_t bufferSize; 193 | uint32_t *buffer; 194 | uint32_t *half; 195 | uint32_t *last; 196 | uint32_t *volatile running; 197 | uint32_t *volatile next; 198 | void enqueue(); 199 | 200 | private: 201 | static void onTransmitEnd(void *me); 202 | //void enqueue(); 203 | uint32_t *cook(const uint32_t *buffer, size_t size); 204 | 205 | CDAC *m_dac; 206 | }; 207 | 208 | /////////////////////////////////////////////////////////////////////////////// 209 | 210 | void CSound::onTransmitEnd(void *_me) { 211 | CSound *me = reinterpret_cast (_me); 212 | if (me->running == me->buffer) 213 | me->running = me->half; 214 | else 215 | me->running = me->buffer; 216 | } 217 | 218 | /////////////////////////////////////////////////////////////////////////////// 219 | 220 | void CSound::begin(uint32_t sampleRate, uint32_t msPreBuffer) { 221 | UNUSED(msPreBuffer); 222 | // Allocate a buffer to keep msPreBuffer milliseconds of audio 223 | bufferSize = 128; 224 | // if (bufferSize < 1024) 225 | // bufferSize = 1024; 226 | buffer = (uint32_t *) malloc(bufferSize * sizeof(uint32_t)); 227 | half = buffer + bufferSize / 2; 228 | last = buffer + bufferSize; 229 | 230 | // Buffering starts from the beginning 231 | running = buffer; 232 | next = buffer; 233 | 234 | // Start DAC 235 | m_dac->begin(VARIANT_MCK / sampleRate); 236 | 237 | m_dac->setOnTransmitEnd_CB(onTransmitEnd,this); 238 | } 239 | 240 | /////////////////////////////////////////////////////////////////////////////// 241 | 242 | void CSound::end() { 243 | m_dac->end(); 244 | free( buffer); 245 | } 246 | 247 | /////////////////////////////////////////////////////////////////////////////// 248 | 249 | //size_t CSound::write(const uint32_t *data, size_t size) { 250 | //const uint32_t TAG = 0x10000000; 251 | //Serial.println(size); 252 | // size_t i; 253 | // for (i = 0; i < size; i++) { 254 | // *next = data[i]; //| TAG; 255 | // next++;} 256 | // enqueue(); 257 | // 258 | // if (next == half || next == last) { 259 | // enqueue(); 260 | // while (next == running) 261 | // ; 262 | // } 263 | // } 264 | //return i; 265 | //} 266 | 267 | /////////////////////////////////////////////////////////////////////////////// 268 | 269 | void CSound::enqueue() { 270 | if (!m_dac->canQueue()) { 271 | // DMA queue full 272 | return; 273 | } 274 | 275 | if (next == half) { 276 | // Enqueue the first half 277 | m_dac->queueBuffer(buffer, bufferSize / 2); 278 | } else { 279 | // Enqueue the second half 280 | m_dac->queueBuffer(half, bufferSize / 2); 281 | next = buffer; // wrap around 282 | } 283 | } 284 | 285 | /////////////////////////////////////////////////////////////////////////////// 286 | /////////////////////////////////////////////////////////////////////////////// 287 | 288 | CSound g_Sound(g_DAC); 289 | 290 | #endif 291 | 292 | /////////////////////////////////////////////////////////////////////////////// 293 | // ~Sound ///////////////////////////////////////////////////////////////////// 294 | /////////////////////////////////////////////////////////////////////////////// 295 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-slate --------------------------------------------------------------------------------