empowering creative people

Videos / How to use Bluetooth Controllers with Python on Raspberry Pi

If you’ve used the RetroPie operating system before, you’ll know how easy it is to integrate USB and Bluetooth gamepads as controllers. But let’s say you’ve got a robot that you want to control with a joystick, or in my case, I’m building an LED Matrix to use for retro games and I want to use the awesome 8Bitdo controllers for it. Well, it’s not quite as simple as connecting it and watching the magic happen.

Search Videos

Related Content



Hey guys, how are you going, Sam here from Core Electronics, and today we're going to take a look at how you can use game pads, game controllers either Bluetooth or USB ones in your code with Python. So if you've installed retro pie on your Raspberry Pi you'll know how easy it is to get started with both USB and Bluetooth game pads but if you want to use it to control your project that's just a Python script something like that which is what a lot of people use the Raspberry Pi for if they're building a robotics project you know a drone a monitor something like that it's a game control like this provides really good ready to go user input. I've got an 8BitDo Zero here because it's on my key ring so small I flipping love this thing it's so cool but it can be a little bit tricky knowing how to interpret those commands and turn them into user input data, inside of Python. So we're going to take a look at that now the first thing you're going to want to do on your PI is, of course, update it to the most current version of raspbian so I put that in there I've already got mine updated to save us some time so go ahead and do that if in doubt and then open up your terminal.

So I'm going to be using a Bluetooth device for the examples in this because the Bluetooth device is a bit more involved in the connection process the USB device you just plug in and every other step is the same. So I'll go through how to set this up with Bluetooth Bluetooth devices but if you're just using USB one then go ahead and skip ahead to the to the EV dev section.

So I'm gonna be using Bluetooth inside the terminal because I feel like it's a lot more intuitive maybe not intuitive but it's easier to understand what's going on in our Python script once we've done in the terminal and if you're not familiar with Terminal I encourage you to give it a go because it will make everything come together a lot more than just using the GUI it's a bit more powerful and it gives you these tools to use for your future projects you can just use the standard Bluetooth tools on the Pi you don't need anything fancy and the first thing we're going to do is launch the Bluetooth control in terminal here so we're just going to do

sudo Bluetooth CTL

Then enter and it's going to do a scan of nearby Bluetooth devices and this is just like activating the Bluetooth client in our terminal and we can keep entering in commands so if you've not got a fresh image of raspberry pi perhaps you've got Bluetooth turned off perhaps you know your config settings are going to be slightly different than a fresh version so we're going to enter a few commands to just ensure that it's on first we're going

Power on

you can see that succeeded, that's good then we're going to go

agent on

your registered make sure using the default agent two thumbs up that should be fairly straightforward. Now we're going to go scan, so we're going to rescan for Bluetooth devices you can do this one of two ways you can either scan it with it off and then turn your gamepad on and initiate another scan or you can just scan because most devices are going to give it you know the device name within the scan, now up in the tutorial, the written content, I put you know do a double scan because it's a safer method but I know that this an 8BitDo controller turns on and gives the device name anyway so turn that guy on and I'm entering it into the keyboard mode:

scan on

and then it's going to go through and do a scan of all of the available nearby Bluetooth controllers so I can see a couple of different couple of different Bluetooth devices at the moment and sometimes it may not actually pick up on it and this is depending on whether it's the on the Raspberry Pi side or the 8-bit-do side I have been informed its 8-bit Doe perhaps someone pointed out that you don't say a nintendoo you say Nintendo but if you're saying the word do it's also spelt do, 8-bit do, do so that's how we're going to say 8-bit do, deal with it. Now I can see it's finished scanning I've got device E4 and that's that it says there 8BitDo Zero gamepad which is good this is good we found it. Now what we need to do all to pair it is simply type pair and enter the device's unique address so in this case, im going


