Search code examples
pythonbluetoothmodbus

Python Bluetooth MODBUS RTU


I am attempting to create a python application that is able to communicate over Bluetooth with my DPS3005 power supply module. I found this GitHub repository which implements what I wish to do however it utilises the now deprecated rfcomm connect rfcomm0 XX:XX:XX:XX:XX:XX command.

I believe I should be able to achieve the same functionality using Bluetooth sockets in python and have written the following code:

# ------------------------------ Imports modules ----------------------------- #
import bluetooth
import time
import struct

# ----------------------------- Program Constants ---------------------------- #
DEVICE_ADDRESS = "98:DA:20:01:13:09"
DEVICE_PORT = 1

# ------------------------ Connect to bluetooth device ----------------------- #
sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
sock.connect((DEVICE_ADDRESS,DEVICE_PORT))
print("Connected to device!")

time.sleep(0.005)

# ------------------------ Attempt to send data packet ----------------------- #
# Set voltage to 21v
req = struct.pack('10B',
                    0x01, #Start Bit
                    0x01, #Slave Address
                    0x06, #Function Code (0x06 = Write Single Register)
                    0x00, 0x00, #Register Address (0x0000 = Voltage Set Register)
                    0x08, 0x34, #Register Value (0x0834 = 21.00v)
                    0xFB, 0xB2, #CRC Checksum values
                    0x01 #End Bit
                    )

print("TX: (%s)" % req)

sock.send(req)
print("Data Sent!")

# ----------------------------- Close connection ----------------------------- #
sock.close()

I used this document provided by the manufacturer to try and understand how I need to structure my message to the device however it does not appear to understand my request.

I am quite new to working with communications in this low-level way and I would like to ask if such a transmission is in accordance with the MODBUS RTU specification pictured below and specifically what the start and stop bits should be.

Clippings from afore mentioned specification document: enter image description here and Voltage Set Example

Many thanks for any suggestions and help!


Solution

  • Thank you very much 'Brits' for you comment. I managed to get my software working using this subroutine I wrote to calculate a CRC value according to the provided specification.

    # ----------------------- Calculate the CRC Check Value ---------------------- #
    def calcCRC(data):
        register = 0xFFFF
    
        for byte in data:
            register ^= byte
            for i in range(8):
                lsb = register & 1
                register = register >> 1
                if lsb:
                    register ^= 0xA001
            
        return register & 0xff, register >> 8 #Return the higher and lower bytes