Duo Pinball controller CAN be made to work on a Windows tablet

Alex Atkin UK

New member
Sep 26, 2012
300
0
HOWTO: Use the Duo Pinball controller on PC

I bought a Duo Pinball for £12.59 off Amazon, a fairly simple Bluetooth device that simulates two flipper buttons and a plunger. Its normally only compatible with Pinball HD Collection on iPad but as I have just bought an Asus Transformer Book T100TA and it runs Pinball Arcade well enough (with everything off except texture filtering, which still looks better than on PS Vita), I figured it was worth a look.

I am happy to report that with my very first functional C# application I have made the Duo Pinball compatible with PC. Its mapped to left/right shift for the flipper buttons and space bar for the ball launcher.

While the plunger is technically only digital (its just pressing and releasing a button) what actually happens is pulling down on the plunger presses the space bar, after releasing the plunger it hits a button internally that triggers releasing of the space bar. This feels surprisingly authentic as it means the ball is hit at exactly the time you would expect it to in relation to the plunger returning to its home position.

Tips:
Map space bar to Menu Select in keyboard configuration in Pinball Arcade. That way when you get a hiscore you can select the letters with the flipper and okay them with the plunger.

Drawbacks:
Lack of nudge support, as naturally the iPad would have this built-in but as far as I am aware neither Pinball Arcade or Pinball FX2 support motion sensors on PC, even if you have a tablet with motion sensors in it like I do. (I could be wrong as I noticed Pinball FX2 does support touch screen controls, even the Steam version)

Known Bugs (keyboard version):
If the application is closed while a button/plunger is still being held down then that key will remain held. Simply press the corresponding key on your keyboard a few times or (if possible) launch the application again and the key presses will be reset.

Known Bugs (Xbox Controller version):
I had one occasion where I was playing Pinball FX3 Windows Store version and when it lost the controller it wouldn't find it again without relaunching the game. Not had this happen on Steam version.

On rare occasions the flippers can stick or fail to register.

Analog plunger doesn't register that well if you try to be slow and precise, it doesn't seem to release properly. Although this might actually be a bug with Pinball FX3 as I've experienced the same when using a controller where letting go doesn't react as if I let go of the plunger and so doesn't hit the ball hard enough to launch.

Changelog:
1.0 (2013-12-30) - Initial release

1.1 (2014-01-03) - Typo fixed where it said "Flippers Released" instead of "Pressed" when you held both fippers.

Added code to automatically reconnect after 280 seconds idle as Duo Pinball goes to sleep after this time.

Added code to check carrier on the serial port so it automatically tries to reconnect if you go out of range of bluetooth or replace the batteries.

1.2 (2014-01-04) - Added icon and window title.

1.3 (2021-12-13) - Switched to VigEm Xbox 360 Controller emulation enabling analog plunger support.

Download:
Download from my website. You will need .NET Framework 4.8 installed.
 
Last edited:

Shaneus

New member
Mar 26, 2012
1,221
0
Wow, that's pretty great! How does the controller itself feel?

