Arduino Serial reading to integers

Hi All,
I have this code which reads a digital scale data via Rs232.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(8, 9);  // -1 if not using TX to save a pin

const byte numChars = 16;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

float number = 0;

float YR =0;
void setup()
{
   Serial.begin(19200);
   //Serial.println("<Arduino is ready>");
   mySerial.begin(19200);
}

void loop()
{
   recvWithEndMarker();

   if (newData)
   {
      showNewData();
      number = atof(receivedChars);

      newData = false;
   }
}

void recvWithEndMarker()
{
   static byte ndx = 0;
   char endMarker = '\r'; // 0x0d carriage return
   char rc;

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

void showNewData()
{
   //Serial.print("This just in ... ");
   Serial.println(receivedChars);   
      
}


And its serial read as follows.

Readings are fine and works well. I need to receive them in integers. my purpose is to on/off a relay according to scale data. Please help me out. thanks

What are you doing in hardware to convert the RS232 signal into a TTL serial signal?

Please do not post screenshots as images, post them as if they were code.

Yes convert to TTL by using MAX232 module prior to arduino

Well you are using software serial at a very fast rate, perhaps faster than it can manage.

How fast is the data coming in?

Also serial input only reads a byte at a time, you need to read them in pairs and combine them to be integers before you store them.

Do not use string variables in any way form in this project, stick to bytes.

19200, I Cannot change that scale data speed rate is that,

Can you help me with the read them as pairs and combine them as integers. I'm struggling to right the array

As far I see, you don't have an issues with receiving the data. What is your problem?

What is the format of the data coming from the scale. Can you provide a link to the scale?

What do you see for number using
number = atof(receivedChars);

Type here as a post what you are seeing on the Serial Monitor.

Note that the Software Serial Port works well at Bd = 9600. In that case, if you are using UNO, then you might need to connect your scale with Hardware UART Port. If you are using MEGA, then connect your scale with Serial1/UART1.

And still, there is a way to operate the scale using Hardware UART Port of UNO at Bd = 19200 and viewing the incoming signal on Serial Monitor using Software Serial Port for which you need another TTL <---->RS232 converter.

intValue = (msb << 8) | lsb)

where msb is the most significance bit and lsb is the least significant bit, with intValue is the integer value you want.

Do you know what order the values are sent?
Assuming you get the msb first then try a function:-

int ReadInt(){
while (Serial.available() >0) ; // hold until you have a byte to read
msb = Serial.Read():
}
while (Serial.available() >0) ; // hold until you have a byte to read
lsb = Serial.Read():
intValue = (msb << 8) | lsb);
  return(intValue);
}

Variables would be globals.

This would use the normal serial, port which uses pins 0&1 and you would use a double pole switch to isolate these pins when programming them.

However, you need to tell us more about your application.

Are you tapping into an ongoing stream, or can you start the program first and then start the stream?

If it is an ongoing stream then you need to sort out the order in some other way maybe from some property between msb and lsb.

You're going to want to read the scale data into a "string". It can be converted into an integer but if all you want is the weight on the scale to act as the switch simply set a threshold. Basically a software limit switch. Lots of ways to code that if, while, for statements/loops. You can have two serial variables one for the monitor and one for the scale readings.

This code might work for you.

const int relayPin = 8;          // Pin connected to the relay
const int weightThreshold = 500; // Example threshold value in grams (adjust as needed)

void setup() {
  // Initialize serial communication with the computer
  Serial.begin(9600);
  
  // Initialize serial communication with the digital scale at 19200 baud rate
  Serial1.begin(19200); // Serial1 is used for pin 0 (RX) and pin 1 (TX)
  
  // Set the relay pin as output
  pinMode(relayPin, OUTPUT);
  
  // Ensure the relay is off at the start
  digitalWrite(relayPin, LOW);
}

void loop() {
  // Check if data is available from the digital scale
  if (Serial1.available()) {
    String weightData = "";  // Initialize a string to hold the incoming data
    
    // Read the incoming data from the scale
    while (Serial1.available()) {
      char incomingByte = Serial1.read();
      weightData += incomingByte;
    }

    // Convert the weight data to an integer
    int weight = weightData.toInt();
    
    // Print the received data to the Serial Monitor
    Serial.print("Weight: ");
    Serial.println(weight);
    
    // Check if the weight exceeds the threshold
    if (weight > weightThreshold) {
      // Turn the relay on
      digitalWrite(relayPin, HIGH);
      Serial.println("Relay ON");
    } else {
      // Turn the relay off
      digitalWrite(relayPin, LOW);
      Serial.println("Relay OFF");
    }
  }
  
  delay(500);  // Add a small delay to prevent flooding the serial monitor
}

