The Raspberry Pi Foundation's Hackspace Issue 44 https://hackspace.raspberrypi.org/issues/44 had a really interesting article. This code is based on code found in HACKSPACE #44 p98,p100 simpleterm using webpage. do view source to see how it works.
use cntrl-shift-I to open developer tools to see console.log() output >
When using MODBUS send a command and await a response.
frame = [address, function, start_high, start_low, count_high, count_low], CRC16_low, CRC16_high
1,4,0,1,0,1,0x60,0x0A // worked: request temperature
1,4,0,2,0,1,0x90,0x0A // worked: request humidity
The modbus returns a stream of bytes, but not all at once. Aggregate them.
response: 1,4,2,th,tl, crc-l,crc-l
response: 1,4,2,hh,hl, crc-l,crc-l
paste the codes into the box below. It works out the CRC as each byte is added. If it includes the CRC,( CRC-low, CRC-H ) should get a 0x00 if all is okay.
Examples: 0x01,0x03,0x00,0x02,0x00,0x02, 0x65,0xCB 0x01,0x03,0x04,0x01,0xe6,0xff,0x9f, 0x1b,0xA0
output_crc
https://how2electronics.com/modbus-rtu-with-raspberry-pi-pico-micropython/ had a CRC function example.
Python example:-
def calculate_crc(frame):
crc = 0xFFFF
for pos in frame:
crc ^= pos
for _ in range(8):
if crc & 0x0001:
crc >>= 1
crc ^= 0xA001
else:
crc >>= 1
return crc
def construct_modbus_request(address, function, start_high, start_low, count_high, count_low):
frame = [address, function, start_high, start_low, count_high, count_low]
crc = calculate_crc(frame)
frame.append(crc & 0xFF) # CRC low byte
frame.append((crc >> 8) & 0xFF) # CRC high byte
return bytes(frame)
CRC16/MODBUS
x^16 + x^15 + x^2 + 1 = 0x18005 or bit reversed 0XA001.8
16 0x8005 0xFFFF 0x0000 true true Used in Modbus industrial protocol
uint16_t calc(uint8_t *packet, uint8_t size)
{
uint16_t crc_polynome = 0xa001;
uint16_t crc = 0xffff;
for (uint8_t j = 0; j < size; j++)
{
crc ^= packet[j];
for (uint8_t i = 0; i < 8; i++)
{
if (crc & 0x1)
{
crc >>= 1;
crc ^= crc_polynome;
}
else
{
crc >>= 1;
}
}
}
return crc;
}
This webpage helps https://www.simplymodbus.ca/ASCII.htm
CRC calc crc and lrc javascript have a go.
This is how to get the WebAPI serial to send the bytes to the MODBUS module.
//
async sendModBusTemp() {
//let bytes = new TextEncoder("utf-8").encode(text);
let bytes = new Uint8Array([ 1,4,0,1,0,1,0x60,0x0A ]); // worked:- request temperature
console.log( ":",bytes )
await this.writeUint8Array(bytes);
}
// bytes.toString() returns a Comma Separated Values list.
// let bytes = new Uint8Array( " 1,4,0,1,0,1, 0x60,0x0A ".split(",") );
// The bytes are sometimes received in multiple responses.
// Aggregate the responses to get the reponse
// This page aggregates the CSV list.
// It is possible to see the temperature in the response.
handleIncomingBytes(bytes) {
// we have some more bytes.
// console.log( typeof( bytes ), bytes.length )
// bytes is of type Uint8Array, the toString() converts to comma seperated values (CVS)
// I cannot work out how to append the bytes, so convert to CSV and append
numberOfBytesReceived += bytes.length
ipBuffer = ( ipBuffer+"," )+ bytes.toString()
console.log( "IP:len:",bytes.length," :", bytes.toString() )
// The example code converted the bytes stream to text and decode multi-byte characters.
//var text = new TextDecoder("utf-8").decode(bytes);
//this.handleIncomingText(text);
// we could pass in the number of bytes received since command sent
// We could only hold back sending text until enough bytes have been received
// We could await the full response before reporting it
// report length and bytes as a CSV list
// the modbus command is
this.handleIncomingText( "length:" +numberOfBytesReceived+", bytes: "+ipBuffer )
return;
}
https://www.modbustools.com/modbus.html#function03 - modbus info that could be useful.
USB to RS485 Communication Module Adapter CH343G Chip Driver Converter New
This module has LEDs that flash when it sends a command and gets a response.

I brought a temperature humidity sensor, and the following information found on an Ali Express Advert helped get a response from it. I powered the module from a modified USB lead plugged into a PowerBank.
Ali Express Advert with really useful information about the XY-MD01 module
This web page provides enough information to trigger a response from the XY-MD01 module.