Software serial problem

Hello everyone!

I'm confused with a simple task.

I have Arduino Nano with a TTL/RS422 shield. It connected to some device (RS232 via 232to422 moxa converter) which produce some ASCII protocol commands. Sketch is very simple (see below).

I know ASCII commands produced fine, because I can receive it with a hardware converter connected to my PC.

But in Arduino I have distorted data. It have size and structure of expected commands, but data is just a trash.

I've got
6E 75 76 56 0
6E 55 D9 56 B9 4B 95 9F E5 0
6E 95 B6 56 B9 57 95 9F E5 B9 4B 95 9F E5 0
6E D5 F6 E5 B9 57 95 9F E5 B9 4B 95 9F E5 0

but expect something like
[STX]OSD[ETX]
[STX]ASQ:1234[ETX]
[STX]PRD:3453:2345[ETX]

e/g [STX] must be 0x02
[HTX] - 0x03
: - 0x3A

I have tested it with RS232/TTL converter and got exactly same trashed data.
Baudrate 9600, 8n1.

#include <SoftwareSerial.h>

// Define debug
#define debug

// Define our tx/rx pins

#define OutTx 10   // tx pin from OUT side
#define OutRx 11   // rx pin from OUT side

SoftwareSerial OutSerial(OutRx,OutTx);

// define some variables

byte OutArray [64];
byte OutByte=0;
byte br=0;
byte avail=0;

void setup() {

  OutSerial.begin(9600);    // set OUT speed
  OutSerial.listen();

  avail=0;
  avail=OutSerial.available();
  OutSerial.readBytes(OutArray,avail);

 
  #ifdef debug
    // init terminal serial
    Serial.begin(115200);
    Serial.println("Started - vtester");
  #endif

}

void loop() {

  
  avail=OutSerial.available();
  Serial.print(avail);
  Serial.println(" bytes available");

  br=OutSerial.readBytes(OutArray,avail);

  Serial.print(br);
  Serial.println(" - bytes received");

  for(byte a=0;a<br;a++){
    Serial.print("0x");
    Serial.print(OutArray[a],HEX);
    Serial.print(" ");
      
  }
  Serial.println();
  
}

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

Try the 3rd example and change the start and end markers to STX and ETX and see what happens.

I assume 8N1 is correct for whatever device is sending the data?

...R

Your initialization of the Serial object is a conditional:

 #ifdef debug
    // init terminal serial
    Serial.begin(115200);

But after that, none of your prints to Serial are enclosed in the same conditional. In your example code, this isn't going to matter because you also #define debug. But in general, it is not a good idea to do this.

If the SoftwareSerial device has no bytes available, you try to read zero bytes anyway.
It would make more sense to wait until there's something to print:

 avail=OutSerial.available();
  if(avail == 0)return;

If you read anything, you print it to the serial monitor with a '0x' prefix:

   Serial.print("0x");

but none of the examples you showed have the 0x prefix. Apply the fix for 'avail == 0' and then show us what it really outputs.

It connected to some device

Which device generates this stream of characters?

Pete

Robin2:
Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

Try the 3rd example and change the start and end markers to STX and ETX and see what happens.

I assume 8N1 is correct for whatever device is sending the data?

...R

Ok, I'll try, but...
Of course device settings is correct.

doublehead:
Of course device settings is correct.

Long experience has taught me not to be emphatic like that :slight_smile:

Ok, I'll try, but...

Why the "but" ?

...R

el_supremo:
but none of the examples you showed have the 0x prefix. Apply the fix for 'avail == 0' and then show us what it really outputs.
Which device generates this stream of characters?

Pete

Dear Pete,

I know, my code is inaccurate and dirty, because it was edited many times during last week, and I just leave some conditions from my initial code.

About available bytes - i dont think this matters. readBytes data length parameter have type int. So you can pass -2 for example :wink: isn't it? But I correct it...

Output just cleaned up.. raw output here

15 bytes available
15 - bytes received
0x6E 0x55 0xF6 0x56 0x0 0x6E 0xD5 0xD9 0x56 0xB9 0x4B 0x95 0x9F 0xE5 0x0
15 bytes available
15 - bytes received
0x6E 0x55 0xF6 0x56 0x0 0x6E 0xD5 0x59 0x56 0xB9 0x4B 0x95 0x9F 0xE5 0x0
15 bytes available
15 - bytes received
0x6E 0x55 0xF6 0x56 0x0 0x6E 0x55 0x36 0x56 0xB9 0x4B 0x95 0x9F 0xE5 0x0
15 bytes available
15 - bytes received
0x6E 0x55 0xF6 0x56 0x0 0x6E 0x55 0xD6 0x56 0xB9 0x4B 0x95 0x9F 0xE5 0x0
28 bytes available
28 - bytes received
0x6E 0x55 0xF6 0x56 0x0 0x6E 0x55 0x36 0x56 0xB9 0x4B 0x95 0x9F 0xE5 0x0 0x6E 0x55 0xF6 0x56 0xB9 0x57 0x95 0x9F 0xE5 0xB9 0x4B 0x95 0x9F
2 bytes available
2 - bytes received
0xE5 0x0
0 bytes available
0 - bytes received

0 bytes available
0 - bytes received

0 bytes available
0 - bytes received

0 bytes available
0 - bytes received

15 bytes available
15 - bytes received
0x6E 0x55 0xF6 0x56 0x0 0x6E 0x55 0x59 0x56 0xB9 0x4B 0x95 0x9F 0xE5 0x0
30 bytes available
30 - bytes received
0x6E 0x55 0xF6 0x56 0x0 0x6E 0x55 0x59 0x56 0xB9 0x4B 0x95 0x9F 0xE5 0x0 0x6E 0x75 0xD6 0xE5 0x0 0x6E 0x55 0x59 0x56 0xB9 0x4B 0x95 0x9F 0xE5 0x0
60 bytes available
60 - bytes received
0x6E 0x75 0xD6 0xE5 0x0 0x6E 0xD5 0xB6 0x56 0xB9 0x4B 0x95 0x9F 0xE5 0x0 0x6E 0x75 0x36 0x56 0x0 0x6E 0xD5 0xB6 0x56 0xB9 0x4B 0x95 0x9F 0xE5 0x0 0x6E 0x75 0x36 0x56 0x0 0x6E 0xD5 0x16 0x56 0xB9 0x4B 0x95 0x9F 0xE5 0x0 0x6E 0x75 0x76 0x56 0x0 0x6E 0xD5 0x16 0x56 0xB9 0x4B 0x95 0x9F 0xE5 0x0
22 bytes available
22 - bytes received
0x6E 0x75 0x76 0x56 0x0 0x6E 0xD5 0x76 0x56 0xB9 0x4B 0x95 0x9F 0xE5 0x0 0x6E 0x75 0x76 0x56 0xB9 0x57 0x95
23 bytes available
23 - bytes received
0x9F 0xE5 0xB9 0x4B 0x95 0x9F 0xE5 0x0 0x6E 0x55 0xF6 0x56 0xB9 0x57 0x95 0x9F 0xE5 0xB9 0x4B 0x95 0x9F 0xE5 0x0
0 bytes available
0 - bytes received

0 bytes available
0 - bytes received

0 bytes available
0 - bytes received

0 bytes available
0 - bytes received

0 bytes available
0 - bytes received

15 bytes available
15 - bytes received
0x6E 0x55 0x76 0x56 0xB9 0x57 0x95 0x9F 0xE5 0xB9 0x4B 0x95 0x9F 0xE5 0x0
15 bytes available
15 - bytes received
0x6E 0x35 0x36 0x56 0xB9 0x57 0x95 0x9F 0xE5 0xB9 0x4B 0x95 0x9F 0xE5 0x0
15 bytes available
15 - bytes received
0x6E 0x15 0xF6 0xE5 0xB9 0x57 0x95 0x9F 0xE5 0xB9 0x4B 0x95 0x9F 0xE5 0x0
15 bytes available
15 - bytes received
0x6E 0xD5 0x9F 0xE5 0xB9 0x57 0x95 0x9F 0xE5 0xB9 0x4B 0x95 0x9F 0xE5 0x0
26 bytes available
26 - bytes received
0x6E 0xD5 0x93 0xE5 0xB9 0x57 0x95 0x9F 0xE5 0xB9 0x4B 0x95 0x9F 0xE5 0x0 0x6E 0xD5 0x9F 0xE5 0xB9 0x57 0x95 0x9F 0xE5 0xB9 0x4B
19 bytes available
19 - bytes received
0x95 0x9F 0xE5 0x0 0x6E 0x55 0xF6 0x56 0xB9 0x57 0x95 0x9F 0xE5 0xB9 0x4B 0x95 0x9F 0xE5 0x0
0 bytes available
0 - bytes received

Device - Vaddio video panel. Data - commands for Panasonic PTZ camera.

NOTE: I was wrong...
First record
0x6E 0x55 0xF6 0x56 0x0 must be
0x23 0x5A 0x35 0x30 0x0d (#Z50)

raw output from Vaddio on my PC:

23 50 34 39 0d 23 54 35 30 0d 23 5a 35 30 0d 23 #P49.#T50.#Z50.#
50 33 38 0d 23 54 35 30 0d 23 5a 35 30 0d 23 50 P38.#T50.#Z50.#P
33 30 0d 23 54 35 30 0d 23 5a 35 30 0d 23 50 32 30.#T50.#Z50.#P2
36 0d 23 54 35 30 0d 23 5a 35 30 0d 23 50 35 30 6.#T50.#Z50.#P50
0d 23 54 35 30 0d 23 5a 35 30 0d .#T50.#Z50.
23 50 35 31 0d 23 54 35 30 0d 23 5a 35 30 0d 23 #P51.#T50.#Z50.#
50 35 38 0d 23 54 35 30 0d 23 5a 35 30 0d 23 50 P58.#T50.#Z50.#P
36 30 0d 23 54 35 30 0d 23 5a 35 30 0d 23 50 35 60.#T50.#Z50.#P5
30 0d 23 54 35 30 0d 23 5a 35 30 0d 0.#T50.#Z50.
23 50 35 30 0d 23 54 34 39 0d 23 5a 35 30 0d 23 #P50.#T49.#Z50.#
50 35 30 0d 23 54 35 30 0d 23 5a 35 30 0d P50.#T50.#Z50.

Robin2:
Long experience has taught me not to be emphatic like that :slight_smile:
Why the "but" ?

...R

Because I have done it in many ways :):):slight_smile: and with markers too. and I always get the same corrupted data.

PS: I have plenty experience with a serial communications on arduino and under linux. But I never seen similar data corruption.

[quote]readBytes data length parameter have type int. So you can pass -2 for example[/quote]
Just because you use the correct data type doesn't mean that the value that you pass is valid. I think the data type used by readBytes is actually size_t which is an unsigned integer. If so, asking for -2 bytes will actually try to read 65534 bytes (if you're using a 16-bit processor).

The fact that you are consistently getting messages which always begin with 0x6E, I'd say that what you are reading is what is being sent.

In your first post you said:
[quote]I know ASCII commands produced fine, because I can receive it with a hardware converter connected to my PC.

but now you show output ...

raw output from Vaddio on my PC:

which doesn't contain STX or ETX which you said is what should be there.

Exactly which device is sending that data and where is the documentation for the protocol that it uses?

Pete

doublehead:
Because I have done it in many ways :):):slight_smile: and with markers too. and I always get the same corrupted data.

PS: I have plenty experience with a serial communications on arduino and under linux. But I never seen similar data corruption.

Trying "many ways" is seldom a good debugging technique. Get a receiving program that works (and is proven to work) and stick with it. If there is a problem then suspect the sending program or the wiring or the comm-port settings.

For testing, can you arrange to receive the data using HardwareSerial - perhaps on a Mega?

...R

Hello guys!

Pete, Robin2 you both were right.

I really get data which were sent by device. And I'm an idiot - device have 9600 8n1 !HALF-DUPLEX! mode.

I make test with a two arduinos, if one send data with speed 4800 and another recevie it with speed 9600 I've got a similar data corruption. Values are very close to data which I've got from Vaddio device. And very similar data corruption we've got if model of processor (in IDE) was set incorrectly (16 MHz instead 8MHz), because software serial library uses processor speed to calculate timings.

So, result question is how to set right mode for software serial?

doublehead:
So, result question is how to set right mode for software serial?

What mode do you want it to be?

...R