Two ways RS-232 repeater.

Hello,
I am using a device from which information are gathered via a RS-232 port on a PC (19200 bps).
The software running on the PC polls the device to retrieve the data every 200 ms.

PC: Value1 poll
Device: Current value1
PC: Value2 poll
Device: Current value2
PC: Value1 poll
Device: Current value1
loop...

I can't modify the software but I need to gather the other information New_Value which will be processed and displayed on a LCD by an Arduino module.
The idea is to insert the Arduino in the serial line and ask it to repeat in both ways the serial exchanges between the PC and the device, and to insert a new request between two polls.

PC: Value1 poll
Arduino: read "Value1 poll" from PC
Arduino: send "Value1 poll" to the device
Device: Current value1
Arduino: read "Current value1" from the device
Arduino: send "Current value1" to the PC
Arduino: send "New_Value poll" to the device
Arduino: read "Current New_Value" from the device and displays it on a LCD
PC: Value2 poll
Arduino: read "Value2 poll" from PC
Arduino: send "Value2 poll" to the device
Device: Current value2
Arduino: read "Current value2" from the device
Arduino: send "Current value2" to the PC
loop...

Is this feasable with an Arduino (probably with NewSoftSerial and a MAX232)?

yes

if you use a MEGA or a teensy 3.0 you can have hardware serials which are more reliable.

Hi,
I would really like to use a Pro Mini that I have in stock.
By the way, reliability is not an issue as the data are polled every 200 ms, I can miss one or two without consequences.

doable, core could looks like this

void loop()
{
  if (Serial1.avialable()) { Serial2.write(Serial1.read()); };
  if (Serial2.avialable()) { Serial1.write(Serial2.read()); };
}

Not sure to understand.
TXD and RXD are not on the same pin. Don't you think I'll need 4 I/O ports :

  • One for TXD from PC (Serial1)
  • One for RXD from PC (Serial2)
  • One for TXD from device (Serial3)
  • One for RXD from device (Serial4)

And do something like that ?

void loop()
{
if (Serial1.avialable()) { Serial4.write(Serial1.read()); }; // PC-TXD -> Device-RXD
if (Serial3.avialable()) { Serial2.write(Serial3.read()); }; // Device-TXD -> PC-RXD
}

You would need to use SoftwareSerial to give yourself a second serial port.

Serial1 and Serial2 are found on a Mega. The principle will be the same.

...R

Yes, that was the original idea.
But do you agree I'll need 4 (2x TXD and 2x RXD) I/O ports?

You need 4 pins, but only 2 serial "ports". So Rob's example is correct as it only uses Serial1 and Serial2, each of which has an RxD and a TxD pin.


Rob

1 Like

OK, one Serial includes both TxD and RxD !
Thanks for your help, I will try that.

Hi,
I have tried the code you proposed by it did not work, so I decided to go step by step.
I got some issues with my code, running on a Nano :

#include <SoftwareSerial.h>

SoftwareSerial Device(9,11);	// RX, TX
SoftwareSerial PC(12,10);	// RX, TX

String str;
String str2;

/*
Data format:
 Poll : IF;
 RX : IF00118072000+000000300000;
*/

void setup() {
    Serial.begin(9600);
    PC.begin(19200);
    Device.begin(19200);
    digitalWrite(led, LOW);
}

void loop() {
 
  PC.listen();
  if (PC.available()) {
      str = PC.readStringUntil(';');
      str.concat(";");
      Serial.println(str);
      Device.println(str);
  }

/*
  Device.listen();
  if (Device.available()) {
      str2 = Device.readStringUntil(';');
      str2.concat(";");
      Serial.println(str2);
      PC.println(str2);
  }
*/
}

That works pretty well as soons as only one of the two blocks is uncommented, and I can either monitor the data sent by the PC or by the device with the regular serial console.

Serial console with block 1 uncommented (data poll):

IF;
IF;
IF;

Serial console with block 2 uncommented (device's answer):

IF00124895000+000000300000;
IF00124895000+000000300000;
IF00124895000+000000300000;

But as soons as I uncomment the other block the program does not work anymore. The data displayed comports specials characters and I suspect them to make the whole program not working:

?4fÌ?24895000+000000300000;
´fÍ»IF00124895000+000000300000;
´fÍ?IF00124895000+000000300000;
3fØ000300000;
4fÌ?24895000+000000300000;
&F??V¶ &Ì?00300000;

Did I miss something ?

I think you may still be a little confused.

If you want to communicate with your PC and another device you need 2 serial connections - but you have created 3.

Serial.print() is the standard connection to the PC. So you just need one instance of SoftwareSerial to talk to your device.

SoftwareSerial Device(9,11);	// RX, TX

Reading data from your PC should simply be done with Serial.readBytesUntil()

I don't recognize the function Device.readStringUntil(';'); - where does that come from? Are you showing us all your code?

...R

Hi,
Yes, all the code is here.
I am using a 3rd serial port because I wanted to use the integrated one for debugging purpose (which looks mandatory ;))
I use readStringUntil (Stream.readStringUntil() - Arduino Reference), as the semi-colon is a delimiter.
The correct exchanges between both devices is :
IF; (data poll)
IF00124895000+000000300000; (answer)

str and str2 content the data exchanged, and this data will be processed afterward.
For the moment, I am just trying to set up the dialog between the PC and the Device by simply forwarding the requests and the answers.

Jibeji:
I am using a 3rd serial port because I wanted to use the integrated one for debugging purpose (which looks mandatory ;))

Then you need to explain what external devices the two SoftwareSerial instances are connected to.

You cannot use SoftwareSerial to talk to a PC without some external device such as a USB-TTL cable.

...R

Hi,
Kind of diagram : :slight_smile:

PC RS232 port <--> RS232/TTL converter <--> Arduino <--> TTL/RS232 converter <--> Device

I use a MAX232 to convert from RS232 levels to TTL.

Do you mean you are using a PC with an old-fashioned serial port as well as the USB connection to the Arduino?

I haven't seen a PC with a "real" serial port for a long time.

That would mean that your PC can see your Arduino on two different ports - is that correct?

You need to be aware that SoftwareSerial can only do one communication at a time - send or receive on one instance.

...R

Yes, the PC has two connection to the Arduino:

  • One via a real RS232 interface (remember, the old DB9 plugs :slight_smile: )
  • One via an USB port, to the FTDI integrated chipset.

Your last sentence point me one the right direction, it seems that only one interrupt can be handeled whatever the number of SoftwareSerial declarations.
I will give a try using the integrated serial port and only one SoftwareSerial instance.

Hi,
I have tried exactly the same pattern and same code but with one SoftwareSerial instance and the integrated serial port, it works like a charm !!!
I guess I was encountering a kinf of interrupt issue, the running SoftwareSerial call was disturbed as soon as the other one received some data.
The exchanges between the PC and the device are now forwarded both ways, next step is to process the data.
Thank you very much for your support. :wink: