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

Modbus direction pin #10963

Closed
wants to merge 4 commits into from
Closed

Conversation

barbudor
Copy link
Contributor

Description:

Some meters such as the SDM120 are using RS485 interface.
RS485 interface is a bi-directional bus where normally only 1 can talk at a given time. It normally requires a 3rd signal to control the direction such as the "flag" signal here:
image

There are some boards that tweak a direction signal by inverting the TX data but that is not very clean because direction is changed on every bit. And it may happens that you don't have such board and just a standard MAX485 driver.

This PR aims at offering a new optional pin named SDM120 Dir which, when assigned to a GPIO connected to pins DE and nRE of the MAX485 change the driver's direction.

This is a draft for review has, while I have checked the timing on the logic analyser, I'm waiting for feedback from user Anwar on Discord.

Note that this is the 1st time I am adding pin in Tasmota, so please check carefully what I've done here:

  • Declaration of the pins in the various arrays
  • Testing the pin is configured on not by comparing with 99

I have some questions:

  • I understand that when a pin is not defined in the configuration, the return values from Pin(...) is 99. I used the same value in TasmotaModbus. Is that ok ? In other drivers I've seen undefined pin as -1 (like in TasmotaSerial) so it means a "translation" from 99 to -1 has to be done ?

  • Is there a trick to had the Pin drop-down menu text in all language or should it be done manually ?

Thanks for your review

Checklist:

  • The pull request is done against the latest development branch
  • Only relevant files were touched
  • Only one feature/fix was added per PR and the code change compiles without warnings
  • The code change is tested and works on Tasmota core ESP8266 V.2.7.4.9
  • The code change is tested and works on Tasmota core ESP32 V.1.0.5-rc6
  • I accept the CLA.

NOTE: The code change must pass CI tests. Your PR cannot be merged unless tests pass

@arendst
Copy link
Owner

arendst commented Feb 15, 2021

Thx.

For my understanding, this is needed when more than one sdm120 is connected to the bus? As far as I know a single sdm120 does not need this. All previous sdms worked fine.

The gpio result of 99 has just been changed yesterday to the "standard" -1 result. Pay attention to use an integer ready to support negative values.

I still need to evaluate the code changes regarding the new gpio.

@barbudor
Copy link
Contributor Author

Hi @arendst
As soon as you have Tasmota and 1 meter, each device needs to handle its driver at its own end.
You can see RS485 like the good old TalkieWalkie where you need to press the push-to-talk. If you don't release the button, no-one else can speak, even if there is only 2 of you.
If you don't have a board with the cheat/cheap trick of changing the direction based on the TX signal, you can't send and receive. This kind of module would be the like the voice-activation that is available on some Talkie.

Some SDM comes with a standard RS232 with separated RX and TX and thus do not need that.

If you use a bare MAX485 with an ESP without managing the nRE+DE signals, the MAX485 is either in receive only or in transmit only. If in receive only, you can listen to what the meter sends but can't send the requests. If in transmit only, you can send the request but blocking the bus preventing the meter to respond (bus contention).

A board like this one do not need this : https://www.aliexpress.com/item/1005001346792286.html
It is more or less this :
image
as there is a circuit to manage the nDE+DE pins (not a transistor but a 74HC04 inverter)

A board like this one need this : https://www.aliexpress.com/item/32902021999.html
image
Bare MAX485

The added code normally is so that if you have one of the module that has the trick, you don't define the DIR pin and let teh module control it.

I will review the code to use -1
Is there a #define somewhere for this value (aka GPIO_NOT_CONFIGURED or similar) ?

It would be nice too to have a TasmotaLog.h header in order to easily insert AddLog_P(..) in libraries.

@arendst
Copy link
Owner

arendst commented Feb 15, 2021

In the early days of this modbus driver we decided a user needed the first noted converter. The second was rejected by the early driver writer. Since then no problems were reported until recently where the wrong converter poppes up again.

I'm not convinced to this exercise just to support a bad functioning converter.

I have two of the correct converters either to a sdm630 and a pzem and they work wonderfully right with just two wires connected.

@barbudor
Copy link
Contributor Author

If one converter should be considered as bad, it is the one that does the cheap trick. The direction signal should be stable during the whole transmission from the 1st start-bit to the last stop bit and not just following the TX bit.
And nowhere in the docs it is written to use this tricky adapter instead of a standard MAX485

As you wish Theo.

@arendst
Copy link
Owner

arendst commented Feb 15, 2021

This #2694 (comment) is the only working and supported converter we/I ever use.

@barbudor
Copy link
Contributor Author

ok

@barbudor barbudor closed this Feb 15, 2021
@barbudor barbudor deleted the modbus_dir_pin branch February 15, 2021 10:52
@vic42
Copy link

vic42 commented Feb 15, 2021

A direction pin would have been a useful option if you are not forced to use it.

In fact the "supported" adapter employs a very ugly hack (timing by an R/C on a CMOS gate input) to stretch the send gate over TxD transitions (and several milliseconds beyond).
Spectacle Z12885
From an electrical engineering standpoint a direction pin would constitute a proper solution to control standard half duplex RS485 Transceivers. The number of bus participants is irrelevant in this respect.

@hallard
Copy link
Contributor

hallard commented Mar 4, 2021

Happy to enter this interesting issue.

Modbus has always been complicated because we've got two school for driving RS485. The correct one as mentioned @barbudor and the "working not compliant" one with it kind of auto detection.

You can check every forum (Pycom, arduino, RPI, ...) that we are not discussing any personal issue and this issue is raised on periodic time. Every descent Modbus library has the option to drive this line and, worth mentioning that Modbus official shields are also hardware ready to do both ways (good and tricky one)

I designed a ModBus shield (OMG 7 years ago) and already faced this issue. Check the schematic, as you can see, you need a GPIO to control DE/RE line of RS485 driver.

So having this option should not hurt anyone (if not selected will act as today) but giving user the way to drive would be a really nice feature. I looked at @barbudor implementation, looks like does not take too much ressources nor size. I just would have called this pin a kind of GPIO_MODBUS_DIR instead of SMD120 because has it's Modbus it can be used with all Modbus devices, not only SMD120 :-)

But once again it's @arendst's decision.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants