You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Arduino Modbus RTU传输JSON:Python端uint16_t与字符串互转求助

Got it, let's break this down for you. I see you're doing a fun (if unorthodox) workaround shoving JSON into Modbus registers—let's get that data conversion sorted out properly.

1. Converting uint16_t Register Data Back to JSON String (Python)

Your Arduino code packs two ASCII characters from the JSON string into each uint16_t register using word(json[i], json[i+1]), which treats the first character as the high byte and the second as the low byte (big-endian order). To reverse this in Python:

# Your received register data from minimalmodbus
received_regs = [31522, 26980, 30754, 14897, 13363, 12332, 8814, 30305, 27765, 25890, 14896, 11298, 29558, 24940, 30053, 8762, 8749, 13624, 11824, 12322]

def regs_to_json(register_data):
    json_chars = []
    for reg in register_data:
        # Convert each uint16_t to 2 bytes in big-endian order
        byte_pair = reg.to_bytes(2, byteorder='big')
        # Decode each byte to its ASCII character and collect
        json_chars.append(byte_pair[0].decode('ascii'))
        json_chars.append(byte_pair[1].decode('ascii'))
    # Join characters and strip any trailing null bytes (from unused registers)
    return ''.join(json_chars).rstrip('\x00')

# Test the conversion
original_json = regs_to_json(received_regs)
print(original_json)
# Output should be: {"idx":1430,"nvalue":0,"svalue":"-58.00"}

2. Converting a Python String to uint16_t Array for Modbus Transmission

To send a JSON string (or any string) from Python to your Arduino via Modbus, we reverse the packing process: take two characters at a time, convert each to their ASCII value, then combine them into a uint16_t (high byte first):

def json_to_regs(json_string):
    register_array = []
    # Pad string with a null byte if length is odd (to make pairs)
    if len(json_string) % 2 != 0:
        json_string += '\x00'
    # Process characters in pairs
    for i in range(0, len(json_string), 2):
        # Get ASCII values of the two characters
        high_byte = ord(json_string[i])
        low_byte = ord(json_string[i+1])
        # Combine into a uint16_t (shift high byte left by 8 bits, OR with low byte)
        register_val = (high_byte << 8) | low_byte
        register_array.append(register_val)
    return register_array

# Test the conversion with your original JSON
test_json = '{"idx":1430,"nvalue":0,"svalue":"-58.00"}'
converted_regs = json_to_regs(test_json)
print(converted_regs)
# Output should match the first 19 values of your received register data (since 38 chars = 19 registers)

Key Notes to Keep in Mind

  • Byte Order Matters: Always use big-endian (byteorder='big') when converting—this matches how Arduino's word() function packs the characters. Using little-endian will give you garbage text.
  • Unused Registers: Your Arduino exposes 100 registers, so Python may read trailing null values. The rstrip('\x00') in the first function cleans these up so your JSON is valid.
  • String Length Limits: Each register holds 2 characters, so your JSON can't be longer than 200 characters (for 100 registers). If you need longer strings, you'll have to split them across multiple read/write operations.
  • Modbus Best Practice: As you noted, this isn't how Modbus was designed. For production use, consider using standard register mappings or a protocol built for string/JSON data (like MQTT) instead.

内容的提问来源于stack exchange,提问作者martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:49:44