Serial.Read returning wrong data

Hey guys,

I am new to Arduino programming and thoguht I had a pretty basic program but I am not getting the expected results.

I have a Crestron RMC3 processor which I want to communicate over Serial to my Arduino Leonardo. The Crestron processor has a "1-way serial TTL/RS-232 (0-5 Volts) up to 115.2k baud" which I have connected my Arduino to.

For my test I have the following code,

void setup() {
  // open the serial port:
  Serial1.begin(9600);
  Serial.begin(9600);
}

void loop() {
  // check for incoming serial data:
  if (Serial1.available() > 0) {
    // read incoming serial data:
    char inChar = Serial1.read();
    
    Serial.println(inChar, DEC);
    Serial.println(inChar, HEX);
    Serial.println(inChar, OCT);
    Serial.println(inChar, BIN);


    delay(50);
  }
}

So for my test I am reading from Serial1 but I am printing to Serial so that I can troubleshoot my program.

The issue I have is if I send hex value 77 from my Crestron processor (ascii charecter "w"), then I get the following printed on my laptop,

68
44
104
1000100

Why is that? I dont see why the data arrives corrupt?

Any idea what I am doing wrong? I have checked the connection and both are correctly set to 9600 8N1 and I even tried a lower speed but it made no difference.

What am I missing?

(deleted)

spycatcher2k:
What RS232 to TTL converter did you use? The output is inverted on the Crestron.

I didn't think I would need any sort of converter? The spec on the Arduino says that pins 0 and 1 are 0-5V TTL. The Crestron spec says the port can do 1-way serial TTL/RS-232 (0-5 Volts).

So I thought they were both 0-5V TTL?

(deleted)

spycatcher2k:
Regardless of what you think, the output is inverted on the Crestron. A TTL RS-232 port is a 5V logic level port running the RS232 protocol, The arduino UART is running an inverted protocol compared to the RS232. You can build a simple inverter with a transistor and a resistor.

I see, thanks for clarifying.

I basically have two options then,

Option 1) Use a converter

Option 2) Program around it

I am basically building a USB-HID emulator. So I just need to send a byte from the Crestron processor to tell the Arduino to press a keyboard button.

Option 1 would be nicer programatically but would introduce an extra piece of hardware in the chain.

Option 2 is not pretty but I guess I could map it so that if I send \x77 then I should look for \x44 on the Arduino.

Is there any danger going down the route of using option 2? Even though its inverted, will it reliably produce the same output each time?

(deleted)

If you mean that the logic is inverted from one to the other, you could do this very easily in program:

void setup() {
  // open the serial port:
  Serial1.begin(9600);
  Serial.begin(9600);
}

void loop() {
  // check for incoming serial data:
  if (Serial1.available() > 0) {
    // read incoming serial data:

    //See that tilde? That's the magic! It's a bitwise invert (called a "complement")
    char inChar = ~Serial1.read();
    
    Serial.println(inChar, DEC);
    Serial.println(inChar, HEX);
    Serial.println(inChar, OCT);
    Serial.println(inChar, BIN);


    delay(50);
  }
}

Fuzzyzilla:
If you mean that the logic is inverted from one to the other, you could do this very easily in program:

void setup() {

// open the serial port:
  Serial1.begin(9600);
  Serial.begin(9600);
}

void loop() {
  // check for incoming serial data:
  if (Serial1.available() > 0) {
    // read incoming serial data:

//See that tilde? That's the magic! It's a bitwise invert (called a "complement")
    char inChar = ~Serial1.read();
   
    Serial.println(inChar, DEC);
    Serial.println(inChar, HEX);
    Serial.println(inChar, OCT);
    Serial.println(inChar, BIN);

delay(50);
  }
}

Thanks, I tried it but it didn't work unfortunately. It returned,

-69
FFFFFFBB
37777777673
11111111111111111111111110111011

What I was thinking about doing otherwise was something along this,

switch (inChar) {
case 68:
Keyboard.write('w');
break;
}

Simply inverting the values in software isn't going to work if it is the line that needs inverting - start bit detection by the USART is going to be data-dependent.

Isn't -69 equal to 'W'?

Try just serial printing the char. It should say 'w'

SoftwareSerial has an 'inverted signal' option:

SoftwareSerial RMC3(RxPin, TxPin, true);

Fuzzyzilla:
Isn't -69 equal to 'W'?

Not even close.

oqibidipo:
SoftwareSerial has an 'inverted signal' option:

SoftwareSerial RMC3(RxPin, TxPin, true);

Not even close.

You are a genius! Thanks, SoftwareSerial worked perfectly! I now get exactly what I sent coming through!

Only thing I'll point out for other people in case they read this thread in the future is that I was unable to use SoftwareSerial on pins 0 and 1. I had to use pin 8 instead on my Leonardo board, but it worked like a charm!

Thanks to everyone on here for all your help!

Edit: Here is what my final code looks like,

#include "Keyboard.h"
#include <SoftwareSerial.h>

SoftwareSerial RMC3(8, 1, true);

void setup() {
  // open the serial port:
  RMC3.begin(9600);

  // initialize control over the keyboard:
  Keyboard.begin();
}

void loop() {
  // check for incoming serial data:
  if (RMC3.available() > 0) {
    // read incoming serial data:
    int inChar = RMC3.read();

    Keyboard.write(inChar);

  }
  delay(100);
}