UART RS485 Problem

Mousivandhossein

Joined Dec 8, 2020
26
Hi,

I want to make a circuit to collect the temperature of some locations in a control panel.
I have a control panel that is connected to several microcontroller circuits. Each microcontroller circuit measures its ambient temperature.
the control panel sends a number from 1 to 20 for example send number 4, the circuit number 4 must send the temperature that measured.

The microcontroller for the control panel and circuits is ATMEGA48. (schematic of control panel and microcontroller)
I enabled uart on atmega48 for connection between microcontrollers.
Unfortunately, I have a problem with the connection, when I tested a control panel and a microcontroller, the operation was OK, but I connect several microcontrollers the operation was not OK.
I used interrupt for control panel and when a data has been received from a microcontroller the routine of the interrupt will be executed.
I didn't use the interrupt for The other microcontrollers, and other microcontrollers wait and check to receive a data, and if the data is equal with its number address then send the amount of temperature that measured.

Please give me a code (codevision) for the control panel and microcontrollers.

Papabravo

Joined Feb 24, 2006
17,573
A common error made by novices to RS-485 is to ignore the effects of multiple nodes connected to a bus. It seems that each of your boards has some arrangement of resistors on the A & B bus line. When you connect a bunch of identical nodes together ALL those resistor networks are connected in parallel. Whenever you put things in parallel it loads down the transmit driver to the point where it cannot drive the cable AND all the terminations. Let me make this perfectly clear. Do NOT place termination resistors on PC boards. Place them on the cable at each end. Now you can connect nodes in parallel and what you have is the load impedance of all the recivers in parallel. That load impedance is on the order of 10-20KΩ soe even a couple dozen nodes in parallel should work OK.

Back of the envelope calculation:

$$5 \times 470\;\Omega\;=\;94\;\Omega$$

Which is less than the characteristic impedance of twisted pair cable. More nodes will make it worse, especially when you start getting reflections at the wrong time.

JohnInTX

Joined Jun 26, 2012
4,628
I didn't use the interrupt for The other microcontrollers, and other microcontrollers wait and check to receive a data, and if the data is equal with its number address then send the amount of temperature that measured.
That is one problem. Unless the microcontrollers have an addressable UART, all of them receive all messages from the controller. That, in my experience, always requires a buffered interrupt-driven UART receiver for successful operation. Each microcontroller receives all messages. The addressed one replies, the rest discard the message and wait for the next one. That is difficult to do without interrupts.

You need some kind of protocol to organize the messages. Check out Access.BUS, MODBUS et. al. for examples or roll your own. Messages need a unique 'START' character like SOH, a checksum and EOT to frame the payload. Otherwise it is very easy for someone to lose track of where in the message stream they are and foul things up. Your protocol should specify the timings between the master releasing the bus transmitter and the addressed slave taking the bus to reply. Some mechanism must be present to recover from a fouled bus i.e. no reply from a dead or non present slave or a corrupt message.

A common error with the MAX485 is turning off the transmit driver when the last character is loaded into the UART. The UART is double buffered in the ATmega and you have to wait until the loaded character is actually shifted out before switching over to receive.

Always include an ECHO message in your protocol and code that first. That way you can debug the bus before going on to reading your data packets.

RS-485 is not particularly difficult but it isn't trivial either. A well defined protocol will help a lot.

Good luck.