RS 485 RTS/DE pin

dg9ngf
Posts: 40
Joined: Mon Sep 16, 2019 6:49 pm

RS 485 RTS/DE pin

Postby dg9ngf » Sun Jun 12, 2022 2:26 pm

Hello,

I'm looking into how RS 485 works with the ESP32. I've already successfully implemented a solution on the AVR ATtiny1614 microcontroller which has the XDIR pin that is automatically managed when sending RS 485. On the AVR I can even detect changes to the RX pin to prevent any transmitting at the earliest stage. This has reduced collisions massively in my tests.

From what I've read now, the ESP32 has no such support and relies on the driver (in ESP-IDF?) to set a pin at the correct times. Let's hope its timing is accurate and the bugs I've seen here will eventually be fixed (sometime after the current IDF 4.4.1).

Everybody's talking about using the RTS pin for the used UART. Now that's a big problem, because no such pins are actually available on the WROOM module. The UART0 is used by the serial terminal and prints all kinds of stuff all the time, also at boot. I'll also need that for firmware upgrades. UART1 is blocked by the flash memory and UART2 is still free. That's what I'll have to use in my application. But the RTS pins of UART1 and 2 are also blocked by flash. Can I just use any other pin? And since this is all software-defined, could I use another workaround with any custom GPIO? What's the recommended procedure here for new designs?

Also, can I still run an interrupt on RX level changes to detect the beginning of a bus transmission before the first byte is complete?

ESP_Sprite
Posts: 9723
Joined: Thu Nov 26, 2015 4:08 am

Re: RS 485 RTS/DE pin

Postby ESP_Sprite » Mon Jun 13, 2022 2:43 am

The UARTs can be routed through the GPIO matrix to any GPIO (keeping in mind pins already used for flash and input-only pins); the ones in the datasheet are simply the 'default' ones (actually the ones that can be routed via the IOMUX rather than the GPIO matrix, but for the UARTs there's no practical difference there)

dg9ngf
Posts: 40
Joined: Mon Sep 16, 2019 6:49 pm

Re: RS 485 RTS/DE pin

Postby dg9ngf » Tue Jun 14, 2022 8:56 am

Sounds good. I've seen several long lists and tables of function numbers. But I wasn't able to find any practical information about how to use GPIO matrix. From other comments I could find, it seems like a well-kept secret. Is it supported in ESP-IDF, and how? Is there any sample code for it?

IO MUX doesn't seem to provide any alternate pins for UART, so it's not useful for me now.

ESP_Sprite
Posts: 9723
Joined: Thu Nov 26, 2015 4:08 am

Re: RS 485 RTS/DE pin

Postby ESP_Sprite » Tue Jun 14, 2022 9:27 am

It's usually 'hidden away' in the drivers, only showing by the fact that you can assign random IO pins to the peripheral. See e.g. uart_set_pin() and the initialization functions for SPI, I2C and I2S: they all allow you to use a given IO as an input/output pin.

dg9ngf
Posts: 40
Joined: Mon Sep 16, 2019 6:49 pm

Re: RS 485 RTS/DE pin

Postby dg9ngf » Tue Jun 14, 2022 12:13 pm

I see. Thanks!

jimmy_x86
Posts: 2
Joined: Mon Dec 04, 2023 11:41 pm

Re: RS 485 RTS/DE pin

Postby jimmy_x86 » Mon Dec 04, 2023 11:50 pm

Hi @dg9ngf,

I'm working on a very similar project (ESP32 <-RS485-> ATtiny1616) and would like to get the best results.

When you say "implemented a solution on the AVR ATtiny1614 microcontroller which has the XDIR pin that is automatically managed when sending RS 485" you mean you connected PB0 pin (XDIR) to RS485 DE-RE pin and enabled Serial RS485 mode in software, right?

Can you please share how did you implement "On the AVR I can even detect changes to the RX pin to prevent any transmitting at the earliest stage"? I'm very interested in getting the same, in order to reduce collisions.

Also, did you find a way to do the same on ESP32?

Thanks!

dg9ngf
Posts: 40
Joined: Mon Sep 16, 2019 6:49 pm

Re: RS 485 RTS/DE pin

Postby dg9ngf » Thu Dec 21, 2023 9:39 pm

Right, the XDIR pin can be connected with the DE and /RE pins of the RS485 transceiver chip. That's exactly what they made these pins for. Ideally, the XDIR pin goes high a little bit before sending so that the transmitter can set things up properly.

How I detected the beginning of an incoming transmission before the interrupt of the first received full byte? With a simple interrupt handler (ISR) on the RX pin. I had to look a while to find it, and I noticed that my electronics projects are sleeping for way too long already. I don't fully understand the code right now but maybe this information already helps. Here are some random code snippets, hope they make sense:

Code: Select all

int main()
{
	// Set up RX detection interrupt
	PORTA.PIN2CTRL = PORT_ISC_FALLING_gc;   // RX-alt = PA2

	// ... set up UART and rest of program

	// later in the write/read loop:

	// Don't try to send while we're receiving a message
	if (!recvStarted && recvByteCount == 0)
	{
		while ((message = dequeueSend()) != NULL)
		{
			sendMessage(message);
		}
	}

	// ... now do the reading
}

ISR(PORTA_PORT_vect)
{
	if (PORTA.IN & 1 << 2)   // RX-alt = PA2
		setRecvStarted();
	PORTA.INTFLAGS = PORT_INT2_bm;
}

// Some hooks that allow custom code at certain events
#ifndef onReceiveStart
	#define onReceiveStart()
#endif

// Sets the flag that indicates that data is being received. This should be determined from an
// interrupt handler on the falling edge of the UART RX pin.
// Code size: ___ byte
void setRecvStarted()
{
	if (!recvStarted)
	{
		recvStarted = true;
		onReceiveStart();
	}
}
Did I find the same on ESP32? I haven't searched yet. Actually, getting the same serial communication to work on ESP32 is my very next task that I need to do – as soon as I find some time to work on these things again...

jimmy_x86
Posts: 2
Joined: Mon Dec 04, 2023 11:41 pm

Re: RS 485 RTS/DE pin

Postby jimmy_x86 » Tue Jan 09, 2024 12:06 pm

Thank you very much! This is very helpful.

Who is online

Users browsing this forum: No registered users and 31 guests