Description
I am using Esp32, MAX485 AND Sensor
while trying to read slave(Sensor) from read_holding_registers function
sending the frame correctly
b'\x08\x03\x00\x00\x00\x02\xc4\x92'
but the response receive is wrong
b'\xc2\xb0\xdc\xa4\xe6X\x7f'
Error reading Modbus registers: invalid response CRC
i had played with some of the delay but does not able to resolve the issue.
kindly help me to resolve the issue. Thanks in advance. In code I will attach what are the modification I tried
Reproduction steps
1.In issue#50,73, 75 i have read but doesn't get an idea how to fix my issue
2.
3.
...
MicroPython version
v1.23.0
MicroPython board
ESP32
MicroPython Modbus version
# e.g. v2.3.7
# use the following command to get the used version
import os
from umodbus import version
print('MicroPython infos:', os.uname())
print('Used micropthon-modbus version:', version.__version__)
Relevant log output
MPY: soft reboot
Used micropthon-modbus version: 2.3.7
User code
main.py
from umodbus.serial import Serial
from machine import Pin
from machine import UART
import time
# Define the pins for Modbus communication
rtu_pins = (Pin(17), Pin(18))
# Initialize the Modbus object
m = Serial(baudrate=9600, data_bits=8, stop_bits=1, parity=None, pins=rtu_pins, ctrl_pin=Pin(15), uart_id=2)
# Increase timeout for Modbus response
m._uart.init(timeout=2000) # Set UART timeout to 2000 ms (2 seconds)
# Function to read current die height
def readCurrentDieHeight():
slave_addr = const(0x08) # Modbus slave address (updated to 8)
starting_address = const(0x00) # Start reading from address 0x0000
register_quantity = const(2) # Read two registers (32-bit value)
# Try reading the holding registers
try:
time.sleep(0.2) # Small delay to give slave time to respond
register_values = m.read_holding_registers(slave_addr, starting_address, register_quantity, signed=False)
except Exception as e:
print(f"Error reading Modbus registers: {e}")
return False, 0.0
while True:
print("start")
success, die_height = readCurrentDieHeight()
In serial.py
# using _send function I had varied time.sleep_us(85) also eliminate +100 from sleep_time_us because my slave baud rate is 9600
def _send(self, modbus_pdu: bytes, slave_addr: int) -> None:
print("................trace send frame...................")
"""
Send Modbus frame via UART
If a flow control pin has been setup, it will be controlled accordingly
:param modbus_pdu: The modbus Protocol Data Unit
:type modbus_pdu: bytes
:param slave_addr: The slave address
:type slave_addr: int
"""
# modbus_adu: Modbus Application Data Unit
# consists of the Modbus PDU, with slave address prepended and checksum appended
modbus_adu = bytearray()
modbus_adu.append(slave_addr)
modbus_adu.extend(modbus_pdu)
modbus_adu.extend(self._calculate_crc16(modbus_adu))
print(modbus_adu)
if self._ctrlPin:
self._ctrlPin.on()
#print('on')
# wait until the control pin really changed
# 85-95us (ESP32 @ 160/240MHz)
#time.sleep_us(200)
time.sleep_us(85)
# the timing of this part is critical:
# - if we disable output too early,
# the command will not be received in full
# - if we disable output too late,
# the incoming response will lose some data at the beginning
# easiest to just wait for the bytes to be sent out on the wire
send_start_time = time.ticks_us()
#print(f"Send start time: {send_start_time}")
# 360-400us @ 9600-115200 baud (measured) (ESP32 @ 160/240MHz)
#print(f"control pin condition befor write: {self._ctrlPin.value()}")
self._uart.write(modbus_adu)
send_finish_time = time.ticks_us()
#print(f"Send finish time: {send_finish_time}")
if self._has_uart_flush:
self._uart.flush()
time.sleep_us(self._t1char)
else:
sleep_time_us = (
self._t1char * len(modbus_adu) - # total frame time in us
time.ticks_diff(send_finish_time, send_start_time)+
100 # only required at baudrates above 57600, but hey 100us
)
time.sleep_us(sleep_time_us)
if self._ctrlPin:
self._ctrlPin.off()
#print('off')
in _uart_read I didn't change anything and try to print the response which is wrong
def _uart_read(self) -> bytearray:
"""
Read incoming slave response from UART
:returns: Read content
:rtype: bytearray
"""
response = bytearray()
print("...........trace response frame inside _uart_read..........")
# TODO: use some kind of hint or user-configurable delay
# to determine this loop counter
for x in range(1, 120):
if self._uart.any():
# WiPy only
#response.extend(self._uart.readall())
response.extend(self._uart.read())
# variable length function codes may require multiple reads
if self._exit_read(response):
break
# wait for the maximum time between two frames
time.sleep_us(self._inter_frame_delay)
print(response)
return response
Additional informations
No response
Description
I am using Esp32, MAX485 AND Sensor
while trying to read slave(Sensor) from read_holding_registers function
sending the frame correctly
b'\x08\x03\x00\x00\x00\x02\xc4\x92'
but the response receive is wrong
b'\xc2\xb0\xdc\xa4\xe6X\x7f'
Error reading Modbus registers: invalid response CRC
i had played with some of the delay but does not able to resolve the issue.
kindly help me to resolve the issue. Thanks in advance. In code I will attach what are the modification I tried
Reproduction steps
1.In issue#50,73, 75 i have read but doesn't get an idea how to fix my issue
2.
3.
...
MicroPython version
v1.23.0
MicroPython board
ESP32
MicroPython Modbus version
Relevant log output
User code
Additional informations
No response