[SOLVED] UART.read and UART.write not cooperating with modbus slave



  • Hi,
    I'm having trouble getting my LoPy to work as a simple modbus RTU master.

    I have the LoPy UART1 connected to a weather station via a max3232 RS232<-->TTL converter (set to 3.3V TTL). I've then tried the following code:

    from machine import UART
    import struct
    import time
    port = UART(1,19200)
    port.init(19200,bits=8,parity=UART.EVEN,stop=1)
    while 1:
    port.write(b'\x01\x03\x00\x03\x00\x16\x34\x04')
    print('data sent')
    time.sleep(0.5)
    for i in range(5000):
    if port.any() > 0:
    print(port.read(port.any()))
    time.sleep_ms(1)

    This sends a modbus request to read holding registers. The message is taken directly from a Python script that I have working on my PC using serial.Serial, so I'm confident that the message should be correct. I've used a serial sniffer to confirm that the message sent by the LoPy looks the same as that sent from the PC using serial.Serial.

    Loopback tests have worked and I can UART.read/UART.write data to/from the LoPy from/to my PC as expected, so I'm confident that the baud rate, parity, etc. are all good.

    However, when I run this script, nothing is read. So the message is either being written incorrectly (incorrect timing, possibly?) or the read command is just not picking up the incoming data...

    I've tried setting the weather station and LoPy up with different baud rates, parity, etc. with no luck - I never see any data come in. I also tried sending data continuously from the weather station (every second), and still can't read anything on the LoPy, which makes me think it must be an issue with UART.read (or it's compatibility with the weather station somehow...). Python on my PC can read the continuous stream of data using Serial.read.

    Any help would be great! I've been banging my head against this for a few days now...



  • @alg cool, glad to hear that your problem is solved :-)



  • Problem solved thanks to @daniel 's suggestion. Playing around with the oscilloscope, I realised that the TX and RX wires on the RS232-side of the max3232 converter needed to be swapped (even though the old configuration had worked for weather station-PC communication and LoPy-PC communication).
    I have data coming in fine now. :)



  • @daniel OK, I found an oscilloscope, and can see the request but no response from the weather station. So there must be an issue in the message itself, or UART settings, I guess?
    Could it be the change from \x16\x34 to \x164 mentioned below?



  • There isn't any flow control that I'm aware of - I'm only using RX and TX wires, with the default 'flow' in UART (which I think is 0?). I don't have a logic analyser at hand, but I'll try to borrow one today and will report back with results.
    One thing that I have noticed is that micropython interprets b'\x01\x03\x00\x03\x00\x16\x34\x04' as b'\x01\x03\x00\x03\x00\x164\x04'. I don't have very much experience with hex, binary, etc. - are these two messages equivalent?



  • @alg do you have some kind of flow control enabled on the bus? Maybe the LoPy is not setting the control pin properly? Can you hook up a logic analyser and check that data is actually flowing into the LoPy?



Pycom on Twitter