Are you looking for atoi() or atol() instead of atof()?

https://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html

Or maybe you want something from:

You could always use the end marker to synchronise the message msb / lsb order.

The @yeshantcc has not told us about the scale and whether it is sending the weight data as a character string or or as the bytes of either integer or float data.

The attached images in the first posting would indicate the character string is being sent, and in that case atoi would be appropriate.

Thanks for this code, But it did not work. My scale is ADAM GBK 32. And I have manager to lower its bit rate to 600. Can you please edit on my code. I am capable of writing the relay code. I need more than one relay to work on. I need you help on reading the code as a number. RX TX as 8 and 8 can you help editing this code. much apricated`
I am receiving weight values but cannot control the relay due to unwanted characters

#include <SoftwareSerial.h>

SoftwareSerial mySerial(8, 9); 

const byte numChars = 25;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

float number = 0;

float YR =0;
void setup()
{
   Serial.begin(600);
   //Serial.println("<Arduino is ready>");
   mySerial.begin(600);
}

void loop()
{
   recvWithEndMarker();

   if (newData)
   {
      showNewData();
      number = atof(receivedChars);

      newData = false;
   }
}

void recvWithEndMarker()
{
   static byte ndx = 0;
   char endMarker = '\r'; // 0x0d carriage return
   char rc;

   while (mySerial.available() > 0 && newData == false)
   {
      rc = mySerial.read();
      if (rc != endMarker)
      {
         receivedChars[ndx] = rc;
         ndx++;
         if (ndx >= numChars)
         {
            ndx = numChars - 1;
         }
      }
      else
      {
         receivedChars[ndx] = '\0'; // terminate the string
         ndx = 0;
         newData = true;
         number = atof(receivedChars);
      }
   }
}

void showNewData()
{
   //Serial.print("This just in ... ");
 
   Serial.println(receivedChars);  
   Serial.println(number);  
   
   delay(500) ;
      
}
#include <SoftwareSerial.h>

SoftwareSerial mySerial(8, 9); 

const byte numChars = 25;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

float number = 0;

float YR =0;
void setup()
{
   Serial.begin(600);
   //Serial.println("<Arduino is ready>");
   mySerial.begin(600);
}

void loop()
{
   recvWithEndMarker();

   if (newData)
   {
      showNewData();
      number = atof(receivedChars);

      newData = false;
   }
}

void recvWithEndMarker()
{
   static byte ndx = 0;
   char endMarker = '\r'; // 0x0d carriage return
   char rc;

   while (mySerial.available() > 0 && newData == false)
   {
      rc = mySerial.read();
      if (rc != endMarker)
      {
         receivedChars[ndx] = rc;
         ndx++;
         if (ndx >= numChars)
         {
            ndx = numChars - 1;
         }
      }
      else
      {
         receivedChars[ndx] = '\0'; // terminate the string
         ndx = 0;
         newData = true;
         number = atof(receivedChars);
      }
   }
}

void showNewData()
{
   //Serial.print("This just in ... ");
 
   Serial.println(receivedChars);  
   Serial.println(number);  
   
   delay(500) ;
      
}

number records as 0.00

A line starting with “GROSS…” parses as 0.

Take a look at:

Just using the wrong variable type atof is float, atoi is integer.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(8, 9); 

const byte numChars = 25;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

int number = 0;  // Change this to int to store integer values

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

void loop()
{
   recvWithEndMarker();

   if (newData)
   {
      showNewData();
      number = atoi(receivedChars);  // Convert received data to an integer

      newData = false;
   }
}

void recvWithEndMarker()
{
   static byte ndx = 0;
   char endMarker = '\r'; // 0x0d carriage return
   char rc;

   while (mySerial.available() > 0 && newData == false)
   {
      rc = mySerial.read();
      if (rc != endMarker)
      {
         receivedChars[ndx] = rc;
         ndx++;
         if (ndx >= numChars)
         {
            ndx = numChars - 1;
         }
      }
      else
      {
         receivedChars[ndx] = '\0'; // terminate the string
         ndx = 0;
         newData = true;
         number = atoi(receivedChars);  // Convert received data to an integer
      }
   }
}

void showNewData()
{
   Serial.println(receivedChars);  
   Serial.println(number);  
   
   delay(500);
}