1

The idea is to connect more than 1 arduino slave to master as shown in schamatic

schematic

simulate this circuit – Schematic created using CircuitLab The problem is TX slave can not just combine to master RX. It need to done some trick like tri-state buffer to make slave TX one at time. Anyway, avr port can config as tristate buffer. (Q1)Is there any software solution to done this? Second If I connnect TX to RX for half-duplex communication (using 1 data line). How to make Rx stop listenning to its self while transmiting data?

2
  • Diodes and a resistor. – Majenko Aug 21 '20 at 18:02
  • Two resistors--that's it! I just added my answer. – Gabriel Staples Aug 27 '20 at 4:58
2

You can do it with two diodes and a resistor:

schematic

simulate this circuit – Schematic created using CircuitLab

You'll still have to implement some system to prevent collisions, but electrically that will be sound.

7
  • 1
    Does it have programing solution? – M lab Aug 22 '20 at 9:01
  • Tip magically turn the shave devices into open drain? No. Not unless you have the ability to reprogram the slaves and write your own implementation of software serial that emulates open drain. – Majenko Aug 22 '20 at 9:02
  • Will something like Serial.end() and oinMode(x,INPUT) trick work? or I need to write my own Serial library? – M lab Aug 22 '20 at 9:04
  • 2
    On the slave devices, yes, that would work - but would also disable serial reception. To prevent collisions you need the master to tell a slave it can send, which means reception needs to be working, or you need to implement some other form of signalling architecture (and that would most likely need more changes to your hardware). It's simplest to just add those diodes and a resistor and do it properly - or not use Serial at all and use a proper bus system like I2C. – Majenko Aug 22 '20 at 10:55
  • 2
    Without the diodes or some form of direct control over when each slave can send a collision could be fatal to one or both of the slaves. It could cause a dead short circuit (one sends a 1 and the other a 0 at the same time) which could burn out the IO pins. – Majenko Aug 22 '20 at 11:28
1

For this scheme to work, you need to make sure that at most one slave drives its TX at any given time. You will have to devise some protocol by which the master addresses one slave, and then only that slave responds. The problem is:

  • both slaves must have their serial ports turned on in order to notice when they are addressed by the master
  • an active serial port keeps its TX pin in a low impedance state, actively driving it HIGH when not transmitting data.

The best way out of this dilemma is to modify the hardware, as per Majenko’s answer. If, for whatever reason, you cannot do that modification, there may be a software-only solution, but only if the underlying hardware allows you to turn off the serial transmitters of the slaves, while keeping the serial receivers active.

The Arduino API dos not allow you to keep the serial transmitter active while the receiver is disabled: the functions Serial.begin() and Serial.end() control the transmitter and the receiver as a whole. You may be able to do that by accessing the hardware at a lower-level. You didn't state what kind of Arduino you are using. Assuming you have something similar to an Uno, you can disable the transmitter with:

UCSR0B &= ~_BV(TXEN0);

and enable it again with:

UCSR0B |= _BV(TXEN0);

If you want to use the Arduino API for serial communication, you will have to disable the transmitter right after Serial.begin():

const uint8_t TX_PIN = 1;

void setup() {
    pinMode(TX_PIN, INPUT_PULLUP);  // valid when transmitter is off
    Serial.begin(9600);             // enable serial port
    UCSR0B &= ~_BV(TXEN0);          // disable transmitter
}

But beware that then it will be enabled for a sort time (no more than a few microseconds), right before you disable it. This may cause a short if one slave boots while the other is transmitting data.

One problem with this kind of software-only solution is that bugs do happen, and with your circuit, a bug in the protocol handling can burn your hardware. If you can manage to at least add some protective resistors, as in Gabriel Staples’ answer, that should keep you safe.

0

You can use a single-pole dual throw switch. a simple switch that can switch lines between multiple slaves.

Limitation: The salve will not be able to create a request unless the master has selected its corresponding lines. Master has to actively ask for the data or send commands to the slaves. Slaves may not be able to initiate the communication (when not selected)

enter image description here

1
  • Appreciate for your participation but I prefer software solution first. – M lab Aug 28 '20 at 17:00
-1

Update Nov. 2020: my answer below, though a bit insightful and with many correct statements, is wrong. My schematic below will indeed prevent the Arduinos from damaging each other, but it will not allow proper communication. Majenko's answer here is right. Use his schematic, but read my answer below as well for additional insight and ideas.


ORIGINAL ANSWER:

You can do it with 2 resistors, as shown below. That's it! Super simple!

Electrical explanation:

The goal is simply to protect the two Tx pins from killing each other. Without the resistors one Slave might be writing output LOW while the other Slave is writing output HIGH, which is a dead short--damaging both devices. Simply putting a 1k resistor in series with each Tx pin like this prevents that dead short. Now, if one Tx pin is HIGH while the other is LOW, you get current flow from one into the other through a total of 2kOhms, which means the current will be only I = V/R = 5V/2000 Ohms = 2.5mA, which isn't a problem, as each pin can handle 40mA max and 20mA~30mA continuous safely. Also, a 1k resistor isn't much load, so you should still get good serial throughput even at fairly high baudrates.

schematic

simulate this circuit – Schematic created using CircuitLab

The code:

The communication code will be done as normal with Serial.print() or Serial.write(), Serial.read(), etc. Nothing special about the code, except you should make an effort to keep the slaves from talking at the same time to prevent data corruption from slave to master. So, you should have Master request data from a Slave, and a Slave should only talk when it knows the other Slave is not talking (ex: it should only talk when spoken to). The Master coordinates the communication. In this way, this is like SPI: the Master is in charge and tells each Slave when to talk. Since both Slaves are always listening, just use an "ID" to indicate which slave is being spoken to. If a Slave doesn't see it's ID, it should ignore the message.

Ex:

Request a new temperature reading from Slave 1:

Serial.println("1:T");

Now, wait until you get the full response from Slave 1, then send out a request for...let's say, some current reading, from Slave 2:

Serial.println("2:C");

The exact communication codes are up to you--your imagination is the limit.

Again, both slaves see both messages, but they look at the number at the beginning and only reply if it's their number. Doing this technique, you could connect nearly infinite Slaves all on the same line, just adding a 1k resistor to each Slave's Tx line before the junction where they all connect back to the Master's Rx line.

Pretty cool. I never thought of doing this before until you asked the question. Good question.

5
  • You hardware setup can prvent damage but I wonder if one slave send no data (given High signal) will the data get voltage divider effect that divide signal amplitude to half? – M lab Aug 28 '20 at 17:07
  • @Mlab: Indeed. A “silent” TX actively pulls the line HIGH. That's why you need the diodes. – Edgar Bonet Aug 28 '20 at 17:13
  • @EdgarBonet that why I seraching for solution to make A “silent” TX become high impedance. it should be possible by software some how. – M lab Aug 28 '20 at 17:20
  • 1
    I think my answer is wrong, and needs the diodes due to idle Tx being actively driven (low impedance) HIGH. I'll update my answer as soon as able. I measured the impedance of a HIGH Tx line at something like 26 Ohms early this morning. – Gabriel Staples Aug 28 '20 at 18:07
  • 2
    26 Ω is the expected resistance of an ATmega pin configured as OUTPUT. C.f. the datasheet section on pin driver strength. – Edgar Bonet Aug 28 '20 at 20:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.