Tuesday, February 9, 2021

Pair HC-05 (Master & Slave) using Raspberry Pi Pico/MicroPython

Last exercise "pair HC-05 and HC-06 Bluetooth 2.0 Modules", it's another exercise pair two HC-05 modules as master and slave using Raspberry Pi Pico/MicroPython.

Connetion:

Please notice that the default BAUD (after AT+ORGL command) is 38400. Most factory preset it 9600 baud in order to make it compatible with HC-06. In this exercise, it's reset to 38400.

For Slave:
ROLE = 0

For Master:
ROLE = 1

mPico_pair_HC-05s_20210210a.py
import uos
import machine
import utime

"""
Raspberry Pi Pico/MicroPython
Pair two HC-05s as Slave & Master
Slave HC-05 connected to UART0
Master HC-05 connected to UART1
CMODE=1 - connect any address

default UART
UART(0, baudrate=9600, bits=8, parity=None, stop=1, tx=0, rx=1)
UART(1, baudrate=115200, bits=8, parity=None, stop=1, tx=4, rx=5)

Connection:
RPi Pico UART0  Slave HC-05
GP0(pin 1)      RX
GP1(pin 2)      TX

RPi Pico UART1  Master HC-05
GP4(pin 6)      RX
GP5(pin 7)      TX

To enter AT-Command mode-
HC05:
Press & Hold the onboard button while power on.

ROLE  0 = Slave
      1 = Master
      2 = Slave-loop
CMODE 0 = connect fixed address
      1 = connect any address
      2 = Slave-loop
"""

print(uos.uname())
uart0 = machine.UART(0,baudrate=38400)  #at-command
uart1 = machine.UART(1,baudrate=38400)  #at-comand

#2 sec timeout is arbitrarily chosen
def sendCMD_waitResp(cmd, uart=uart0, timeout=2000):
    print("CMD: " + cmd)
    uart.write(cmd)
    waitResp(uart, timeout)
    print()
    
def waitResp(uart=uart0, timeout=2000):
    prvMills = utime.ticks_ms()
    resp = b""
    while (utime.ticks_ms()-prvMills)<timeout:
        if uart.any():
            resp = b"".join([resp, uart.read(1)])
    print(resp)

#indicate program started visually
led_onboard = machine.Pin(25, machine.Pin.OUT)
led_onboard.value(0)     # onboard LED OFF/ON for 0.5/1.0 sec
utime.sleep(0.5)
led_onboard.value(1)
utime.sleep(1.0)
led_onboard.value(0)

print(uart0)
print(uart1)

print("- uart0 -")
waitResp()
sendCMD_waitResp("AT\r\n")
sendCMD_waitResp("AT+ORGL\r\n")           #Restore default setting
sendCMD_waitResp("AT+VERSION\r\n")
sendCMD_waitResp("AT+UART?\r\n")
#sendCMD_waitResp("AT+UART=9600,0,0\r\n")  #9600 baud, 1 stop, parity=none
#sendCMD_waitResp("AT+UART?\r\n")
sendCMD_waitResp("AT+PSWD?\r\n")
sendCMD_waitResp("AT+PSWD=4321\r\n")      #Set PIN = "4321"
sendCMD_waitResp("AT+PSWD?\r\n")
sendCMD_waitResp("AT+ROLE?\r\n")
sendCMD_waitResp("AT+ROLE=0\r\n")         #Slave
sendCMD_waitResp("AT+ROLE?\r\n")
sendCMD_waitResp("AT+CMODE?\r\n")
sendCMD_waitResp("AT+CMODE=1\r\n")        #connect any address
sendCMD_waitResp("AT+CMODE?\r\n")
sendCMD_waitResp("AT+NAME?\r\n")
sendCMD_waitResp("AT+NAME=HC-05S\r\n")
sendCMD_waitResp("AT+NAME?\r\n")
sendCMD_waitResp("AT+ADDR?\r\n")

print("- uart1 -")
waitResp(uart1)
sendCMD_waitResp("AT\r\n", uart1)
sendCMD_waitResp("AT+ORGL\r\n", uart1)           #Restore default setting
sendCMD_waitResp("AT+VERSION\r\n", uart1)
sendCMD_waitResp("AT+UART?\r\n", uart1)
#sendCMD_waitResp("AT+UART=9600,0,0\r\n", uart1)  #9600 baud, 1 stop, parity=none
#sendCMD_waitResp("AT+UART?\r\n", uart1)
sendCMD_waitResp("AT+PSWD?\r\n", uart1)
sendCMD_waitResp("AT+PSWD=4321\r\n", uart1)      #Set PIN = "4321"
sendCMD_waitResp("AT+PSWD?\r\n", uart1)
sendCMD_waitResp("AT+ROLE?\r\n", uart1)
sendCMD_waitResp("AT+ROLE=1\r\n", uart1)         #Master
sendCMD_waitResp("AT+ROLE?\r\n", uart1)
sendCMD_waitResp("AT+CMODE?\r\n", uart1)
sendCMD_waitResp("AT+CMODE=1\r\n", uart1)        #connect any address
sendCMD_waitResp("AT+CMODE?\r\n", uart1)
sendCMD_waitResp("AT+NAME?\r\n", uart1)
sendCMD_waitResp("AT+NAME=HC-05M\r\n", uart1)
sendCMD_waitResp("AT+NAME?\r\n", uart1)
sendCMD_waitResp("AT+ADDR?\r\n", uart1)

print("Done")

The test program is same as in last exercise, except baud rate = 38400.

mpyPico_comm_38400_20210210a.py
import uos
import machine
import utime

"""
Raspberry Pi Pico/MicroPython to test bluetooth/Sertal
bi-direction commnunication between HC-05/HC-06

default UART
UART(0, baudrate=9600, bits=8, parity=None, stop=1, tx=0, rx=1)
UART(1, baudrate=115200, bits=8, parity=None, stop=1, tx=4, rx=5)

both set to 9600 baud

Connection:
RPi Pico UART0  HC-05/06
GP0(pin 1)      RX
GP1(pin 2)      TX

RPi Pico UART1  HC-05/06 
GP4(pin 6)      RX
GP5(pin 7)      TX

To enter normal mode:
HC-05:
Just power on WITHOUT pressing the onboard button
HC-06:
Just power on

"""

print(uos.uname())
uart0 = machine.UART(0,baudrate=38400)
uart1 = machine.UART(1,baudrate=38400)
    
def clartBuf(uart=uart0):
    print("Clear UART buffer "+ str(uart))
    while uart.any():
        print(uart.read(1))

#indicate program started visually
led_onboard = machine.Pin(25, machine.Pin.OUT)
led_onboard.value(0)     # onboard LED OFF/ON for 0.5/1.0 sec
utime.sleep(0.5)
led_onboard.value(1)
utime.sleep(1.0)
led_onboard.value(0)

print(uart0)
print(uart1)

clartBuf()
clartBuf(uart1)

#Master HC-05 send a dummy bytes in lower case
uart1.write("1234567890abcdefghijklmnopqrstuvwxyz\r\n")

#Slave HC-05 convert received bytes to upper case, and echo back.
#if you see in REPL a byte in lower case, it is send from Master to Slave,
#in upper case, it is echo back from Slave to Master.
prvMills = utime.ticks_ms()
bUart0 = b''
bUart1 = b''
while (utime.ticks_ms()-prvMills)<3000:
    if uart0.any():
        b0 = uart0.read(1)
        bUart0 = bUart0 + b0
        print("UART(0): " + b0.decode('utf-8'))
        uart0.write(b0.upper().decode('utf-8'))
    if uart1.any():
        b1 = uart1.read(1)
        bUart1 = bUart1 + b1
        print("UART(1): " + b1.decode('utf-8'))

print("UART0: ")
print(bUart0)
print("UART1: ")
print(bUart1)

print("===========")
if bUart0 == bUart1.lower():
    print("MATCH")
else:
    print("UN-MATCH!!!")
print("===========")
    
print("- Done -")
In the above code, CMODE is 1, connect any address. Such that the master will connect to any HC-05 or HC-06 with matched PIN. If you want the master connect to a specified slave only, you can set CMODE=0, connect fix address. and bind the slave address to master using AT+BIND= command.

mPico_bind_HC-05s_20210210a.py
import uos
import machine
import utime

"""
Raspberry Pi Pico/MicroPython
Pair two HC-05s as Slave & Master
Slave HC-05 connected to UART0
Master HC-05 connected to UART1
CMODE=0 - connect fix address
and bind Slave address to Master

default UART
UART(0, baudrate=9600, bits=8, parity=None, stop=1, tx=0, rx=1)
UART(1, baudrate=115200, bits=8, parity=None, stop=1, tx=4, rx=5)

Connection:
RPi Pico UART0  Slave HC-05
GP0(pin 1)      RX
GP1(pin 2)      TX

RPi Pico UART1  Master HC-06 
GP4(pin 6)      RX
GP5(pin 7)      TX

To enter AT-Command mode-
HC05:
Press & Hold the onboard button while power on.

ROLE  0 = Slave
      1 = Master
      2 = Slave-loop
CMODE 0 = connect fixed address
      1 = connect any address
      2 = Slave-loop
"""

print(uos.uname())
uart0 = machine.UART(0,baudrate=38400)  #at-command
uart1 = machine.UART(1,baudrate=38400)  #at-comand

#2 sec timeout is arbitrarily chosen
def sendCMD_waitResp(cmd, uart=uart0, timeout=2000):
    print("CMD: " + cmd)
    uart.write(cmd)
    waitResp(uart, timeout)
    print()
    
