Digital Pinball Machine
Infrared remote control power button emulator
A small PIC-based IR remote emulator designed to switch the pinball machine displays on automatically after mains power is applied.
Why this was needed
The purpose of this project is to switch a TV on when connected to mains power without using the original remote control. It was specifically designed for my digital pinball project, but the same idea could be useful elsewhere.
Most TVs do not automatically turn on when mains power is restored. That is normally a good thing, especially after a power cut, but it creates a problem inside the pinball machine. Each time the machine is powered up, multiple displays need to be turned on before Windows starts.
With Windows 7, starting the PC before all monitors were online caused the screen layout to become badly messed up. I do not think this is as much of an issue in Windows 10, but resetting the screen layout is still something I would rather avoid.
The solution
The solution I came up with was to make small devices that recreate the infrared power-on signals from the original remote controls.
I used PIC microcontrollers with a sounder and an IR LED attached. Once the whole pinball machine is powered up, the IR emulator waits long enough for the LCD screen to initialise, then sends the IR power-on signal.
Once all screens are on, I can then press the PC power button.
There are likely much easier ways to do this now. I made these devices around 2015 using spare parts I already had.
Capturing the IR codes
To work out how to copy the codes, I used an oscilloscope with an old IR receiver from a very old CRT TV.
The first remote control was from the main playfield display, a Sharp 40 inch TV. The oscilloscope image shows the captured data when the infrared remote power button is pressed. All timings are included.
The second remote control was for the backglass display, a Hannspree TV. This oscilloscope image is a capture of the data sent when the infrared remote power button is pressed.
In the PIC code below, I took those timings and made the PIC recreate each on/off pulse exactly as shown by the oscilloscope. Ideally, I would have created calls for each repeated on/off timing, but this was written as a quick routine to emulate the code.
Most infrared remote controls modulate the IR LED at around 38kHz while the LED is active. This can be achieved directly with the PIC, avoiding extra modulation electronics.
Sharp TV IR code example
This is the code to operate the Sharp TV playfield power-on command. Only the core code is shown here. The crystal used is the internal 4MHz oscillator on a PIC16F88.
; Whats happening? ; 2 routines make this work. ledON and uSdelay. ; Take a look at the scope image for the Share 40" TV power button. ; The first thing in the timing is to switch the IR LED on for 980uS ; Each time the ledON routine runs, it takes 28.1uS to complete, so we loop the by setting the W register ; to the number of loops required. In this case, we can get close by looping 35 times. ; ; Once that has happened, the LED needs to stay off for 780uS ; That is the first bit sent to the LED. ; The 4 lines of code below do exactly this. MOVLW d'35' ; LET W=35; Do ledOn for 980us, 35 x28.1µS = 984uS in the ledON routine CALL ledON ; GoSub ledON; Do routine for the delay specified above MOVLW d'78' ; off for 780µS; This is a delay routine where 78 = 780µS. LED is off here CALL uSdelay ; ; the ledON is a bit more complex than just swiching on. When it is on, its infact flashing off and on at 38Khz. ; The routine is near the end of the code that achieves this. ; the code continues for the remaining data to be sent to the IR led. ; This rebuilds the same power button code seen in the image above ;--------------------------------------------------------- MOVLW d'67' ; on for 1880(66=1881) CALL ledON MOVLW d'78' ; off for 780µS CALL uSdelay ;block of 3 MOVLW d'35' ; on for 984 (nearest to 980) CALL ledON MOVLW d'78' ; off for 780µS CALL uSdelay MOVLW d'35' ; on for 984 (nearest to 980) CALL ledON MOVLW d'78' ; off for 780µS CALL uSdelay MOVLW d'35' ; on for 984 (nearest to 980) CALL ledON MOVLW d'78' ; off for 780µS CALL uSdelay MOVLW d'35' ; on for 984 (nearest to 980) CALL ledON MOVLW d'164' ; off for 1640µS - 1ST BIG OFF TIME CALL uSdelay MOVLW d'67' ; on for 1880(66=1881) CALL ledON MOVLW d'78' ; off for 780µS CALL uSdelay MOVLW d'35' ; on for 984 (nearest to 980) CALL ledON MOVLW d'164' ; off for 1640µS - 2ND BIG OFF TIME CALL uSdelay MOVLW d'35' ; on for 984 (nearest to 980) CALL ledON MOVLW d'78' ; off for 780µS CALL uSdelay MOVLW d'67' ; on for 1880(66=1881) big on time CALL ledON MOVLW d'78' ; off for 780µS CALL uSdelay MOVLW d'35' ; on for 984 (nearest to 980) CALL ledON ; Data sending is complete ;========================================================================================== ; LEDON ROUTINE ; LED on routine that turns the led on/off at 38 Khz for X uS before return ledON ;MOVLW d'25' ; This is where the code starts when ledON is called MOVWF delayCounter ; That value set in W is copied into delayCounter irONloop bsf PORTA, 2 ; Switch on pin2 on PORT A (The IR LED) MOVLW d'3' ; W = 3 (tuned timing routine) MOVWF delayValue ; delayValue = W innerloop7 DECFSZ delayValue,F ; delayValue = delayValue- 1, if delayValue=0,skip the next instruction GOTO innerloop7 bcf PORTA, 2 ; Switch off pin2 on PORT A (The IR LED) MOVLW d'4' ; W = 4 MOVWF delayValue ; delayValue = W innerloop8 DECFSZ delayValue,F GOTO innerloop8 ; This is a precisely tuned delay routine that has become a pain in the Ass DECFSZ delayCounter,F GOTO irONloop return ;**************************************************************** ;uSdelay - a value of 10 = 100uS at 4Mhz ;**************************************************************** uSdelay ; Precision delay routine starts here (as per the description above) MOVWF delayCounter ;LET delayCounter = W outerloop MOVLW 0x2 ;Innerloop to loop twice MOVWF delayValue ;LET delayValuer = W (which has the value 2) innerloop99 DECFSZ delayValue,F ;delayValue = delayValue - 1, if delayValue = 0, skip the next instruction GOTO innerloop99 ; DECFSZ delayCounter,F ;delayCounter = delayCounter - 1, if delayCounter=0,skip the next instruction GOTO outerloop RETURN ;***********************************************
Downloads
The final code goes a step further than the example above and includes a delay timer at the start. This beeps a sounder while waiting for the TV or monitor to become ready for the power-on signal.
I developed the code using Labcenter Proteus, which I purchased sometime in the early 2000s. If you have this software, you can load my work directly into it using the Proteus download above.
Circuit