Replicating the MicroPython REPL across an HC-05 HC-06 Bluetooth link
Get link
Facebook
X
Pinterest
Email
Other Apps
I wanted to run the MicroPython REPL and program code on an RP2040 over Bluetooth so I could avoid wires and still get into the device if there was some kind of Wi-Fi issue. Read here or watch the video.
Bluetooth supports virtual serial ports in the same way USB devices can. RFCOMM-supporting Bluetooth adapters act as a transparent serial bridge between some RX/TX serial ports and the virtual serial port on a PC, phone, or another device type. Virtual serial ports appear on PCs after a successful pairing. We can open the Bluetooth RFCOMM virtual serial port to read and write data as if it was serial over USB or a physical port.
We can leave that as a bare serial connection for data/commands or we can enable the MicroPython REPL to do programming, troubleshooting, and data transfer. The truly awesome RP2040 has two software UARTS in addition to the USB serial connection. We can connect either of these to serial RX/TX pairs to an RFCOMM-capable Bluetooth adapter virtually connecting the PC to the RX/TX pair. That is simple as shown below.
As of 2023/02 The RP2 MicroPython dupterm is only available on Pico-W because of a code switch in the underlying header file. I'm not sure why they put this restriction in when the Pico has two open UARTs that could be duplicated too.
Example System Topology
The Pico RP2040 is connected to the PC via USB. We can interact with the REPL over the USB connection's USB Serial virtual port.
The RP2040 Pico and the USB HC-05/06 Bluetooth are connected via UART0 RX/TX wiring. The HC Bluetooth adapter is then paired with a PC over the PC's Bluetooth adapter. This creates a virtual serial port on the 2nd PC. We can interact with the REPL on the Bluetooth's virtual serial port using something like Putty or Screen.
P0 and P1 are connected to UART0 and the HC-05/06
Videos
Data Rates
Our data path is as shown
PC - USB - SBC USB - SBC - UART0 - HC-05/HC-06 - Bluetooth - PC
My super cheap 10-year-old HC-05 won't go into command mode to change the data rate. This means that it is stuck and 9600 bits per second.
My super cheap 10 year old HC-06 was easy to reconfigure to a higher serial rate. That is the data rate between the Pico and the Bluetooth device is essentially the max serial throughput for this setup.
HC-05/06 default speed is 9600
HC-05/06 can be reconfigured up to 115200. So do that!
The Virtual USB serial ports can be configured to run at 115200
Serial over USB
Serial over Bluetooth
The HC-05/06 output buffer can be overrun if left at the default speed with a lot of output like when replicating too much data. Ex: the console help() command shown elsewhere.
Changing the Data Rate and Replicating the REPL
Two lines of MicroPython code change the data rate for UART0 and duplicate the REPL terminal to the configured UART. You can test this at the REPL prompt. Put the code in `boot.py` to enable the Bluetooth REPL on startup.
Default Speed
This code configures the RP2040 UART0 for an HC-05/06 at the default speed of 9600.
import machine
import os
u = machine.UART(0, baudrate=9600)
os.dupterm(u)
After Changing the HC-05/HC-06 UART Speed
This code configures the RP2040 UART0 for an HC-05/06 that has had its serial speed set to 115200 (BAUD8)
import machine
import os
u = machine.UART(0, baudrate=115200)
os.dupterm(u)
dupterm() causes all console traffic to be replicated across the UART and the USB connection. This lets me program/interact with a Pico that isn't on the Wi-Fi network or is on a Wi-Fi network I don't have access.
You can use the Bluetooth connection as a pure data UART without an OTA REPL. In that case, you just need to set the UART speed and write code to directly read/write with it.
Buffer Overrun
The Bluetooth RX channel can be overrun if its data rate is not high enough. This isn't an issue with low data rates or small bursts that fit within the buffer.. Ex: output os.uname() elsewhere in this blog.
The following screen image shows two terminal windows, one bound to the USB virtual serial port and one bound to a 9600 bps Bluetooth connection. You may be able to see that a longer result like the output of help() in the REPL is truncated over the COM27 Bluetooth link in the upper right. There are way more lines of output on the USB-connected connection. You can mitigate this by increasing the data rate on the RX/TX pins of the USB device.
The left-hand terminal is in VS Code over the USB connection. The upper right terminal is the Putty connected to the Bluetooth serial port.
I changed the data rate for my HC-06 device to 115200 and the buffer overrun issue went away for the sample help() command.
Change your Default Data Rate
Change the default data rate and the default name of your HC-05/06 device.
Changing the default name lets you reliably connect to more than one device via Bluetooth.
Changing the data rate lets you lower the risk of buffer overrun.
Geezers using Putty on Windows
I use Putty to connect to the virtual serial ports on my Windows PC This is my Putty configuration for a Bluetooth Serial connection coming in on COM7 with an HC-06 whose data rate has been changed to 115200.
Pairing
Pair with the PC like any other device. The cheap ones all have the same name: linvor
Chang my name - Change my name
You are better off changing the name of your module to something other than the default. There are plenty of guides about how to change the module name.
Input and Output are Replicated
Both terminals are hooked to the REPL. What ever is entered in one shows up on the other. Whatever is returned from the Pico or other board is replicated on both serial channels and will show up in both terminal windows.
References
This Instructable blog article helped me realize that my HC-05 modules were actually HC-06 modules because my modules were always in AT limited capability AT command mode.
In freemansoft/Flutter-AdaptiveCards a demonstration Dart chat server hands a question to a local Ollama model. It asks for the answer as Adaptive Card JSON, a strict, closed-vocabulary schema that a Flutter client renders as interactive UI rather than as text. A set of probes in that repository puts identical questions to different local models. Probe context_fill_probe.dart produced every figure in this article. It runs 25 test cases, one question each. A test case passes only if the reply used an element type that would answer the question. Every other probe in that set had been asking into a nearly empty window. That window holds a system prompt, one question, and at most a short canned exchange showing the model the shape of a card. The literature documents that a long context degrades model behavior. What it does to a model's adherence to an output format is measured less often. The test probe simulates a long conversation by filling three q...
I do a lot of my development and configuration via ssh into my Raspberry Pi Zero over the RNDIS connection. Some models of the Raspberry PIs can be configured with gadget drivers that let the Raspberry pi emulate different devices when plugged into computers via USB. My favorite gadget is the network profile that makes a Raspberry Pi look like an RNDIS-attached network device. All types of network services travel over an RNDIS device without knowing it is a USB hardware connection. A Raspberry Pi shows up as a Remote NDIS (RNDIS) device when you plug the Pi into a PC or Mac via a USB cable. The gadget in the Windows Device Manager picture shows this RNDIS Gadget connectivity between a Windows machine and a Raspberry Pi. The Problem Windows 11 and Windows 10 no longer auto-installs the RNDIS driver that makes magic happen. Windows recognizes that the Raspberry Pi is some type of generic USB COM device. Manually running W indows Update or Upd...
In freemansoft/Flutter-AdaptiveCards a demonstration Dart chat server asks a local Ollama model for an answer as Adaptive Card JSON. That is a strict, closed-vocabulary schema, which a Flutter app renders as interactive UI. The card system prompt that describes the element vocabulary is about 3,755 tokens. The chat server replays up to ten prior exchanges on every turn. Each Ollama runner keeps a prefix cache, so a request whose opening tokens match an earlier one does not have to process them again. Ollama 0.33.3 and later report, in prompt_eval_cached_count , how many of a reply's prompt tokens came from that cache. A chat server can read from that field how much of each prompt the cache served and where it missed. Every reading below comes from ModelBehavior.md , the lab notebook in that repository. A new conversation reuses a cached system prompt on some models and not on others. The split follows how the model stores its context. A pr...