and it will come up attempting to pair, I can see the activity light on my 8BitDo controler there and a little dialog will pop up saying has requested pairing do you wish to accept this request, yes I do, successfully awesome awesome so now that changes to a solid blue and it will vary depending on you say that yeah it'll vary depending on what gamepad you have but in this case solid blue means connected, cool cool. USB devices plug them into the USB port easy as that's all there is to it hence why I'm using a Bluetooth one to go through the extra steps.

Alright now let's see if our device is communicating with our Raspberry Pi successfully with input devices like these their communications are stored in a folder so it's in the dev input folder that's coming up to spring even tell my hay fever is kicking in that's stored in the device input folder. So I'm just going to exit out this terminal for a sec what we're going to do is list the contents of that folder and we can see all of the different input devices that are there and then we can actually read out that data but there are a few more steps required because it's not actually quite that easy so I'm just going to go

LS dev/input

which is the folder (helps if you can spell input correctly) and it's going to list all the devices here. Now I can see event 0 1 2 3 mice Mouse are available there now if I turn this guy off, I hold start, let's get that command again you see it's acting as the keyboard there. List it again so I don't have event 3 so I know that event 3 is going to be this device so I'm going to go ahead and turn that back on and it's going to flash because it takes a few seconds to pair, now once that has gone solid, there we go, list again, Event 3. so this is event 3, so that's important, make a note of that.

So now we can actually see the communication stream, the raw data, by going

cat /dev/input event 3

So I'm using event three and when we press it we get garbled junk, garbled junk! Now garbled junk, in this case, is actually really good we like garbled junk for this because it shows that there is data there although we can't read it. So what we need to do is use a tool called EV dev which is going to allow us to read that data and use it within our Python script.

So again I'm just going to close this so we don't have to look at that anymore probably good clear a bit I'm a little lazy so you're going to need to install a couple more tools so follow the tools listed there in the written tutorial, you want those ones so install those which just makes sure you've got all of your Python packages on there as well as installing EV dev now once you have that I pre installed it again to save some time but hopefully just get a bunch of successes it's important to do it in that order because if you're trying to install EV dev before the Python steps it's going to give you an error so we're going to now run a test script that comes with EV dev, so in Python we're going to the following directory:


I could have pre-written this out and auto-filled, but hey all right. Now the script is called EB test.py and when we run this it asks for the event which would like to test with the event of us so going a met three enter so listening for events when we press buttons really usable data we've got time stamps there we can see the type of input it is the key the code and the value and some other things along with the synchronization events which you don't really need to pay attention to but we can see it's working it's working that's good it's very good.

So going to close that and we're gonna get mapping the controller inside of Python all right so open up your Python, are you, I'm going to make that a bit bigger how do i do that, preferences options configure trying to up that font a bit so that you guys can actually read it, and I can read it, that should be good, ah heaps better. There we go, that should be much more readable.

So there are three scripts which we're going to be going through, it's going to open up, what have we got there, the raw input. Now this script is really straightforward what we're doing is we're importing EV dev into our script then we're setting up a new object, our gamepad, as input device and that's part of the EV dev module it grabs all the data from that file where we mentioned it's stored to start it prints out the device info for a gamepad and then the EV dev module takes care on this line I've actually just continuously looping and looking for that data so we don't have to use sections or loops it's all taken care of there.

And then we're going to print out, just categorized events which make it a little easier to understand. So once you've got that written out let's hit run and prompt you to save, when I press a button it gives me this same stream of events and data you can see how it's actually importing the characters because the particular mode I'm using for that 8-bit-Do controller is the keyboard mode which is really good because all of the event types are the same which we'll get to in a second rather than being all different like it is in the game pad mode so it just makes it a bit easier for the particular project I'm working on there's no cable there's no display so don't even need to worry about the, you know, that issue but that's all well and good.

So we're going to close that and so that is how you can determine the raw input which is really good so run that again and I'm going to just clear the screen I'm going to point out a couple of key things that we need to watch out for here. I'll drag that over there. So I'm going to press this and I can see that there are three different lines which been triggered for each event so an event is the press and then the release again and we're not to worry that's the device print up the top there, I'm going to complete that. So this is what we're looking for here that we've got event and then we've got the key event, all right, and there are two important bits of data.

