How to Make a Simple Bluetooth Scanner on Windows with Python

Proto Bioengineering
6 min readMar 15, 2023

--

Find all the smart gadgets in your area with a Windows computer and code.

Photo by Dan LeFebvre on Unsplash

Other versions of this article:

If you’re sitting at home or in your work office (the same for many people these days), you are surrounded by wireless Bluetooth devices that are all talking to each other at the speed of light. Perhaps you just bought one these particular devices (a smart lightbulb, smart oven, Arduino board, etc.) and want to try to connect to it and control it.

Whether you want to snoop on your neighborhood or eventually connect to your new smart gadget, the first step is to find these devices by making a Bluetooth scanner.

Note: This tutorial is for Bluetooth Low Energy (BLE), the most common type of Bluetooth in modern wearables and smart devices. Most headphones and older Bluetooth devices use Bluetooth Classic instead. Code that works for Bluetooth LE will not work for Bluetooth Classic devices.

A Bluetooth scanner is not a physical thing but a piece of code. It can run on your computer and find all the Bluetooth devices near you, and it’s only about 10 lines of Python.

This is possible, because Bluetooth devices are always sending out signals into the air saying, “My name is [Steve’s Smart Watch], and I want to connect!” Then other devices, like your laptop, can listen in on the broadcast like a radio. These signals are called “advertisements.”

Bluetooth devices are advertising that they’re available all the time, unless they’re already connected.

Our scanner will work by listening for these “I want to connect!” messages from every device in the area for 5–10 seconds, but instead of connecting to any of the devices, we’ll just write the info from those device’s advertisements to our computer screen.

This will be the output of the Bluetooth scanner that we code below.

Each line above is a Bluetooth addresses (2C:16:15:A4:B5:CC) and a name (Samsung AU8000 50 TV) for every Bluetooth device in our area (within ~100 meters). In upcoming tutorials, we will then add code to connect to these devices and actually start to control them. Note how not every device is nice enough to tell us its name (lots of None responses). Thankfully though, the address is enough to connect to it later.

Note: these device addresses are called “MAC addresses,” and they help wireless devices tell each other part. They’re like a permanent IP address baked into the hardware.

Let’s get started on the building the scanner.

Technical Requirements

  • Windows 10+
  • Python 3
  • Bleak (a Python Bluetooth LE library)
  • Bluetooth LE devices within 20–100 meters of you

Overall Steps to Making a Scanner

The code for the scanner is pretty simple:

import asyncio
from bleak import BleakScanner

async def main():
devices = await BleakScanner.discover()
for device in devices:
print(device)


asyncio.run(main())

That’s it. It starts a process that listens for Bluetooth LE devices‘ advertisements (their “I’m a Samsung Smart Oven, and I want to connect!” messages) and then prints them.

The most tedious parts are:

  • Installing Bleak (the Bluetooth Python library)
  • Understanding asyncio (though this is optional)

If you already understand asyncio and have Bleak installed, you can copy-paste the above code into a Python file and ignore the rest of this article.

But if you’re new to asyncio and Bleak…

How to Install Bleak

Bleak is a robust Python library that will help us find Bluetooth LE devices.

If you’re familiar with Pip, you can install Bleak with following and skip to the next section:

pip install bleak

If you’re not familiar Pip, it is the most popular package manager for Python and comes with most modern installs of Python 3. Pip is needed to install Bleak (and installing Pip will make all future Python tutorials that you do easier, since Pip is ubiquitous in the industry).

To check if you have Pip on your computer, open Command Prompt and type pip. If you have it, you’ll see a help menu.

If you don’t, you’ll get an error:

‘pip’ is not recognized as an internal or external command,
operable program or batch file.

To install Pip for Windows, run the following in Command Prompt:

py -m ensurepip --upgrade

If you’re having trouble installing Pip, check out Pip’s Installation page.

Now that Pip is installed, we can install Bleak in Command Prompt by running:

pip install bleak

Now, we can use Bleak in our Python code.

Writing Our Bluetooth Scanner

We’ll give you the full code and then explain its pieces:

# scanner.py

import asyncio
from bleak import BleakScanner

async def main():
devices = await BleakScanner.discover()
for device in devices:
print(device)


asyncio.run(main())

It’s only 10 lines of code.

The first thing that’s different from the average Python script is that we use asyncio, which includes async and await.

This is called asynchronous code, and it’s necessary when coding for Bluetooth devices. Asyncio is used to tell our code to start our Bleak scanner but then wait for messages from Bluetooth devices. Without asyncio, our code would start the Bleak scanner, realize it didn’t hear anything back in the 2 milliseconds it took to run, then immediately quit without any scan results.

Since Bluetooth (and wireless and networking in general) relies on waiting on other devices to do their thing, we use asynchronous code to tell our script to wait a bit before quitting or erroring out due to lack of Bluetooth responses. A full guide on Asyncio and asychronous code is available here.

What is inside main() is super simple:

devices = await BleakScanner.discover()
for device in devices:
print(device)

Above, we use BleakScanner ‘s discover() function to listen for Bluetooth advertisements and tell Python to wait a bit for this function to complete with await. Then we print them. And we’re done. It’s the easiest part.

The async/await keywords are not always intuitive. See Real Python’s guide on Asyncio for a more thorough explanation on why we use await above.

Running the Bluetooth Scanner

If you’re new to running Python scripts on your computer, check out our How to Make a Standalone Python Script article for both Mac OS and Windows.

To run the script:

  1. Save the scanner code from the previous section in a new file, scanner.py
  2. Run scanner.py from Command Prompt

The script will run for 5–10 seconds. The output will look like:

We see MAC addresses on the left (AB:CD:EF:12:34:56) and device names on the right.

Our simple Bluetooth LE scanner is complete.

Troubleshooting

  • If you get a device not found error or something similar, make sure your computer’s Bluetooth is on.
  • If your script prints nothing at all, try running it again. Sometimes, there are so few devices near you that your computer won’t pick up any signals.

Read More in Our eBook

We now have an e-book about how to control and stream real-time data from Bluetooth LE devices. Pay What You Want until June 1st, 2024 on Ko-fi!

Questions and Feedback

If you have questions or comments, email us at protobioengineering@gmail.com or message us on Instagram (@protobioengineering).

If you liked this article, consider supporting us by donating a coffee.

--

--

Proto Bioengineering
Proto Bioengineering

Written by Proto Bioengineering

Learn to code for science. “Everything simple is false. Everything complex is unusable.” — Paul Valery