Help Needed.  Serial data manipulation.

Hi All,

Please do not beat me up to much if I posted in the wrong area. I am just getting started and a newbie to the Arduino and the group.

I am wondering if someone can help with some code. What I am trying to do is take rs232 data in on pin0 and output it in a different format on pin1.

Data coming in looks like this. The data is always starts with 3 digits then ends with 1 digit.

005 5 120 8 160 9

I would like to have that data output like this

%005/5 %120/8 %160/9

Any help would be greatly appreciated. Thanks Everyone, Mike G

This is the correct place for software issues, so nothing to worry about there.

If you know the data comes in like you've shown, you must have some code that reads the data, and prints it out.

Show us that code, and we'll show you how to change it.

Basically, though, you don't need to print everything with Serial.println. The Serial.print command does the same thing that Serial.println does, except print the carriage return.

You can also print constant strings, like this:

Serial.print("%");
Serial.print("/");

Hi Paul,

I do not have any code for the devices. What I have is a direction finder kinda like a LoJack tracking unit. http://www.dopsys.com/ser5900.htm The box outputs 4800 baud plain text serial data. The 3 digits is a heading of the signal based on 360 degrees. The next line of outputs is how strong the signal is from 1 to 9.

The software you run on a laptop wants to see it in a different way. The message format is %XXX/Y(cr), where XXX = relative bearing to signal, Y = bearing quality. http://www.silcom.com/~pelican2/PicoDopp/WINDOPP_MORE.html

Thanks, Mike

Data coming in looks like this. The data is always starts with 3 digits then ends with 1 digit.

005 5 120 8 160 9

Are you reading this from pin 0? Or are you hoping this is true?

I am guessing I am going to from pin0 unless there is a better way. I know I will need to add a MAX232 to mate it to the Arduino. That is what the data looks like from a term window.

Thanks Paul, Mike

So is this harder to do that than I think?

I am not sure where to research what I am looking for. If someone can point me in the right direction that would be great.

I guess an Arduino is not for beginers. Ohhh well. :(

Thanks, Mike

You'll find there's lots of help here, but not many people willing to solve a problem end-to-end. Show some stuff you've tried that doesn't work, and explain the specifics surrounding what you expected and what you got. You'll see some suggestions show up then.

Welcome to Arduino.

Okay. Don't laugh now I told you I was a newbie. :P I am not sure if this is the correct way to do it. :-/

int incoming3Byte = 3;      // for incoming serial data
int incoming1Byte = 1;      // for incoming serial data

void setup() {
      Serial.begin(4800);      // opens serial port, sets data rate to 4800 bps
}

void loop() {

      // send data only when you receive data:
      if (Serial.available() > 0) {
            // read the incoming byte:
            incoming3Byte = Serial.read();
            incoming1Byte = Serial.read();

            // say what you got:
            Serial.print("%");
            Serial.print(incoming3Byte);
                Serial.print("/");
                Serial.println(incoming1Byte);
      }
}

I wonder how bad I did on this test?

Thanks all, Mike

Nope, no laughing at noobs that learn. Only laughing at noobs that don't.

You just need some experience to start thinking a little more like a computer. It looks like you expect Serial.read to read 3 numbers when you assign it to incoming3byte. But serial.read only ever reads 1 byte at a time.

You also might need some info on the difference between a byte value and the ASCII representation. Numbers 0-9 as ASCII characters have decimal values of 48-57. See http://www.asciitable.com/ Note decimal 13: carriage return. There is an invisible byte (maybe two) sent between the first 3 digits and the 4 digit that indicates the new line and/or carriage return.

The last point I'll make is that just because Serial.available() is true, it doesn't mean that Serial.Has3DigitNumber_andalso_1digitNumber is true. Depending on how fast the data coming in is injected onto the serial port the Arduino might try and read it before it arrives.

Here's some half-baked code off the top of my head of what I think you're trying to do. I'll leave it to you to try and fix my mistakes and get it to compile (and fix the bugs)...

byte AllFourDigits[4];
byte index = 0;

void loop()
{
  if (Serial.available()) {
    byte b = Serial.read();
    if (b != 13 && b != 10)  // swallow newline/carriage return characters
    {
      AllFourDigits[index] = b;
      index++;
    }
  }

  if (index == 4)
  {
    Serial.print("%");
    Serial.print(AllFourDigits[0]);
    Serial.print(AllFourDigits[1]);
    Serial.print(AllFourDigits[2]);
    Serial.print("/");
    Serial.println(AllFourDigits[3]);
    index = 0;
  }
}

Thanks Mitch,

Hope you can point me in the right direction for this part. I just need to know what to research.

This code listed below does work if I make sure the Arduino it up and running 1st before starting the input serial source. My next step is to figure out how to check for 3 digits and a carriage return before it starts its process. Maybe an array or something. If the Arduino starts inputting the data at the wrong time like taking in the single digit 1st before the 3 then the output string will be all messed up. My other is that the 3 digit data will be from 000 to 360 and the single digit is always 0 to 9. Maybe try to check for a valid range or something.

Here is the code that works with no error checking.

byte First3Digits[3];
byte LastDigit[1];
byte index = 0;

void setup() {
      Serial.begin(4800);      // opens serial port, sets data rate to 4800 bps
}

void loop()
{
  if (Serial.available()) {
    byte b = Serial.read();
    if (b != 13 && b != 10)  // swallow newline/carriage return characters
    {
      First3Digits[index] = b;
      LastDigit[index] = b;
      index++;
    }
  }

  if (index == 4)
  {
    Serial.print("%");
    Serial.print(First3Digits[0]);
    Serial.print(First3Digits[1]);
    Serial.print(First3Digits[2]);
    Serial.print("/");
    Serial.println(LastDigit[0]);
    index = 0;
  }
}

Thanks again Mitch. I am glad there are people like you willing to work with newbies. I know we can be a pain in the rear sometimes. ;)

Mike

Sounds like you're already talking yourself through the necessary logic. The details depend on your specific application. Are you concerned about dropping/discarding data? What are the possible errors you'll encounter?

You need to consider the logic rules the input will follow and write the handler accordingly. If the input doesn't match the expected, then reset the state and wait for a delimiter to resume processing.

Right now you've described this unique pattern that defines the start of a new data packet: carriage-return, single digit, carriage-return

I am not concerned about dropping some data since there is alot of it so missing a small about will be nothing. So I always want to start with the 3 digits. If I check for 3 and drop the 4 than I want to start over and look for the 3 before seeing a carriage return. I want to also avoid the 1st 3 in and missing the single or getting the single from the one after.

Thanks, mike