Simple Serial Routine is translating data when it shouldn't be

Hi All,

I've got a simple sketch that reads the output from a Laptop's RS232 DB9 connector and then is meant to display the same character on a LCD connected to a Arduino Mega 2560.

Each character is also supposed to be sent from the software serial port, which I can read using the serial monitor on another PC which is connected to the Arduino via USB.

eg.

Laptop 1 ------------ ARDUINO <USB (com7)>----------- Laptop 2

|
|
Terminal Program LCD Serial Monitor

Every time I enter a character on Laptop 1's Terminal Program, I see a corresponding character on both the Arduino's LCD and Laptop 2's Serial Monitor.

The problem is that the character typed into Laptop 1's Terminal Program is not what is being displayed on the Arduino LCD and Laptop 2.

Somehow the data is being translated, however I haven't been able to identify how or why it's happening.

If I program the Arduino with a simple sketch to display "hello world" onto the LCD, it is displaying correctly on both the LCD and the Laptop 2 Serial Monitor.

An example of the translated data is as follows:

COM1 Input COM7 & LCD Display

HEX BINARY DECIMAL HEX BINARY DECIMAL

61 0110 0001 97 4F 0100 1111 79
62 0110 0010 98 27 0010 0111 39
63 0110 0011 99 4E 0100 1110 78
64 0110 0100 100 13 0001 0011 19
65 0110 0101 101 4D 0100 1101 77
66 0110 0110 102 26 0010 0110 38
67 0110 0111 103 4C 0100 1100 76
68 0110 1000 104 09 1001 1001 9
69 0110 1001 105 4B 0100 1011 75
6A 0110 1010 106 25 0010 0101 37
6B 0110 1011 107 4A 0100 1010 74
6C 0110 1100 108 12 0001 0010 18
6D 0110 1101 109 49 0100 1001 73
6E 0110 1110 110 24 0010 0100 36
6F 0110 1111 111 48 0100 1000 72
70 0111 0000 112 04 0100 0100 4
71 0111 0001 113 47 0100 0111 71
72 0111 0010 114 23 0010 0011 35
73 0111 0011 115 46 0100 0110 70
74 0111 0100 116 11 0001 0001 17
75 0111 0101 117 45 0100 0101 69
76 0111 0110 118 22 0010 0010 34
77 0111 0111 119 44 0100 0100 68
78 0111 1000 120 08 1000 1000 8
79 0111 1001 121 43 0100 0011 67
7A 0111 1010 122 21 0010 0001 33

The sketch is as follows:

#include<LiquidCrystal.h>

LiquidCrystal lcd(12,11,5,4,3,2);
byte ch;
int col=0;
int row=0;
void setup() {
  
  Serial.begin(4800);
  Serial1.begin(4800);            //pins 18 TX ,19 RX

//Serial1.begin(4800,SERIAL_8N1); //pins 18 TX ,19 RX


    
  lcd.begin(16,2);
  lcd.clear();
 




}

void loop() {

  if(Serial1.available()){
    char ch=Serial1.read();
    Serial.write(ch);

//    Serial.println();

    lcd.setCursor(col,row);
    lcd.write(ch);
    col++;
  
  if(col>15){
    row++;
    col=0;
    lcd.write(ch);
  }
  


}

if(ch=='*' ||row==1&&col>=15){
  lcd.clear();
  col=0;
  row=0;
}
}

I also have a serial port debugger program on both laptops and both debuggers are confirming that the correct code is leaving Laptop 1 Serial Port (Com1) and that the translated code is being sent from the Arduino Serial Port (Com7)

Any ideas or assistance would be welcomed.

Thanks in advance.

I'd make a copy of the sketch, remove all the LCD code and try that to see if the translation is still happening. You might wish to disconnect the LCD too.

If that fails, I'd have the Arduino just echo back what it's getting to the sender.

I've got a simple sketch that reads the output from a Laptop's RS232 DB9 connector

The Arduino COM port works at TTL level not RS232. Have you got some kind of level translation device between the PC and the Arduino or is it a direct connection ?

Hi,

Thanks for your reply.

Yes, I have an isolating level converter board between the RS232 port and the Arduino Serial pins.

I've checked the input and output pins of that board with an Oscilloscope and the data appears to be in sync across the level converter, so there doesn't appear to be any distortion of the serial comms or signal inversion. The only difference that I can see between the input and output is the DC level.

I've tried setting the output levels going to the Arduino to both 3.3V and 5.0V and there is no difference in the behaviour.

@Wildbill, thanks for your reply.

I'll give it a try tonight to see what happens when I remove the LCD code and echo back to Laptop1.

I'll post the results.