So what you can be doing here is the next script we're actually going to go through and filter it through which is cool so we can filter out the event types and the codes. So I can see here that is event type it's a key event because it's acting as a keyboard which is just as I would expect and then here 36 I've got the event code so all of these can trigger events but if I press that it's going to give me a different event code then that would in the event type heaps of different event types relative, absolute, depending on what sort of input you're using.

So if I press this I can see its event code 46 which corresponds to key C, the Y button is event code 23 and there you go which is cool so make a note of those and draw out a bit of a sketch mapping all of your buttons to the event codes write those down because we're going to use them in the next, I guess the next config sketch, we're going to be finding out a bit more about our controller.

So again we're going to open up, where's my other sketch, well that's the wrong one, I definitely should have made that a little bigger, but that's okay I'm having a filter there we go it's what we want! Okay now exactly the same but we've added one extra line of code which is this if statement here what this does is it filters out the event types you could see there we had events we had synchronizing events and then we've got the key events and it filters it via event type so if using a different controller it may use absolute events in which case you need "abs" or "rel" you can check out some more of those on the EV dev website I will put a link into the tutorial so just click on that and follow that. But what this is going to do is just reduce the noise you know all of that data and make it a little bit easier to see so when I press it and they get to events for the press and then the release of each button which is really cool so I can see a lot more clearly, I've got the code 23, the values so 1 or 0.

Now you'll notice as well that I'm just printing the event not categorize event and that's because when you categorize the main difference in the data read out instead of being 1 or 0 it classifies it up or down, so sort of streamlines things a bit and that can be good, but because it's in our script it's a lot easier to look for the 1 and the 0 than it is for a string so we eye 1 and 0 is heaps easier to work with when you're just talking about digital control so that's what we're gonna work with. Alright, so I can see now you go to 46 32 18 33 start, they all do stuff and they will correspond to the keyboard inputs which again you can work around or you can disable if you want but it's not it's not too big of a deal.

So I'm gonna kill that again, so, by now we've got our event types we've got all of the event codes and the event values which are really just you know ones and zeros they're pretty straightforward but if you had analog joysticks, for example, you need to work out some more detailed mapping for those so I'm gonna go here and I've got a script here which just uses some simple mapping so I've got some variables here which I've gotten those codes in and filled those in so you can see my A, X, Y, up, down and so on and so forth, exactly the same thing I'm filtering it by the event type key and I'm also filtering it with the event value being that I only wanted to activate on a press, not on release. You could add some more logic in there if you wanted to use that release or you want to use the hold feature that'll come into play as well but you know it works pretty well, and you can see X, Y, B, A, up, down, left, right, triggers, triggers start select and I actually wanted to leave the keyboard input in here because I think it actually highlights what the Bluetooth control is doing it's really easy to look at Bluetooth device and think well they just magically send data and somehow we can interpret it but know it's a keyboard and you can follow this exact same concept with an actual keyboard if you didn't want to use the built-in you know Python handling then you could use EVDev, it works for any standard input device which is really really neat and from there you can just help I guess you can use it however you like so if you wanted to control a robot for example then every time you registered that left press you could just correspond that to a motor drive or at the moment I'm building a big, big giant pixel matrix game so I'm going to be using this same part of this same script and control some arcade figures, whether it's snake or you know a Pong type thing whatever it is I'm going to be using it for that and I just wanted to put this tutorial together because it I did a little bit of searching around on the easiest way to do this and there's a lot of not miss information but just definitely not easy ways to do this and I feel like this is really really easy anyone should be able to follow this and then implement it into their Python script so I hope you guys have enjoyed this check out some more of our Raspberry Pi tutorials hopefully I'll have this project up soon which will be awesome and check out more of our tutorials at CoreElectronics.com.au. I'll see you next time guys.