ArduinoModbus icon indicating copy to clipboard operation
ArduinoModbus copied to clipboard

RP2040: RX works, but always times out

Open pomplesiegel opened this issue 2 years ago • 12 comments

Hello! Great library. I'm trying to get up and running on a RP2040 (raspberry pi pico) to make a very low cost solution using this library and RS485.

For hardware I am using:

I am able to successfully send commands from a host to the RP2040, but they always time out, even though the value is received by the node. This is the same whether we're talking about a holding register, coil, etc...

To simplify the debug process, below is MVP code to replicate the issue using this hardware:

#include <Arduino.h>
#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
#include <ArduinoModbus.h>

RS485Class _RS485(Serial1, 0, 6, 1); //middle value (DE) is driver enable - need custom pinout

void setup() 
{
  Serial.begin(115200);

  //slave id 1
  if ( !ModbusRTUServer.begin(_RS485,1,9600,SERIAL_8N1) ) 
  {
    Serial.println("Failed to start Modbus RTU Server!");
    while (1);
  }

  // configure 1 coil at address 1
  ModbusRTUServer.configureCoils(1,1);
}

void loop() 
{
  // poll for Modbus RTU requests
  if (ModbusRTUServer.poll() )
  {
    Serial.println("Received request!"); 
    Serial.println( "Coil value: " + String(ModbusRTUServer.coilRead(1)) );
  }
}

When calling from a host (whether python or a GUI-based program like ModbusMechanic) the result is the same. My node can see the command from the host, but the response is never seen by the host. It always times out.

See resulting serial output from node below, when I send a 0, followed by a 1 for the coil value from a host to the node:

Received request!
Coil value: 0
Received request!
Coil value: 1

NOTE: to get the code to compile I had to change a couple default pin values within RS485.h, just because the RP2040 doesn't have an A5 or A6:

#ifndef RS485_DEFAULT_DE_PIN
#define RS485_DEFAULT_DE_PIN 6
#define RS485_DEFAULT_RE_PIN 1
#endif

I'm wondering if this could be an issue with the software serial on the RP2040's compatibility with the library? Looking forward to others' thoughts!

Thank you! Michael

pomplesiegel avatar Mar 14 '23 18:03 pomplesiegel

In the meantime, what are supported chipsets to use the library with? I can compare the behavior between this and the RP2040.

Thank you!

pomplesiegel avatar Mar 15 '23 12:03 pomplesiegel

Confirmed working on an Adafruit Grand Central M4 Express (SAMD51). This appears to be a RP2040 (raspberry pi pico) issue. Any ideas how to get it working on that particular platform, as it's quite common now?

pomplesiegel avatar Mar 16 '23 01:03 pomplesiegel

Hi @facchinm and @aentinger, hope you're doing well! From your perspective, any idea on how much work it would take to get the library running correctly on the RP2040? Thank you very much!

pomplesiegel avatar Mar 20 '23 12:03 pomplesiegel

Mostly well, thank you :bow: I don't have any RS485 slave available, but I'll try and take a look into this, mkay?

aentinger avatar Mar 20 '23 13:03 aentinger

@aentinger great, thank you very much!

pomplesiegel avatar Mar 20 '23 13:03 pomplesiegel

Hi! I've started to use this library on raspberry pi pico with my custom board. There is half duplex rs485 and de pin and re pin is the same (gp18). In file pins_arduino.h I've defined another serial (Serial2) with my pins (gp16 and gp17) The problem I've encountered was "Checksum incorrect". I've looked on osciloscope that de/re pin change before serial transmit all data out. So far I've added 5ms delay after flush fcn in RS485.cpp in endTransmission() and it works well ;) Hope it helps

Edit: In RS485.h there is acctually appriopiate define for delay: RS485_DEFAULT_POST_DELAY and now I've change it to 5000 for 19200 baudrate

martinez20m avatar Mar 21 '23 10:03 martinez20m

@martinez20m, very cool!! Thank you for the post. Would you mind sharing a gist or inline code of your actual changes?

pomplesiegel avatar Mar 21 '23 13:03 pomplesiegel

We'd also be taking a PR with both PIN definitions and other related changes :grin: :bow: .

aentinger avatar Mar 24 '23 05:03 aentinger

@martinez20m, hope you're doing well! Would you mind sharing some code, since you have this working on a RP2040? No worries if it's just informal snippets.

Thank you!

pomplesiegel avatar Mar 27 '23 15:03 pomplesiegel

Hi @pomplesiegel, thanks, quite good;) Here are my changes: https://gist.github.com/martinez20m/2597dd791224aa96e883bbdbef6921ef

martinez20m avatar Mar 27 '23 18:03 martinez20m

Hi @pomplesiegel ☕ 👋

Did those files help you with your problem? If you've got any changes to extend this libraries support for RP2040, please feel free to contribute a PR 🙇 .

aentinger avatar Mar 30 '23 04:03 aentinger

Hi @martinez20m and @aentinger, thank you so much for your help! Indeed, these changes worked well. I found that the only changes I actually needed to make were within RS485.h. I'm not sure what would be the best approach to keep to the existing style here. The two changes which need to occur in order to have this running correctly on a Feather RP2040 or Raspi Pico are for

  • the platform detection to work correctly in these cases for default pin definitions
  • Changing the RS485_DEFAULT_POST_DELAY (and possibly the RS485_DEFAULT_PRE_DELAY) to match the timing for the platform.

Thankfully the only changes necessary are within RS485.h! However, this is a library dependency, so I'm not sure what the best approach is here...

To address this:

  1. When using Serial2 the default pins on my RP2040 feather are TX = 0, RX = 1, and since it is nearby DE = 6. How should we best define this in RS485.h for compatibility and auto-detection? I'm currently just hard-coding the values in this file.
  2. I am currently using the settings below for pre-post delay and it's working well on my RP2040! I imagine this should be platform-dependent as well? Not sure why we require the extra delay on this platform, but it is indeed necessary.
#define RS485_DEFAULT_PRE_DELAY 100
#define RS485_DEFAULT_POST_DELAY 1000

Looking forward to your collective thoughts. Thank you again for finding the fix!! Thank you!

pomplesiegel avatar Mar 30 '23 15:03 pomplesiegel