This content originally appeared on DEV Community and was authored by Daniel Guerrero
Long time ago, while researching ways to communicate through arduino, I found XBee modules, I was looking LoRa modules and this seems to fit so I got several of them
since the pins are smaller than regular later I got something called an XBee Explorer to connect to computer
I didn’t know at the time much about communication modules so didn’t do much research.
Recently I wanted to test the modules again, so I started doing the research.
The original XBee are devices from Zigbee that have a specific shape and specific pins, there are different options for modules, including LoRa, WiFi and Bluetooth
The pinout for the Xbee is this:
Source
Now, the modules I got are labeled “HC05” it turns those are actually a breakout board for a module called HC05 which is soldered to the pin, the module is this:
This module is also a breakout board to only use Serial capabilities
The pinout for the module is this:
Source
So contain a lot of pins that are not used in any board
The HC05 is a Bluetooth module that supports:
- Master / Slave Mode
- AT Commands
- Serial data transmission
So the module is a bit similar to the CH9143 except:
- Master mode can pair to any other device
- There is no USB support on HC05, only Serial
- You can set name of the device (among other things)
Connect to module
There is a lot of examples using Arduino to send Serial data, but in this case will be directly connected to computer with python.
So to connect to computer the XBee Explorer seems like a good solution, this contains an USB to Serial solution. The main issue is to enter into AT Commands you need to set AD0 / Key / BTN pin to VCC, otherwise the module will be in pairing and only sending / receiving data but can’t configure.
So a solution is to use a USB to Serial module and a breakout board (to convert 2mm pins from xbee to standard 2.5mm, an alternative could be to solder into the pin of the XBee Explorer), so the connection is:
- 3.3v -> VCC (PIN 1)
- RX -> Dout (PIN 2)
- TX -> Din (PIN 3)
- GND -> Dout (PIN 10)
- RTS -> AD0/Key/BTN (PIN 20)
The RTS is needed to enter into AT Mode, the serial code will send this signal to enter and leave after paired with other device.
To test you could use the app Serial Bluetooth Terminal
You can run with:
python3 ch05.py /dev/ttyACM1
The output will show some info about the device and wait until you pair the device in the app
Opening port: /dev/ttyACM1
Entering into AT mode
Sending AT... (checking if AT is enabled)
Response: ['ERROR:(0)']
AT+VERSION? ['+VERSION:2.0-20100601', 'OK']
device MAC XX:XX:XX:XX:XX:XX
AT+NAME?: [device name] H-C-2010-06-01
AT+ROLE?: [role, 0=Slave, 1=Master] ['+ROLE:0', 'OK']
AT+ADCN?: ['+ADCN:7', 'OK']
AT+MRAD? [connected device mac]: XX:XX:XX:XX:XX:XX
Pair to the device: H-C-2010-06-01 with password 1234
Waiting until is paired
Sending and receiving messages, press CTRL+C to stop
Creating background receiving thread
Sending ping 0
Sending ping 1
Sending ping 2
Sending ping 3
To pair in device, in the app select the three dots, then Devices
and later the H-C-2010-06-01
(note that name can be different like HC05
or similar but that will show in the console)
And on device will show the ping
Code:
import serial
import threading
import argparse
import time
from typing import List
keep_reading = True
def read_serial(ser: serial.Serial):
while keep_reading:
if ser.in_waiting > 0:
waiting = ser.in_waiting
line = ser.read(waiting).decode("utf-8").strip()
print("Serial Input: ", line)
def send_at_command(ser: serial.Serial, command: str) -> List[str]:
# send command
ser.write(f"{command}\r\n".encode("ascii"))
# read command back
data = []
while True:
line = ser.readline().decode("ascii").strip()
data.append(line)
if line == "OK" or "ERROR" in line:
break
return data
def clean_mac_response(mac: str) -> str:
# first part is always from response
mac = mac.split(":")[1:]
# make a single string
mac = "".join(mac)
# split into groups of 2 values
mac = [mac[i:i+2] for i in range(0, len(mac), 2)]
return ":".join(mac)
parser = argparse.ArgumentParser(prog="HC05 Uart Example")
parser.add_argument(
"serial_port",
help="Serial port like /dev/ttyACM0",
)
args = parser.parse_args()
params = {
"port": args.serial_port,
"baudrate": 38400,
"bytesize": serial.EIGHTBITS,
"parity": serial.PARITY_NONE,
"stopbits": serial.STOPBITS_ONE,
"timeout": 1,
}
print("Opening port: ", args.serial_port)
with serial.Serial(**params) as ser:
print("Entering into AT mode")
# this will set RTS=3.3v
ser.rts = False
time.sleep(0.1)
print("Sending AT... (checking if AT is enabled)")
print("Response: ", send_at_command(ser, "AT..."))
print("AT+VERSION?", send_at_command(ser, "AT+VERSION?"))
mac = send_at_command(ser, "AT+ADDR?")[0]
if "ERROR" not in mac:
print("device MAC", clean_mac_response(mac))
device_name = send_at_command(ser, "AT+NAME?")[0].replace("+NAME:", "")
print("AT+NAME?: [device name]", device_name)
print("AT+ROLE?: [role, 0=Slave, 1=Master]", send_at_command(ser, "AT+ROLE?"))
print("AT+ADCN?: ", send_at_command(ser, "AT+ADCN?"))
mac = send_at_command(ser, "AT+MRAD?")[0]
if "ERROR" not in mac:
print("AT+MRAD? [connected device mac]: ", clean_mac_response(mac))
# wait until is paired
print(f"Pair to the device: {device_name} with password 1234")
print("Waiting until is paired")
while True:
state = send_at_command(ser, "AT+STATE?")[0]
if state == "OK" or state == "+STATE:PAIRED" or state == "+STATE:CONNECTED":
break
else:
time.sleep(1)
# disable AT mode
ser.rts = True
# send and receive data
print("Sending and receiving messages, press CTRL+C to stop")
print("Creating background receiving thread")
thread_read = threading.Thread(target=read_serial, args=(ser,))
thread_read.start()
try:
send_idx = 0
while True:
print(f"Sending ping {send_idx}")
ser.write(f"UART PING {send_idx}\n".encode("ascii"))
send_idx += 1
time.sleep(1)
except KeyboardInterrupt:
pass
finally:
print("Finishing reading thread")
keep_reading = False
thread_read.join()
You will need pyserial
pip install pyserial
Final Notes
There are more commands in AT mode, here is a simple list of all: https://s3-sa-east-1.amazonaws.com/robocore-lojavirtual/709/HC-05_ATCommandSet.pdf
The HC05 module is actually a MCU BC417 with a flash memory with the firmware.
The MCU seems very capable of different things, including sending audio and controlling several GPIO and SPI, but there is no documentation about how to program it.
This content originally appeared on DEV Community and was authored by Daniel Guerrero