Do you know if the plunger registers an analogue signal (even if your wrapper can't translate it)? Opens up a whole new possibility of controllers if it does... even if it's just hacking the thing to bits so you can make something more substantial with a combination of controllers. I believe at that price it's a steal for an analogue-digital plunger!
 

Alex Atkin UK

New member
Sep 26, 2012
300
0
I think the controller feels quite nice actually, they seem to have used nice mechanical key clicks for the buttons so it feels authentic to my untrained fingers.

The plunger reports 64 levels as you pull it further, this is already reported in the application. Its a little more complicated physically hacking it though as the detection internally is done via IR LEDs with the top of plunger being white foam for reflectivity and to give that nice soft bounce.

From the videos I have seen there is some lag on the official iPad game but I wonder if that is actually a fault with the game rather than the controller? Its impossible to guess if it would "feel" right but I don't perceive any lag on the flipper which some people have reported on the iPad game.

I have just updated the build to v1.1 where it now goes into a reconnection loop if left idle for 280 seconds (after which Duo Pinball goes into power save mode) or the carrier on the serial port is dropped. The latter should mean if the batteries run down you can replace them without having to re-launch the application. It does take over 20 seconds for the carrier to actually be dropped though so it still might be quicker to do so.
 
Last edited:

Critic

New member
Jan 4, 2014
2
0
I think the controller feels quite nice actually, they seem to have used nice mechanical key clicks for the buttons so it feels authentic to my untrained fingers.

The plunger reports 64 levels as you pull it further, this is already reported in the application. Its a little more complicated physically hacking it though as the detection internally is done via IR LEDs with the top of plunger being white foam for reflectivity and to give that nice soft bounce.

From the videos I have seen there is some lag on the official iPad game but I wonder if that is actually a fault with the game rather than the controller? Its impossible to guess if it would "feel" right but I don't perceive any lag on the flipper which some people have reported on the iPad game.

I have just updated the build to v1.1 where it now goes into a reconnection loop if left idle for 280 seconds (after which Duo Pinball goes into power save mode) or the carrier on the serial port is dropped. The latter should mean if the batteries run down you can replace them without having to re-launch the application. It does take over 20 seconds for the carrier to actually be dropped though so it still might be quicker to do so.

Would this work on PC? I am getting really into PA and have been looking for a better way to control it - I have been considering the x-arcade, but this seems much better suited due to it's size. If not, does anyone have any suggestions as to where | could get something like this: http://www.ntekgaming.com/pinball-wizard.php - at a reasonable price?

Thanks! Critic

*edit* Ah, upon reading it again I see the post states it works on both PC and tablet. Whoops! I will be very strongly considering grabbing one of these! The only thing keeping me away is the fact that it's battery powered however. If anyone has any other suggestions, I would still love to hear them. Thanks again!
 
Last edited:

Alex Atkin UK

New member
Sep 26, 2012
300
0
In fact it ONLY works on PC. When I refer to tablet I mean only a full blown Windows tablet. It will not work on Windows RT tablets as its a desktop application (and so is Pinball Arcade for that matter).

Like I said though, a drawback is that there is no way to nudge as this controller is designed for iPad where you could use either the touch screen or motion sensors for nudge. But considering how cheap you can get them now, I think its still worth it for more casual play.

I was wondering about the battery situation myself as with it being three AA batteries that is VERY close to USB voltage. I believe sticking a silicon diode in series with a USB supply should drop the voltage low enough.
 
Last edited:

oldredfox

New member
Jan 9, 2014
3
0
Awesome work. =)

I picked up a Windows 8.1 tablet early in December. I've always wanted to build a virtual pinball cabinet and decided it would be perfect to use for it. I'm planning on using a spare 23" monitor I have laying around as play field and making a charging mount area where the scoreboard would go for the tablet to sit. Just before Christmas, I was tempted by the $10 price of the Duo Pinball controller and thought I'd take my chances at trying to get it to work. Figured that I could remove the flipper buttons and run longer wires and remount them to the proper position on the cabinet. But as soon as I got it in, got caught up in holiday stuff and it's been sitting in my to do pile. Made my day to see that you got it up and working in Windows.

Your remapper works great. Looking forward to xbox controller emulation and configuration abilities. I run a few different pinball programs and one of them uses the enter key instead of space for the plunger (space does forward nudge) and the game doesn't offer the ability to remap the key config in game. Is there any chance I could convince you to compile a 2nd build of the app with the plunger mapped to the enter key? Ideally, it would great to see an editable file (or GUI) for choosing what is bound to what, but I'm sure you've got a lot of stuff you're working on and I appreciate what you've already manage to do.
 

Alex Atkin UK

New member
Sep 26, 2012
300
0
As requested, this build should use return/enter instead of space for the plunger.

Just beware, I originally was going to use this mapping but switched to space as I realised its a lot more problematic if you close/crash the application with the plunger held as that means enter gets stuck in the pressed position. I may look into the option for key remapping at some point and even if/when I get joypad emulation working it could be useful to be able to toggle between keyboard/joypad mode for different games.
 

oldredfox

New member
Jan 9, 2014
3
0
Thanks for that quick build. =) It's nice to see a discount/close out piece of hardware get a cool second life thanks to your work.

My C programming is pretty weak, PASCAL is pretty much my main language of choice for coding. I'm guessing right now you have it set to start pressing the key when the plunger is pulled back and then release it when it is back all the way in. Just a random idea for implementation: since there are 64 levels of where the plunger is at, you could try something like not pressing the key when the plunger is pulled back. Instead, set a variable based off the current location, then when drops to zero, trigger a keypress for set amount of time relative to the last value of the plunger. If set to look for a drop to zero in under a second as the trigger, this would allow for you to be able to make subtle adjustments to find the sweet spot for any given table before releasing the plunger to trigger the ball launch. This might give it a real table feel and reduce the odds of a crash/closing the app from causing any issues.
 
Last edited:

Alex Atkin UK

New member
Sep 26, 2012
300
0
I'm not sure that would work as each pinball game triggers the plunger at different speeds. It also would be rather counter-intuitive to be trying to judge the ideal plunger strength based on the Duo Pinball plunger position, especially for games you may have learnt to play on other platforms so know where the on-screen plunger needs to be.

As you can see in My Devices on the left, I have played on various different devices so using the on-screen plunger position is kinda essential. Also playing on a tablet, if I REALLY am in the mood for precise plunger strength I just use the touch screen. ;)

I was looking into simulating dragging the mouse but that runs into problems as the coordinates are relative to the screen resolution, which the application will only know the desktop resolution not what the game may be running at.
 
Last edited:

Zeph

New member
Oct 2, 2014
2
0
I bought a Duo Pinball for £12.59 off Amazon, a fairly simple Bluetooth device that simulates two flipper buttons and a plunger. Its normally only compatible with Pinball HD Collection on iPad but as I have just bought an Asus Transformer Book T100TA and it runs Pinball Arcade well enough (with everything off except texture filtering, which still looks better than on PS Vita), I figured it was worth a look.

I am happy to report that with my very first functional C# application I have made the Duo Pinball compatible with PC. Its mapped to left/right shift for the flipper buttons and space bar for the ball launcher.

Could you share anything about how you connected to the Duo Pinball and interpreted data from it?
 

Alex Atkin UK

New member
Sep 26, 2012
300
0
DuoPinball just presents itself as a serial port, at which point it was fairly simple to figure out what each piece of data it sent represented.

The whole program is relatively short, simple and probably doing something fundamentally wrong as I am not at all familiar with coding for Windows. ;)

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using WindowsInput;

namespace Duo_Pinball
{
    public partial class Form1 : Form
    {
        string serialport = null;
        int plungerval = 0;

        public Form1()
        {
            InitializeComponent();
        }

        public void Form1_Load(object sender, EventArgs e)
        {            
        }