def waitResp(uart=uart0, timeout=2000):
    prvMills = utime.ticks_ms()
    resp = b""
    while (utime.ticks_ms()-prvMills)<timeout:
        if uart.any():
            resp = b"".join([resp, uart.read(1)])
    print(resp)

#indicate program started visually
led_onboard = machine.Pin(25, machine.Pin.OUT)
led_onboard.value(0)     # onboard LED OFF/ON for 0.5/1.0 sec
utime.sleep(0.5)
led_onboard.value(1)
utime.sleep(1.0)
led_onboard.value(0)

print(uart0)
print(uart1)

print("- uart0 -")
waitResp()
sendCMD_waitResp("AT\r\n")
sendCMD_waitResp("AT+ORGL\r\n")           #Restore default setting
sendCMD_waitResp("AT+VERSION\r\n")
sendCMD_waitResp("AT+UART?\r\n")
#sendCMD_waitResp("AT+UART=9600,0,0\r\n")  #9600 baud, 1 stop, parity=none
#sendCMD_waitResp("AT+UART?\r\n")
sendCMD_waitResp("AT+PSWD?\r\n")
sendCMD_waitResp("AT+PSWD=4321\r\n")      #Set PIN = "4321"
sendCMD_waitResp("AT+PSWD?\r\n")
sendCMD_waitResp("AT+ROLE?\r\n")
sendCMD_waitResp("AT+ROLE=0\r\n")         #Slave
sendCMD_waitResp("AT+ROLE?\r\n")
sendCMD_waitResp("AT+CMODE?\r\n")
sendCMD_waitResp("AT+CMODE=0\r\n")        #connect fix address
#sendCMD_waitResp("AT+CMODE=1\r\n")        #connect any address
sendCMD_waitResp("AT+CMODE?\r\n")
sendCMD_waitResp("AT+NAME?\r\n")
sendCMD_waitResp("AT+NAME=HC-05S\r\n")
sendCMD_waitResp("AT+NAME?\r\n")
sendCMD_waitResp("AT+ADDR?\r\n")

#get Slave HC-05 address
uart0.write("AT+ADDR?\r\n")
bindAddr = uart0.readline()
print(bindAddr)
print(type(bindAddr))
print(len(bindAddr))
#Convert the return bytes in b'+ADDR:2014:12:20016\r\n' form
#to string of "xxxx,xx,xxxxxx" form.
#It's used to bind address in Master HC-05
bindAddr = bindAddr[6:len(bindAddr)-2]
print(bindAddr)
strBindAddr = bindAddr.decode('utf-8')
strBindAddr = strBindAddr.replace(":", ",")
print(strBindAddr)

print("- uart1 -")
waitResp(uart1)
sendCMD_waitResp("AT\r\n", uart1)
sendCMD_waitResp("AT+ORGL\r\n", uart1)           #Restore default setting
sendCMD_waitResp("AT+VERSION\r\n", uart1)
sendCMD_waitResp("AT+UART?\r\n", uart1)
#sendCMD_waitResp("AT+UART=9600,0,0\r\n", uart1)  #9600 baud, 1 stop, parity=none
#sendCMD_waitResp("AT+UART?\r\n", uart1)
sendCMD_waitResp("AT+PSWD?\r\n", uart1)
sendCMD_waitResp("AT+PSWD=4321\r\n", uart1)      #Set PIN = "4321"
sendCMD_waitResp("AT+PSWD?\r\n", uart1)
sendCMD_waitResp("AT+ROLE?\r\n", uart1)
sendCMD_waitResp("AT+ROLE=1\r\n", uart1)         #Master
sendCMD_waitResp("AT+ROLE?\r\n", uart1)
sendCMD_waitResp("AT+CMODE?\r\n", uart1)
sendCMD_waitResp("AT+CMODE=0\r\n", uart1)        #connect fix address
#sendCMD_waitResp("AT+CMODE=1\r\n", uart1)        #connect any address
sendCMD_waitResp("AT+CMODE?\r\n", uart1)
sendCMD_waitResp("AT+NAME?\r\n", uart1)
sendCMD_waitResp("AT+NAME=HC-05M\r\n", uart1)
sendCMD_waitResp("AT+NAME?\r\n", uart1)
sendCMD_waitResp("AT+ADDR?\r\n", uart1)

#Bind Slave address to Master
sendCMD_waitResp("AT+BIND=" + strBindAddr + "\r\n", uart1)
sendCMD_waitResp("AT+BIND?\r\n", uart1)

#Deliberately bind not-matched address to Slave
sendCMD_waitResp("AT+BIND=" + "0000,11,23456" + "\r\n")
sendCMD_waitResp("AT+BIND?\r\n")

print("Done")


No comments: