Issues reading RS232 data from Digital Scales

Hi there,

I have a set of digital scales that is outputting continuous data via RS232. I am trying to print the data in the serial monitor, with the end goal of being able to send the data to a HTML file to display the weight on a physical monitor. However, I am trying to walk before I run, and can’t seem to get any data from the scales at present.

I have an Arduino Uno connected via the Max3232 breakout board (VCC, TX, RX, and GND), and an RS232 cable going from the breakout to the scales.

I know the scales are outputting data, because I can read it in a terminal on my PC if I connect directly.

My code is below:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10,11);  //SRX, STX   

void setup()
{
   Serial.begin(9600);
   mySerial.begin(9600);
}

void loop()
{
      if(mySerial.available()>0)
      {
           byte x = mySerial.read();
           Serial.println(x);
      }  
}

I have to admit, I’m a complete beginner when it comes to Serial, and RS232 in particular. So far, my google searches have been fruitless. THe code I’m using is something I stole from someone who was having a similar issue, and it seemed to work for them. Please let me know if I’m missing some crucial info in order to get help!

Thanks.

void loop()
{
while(mySerial.available()>0)//change for to a while
{
byte x = mySerial.read();
Serial.println(x);
}
}

Hi,
Your scale should be sending more than one byte to represent the weight, so you should print all the characters.Keep im mind that serial are more slow that the CPU clock, so at the time you run if(mySerial.available()>0) the first byte has arrived and the next one is about to come in, so not yet in serial buffer.

hugo007:
Hi,
Your scale should be sending more than one byte to represent the weight, so you should print all the characters.Keep im mind that serial are more slow that the CPU clock, so at the time you run if(mySerial.available()>0) the first byte has arrived and the next one is about to come in, so not yet in serial buffer.

Okay, so instead of a byte, I need to work out how the data is actually being delivered? When I read it in the terminal window it shows a value of “3.3kgs” for example. I just don’t know how the Arduino is going to read that value. I guess it can also read the HEX value potentially?

@Oopoe it is okay to read one byte each time the loop() runs. Your sketch is okay.

Using the SoftwareSerial causes a lot of problems. The Arduino Leonardo/Micro has a spare hardware serial port. The Arduino Mega 2560 has three spare hardware serial ports.
Just for a test, you can continue with SoftwareSerial. When you add things to your sketch and something is not working, then the cause is probably SoftwareSerial.

Don't worry about HEX values or formats yet. You first have to see something in the serial monitor.

Not every RS-232 is the same. Does the scale have a specification for it ? Do you know the voltage levels ?

The MAX3232 breakout boards use RX and TX sometimes in a different way.
Some breakout boards have this: The pin labeled "RX" of the breakout board receives data, so it should be connected to the TX of the Arduino. And "TX" to Arduino RX (you use pin 10 for that).
Other breakout boards have this: To help the user, the pin labeled "RX" should be connected to the RX of the Arduino board.
If you are not sure, try to swap them.

Can you measure all the signals ? Then you know for sure where the signal stops.

Some devices need a command to start sending data.

Please check that the wiring among your Scale, RS232-TTL Converter and Arduino is similar to the following:
uartEsZ.png

Also be sure that the Baud Rate (Bd) is correct. How do you know that it is 9600? Also re-try by changing the RS232-TTL converter.

Sample Codes:

void setup()
{
   Serial,begin(9600);
   Serial2.begin(9600);
}

void loop()
{
     byte n = Serial2.available();
     if(n !=0)
     {
         char x = Serial2.read();
         Serial.print(x);                //If Bd is correct, Serial Monitor should how something.
     }
}

uartEsZ.png

Koepel:
Not every RS-232 is the same. Does the scale have a specification for it ? Do you know the voltage levels ?

The MAX3232 breakout boards use RX and TX sometimes in a different way.
Some breakout boards have this: The pin labeled "RX" of the breakout board receives data, so it should be connected to the TX of the Arduino. And "TX" to Arduino RX (you use pin 10 for that).
Other breakout boards have this: To help the user, the pin labeled "RX" should be connected to the RX of the Arduino board.
If you are not sure, try to swap them.

Can you measure all the signals ? Then you know for sure where the signal stops.

Some devices need a command to start sending data.

I don't think is needs a command, as the terminal just reads the data continuously, and in the scales manual it has the option of continuously outputting, which is how I've set it up.

Where should I be measuring signals? I'm not too sure how I can check the voltage levels either, sorry. The manual says the Input signal range is 0mV to +30mV, Loadcell Voltage is 4.4 VDC, and Loadcell Sensitivity is 0.3mV/V to 3mV/V.

