Notes on BTM400_6B Bluetooth serial module

Intro

There are a ton of modules available that present a UART interface to a Bluetooth SPP connection.

There are good modules, like those from SeedStudio, the BlueSMiRF at Sparkfun but these are all relatively expensive.

There are loads of really cheap ones (under $10) on ebay, which look identical to the Seeed module. They are all based on the CSR BlueCore4 chipset and share a common PCB design. However, the firmware varies wildly between suppliers. Some have unreliable/buggy firmware, some won’t store configuration details in a non-volatile manner, some won’t even let you change the device name or baud rate and you’re stuck at 9600. Physically, the modules have USB and audio I/O but they are an artefact of the board being an OEM design for various things including headsets and USB dongles. I have another ‘traditional’ USB Bluetooth dongle that uses a module very similar to this, but whose firmware of course only presents a USB HCI.

My particular eBay gamble is a little better than this. It does higher baud rates, and claims to do an SPP Master mode, though I have no use for this so haven’t tested it. I found no details online about my particular module, so here’s what I found out by poking about:

Pinout

The module runs on a plain 3.3V supply. Basic connections are listed in the datasheet. Here I’m listing only what I used to talk to the module, rather than every GPIO. Pins are on a small 1.5mm pitch and numbered 1 to 34, counterclockwise with antenna at the top:

Pin: Function
1 UART TX (data out of module)
2 UART RX (data into module)
12 3.3V supply
13, 21, 22 Gnd
32 PIO9 ‘Connected’ LED output
34 PIO11 (Cmd/nData)

AT commands

The UART interface defaults to 38400 8N1. I haven’t tried other rates yet. The datasheet lists some AT commands that can be sent when PIO11 is high. Of these, the following were useful at first:

  • AT+ORGL (Factory reset; my module had some odd configuration)
  • AT+ROLE=0 (Set as slave)
  • AT+NAME=MattBT (Set the name seen on discovery)
  • AT+PSWD=1234 (Set the pairing PIN)
  • AT+VERSION? (Returns “+VERSION:1.0-20090818” on my module)
  • AT+INIT DOES NOT return OK/FAIL as per the datasheet

All commands seem to endlessly repeat the “OK” response until I hit enter again. This could be an artefact of my terminal config, though I haven’t seen this anywhere else.

After the above commands, all was good; the module even stores the name/PIN. But I couldn’t make it actually discoverable. :(

Turns out it isn’t until PIO11 is tied to Gnd. At that point you can search/pair & set up your SPP serial port on your host machine.

In this data mode, the UART is interfaced to the serial connection directly. There does not seem to be an escape to then query the connection, drop it, etc. For my application I want to connect this to a microcontroller and for it to be fairly autonomous, negotiating a reset procedure with a host when the connection comes up. On better modules with better firmware one can switch between serial and command mode ‘inline’, receive async notifications (along the lines of CONNECT messages) when the link comes up/down, etc.

A useful way to hook up to microcontroller

If you want connect/disconnect info and link control, your uC should drive the PIO11 pin and read from PIO9 in addition to wiring UART TXD/RXD for the data stream.

On init, verify the link (AT) and AT+RESET, with PIO11=1.

You can then set PIO11=0 to go into data mode. Another device can then pair and connect. Then watch PIO9; when this becomes high, the BT connection is up and you can send/receive data.

If PIO9 falls, you’ve lost the connection. Go back to start & wait for it to go high again.

If you want to disconnect the other end, raise PIO11. In command mode, the module seems to disconnect after a few seconds. You can disconnect quicker by sending AT+DISC. It may be possible to get stats (what?) on the connection by briefly going into command mode and back again without dropping the link.

Beware that in some circumstances I was seeing received data in command mode intermingled with the responses to the AT commands. It may be better to just raise PIO11 then wait until PIO9 falls, discarding all data until it does. THEN, AT command responss should be returned cleanly.

Misc

The module has a few GPIO pins that can be controlled via the AT command set. Some of the pins are dedicated to the command/data mode selection, connection status and ‘misc’ LEDs. Well, I don’t see any point to this unless you’re REALLY strapped for microcontroller IO pins (and even then, it’s faff to go back/forth into AT command mode and risk dropping the link!). There doesn’t seem to be a way to ‘blink’ these GPIO pins via the bluetooth link.