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 1,4,0,1,0,2, 0x90,0x0A // worked: request humidity 1,4,0,1,0,2, 0x20,0x0b // worked: request both 1,3,1,1,0,4, 0x14,0x35 // read the four holding Address 1,3,1,1,0,1 // device Address 1,3,1,2,0,1 // baudrate: 0:9600,1:14400,2:19200 1,3,1,3,0,1 // Temp correction 0.1 1,3,1,4,0,1 // Humidity correction 0.1 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
not connected
used:
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 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.