My wiring matches what you have posted, and I have also tried reversing the Tx/Rx in case they were wrong.

I know it is 9600 because I set that in the scales menu, and can read it at that baud rate in the terminal program on my PC.

I have finally started receiving information (of sorts) in my serial monitor. I am using the below code, but the serial monitor just reads -1, -1, -1…etc

#include <SoftwareSerial.h>

#define rxPin 3
#define txPin 4

SoftwareSerial softSerial =  SoftwareSerial(rxPin, txPin);

void setup()  {
 
 pinMode(rxPin, INPUT);
 pinMode(txPin, OUTPUT);
 softSerial.begin(9600);

 Serial.begin(9600);
}

void loop() {
 
 int data = softSerial.read();
 Serial.println(data);
 
}

Can anyone explain why I’m just getting -1 over and over, with no change when I press on the scales?

From the documentation for the SoftwareSerial library's read() function:
https://www.arduino.cc/en/Reference/SoftwareSerialRead

Returns

the character read, or -1 if none is available

This is why you should check softSerial.available() before reading. You had that in your original sketch. Why did you remove it?

pert:
From the documentation for the SoftwareSerial library's read() function:
https://www.arduino.cc/en/Reference/SoftwareSerialReadThis is why you should check softSerial.available() before reading. You had that in your original sketch. Why did you remove it?

Because I didn't read SoftwareSerial, and I didn't know what that line did.

Try the following Sketch:

#include <SoftwareSerial.h>

#define rxPin 3
#define txPin 4

SoftwareSerial softSerial(rxPin, txPin);

void setup()  {
 
 softSerial.begin(9600);

 Serial.begin(9600);
}

void loop() {
 byte n = softSerial.available();
if(n!=0)
{
 char data = softSerial.read();
 Serial.print(data);
}
 
}
1 Like

GolamMostafa:
Try the following Sketch:

You are my new favourite person. I'm now getting legible data from the scales. Quick question as I couldn't find too much info on this on the reference page. I'm now getting this data as a "char" and it reads for example, 0.0kg and so on. Is there a way I can convert my readings into int values so that I can set trigger points depending on weight values?

If the scale is sending out bytes continuously, how do you know that you are reading the first byte and not the second or the third byte? How do you know which byte you are reading?

Until you can answer this, the bytes are you are reading will be meaningless.

.

Please, place about 500gm weight on the load cell. Record what you are seeing on the Serial Monitor. Post this record and then I will show you how to convert that string into decimal-integer/decimal-float using atoi()/atof() function.

ieee488:
If the scale is sending out bytes continuously, how do you know that you are reading the first byte and not the second or the third byte? How do you know which byte you are reading?

Until you can answer this, the bytes are you are reading will be meaningless.

The scale is free running machine. It is acquiring the weight, formatting it into a fixed point decimal value. The scale then converts each symbol (digit + point) into ASCII codes which are transmitted at regular intervals. The data frames are clean and well separated from each other. There will be absolutely no ambiguity to extract weight values from the received frames.

GolamMostafa:
The scale is free running machine. It is acquiring the weight, formatting it into a fixed point decimal value. The scale then converts each symbol (digit + point) into ASCII codes which are transmitted at regular intervals. The data frames are clean and well separated from each other. There will be absolutely no ambiguity to extract weight values from the received frames.

what is the duration of the "regular" interval ?

Anyway, since you seem to be in your element and know so much I am out.

GolamMostafa:
Please, place about 500gm weight on the load cell. Record what you are seeing on the Serial Monitor. Post this record and then I will show you how to convert that string into decimal-integer/decimal-float using atoi()/atof() function.

So it is constantly outputting "0.0kg", until I place weight on it, in which case it will say 1.2kg or 3.5kg for example. It also has little square like an unrecognised character, if that makes sense. It is always to one decimal place. The data seems to come through roughly 10 times a second I guess.

I am not with the machine at the moment, but can provide screenshots tomorrow (UK based).

ieee488:
what is the duration of the "regular" intervals?

That can be estimated by the OP from the readings of the Serial Monitor with time stamp enabled.

GolamMostafa:
That can be estimated by the OP from the readings of the Serial Monitor with time stamp enabled.

If you say so.

ieee488:
If you say so.

The OP has already answered in Post#15 (10 frames/sec).

GolamMostafa:
The OP has already answered in Post#15 (10 frames/sec).

Fine.

Not my project to make working.