Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RP2040: RX works, but always times out #111

Open
pomplesiegel opened this issue Mar 14, 2023 · 12 comments
Open

RP2040: RX works, but always times out #111

pomplesiegel opened this issue Mar 14, 2023 · 12 comments
Labels
topic: code Related to content of the project itself type: enhancement Proposed improvement

Comments

@pomplesiegel
Copy link

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

@per1234 per1234 added the type: imperfection Perceived defect in any part of project label Mar 14, 2023
@pomplesiegel
Copy link
Author

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
Copy link
Author

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
Copy link
Author

pomplesiegel commented Mar 20, 2023

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!

@aentinger
Copy link
Contributor

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

@pomplesiegel
Copy link
Author

@aentinger great, thank you very much!

@martinez20m
Copy link

martinez20m commented Mar 21, 2023

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

@pomplesiegel
Copy link
Author

pomplesiegel commented Mar 21, 2023

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

@aentinger
Copy link
Contributor

We'd also be taking a PR with both PIN definitions and other related changes 😁 🙇 .

@pomplesiegel
Copy link
Author

@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!

@martinez20m
Copy link

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

@aentinger
Copy link
Contributor

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 🙇 .

@pomplesiegel
Copy link
Author

pomplesiegel commented Mar 30, 2023

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!

@per1234 per1234 added type: enhancement Proposed improvement topic: code Related to content of the project itself and removed type: imperfection Perceived defect in any part of project labels Jul 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: code Related to content of the project itself type: enhancement Proposed improvement
Projects
None yet
Development

No branches or pull requests

4 participants