Question/help regarding TTL serial string reading

Hi All,

Hope everyone out there in Arduino land are safe and well under the circumstances.

Hopefully this is the right place to post this question, I’m sorry if I’ve misunderstood the categories.

I’m using an Arduino Micro for this project (I also have a new in box Arduino Uno if that makes life easier?

I am connecting the Arduino to a ‘DollaTek MAX3232 RS232 Serial Port To TTL Converter Module DB9 Connector’. I have successfully used this Arduino and this adapter with serial cable to successfully control an NEC projector over serial/TTL. So as far as I can tell, this hardware is suitable for this new project.

The project is to connect to the serial/TTL port on a Bang & Olufsen Beosystem 3 (the monitor port) and read out the commands it would send to a B&O TV if one was connected to it. The TV’s are essentially Panasonic plasma screens and you can see what I’m expecting to see come out of the BS3 by looking at a Panasonic manual: Panasonic manual

I’m essentially trying to do what Nigel has done on a Raspberry Pi but on an Arduino - Nigel’s Project

So far my code is only a simple serial monitor, it is taking what it sees/hears on the software serial (external) and relays it on the serial monitor. I’m using this to see if I’m getting the correct commands, which I sort of am but it is not in the correct format. The code looks like this:

//Define all appropriate variables
#define rxPin 14
#define txPin 15
int ByteReceived;
char buf[200];
unsigned int i = 0;


#include <SoftwareSerial.h>
SoftwareSerial External(rxPin, txPin); // RX, TX

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Native USB only
  }

  // set the data rate for the SoftwareSerial port
  External.begin(9600);
}

void loop() // run over and over
{
  External.setTimeout(10);
  int len = External.readBytes(buf, 136);
  if (len > 0)
  {

    Serial.print("len");
    Serial.println(len);
    Serial.println(buf);
    Serial.flush();
  }
}

I get a semi useful output on the serial monitor:


From Nigel’s comments I should be looking for something like /02PON/03 however I’m only getting PON.
I work in IT infrastructure and only rarely touch code and if it is, it’s MS PowerShell, so this is all a bit alien to me.
Would someone be able to provide guidance as to how to get the correct format of output? Eventually I will want to add IF/case statements where if ‘power on detected’ then issue a CEC power on command to the TV, but I’m not that far yet.
Really welcome and appreciate any feedback, as I say, I’m not all that good at this!

Welcome,

\x02 and \x03 are not printable characters, that's probably why you don't see them in the serial monitor

guix:
Welcome,

\x02 and \x03 are not printable characters, that's probably why you don't see them in the serial monitor

Thanks for the reply, could explain that then! I guess the question is how do I make it printable? I'm probably using the wrong commands to read from the serial, maybe I want to read as hex and print out of hex, or something along those lines. I've tried googling how to read out hex but just get odd errors where I don't understand the code, perhaps more likely I'm looking for Binary based off the last page of the manual:

well instead of Serial.println(buf);
you could do something like :

for (uint8_t i = 0; i < len; i++) {
  Serial.print((uint8_t) buf[i], HEX);
  Serial.print(", ");
}
Serial.println();

Deva_Rishi:
well instead of

 Serial.println(buf);

you could do something like :

for (uint8_t i = 0; i < len; i++) {

Serial.print((uint8_t) buf[i], HEX);
 Serial.print(", ");
}
Serial.println();

Hi, Thanks for the speedy reply,
So my code now looks like:

//Define all appropriate variables
#define rxPin 14
#define txPin 15
int ByteReceived;
char buf[200];
unsigned int i = 0;

#include <SoftwareSerial.h>
SoftwareSerial External(rxPin, txPin); // RX, TX

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Native USB only
  }

  // set the data rate for the SoftwareSerial port
  External.begin(9600);
}

void loop() // run over and over
{
  External.setTimeout(10);
  int len = External.readBytes(buf, 255);

  for (uint8_t i = 0; i < len; i++) {
    Serial.print((uint8_t) buf[i], HEX);
    Serial.print(", ");
  }
  Serial.println();
}

Is this right?
I now get outputs on the monitor like: 2, 56, 4D, 54, 3A, 31, 3, and 2, 50, 4F, 46, 3, but my serial monitor is running all the time and full of blank space auto scrolling all over the place. It’s hard to understand/catch what is happening.

Hi Al,

OK I feel like I’m getting somewhere thanks to @Deva_Rishi

My loop looks like below:

void loop() // run over and over
{
  External.setTimeout(10);
  int len = External.readBytes(buf, 255);
  //Serial.print("test");
  if (External.available())
    Serial.print("test");
  {
    for (uint8_t i = 0; i < len; i++) {
      Serial.print((uint8_t) buf[i], HEX);
      //Serial.print(buf);
      Serial.print(", ");
    }
    // Serial.println();
  }
}

The Power off command is: 02 50 4F 46 03

and in the output code I now see amongst the noise: 2, 50, 4F, 46, 3

So my next issue is understanding how to print the hex with leading zeros - I have found this https://forum.arduino.cc/index.php?topic=38107.0 but it doesn’t mean much to me and I’m struggling to understand.

The next issue will be making the code output the strings one at a time, seeing as every code should start with a 02 and end with a 03 I assume there is a way to code this in, I just don’t know how.

Thanks again for the support.

Why do you want to see those characters, or print in hex, or print with leading 0s ? This is only for your eyes, but your code don't need any of that to work with those commands.

For example

if ( !strncmp( buf, "\x02" "PON" "\x03", 5 ) ) // if string starts with \x02PON\x03
{
  sendCECPowerOnCommand();
}

guix:
Why do you want to see those characters, or print in hex, or print with leading 0s ? This is only for your eyes, but your code don't need any of that to work with those commands.

Thanks,

Sorry, not sure what happened with my last reply.

I guess I don’t necessarily need to see the correct output, as you say as long as the code understands that is fine. I’m not a coder and your example doesn’t really mean much to me.

Are you able to give a fully working example or show how it would look in practice?

Thanks,

I have updated my previous post

Edited once again to solve a problem with those escaped hex characters...

guix:
I have updated my previous post

Edited once again to solve a problem with those escaped hex characters…

Really appreciate the help,
I’ve got my ‘serial monitor’ sketch close enough that it is usable, I’d like to improve it as it is visually to help with troubleshooting, so the user can see at a glance if the output is right. (that is why I was trying to make it look right).
I’ve now moved onto my actual sketch for the program I’m trying to get to run on the Arduino.

/*
  This is a simple sketch to create a listening serial monitor to allow you to read the values coming across the serial interface.
*/
//Define all appropriate variables
#define rxPin 14
#define txPin 15
char buf[200];
#include <SoftwareSerial.h>
SoftwareSerial External(rxPin, txPin); // RX, TX

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Native USB only
  }
  // set the data rate for the SoftwareSerial port
  External.begin(9600);
}

void loop() // run over and over
{
  External.setTimeout(10);
  int data_output = External.readBytes(buf, 255);
  if (External.available())
    Serial.print("");
  {

    if ( !strncmp( buf, "\x02" "PON" "\x03", 5 ) ) // if string starts with \x02PON\x03
    {
      //sendCECPowerOnCommand();
      Serial.print("PON CMD Detected");
      Serial.println();
    }
    if ( !strncmp( buf, "\x02" "POF" "\x03", 5 ) ) // if string starts with \x02POF\x03
    {
      //sendCECPowerOnCommand();
      Serial.print("POF CMD Detected");
      Serial.println();
    }
  }
}

Based on what you’ve given me I get the following result:

Looks like the power on command works/is recognised MANY times, but the power off command doesn’t get flagged.

  if (External.available())
    Serial.print("");
  {

This is wrong, move the Serial.print below the {

And are you sure the device is sending a POF command? Because in the screenshot in your first post, I can't see a POF.

guix:

  if (External.available())
Serial.print("");

{




This is wrong, move the Serial.print below the {


And are you sure the device is sending a POF command? Because in the screenshot in your first post, I can't see a POF.

the serial print I don't even need, it's there because in the monitor script for what ever reason if it isn't there nothing outputs to the monitor at all.
it 100% sends power off, I thought I posted this but I guess not:

That was me comparing the expected value to the hex outputs at shutdown.

david656:
for what ever reason if it isn’t there nothing outputs to the monitor at all

Because

if (External.available())
    Serial.print(""); // <--  Your conditional block stops here

And this condition will never be true anyway, because you used External.readBytes(buf, 255) BEFORE, so available() will return 0. I suggest that you read Serial documentation and learn how to use it correctly

So my next issue is understanding how to print the hex with leading zeros

Not sure if you still have the issue, but a simpleif ((uint8_t) buf[i] < 16) Serial.print("0");before Serial.print((uint8_t) buf[i], HEX);should work.

The next issue will be making the code output the strings one at a time

It actually is, but due to the Serial.print("");
You and guix have been talking about, The code that print it to the Serial port, gets executed regardless of new data being available. And i suspect that if there is nothing available in the port the variable remains unaltered here : int data_output = External.readBytes(buf, 255);I mean it is sort of like mempy() i thoionk, i never use the function, so i don’t know the details, but from the reference i see you let it time out, ok, but you should then verify that something was altered. So instead of this :

int data_output = External.readBytes(buf, 255);
  if (External.available())
    Serial.print("");
  {

    if ( !strncmp( buf, "\x02" "PON" "\x03", 5 ) ) // if string starts with \x02PON\x03

It should be more something like this :

if (data_output = External.readBytes(buf, 255)) { // readbytes returns 0 if no valid data.
// now the Serial.print and it's semicolon should not be there, guix is right.
    if ( !strncmp( buf, "\x02" "PON" "\x03", 5 ) ) // if string starts with \x02PON\x03

And so forth as it was.
You put the Serial.print(""); back because otherwise you were getting no output, but that was not what was wrong and then you got repeated output, better than nothing though. If the power off CMD does get received, you should have found it in the Serial monitor though, you code just kept repeating what it had received last, but i doubt you would be able to keep scrolling to the end to see it.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.