Go Down

Topic: Need some help with displaying serial data (Read 82 times) previous topic - next topic

donmerch

I am using SoftwareSerial to write to a serial lcd and also communicate with a scale. The message to the scale is a capital W. The return message from the scale looks like "02 000.00 /r where 02 indicates start of message and the carriage return indicates end of message. It's just ascii data being received.

In my code I attempt to trigger on the 0x02 and then put the rest of the data into a string called inputString. When the '/r' is received then I want to print out the inputString string. I think I've made it where it does not store the start character '02' and the end character '/r' but I get some crazy characters printing.

In my setup I use this statement- inputString.reserve(16); to define the size of the inputString. I've tried making it only 6, 7, & 8 and16 bytes but it always acts the same. Using the logic analyzer going into the Arduino pin the data looks perfect everytime. It seems like I'm overflowing a buffer or reading in data somehow that I don't want. What am I doing wrong?

Code: [Select]

void loop() {
  delay(2000);                                         
  float uS = sonar[currentSensor].ping_median(20);    // Send ping, get ping time in microseconds (uS).
  Serial.print(uS / US_ROUNDTRIP_IN);
  LCDSerial.write(0x8C);         // Move to line 0 position 12
  LCDSerial.print("       ");    // Clear data area
  LCDSerial.write(0x8C);         // Move to line 0 position 12
  LCDSerial.print(uS / US_ROUNDTRIP_IN);
  LCDSerial.write(0x22);        // Inches (")
  Serial.println("in");

  ScaleSerial.write(0x57);       // Send "W"
  ScaleSerial.listen();
  inChar = ScaleSerial.read();
  if (inChar = 0x02) {
    while (ScaleSerial.available() > 0) {
      inChar = ScaleSerial.read();
      if (inChar == '\r') {
        Serial.println(inputString);
        LCDSerial.write(0xC8);         // Move to line 0 position 12
        LCDSerial.print("       ");    // Clear data area
        LCDSerial.write(0xC8);         // Move to line 0 position 12
        LCDSerial.print(inputString);
        inputString = "";       
      }
      else {
        inputString += inChar;     
      }
    }
  }
}


I've attached a screen shot of the terminal monitor. It should look like this:

0.00"
000.15
0.00"
000.15

but you can see the garbage in the photo that it prints. The 000.15 is just showing that there is .15 lbs of weight on the scale at present.

Thanks.

AWOL

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

econjack

If you really are using "02 000.00 \r" as the input string, try the code below:
Code: [Select]

void setup() {

 Serial.begin(9600);

}

void loop() {
  char buffer[20];      // Input test string: "02 000.00 \r"
  int charsRead;

  if (Serial.available() ) {
    charsRead = Serial.readBytesUntil('\r', buffer, sizeof(buffer) - 1);
    buffer[charsRead - 2] = '\0';   // Overwrite carriage return characters '\' and 'r'
    if (buffer[0] == '0' && buffer[1] == '2') {   // Necessary leadin?
      Serial.println(&buffer[2]);
    }
  }

}

If you are testing for the newline character, you'd have to modify the code a little.

Robin2

Have a look at the 3rd example in Serial Input Basics. Just change the start and end markers to meet your requirement. There is also a parse example.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

donmerch

Have a look at the 3rd example in Serial Input Basics. Just change the start and end markers to meet your requirement. There is also a parse example.

...R

Ok so I looked at your example and incorporated it into my code.

Code: [Select]

void loop() {
    recvWithStartEndMarkers();
    showNewData();
    delay(2000);
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = 0x02;
    char endMarker = '\r';
    char rc;
   
    ScaleSerial.write(0x57);       // Send "W"
    ScaleSerial.listen();
   
    while (ScaleSerial.available() > 0 && newData == false) {
        rc = ScaleSerial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.println(receivedChars);
        LCDSerial.write(0xC8);         // Move to line 0 position 12
        LCDSerial.print("       ");    // Clear data area
        LCDSerial.write(0xC8);         // Move to line 0 position 12
        LCDSerial.print(receivedChars);
       // inputString = "";
        newData = false;
    }
}


I still get erroneous data occasionally. See the attached screenshots.

In LogicScale1 you see the 'W' sent and the reply from the scale. However I did happen to catch it messing up 1 time with Logic Analyzer. See LogicScale2. Notice that there is a slight delay after the start byte '0x02'. How is this type of situation handled?

As I mentioned earlier I'm using SoftwareSerial. I use it to communicate with the LCD display. I do not receive anything back from the display. It seems if I comment out the portion of code that communicates with the display then the code will seem to run nearly perfect except for when there is a slight delay after the start byte. As soon as I uncomment the LCDSerial lines then there is more occasional chaos. Is there a conflict with the receive buffer between the LCDSerial and ScaleSerial? Is there a way to ignore the Rx buffer of LCDSerial even though I don't even have it connected?

Were getting closer...

Thanks.

donmerch

#5
Today at 12:30 am Last Edit: Today at 12:36 am by donmerch
Here's something else that may be causing an issue. I notice that I don't always get the data displayed on the terminal. The terminal doesn't always display after the scale has been sent a command and data received.



Notice that there had been 8 commands and responses from the scale but only 5 of them displayed. So maybe there's residual data in the buffer?

donmerch

#6
Today at 02:45 am Last Edit: Today at 02:57 am by donmerch
Well I found something while searching other serial examples and it seems to have helped quite a bit but there's still an issue with it not always displaying every time it communicates with the scale. I added this to the beginning of the code:

Code: [Select]

 #define ScalerxPin 2
 #define ScaletxPin 3
 #define LCDrxPin 7
 #define LCDtxPin 8


And this to the setup method:

Code: [Select]

  pinMode(ScalerxPin, INPUT);
  pinMode(ScaletxPin, OUTPUT);
  pinMode(ScalerxPin, INPUT);
  pinMode(ScaletxPin, OUTPUT);


As I mentioned before if I don't communicate at all with the LCD display (by commenting out the LCDSerial write / print routines) and just watch the data on the serial terminal it works fine.

Any ideas or suggestions anyone?

I've considered going to the Mega2560 just to add the additional hardware serial ports or even going back to the Parallax Propeller.

AWOL

Quote
Any ideas or suggestions anyone?
Post your code, post your observations.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Robin2

Slow down a bit - I can't keep up with all of that. Post your latest code (a complete program) with a description of how it behaves.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy