Problem with decoding logs received by UART Serial.

The device sends logs via UART Serial port with the configuration 115200 8N1. To adjust logic to Arduino I’ve used Logic Level Bidirectional converter which is based on BSS138. The problem is that I receive not invalid or wrongly decoded Strings.

// include the SoftwareSerial library so you can use its functions:
#include <SoftwareSerial.h>

#define rxPin 3
#define txPin 2

// set up a new serial port
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);

void setup()  {
  // define pin modes for tx, rx:
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  // set the data rate for the SoftwareSerial port
  mySerial.begin(115200);
  Serial.begin(115200);
  
}

void loop() {
  if (mySerial.available()>0){
  String uartLine = mySerial.readStringUntil('\n');
  Serial.println(uartLine); 
 }
}

And this is a sample of received data by Arduino:

{SBBR}{hnfo}[           _sb_brhdge.c][ 462\ append brovvtC}_o ne vk} aa9sY⸮⸮#⸮5
t{__]  i2ote_]n⸮⸮⸮}⸮ɕ⸮ꅃ⸮⸮ɍ⸮5
_B  r[nc[_Bo s. estc_
}  d6da[dtw_app_mtk]>
{HBBTV_COMP| a_hbbtv_is_launching_bcc b_launchiog = 0FGUMspr3[wpf_browser]>[0718/233554:IOFO:resources_monitor.cc(327)] CheckBrowser  wisep3a
b6Isi3kPRpi7s6 a1pr/Irr)korsi e4eh2
r05:ey4kodch ap3e
r15rschrsew  3t  f]65r⸮⸮⸮K⸮⸮⸮⸮⸮5ɹѥQIՁ⸮́⸮⸮⸮⸮
[brw_axxՋ׭Wj{*$,⸮⸮iwc⸮m 0         _⸮b%ɥdV⸮iu[0:31] X⸮⸮⸮#⸮r+⸮⸮⸮⸮t⸮j{⸮⸮m}⸮⸮ͅ⸮⸮⸮⸮⸮⸮⸮⸮⸮E⸮⸮⸮{Cnb_.5t⸮
pA[vo0nrpgte_]{btg+ʒ⸮pettB  b4  dmR} r1roi,oa
} _e6aad sl[dtw_app_mtk]>
{SBBR}{info}[           _sb_bridge.c][ 462] appdnd broads
t}sco9ee v>}ss]aepd]n _a0 rertat>{_cccei[mSf Mɥ⸮⸮m⸮⸮⸮⸮ف⸮
aS} [dtv_`pp_mtk]>
{HCBTV_COMP} a_hbbtv_is_la]⸮,+⸮⸮⸮%⸮⸮⸮}⸮⸮չ⸮⸮⸮⸮⸮⸮⸮⸮⸮! QY⸮
<5A⸮⸮⸮⸮}⸮⸮j
t>Gn_l> tkMh__a:o
[dtv_app_mtk]>
FGT_PHM:ambi_mtsic_get_sample_user:couot =10366000

Once when I use my UARTtoUSB FTDI converter and Teraterm on my PC (with the same serial settings) logs looks like this:

[wpf_browser]>[DMR][AVTS_ACTION]GetTransportInfo
{SBBR}{info}[           _sb_bridge.c][ 462] append broadcast svc end
{CACP}{info}[  _sb_dvb_act_storage.c][ 792] channel bridge event [1]
{CACP}{info}[  _sb_dvb_act_storage.c][ 795] broadcast services updated
{CACP}{info}[  _sb_dvb_act_storage.c][ 803] current is not profile type2, ignore brdcst svc update
{CACP}{info}[  _sb_dvb_act_storage.c][ 929] cam append service end
{SBBR}{info}[           _sb_bridge.c][ 499] append cam svc end
{SBBR}{info}[           _sb_bridge.c][ 194] bridge record list is empty, no action
{SBBR}{info}[           _sb_bridge.c][ 468] no broadcast svc appended, finish the process directly
FGU_PHM:ambi_music_get_sample_user:count =10938000

Any idea what went wrong and how to fixit?

RS232 inverts the logic. A 1 is actually a negative voltage.

Use a proper RS232 converter. While you wait for that to arrive, SoftwareSerial can flip the polarity in software.

SoftwareSerial will be unreliable at best trying to operate at 115200.

I do run at 115200 but applying reverced logic to Rx pin doesn't solved my issue:

SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin,1);

Yes, I can see some of the letters came through OK in the first example. So the polarity is correct.

I think you have proven that the Arduino you have (you didn't say which) can't run SoftwareSerial at 115200.

I'm using Arduino Uno R3, is there any chance that Leonardo will handle that? Or you suggest to switch this activity to regular serial pins 1&2?

If you use a Leonardo, you get a "free" serial port because it doesn't use pins 0 and 1 to communicate to the PC.

On the hardware Serial ports, you can get really high baud rates, sometimes in the millions.

MorganS thanks for the advice. Seems to be a good direction, however, I’ve spent today few hours trying to run the scripts on Leonardo using SoftwareSerial or Serial and I could not receive any information printed on SerialMonitor, even when the same script was working on UNO :frowning: I’m not sure what i do wrong on Leonardo that I can’t step forward…

On the Leonardo, use Serial1 (Pins 0 and 1) for input and Serial for output:

void setup()
{
  Serial.begin(115200);
  while (!Serial) ;
  Serial1.begin(115200);
}
void loop()
{
  if (Serial1.available())
    Serial.write(Serial1.read());
}

johnwasser, thanks a lot this is exact solution which I missed! I own you and MorganS big beer!

Let me ask one more question. I've already use hardware UART pin 0 & 1 at 115200bps (this is the speed which is need by transmitting device), and I'm still losing some portion of data to be received (from time to time)

Can you advice how to improve this section of code to be more optimized?

    while (Serial1.available()) {
      String uartLine = Serial1.readStringUntil('\n');      
      file.print(uartLine);
      if (saveStatus) saveStatus = false;
      logTime = millis(); 
    }

I read that using Strings in Arduino is not a good idea, how ever I'm not able to find better / more optimized way to read UART data instead of Serial1.readStringUntil('\n')

Use the techniques described in @Robin2's Serial Input Basics - updated tutorial and avoid the String class totally.

I read that using Strings in Arduino is not a good idea

In your case, using Strings is causing the problem.

The problem is in the code you didn't post.