How did you determine your “translation table”?
Did you send the characters one at a time, or as a complete string A-Z in one single go?
I’m assuming the results shown are consistent?

Reverse roles. Laptop 2 sending, laptop 1 receiving. That should give you a clue where the issue is.

Hi pcbbc,

Thanks for your input also.

I sent each character from a to z, one at a time. The results are consistent.

I also subsequently tried another bit of code which sends the data bidirectionally and I find that I'm getting the same result. 'Translation' only occurs between the Arduino and Laptop 1 via Com1.

So to go back to basics, I set up the following sketch, which simply sends a Text string to both serial ports upon any character being received from Laptop 1.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(51, 50); // RX = Pin 51, TX = Pin 50.

byte ch;

void setup() {
  
              Serial.begin(4800);
              mySerial.begin(4800);            //pins 50 TX ,51 RX

            }

void loop() {

           if(mySerial.available()){
    
           char ch=mySerial.read();
           Serial.println("Test String 1 - Serial ");
           mySerial.println("Test String 2 - Serial 1");

          }
  


}

Unsurprisingly, this showed that any data being sent and received to Laptop 1 (Com1) is being 'translated' in both directions, whereas it is being processed normally when sent and received by Laptop 2 (Com7 USB).

The following images show the text being received by Laptop 1 and Laptop 2:

So this is weird, but interesting at the same time.

I also thought I'd try two totally different Pins for TX and RX, so I reconfigured the routine to use Pins 50 and 51, with no subsequent change in behaviour observed. So all ports on the Mega are behaving the same when pointing to Laptop 1's RS232 Port.

I've also just received a new DB9 PCB with onboard MAX232 level converter, so I will replace my existing level converter board with this one (as it's specifically designed for RS232 interfacing) and see what happens. I'll post the results.

Laptop 1.jpg

Laptop 2.jpg

echobot:
Hi,

Thanks for your reply.

Yes, I have an isolating level converter board between the RS232 port and the Arduino Serial pins.

I've checked the input and output pins of that board with an Oscilloscope and the data appears to be in sync across the level converter, so there doesn't appear to be any distortion of the serial comms or signal inversion. The only difference that I can see between the input and output is the DC level.

I've tried setting the output levels going to the Arduino to both 3.3V and 5.0V and there is no difference in the behaviour.

If I recall correctly, RS232 is inverted, with a signal HIGH being a negative voltage on the RS232 and a signal LOW being a positive voltage.

Yes, I have an isolating level converter board between the RS232 port and the Arduino Serial pins.

Which one? It's not sufficient to use the correct levels; it also needs to invert the signal.

I guess your laptop 1 is very old if you're using software that is 20-plus years old :wink:

Hi david_2018 and sterretje,

I'm starting to agree with you and think that I need to revisit the RS232 levels and signal inversion.

When I checked the comms with the CRO, I didn't put the input and output on separate channels and set the trigger to display both signals relative to each other, so it is possible that I've misinterpreted that they are non-inverting. If they are required to be inverting, then that may be the issue because currently they are not as far as I'm aware.

My current RS232 buffer board is the following:

RS232 Bidirectional Buffer

The new interface is the following:

DB9 RS232 Interface

Laptop 1 is a trusty Thinkpad T42 with a genuine DB9 Com Port which is used for legacy radio programming applications. I use Telix on it because it can be preconfigured to start with a dedicated config using batch files (yeah old school - I know) but it works well for that purpose. I can use Secure CRT and similar windows apps, but you need to use the mouse and keyboard to set it up so I don't bother.

Laptop 2 is another trusty Thinkpad R61, which I use for programming with the Arduino and PIC's.

Your RS232 bidirectional buffer is not a RS232-to-TTL converter. Your DB9 RS232 interface seems to be the correct one for the connection from PC (RS232) to Arduino.

I think I'm missing the part where the RS232 bidirectional buffer fits in. Can you make a diagram (reasonably sized (200kB or so) photo of pencil one is fine).

PS
I'm running RealTerm on Windows 7/10; it can be configured to start with certain settings.

Hi All,

Thanks to everyone that assisted with this problem, which I've now rectified.

The issue was that the RS232 buffers that I was using were not inverting the signals as alluded to by sterretje and david_2018.

When I used the new bidirectional buffer which incorporated a MAX232 chip, the problem disappeared.

So hopefully this will help others in future who may strike the same problem.

All of my test routines now reliably transfer serial comms as intended, so it was solely this hardware issue that was 'translating' the data.

The other advantage of the RS232 interface with the MAX232 chip is that it properly handles true RS232 voltages as well as TTL RS232 voltages on the DB9 connector, which ensures compatibility with legacy devices.