Serial Communication with a digital balance

Hi

I have two questions regarding serial communication between my arduino Uno and a FX-120i balance:

  1. When ever I read serial data from the balance the first line is always rubbish. After I press the print button the second time, my data is correct. Why can this be?
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11);  

void setup()  
{
  Serial.begin(19200);  
  mySerial.begin(19200);

}

void loop() 
{
  
  
 while (mySerial.available()){
   Serial.print(mySerial.readString());
}
 }

Output:

See attached picture - Question 1

  1. If I try and command the scale to send me data from the arduino I use the following code:
#include <SoftwareSerial.h>
#include <SPI.h>
#include <Wire.h>

SoftwareSerial mySerial(10, 11);  

 float value = -1.0;

void setup()  
{
  Serial.begin(19200);  
  mySerial.begin(19200);

 

}

int readScale(float *returnValue) {
    
    mySerial.write("Q\r\n");
    delay(50);
    
    if (mySerial.available()) {
      Serial.println("data available");
      bool negative = false;
      bool stable = false;
      String scaleOutput = mySerial.readStringUntil("\n");
      
        Serial.print("SCALE OUTPUT:");
        Serial.println(scaleOutput);
        Serial.println(scaleOutput.indexOf("."));
      
      if ((scaleOutput.indexOf(".") == 8) || (scaleOutput.indexOf('.') == 9)) {
        if (scaleOutput.indexOf('ST') != -1) {
          //Serial.println("stable");
          stable = true;
        }
        if (scaleOutput.indexOf('-') != -1) {
          negative = true;

        }
        String valueString = scaleOutput.substring(4, 12);
        
          Serial.println(valueString);

        
        float value = valueString.toFloat();
        if (negative) value = value * -1;
        Serial.print("Float: ");
        Serial.println(value, 3);
        *returnValue = value;
        if (stable) return 1;
        return 0;
      } else {
        return -1;
      }

    } 
  
  // wrong scale configuration
  return -1;
}

int readScaleStableOrUnstable(float * returnValue) {
 
  
  int stable = 0;
  int errcount = 0;
  float value;
  stable = readScale(&value);
  while (stable == -1) {
    stable = readScale(&value);
    if (errcount++ > 10) {
      return -1;
    }
  }
  *returnValue = value;
  return stable;
}

void loop() {
  
  readScaleStableOrUnstable(&value);

  Serial.print(value);
}

The output can be seen in picture attached - Question 2.

The serial data is available but I don't read anything.

Please advise?

Thanks.

Please display your image(s) in your post so we can see it(them) without downloading it(them). See this Simple Image Upload Guide

If the images are just text from your PC then please just copy and paste the text rather than posting an image of it.

A possible reason for the initial garbage is that the Arduino will have been running and producing output before the Serial Monitor started and that output will have been collected in the PC's serial buffer.

If you want advice about controlling the balance please post a link to its user manual or datasheet.

...R
Serial Input Basics - simple reliable ways to receive data.

Please find the manual of the balance here: https://scalenet.com/pdf/FX-i_Precision_Scales.pdf

The first thing that strikes me is that the balance communicates at RS232 signal levels which are not compatible with the Arduino's TTL signal levels. The RS232 signals might damage an Arduino. You need a MAX232 (or similar) to convert between the TTL and RS232 signal levels.

...R

One thing I notice is that I don't think you're handling is the handshaking in the serial protocol.

The datasheet is not terribly clear on serial messages other than commands, I think that after you send "Q" the scale first sends back an ACK (<06>) and then a second message follows with the scale data.

I wouldn't use String objects for this. Consider instead using a char arrays to send and receive data and implementing a state machine to implement the protocol.

I am using a TTL to RS232 Converter to connect my Arduino to the scale

smithchristof:
I am using a TTL to RS232 Converter to connect my Arduino to the scale

If you had said so earlier it would have avoided a pointless comment.

And you still have not made your images visible.

...R

I don't see anyplace in your code where you reverse the bits in each character. The documentation shows all characters are sent LSB first. So, you need to reverse the bits before you do anything with the message characters, even look for the CR/LF at the end.

Paul

PS. That applies to the messages you send, as well.

Please find my pictures below:

Question 1:

Question2:

@Paul, can you please explain a bit more on what you mean?

Thanks.

Paul_KD7HB:
So, you need to reverse the bits before you do anything with the message characters, even look for the CR/LF at the end.

Presumably it should be possible to figure out the reversed form of LF (or CR) and look for that.

...R

I don't see how I can be any more clear. The bytes sent from the scale have 8 bits per character sent. You assume the bytes are normal ASCII characters or binary numbers sent as bits 7,6,5,4,3,2,1,0. That is what would be sent and received by your Arduino.

The scale sends the bytes as bits 0,1,2,3,4,5,6,7.

Whatever the scale was attached to was programmed to accept serial bits that way and automatically set them the normal way. Perhaps it was an attempt to secure the data.

So you need code to reverse the order of the received bits before processing them as ASCII characters or as numeric values.

The older UART/USART serial chips had a programming bit that allowed data to be serialized output either way. The old IBM bisync could use ASCII and it was sent/received that way.

Paul

Paul_KD7HB:
I don't see how I can be any more clear.

I wasn't challenging that.

I was just thinking that a LineFeed is 00001010 and reversed that is 01010000 which is P - so treat 'P' as the terminating character.

...R

thanks for the feedback. I get what you say but what about the fact that if I run the code below, and press the print button on my scale I get the correct output, after some rubbish on the first print, on my serial monitor as shown in the picture below?

#include <SoftwareSerial.h>
SoftwareSerial mySerial(11, 10);  

void setup()  
{
  Serial.begin(19200);  
  mySerial.begin(19200);

}

void loop() 
{
 
  while(mySerial.available()){
  Serial.print(mySerial.readStringUntil("\n"));
  }
}

Please don't post pictures of text - just copy and paste the text so it is easy to read. I mentioned this in Reply #1

...R

There is ALWAYS the possibility the document you linked to is out of date for your scale.

That is why you need better test equipment if you are going to do this type of programming.

Paul