        public void ConnectSerial()
        {
            ResetLog();
            if (String.IsNullOrEmpty(serialport))
            {
                UpdateStatus("Searching for Duo Pinball, please wait...");
                serialport = null;
                try
                {
                    ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT DeviceID,PNPDeviceID,Caption from Win32_SerialPort");
                    foreach (ManagementObject queryObj in searcher.Get())
                    {
                        UpdateLog(queryObj["DeviceID"].ToString() + "\t" + queryObj["Caption"].ToString());
                        //Search for the DuoPin VID/PID string 
                        if (queryObj["PNPDeviceID"].ToString().Contains("VID&00010039_PID&5035"))
                        {
                            serialport = queryObj["DeviceID"].ToString();
                            UpdateStatus("Paired on " + queryObj["Caption"].ToString());
                            UpdateLog("Duo Pinball found paired to "+serialport);
                            break;
                        }
                    }
                }
                catch (ManagementException error)
                {
                    UpdateLog("Unable to read list of COM ports from WMI: " + error.Message);
                }
            }

            if (String.IsNullOrEmpty(serialport))
            {
                UpdateLog("Unable to find Duo Pinball COM port, please ensure it is paired with Bluetooth before launching this application.");
            }
            else
            {
                SerialPort mySerialPort = new SerialPort(serialport);
                mySerialPort.BaudRate = 9600;
                mySerialPort.Parity = Parity.None;
                mySerialPort.StopBits = StopBits.One;
                mySerialPort.DataBits = 8;
                mySerialPort.Handshake = Handshake.None;
                mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
                try
                {
                    UpdateLog("Opening serial port "+serialport);
                    mySerialPort.Open();
                    ButtonText("Reconnect");
                    UpdateLog("Duo Pinball should now be working, you can see if the buttons are working or not above.\rIn games the flippers are mapped to left and right shift, the plunger button is mapped to Enter.  Analog plunger is not (yet) supported.");
                }
                catch
                {
                    UpdateLog("Unable to open serial port, please ensure Duo Pinball is awake and in range and try again.\rIf this happens and it took a long time to find the Duo Pinball COM port it often means the controller has locked up, try removing and re-inserting the batteries.");
                    ButtonText("Retry");
                }
            }
        }

        public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            string indata = sp.ReadExisting();
            char[] CharArray = indata.ToCharArray();
            byte[] ByteArray = new byte[CharArray.Length];
            // Convert ASCII string to HEX
            for (int i = 0; i < CharArray.Length; i++)
            {
                ByteArray[i] = Convert.ToByte(CharArray[i]);
                ByteArray[i] += 0x30;
            }
            string outdata = "";
            for (int i = 0; i < CharArray.Length; i++)
            {
                outdata += ByteArray[i] + " ";
            }

            // If the first two digits are correct then interpret the command
            if (ByteArray.Length > 3 && ByteArray[0] == 138 && ByteArray[1] == 111)
            {
                if (ByteArray[2] == 49)
                {
                    // Flippers
                    if (ByteArray[3] == 48)
                    {
                        // Flippers Released
                        InputSimulator.SimulateKeyUp(VirtualKeyCode.LSHIFT);
                        InputSimulator.SimulateKeyUp(VirtualKeyCode.RSHIFT);
                        LeftFlipper(false);
                        RightFlipper(false);
                    }
                    else if (ByteArray[3] == 49)
                    {
                        // Left Flipper
                        InputSimulator.SimulateKeyDown(VirtualKeyCode.LSHIFT);
                        InputSimulator.SimulateKeyUp(VirtualKeyCode.RSHIFT);
                        LeftFlipper(true);
                        RightFlipper(false);
                    }
                    else if (ByteArray[3] == 50)
                    {
                        // Right Flipper
                        InputSimulator.SimulateKeyUp(VirtualKeyCode.LSHIFT);
                        InputSimulator.SimulateKeyDown(VirtualKeyCode.RSHIFT);
                        LeftFlipper(false);
                        RightFlipper(true);
                    }
                    else if (ByteArray[3] == 51)
                    {
                        // Both Flippers
                        InputSimulator.SimulateKeyDown(VirtualKeyCode.LSHIFT);
                        InputSimulator.SimulateKeyDown(VirtualKeyCode.RSHIFT);
                        LeftFlipper(true);
                        RightFlipper(true);
                    }
                }
                else if (ByteArray[2] == 50)
                {
                    if (ByteArray[5] == 49)
                    {
                        // Ball Launcher Button
                        Plunger(0);
                        if (plungerval != 0)
                        {
                            plungerval = 0;
                            InputSimulator.SimulateKeyPress(VirtualKeyCode.RETURN);
                        }
                    }
                    else
                    {
                        plungerval = ByteArray[3] - 47;
                        Plunger(plungerval);
                    }
                }
                else
                {
                    UpdateLog("Unknown Command: "+outdata+" ignored.");
                }
            }
            else
            {
                UpdateLog("Garbage received: " + outdata + " ignored.");
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ConnectSerial();
        }
    }
}

Its so incredibly simple that its a shame Pinball Arcade doesn't support it natively so the plunger worked properly.
 
Last edited:

Biff

New member
Sep 18, 2012
1,175
0
Interesting price structure.

Amazon.de -> New 19.99 - 51.12 EUR
Amazon.co.uk -> New 9.95 - 49.99 GBP
Amazon.com -> New 3.38 - 106.59 USD

duo.jpg
 

Zeph

New member
Oct 2, 2014
2
0
Thanks for that tip, I've ordered one.

BTW, it was $3.38 on the Amazon product page (which had been up for a while), but showed as $54.99 in the cart - apparently the same vendor had raised the price dramatically in that time. But other vendors had it for under $4 so I just had to delete and find another vendor. I had some other expensive things in my shopping cart so I almost didn't notice - glad I didn't just click and order!
 

Alex Atkin UK

New member
Sep 26, 2012
300
0
Just be warned, if you are the kind of player that uses nudge there is NO support for that. Also as mentioned, the plunger merely works by holding space then letting go, so its not technically analog but you can learn to time it. Its definitely more for casual play as on very very rare occasions it can miss a button press.

Personally I find the pros vastly outnumber the cons, as I am useless at nudging anyway.

For me the game plays better on my tablet in 768p (that needs things like ball reflections and AA turned off) due to being in portrait with the screen more pinball table angled, than on my home PC at 1080p with everything turned on in portrait, but NOT angled.
 

Cuddlebuddie928

New member
Feb 16, 2013
12
0
The whole program is relatively short, simple and probably doing something fundamentally wrong as I am not at all familiar with coding for Windows. ;)

I quickly glanced over the code that you posted and noticed a few resource leaks. ManagementObjectSearcher and SerialPort implement IDisposable and need to be cleaned up.
 

Alex Atkin UK

New member
Sep 26, 2012
300
0
I quickly glanced over the code that you posted and noticed a few resource leaks. ManagementObjectSearcher and SerialPort implement IDisposable and need to be cleaned up.

I'm not surprised, its mostly just a copy/paste from example code hacked to the point where it works. Microsoft documentation is both extensive and bloody confusing for beginners.

I couldn't even get it to work if I tried it in Windowed mode as I did want the keys to be configurable and naturally have the controller detection/emulation and GUI run in their own threads so they don't slow each other down. That was WAY beyond what I could understand from just browsing the C# documentation though. ;)
 

Alex Atkin UK

New member
Sep 26, 2012
300
0
Is anyone on the forum who is still around familiar with C# and can help me make one last push to get this working with Xbox 360 controller emulation?

I have everything necessary to get it working (I think) but I have a huge blind spot for object oriented programming that is preventing me from figuring out how to get the event handler triggered when a command from the DuoPinball is detected able to access the object for the controller emulator.

I quickly glanced over the code that you posted and noticed a few resource leaks. ManagementObjectSearcher and SerialPort implement IDisposable and need to be cleaned up.

I'd also like to fix this.
 

Alex Atkin UK

New member
Sep 26, 2012
300
0
So I got help over on the Linus Tech Tips forums and sorted this out.

Still wrapping my head around the resource leaks but in the meantime have a new build based on VigEm to simulate an Xbox 360 controller instead of key presses.

This does expose some limitations with the Duo Pinball, the analog plunger doesn't quite work right if you try to be slow and precise, its not hitting the ball hard enough when you let go in FX3. If you just pull and let go, it seems fine, so maybe something you can adjust to.
 
Last edited:

Members online

No members online now.

Members online

No members online now.
Top