RS485 ESP32 half-duplex communication

Hi, I have a question, so I have two identical devices that I would like to communicate via RX / TX (RS485). Both devices are exactly the same component, but as far as I know this is half-duplex mode, which means the first device sends, the second device receives and then again the second device receives and the first device sends. I have no idea how to write code for this communication. I found here as far as this chip is concerned GitHub - nopnop2002/SC16IS752: Driver for SC16IS752 also tried to load on both devices example code SC16IS752/Arduino & ESP8266/example/I2C_RECEIVE at master · nopnop2002/SC16IS752 · GitHub but nothing works. Some ideas?

considering that that there can dozens of endpoints on an rs-485 bus, a common approach is that one is a master that polls all the other slaves.

a slave needs to disable the transmitter on the rs-485 device which is enables when it responds to a message addressed to it.

it must disable the transmitter after the last byte of the message is completely sent. the code can call Serial.flush() which returns when the transmitter output buffer is empty

What would be best aproach? Which example code should help me? I don't even know what to search / try...

It depends on your requirements. When would each station on your bus send what to which target station? How will the receiver know how to interpret the received data?

Common is the master/slave approach - see e.g. CAN or MODBUS spec.

Is there any example code which should I use or which should be easier for me to understand everything?

Something like

void send(char* msg)
{
  digitalWrite(sendPin, HIGH); //enable sending
  Serial.write(msg);
  digitalWrite(sendPin, LOW); //back to receiving
}

But what about my components, I have components SC16IS752 (IO expander) and SN65HVD72 (RS485) on which signal goes throught to ESP should I also use that?

For example, below is the data format between a RS455 sensor and a pc - the data came from the sensor, then transferred by a RS485-TTL module to PC.

The pc sent this inquiry phrase:
0x01 0x03 0x00 0x00 0x00 0x02 0xC4 0x0B
address function register start register length CRC-L CRC-H

And the sensor's mcu answer:
0x01 0x03 0x04 0x02 0x92 0xFF 0x9B 0x5A 0x3D
address function valid data bytes 1st data 2nd data nth data CRC

The communication obey to Modbus-RTU and the data format was in hex, so your work is writing code for writing inquiry phrase and reading answer phrase.

The main point to remember with half-duplex comms is that it for it to work, only 1 device can transmit at any one time. The simplest implementation is the master/slave one as @gcjr indicated in #2.

As a slave device, the key is to only speak when you are spoken to.

Are you going to use an existing protocol, like Modbus, or invent your own? Rolling your own is fairly easy.

You need to decide if your data transferred across the RS485 is going to be in binary or more human friendly plain ASCII text (i.e. easily human readable and printable), but the downside of ASCII is that you need to convert numbers to it for Tx and back from it for Rx.

If you use the friendlier ASCII mode, then have a read of the Serial Input Basics posts as they will show you how to detect a packet of data.

Start off with your slave in permanent Rx mode (controlled by the RE & DE) signals. Set your master up so that its RE & DE signals only switch the line driver to Tx mode when you need the master to send something.

Work out a protocol for your system so that the slave will know what each packet if data means, and whether it needs to send a reply back to the master. Then you can build on the slave sketch to send back replies, and then build on the master sketch to receive and process those replies.

Ok will try it, but as I said should I also somehow implement chip SC16IS752 (IO expander) from which RX/TX data goes through?

Can you upload a higher res schematic than the one in #1 as i can't read some of the details.

Here is a bigger schematic image.

Which details do you miss for answering the questions?

Low res schematic in post #1 - couldn't make out some of the chip & signal names. All good now as OP has uploaded a higher res schematic.

The SC16IS752 is listed as a dual UART of which one set of UART outputs can be used as GPIO instead. You need to implement the I2C comms to it before you can start using it to talk on the RS485 bus.

Yes that's true it's dual UART and I already can use GPIO pins for example. But don't know how to to another part with sending / receiving throught RS485. I also try on two ESP32 without any components and seding / receiving from one to another works via RX/TX.

you forgot the flush() to wait or transmission to complete

  digitalWrite(sendPin, HIGH); //enable sending
  Serial.write (msg, msgLen);

  Serial.flush ();
  digitalWrite(sendPin, LOW); //back to receiving
1 Like

Ok I have now few more things, firtsly I can send/receive between two ESP32 controllers via this code:

#define TYPE "r"
#define LED 23

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

  if (TYPE == "w") {
    Serial.println("writing");
  } else if (TYPE == "r") {
    Serial.println("reading");
    pinMode(LED, OUTPUT);
  }
}

void loop() {
  if (TYPE == "w") {
    Serial.write("test");
    
    delay(1000);
  } else if (TYPE == "r") {
    String received = "";
    while (Serial.available())
    {
      received += Serial.read();
    }

    Serial.println(received);

    if (received.length() > 0) {
      digitalWrite(LED, HIGH);
    } else {
      digitalWrite(LED, LOW);
    }

    delay(1000);
  }
}

On another side I'm getting output 1310, but that is not converted string "text" which I send?

Another thing now if I would use my device from schematic and send data via RS485, would I recive anything on pure ESP32 without any components? So if I send for example string from device for example "test", would I get on ESP32 again output 1310? Also how would be in oposite way if I'm sending data from ESP32 via TX pin to device which have RS485 would be there on this device any output? SO again device contains all components from shematic which I send in earlier post and ESP332 is just a DEV board. Between two ESP32 dev boards I can send via RX/TX some data for start so something is working in this way...

Which is in this case my pin which should be changed?

You would need an RS485 line driver/receiver on your pure ESP32.

I suspect that what you are seeing there are the codes for CR (Carriage Return - ASCII code 13) and LF (Line Feed - ASCII code 10).

If you are able to tap into the circuit to access the I2C UART TXA and RXA signals, then you could route those to the other ESP32. That way you are only changing one side of the comms. Then you can get your I2C UART commands working to transfer the data to the UART and use the other ESP32 to verify/debug.

Then I would work on getting the I2C UART on the 2nd board up and running so that you can transfer test messages between the 2 ESP32s via their I2C UARTS.

Then I would introduce the RS485 element into the mix and the code to control the RS485-R/T signal at either end.