RS232 from animal weigh scale stops after 1 reading

Hello guys,
Ive got an animal weigh scale that outputs in RS232 format so i have an RS232 to TTL converter attached to my mega2560.
the data from the weigh scale device always comes in 4 lines so i set up a bit of code in my arduino with some help from the forums here to read and identify each line. I have attached the image of the serial output from the scale captured by a RS232 to USB cable to this device.
The weigh scale scans a cows ear tag via RFID and posts out the Tags ID number.
the problem is that my Arduino will only read the first piece of data, e.g. the animals ID number and tag number.
I have a 16x2 I2C LCD which displays the tag number for verification.
the issue seems to be that i can read the first tag but it ignores the rest until i reset.
The USB to RS232 cable attached to my laptop will continuously capture data so it must be my code.
I am using the weigh scales output to also measure water consumption of each animal so it needs to keep reading animals RFID tags.
I then store the water consumption, time and date (via RTC) and tag number on an SD card and post the data to a server using the Wiznet W5500 Ethernet module.

Ive attached the code here but i am not sure what is up with it. Any help would be great.

my code uses the following functions to read the data from the weight scale. there is a flag called "linechecker" which doesnt do anything which you can ignore.

so the Serial2 is read when data gets to it until it gets a new line, it then processes the data to see which line of data was received and if its valid. it SHOULD then display this on the LCD. At present it only does this once when connected to the weight reader.
here is the code which reads the serial data and then processes it.

void recvWithEndMarker() {
 
  static byte ndx = 0;
  char endMarker = '\n';
   // char endMarker = '\r';
  char rc;
  while (Serial2.available() > 0 && newData == false) {
    rc = Serial2.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() {
  if (newData == true) {
 
    if (strcmp(receivedChars, "FR\"EIDVID\"")  == 0) { //LINE 1 SHOULD ALWAYS BE FR"EIDVID"
      lineChecker = 1;
    }
    else if (strcmp(receivedChars, "?")  == 0) { //LINE 2 ALWAYS IS JUST A ?
      lineChecker = 2;
   
    }
    else if (line3Checker() != false) {
      lineChecker = 3;
      earTag = receivedChars;
   //   sameCow = true;
    }  
    else if (check_string() == true) {
           if (eidLookup == true) {
              eidTag = receivedChars;
        detectedCow = true;
        duplicateChecker();
      }
    }
    else {
      lineChecker = 0;
    }
    lineChecker = 0;
     lastTag=earTag;
    newData = false;
  }
}
boolean line3Checker() //CHECK LINE 3 FOR - E.G. A VALID TAG NUMBER ETC 200-11
{
  char * pch;
  pch = strchr(receivedChars, '-'); 
  while (pch != NULL)
  {
    return true;
  }
  return false;
}
boolean check_string() {
  int counter = 0;
  char* testChars = receivedChars;
  int string_len = strlen(testChars);
  for (int i = 0; i < strlen(testChars); i++) { //ADD A 0 WHERE THERE IS A SPACE
    if (testChars[i] == ' ')
    {
      testChars[i] = '0';
    }
  }
  for (int i = 0; i < strlen(testChars); i++) {
    if (isdigit(testChars[i])) {
      counter++;
    }
  }

  if ((counter == strlen(testChars) && (strlen(testChars) != 0)))
  {
    lineChecker = 4;
    eidLookup = true;
//EIDLCD=1;
 lcd.setCursor(0,1); 
lcd.print("EID:");
 int len = strlen(receivedChars); 
 lcd.print(&receivedChars[len-8]);  //SHOW THE LAST 8 CHARS OF THE TAG NUMBER
  lcd.setCursor(12,1);
  lcd.print("  ");
    return true;
  
  }
  else {
    eidLookup = false;
    return false;
  }
}

in my main loop there is a piece of code that reads the Serial2, its to flush the serial buffer.
I mainly put this in to have the Serial buffer read and emptied while the start button wasnt pressed. i have a start stop button on the device, when its at stop it should ignore the Serial data but it reads into the buffer anyway. so i used read the buffer.

while (Serial2.available() > 0) {
char x = Serial2.read();
}

However, the above code runs in the loop always, i wonder if its causing an issue.

also here is my main loop.

void loop() {
////////////////////DAYLIGHT SAVINGS TIME CODE //////////////////////////
DateTime now = rtc.now();   
if (now.dayOfTheWeek() == 0 && now.month() == 3 && now.day() >= 8 && now.day() <= 16 && now.hour() == 2 && now.minute() == 0 && now.second() == 0 && DST == 0)     
{       
rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour()+1, now.minute(), now.second()));       
DST = 1;       
EEPROM.put(0, DST);     
}     
else if(now.dayOfTheWeek() == 0 && now.month() == 11 && now.day() >= 1 && now.day() <= 8 && now.hour() == 2 && now.minute() == 0 && now.second() == 0 && DST == 1)     
{       
rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour()-1, now.minute(), now.second()));       
DST = 0;       
EEPROM.put(0, DST);     
}
////////////////////////////////////////////////////////////



  
  currentMillis = millis(); 

  int reading = digitalRead(startButton); //START BUTTON WILL SET A FLAG TO READ DATA OR IGNORE DATA
//  Serial.println(reading);
  if (startStop == 1)
  {
   recvWithEndMarker(); //CHECK SERIAL DATA
  showNewData(); 
    redBlink(); //SHOW A BLINKING LED AND SHOW THE WORD 'REC' ON THE LCD
    readyMsg=1;
  } 
  else {
    if(readyMsg==1){
    lcd.setCursor(0,0); 
lcd.print("STANDBY");
    }
     

    
while (Serial2.available() > 0) {
char x = Serial2.read();
}
 digitalWrite(redLED, HIGH);
  }
  if (reading == LOW && previous == HIGH && millis() - time > debounce) {
    if (state == LOW)
      state = HIGH;
    else
      state = LOW;
    time = millis();
  }
  startStop = state;
  if ((enteredLoop == 1) && (startStop == 1)) {
    if (currentMillis - previousMillis >= 60000) {
      saveData();
    }
    else if ((currentMillis - previousMillis <= 60000) && (detectedCow == true)) 
    {
      if (started == 0)
      {
        getTime();
      }
      checkLevel();
    }
  }
  previous = reading;
  lastButtonState = startStop;
}

My issue is that the Serial only reads and displays the data on the LCD ONCE on reset but not again.

DOLGAN_TEST_CODE.ino (15.9 KB)

Dude, you've got way to much code if you can't just read in 4 lines of data and display them on the LCD. I would strongly suggest you copy this code to a new sketch and then get rid of 90% of it so all you are doing is reading the Serial2 data, successfully parsing it and displaying it on the LCD.

Once that is working, then add in saving the data to the SD card. Then worry about sending it to a website, etc.

So,

One Transmission Frame of your animal weighing scale consists of:
Line-1 is always: FR"EIDVID". Do you know the line ending character? Is it newline character (0x0A)?

Line-2 is always ?. Do you know the line ending character? Is it newline character (0x0A)?

Line- is a 16-digit tag like/similar: 969 000000681069. Do you know the line ending character? Is it newline character (0x0A)?

Please, provide the above information.

GolamMostafa:
So,

One Transmission Frame of your animal weighing scale consists of:
Line-1 is always: FR"EIDVID". Do you know the line ending character? Is it newline character (0x0A)?

Line-2 is always ?. Do you know the line ending character? Is it newline character (0x0A)?

Line- is a 16-digit tag like/similar: 969 000000681069. Do you know the line ending character? Is it newline character (0x0A)?

Please, provide the above information.

Hello GolamMostafa,
thanks for your reply.
Yes to confirm line 1 is always FR"EIDVID" with a newline terminator, there is no carriage return.
Line 2 is always a ?
these first two lines dont have any data i actually want.
I need line 3 which is sometimes blank as sometimes there is no TAG number which follows the format 1234-56. there is a hypen or '-' in line 3 if a TAG number was assigned. Its not super important but i am checking for the '-' if its there it gets recorded, if not its saved as blank.
the last line, line 4 is the one i really need. its 16 digits (IIRC) but it has a blank so like 969 012345678965 etc etc.
I am checking for the blank and putting a 0 in it.
The problem i have is that it does work ONCE but i am not sure if a flag gets set that prevents it from running again.

@cfcorp, please post a link to the scale you're using. I may have an application for such a device. Thanks.

gfvalvo:
@cfcorp, please post a link to the scale you're using. I may have an application for such a device. Thanks.

Hello gfvalvo,
thanks for the response.
The device i have is the Tru-Test XR5000 found here:
https://livestock.tru-test.com/en/indicators/xr5000
I really appreciate it.
Thanks

cfcorp:
Yes to confirm line 1 is always FR"EIDVID" with a newline terminator, there is no carriage return.
Line 2 is always a ?

I have not got full answer --

Does Line-2 has a newline termination whose ASCII code is 0x0A? If not, what is line terminator?

Does Line-3 has a newline terminator whose ASCII code is 0x0A? If not, what is the line terminator?

Hello,
Yes that is correct. It's a 0XOA or newline terminator for all lines.
Thanks

Is the first reading you receive correct?

zoomkat:
Is the first reading you receive correct?

hello zoomkat, yes it is.its just not reading again after the first reading.

You might try making some simple code that all it does is receive and print the incoming scale data to the serial monitor. This might help sorting out any communication issues in receiving all the data being sent. When that is working, then you can start incorporating the other features which in themselves are causing the issue.

Do you have any reason to assume the maximum record length is 20 characters? numChars = 20 in the code?
Perhaps be a bit more conservative, treat both 0x0a and 0x0d as terminators, and set numChars higher?

Try this code; where, the DPin-2 and DPin-3 of UNO are respectively connected with TXD-pin and RXD-pin of your Weighing Scale. GND of UNO is connected with GND pin of the scale.

#include<SoftwareSerial.h>
SoftwareSerial SUART(2, 3); //SRX = 2, STX = 3
byte m;

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

void loop()
{
   byte n = SUART.available();
   if(n != 0)
   {
       char x = SUART.read();  
       Serial.print(x);                //just print as the characters/data are coming form scale.
   }
}

If you still get 'data frame' from the scale only for once, then it might mean that the scale needs some kind of command from the user/UNO to send data.

Just trying to remember the Arduino schematic, you might just try connecting the scale and Arduino grounds together, and connect the Arduino and scale tx lines together, open the serial monitor, and see if you get the scale output displayed in the serial monitor.

GolamMostafa:
Try this code; where, the DPin-2 and DPin-3 of UNO are respectively connected with TXD-pin and RXD-pin of your Weighing Scale. GND of UNO is connected with GND pin of the scale.

#include<SoftwareSerial.h>

SoftwareSerial SUART(2, 3); //SRX = 2, STX = 3
byte m;

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

void loop()
{
  byte n = SUART.available();
  if(n != 0)
  {
      char x = SUART.read(); 
      Serial.print(x);                //just print as the characters/data are coming form scale.
  }
}





If you still get 'data frame' from the scale only for once, then it might mean that the scale needs some kind of command from the user/UNO to send data.

Hello
Thanks for the reply,
I will give it a go although ill have to check if digital pins 2 and 3 are free and i am also using a Mega2560.
I never thought of using the software serial, did you suggest the software serial as i maybe wasnt clear enough that i am using the Mega2560?
Any specfic reason for the Software Serial, could i keep using Hardware serial port 2 and just print to Serial 1 (USB) of my Arduino?

Also I have no issue getting data continuosly with the RS-232 to USB cable i have. I tried using the cable to view data in the PUTTY terminal and i could see it constantly coming in. I am therfore not sure if the Arduino needs to send anything back after getting a frame of data as I am not sending anything back when using the RS232 to USB cable and Putty.

Thanks for your help. I really appreciate it!!

MarkT:
Do you have any reason to assume the maximum record length is 20 characters? numChars = 20 in the code?
Perhaps be a bit more conservative, treat both 0x0a and 0x0d as terminators, and set numChars higher?

Hello Mark,
thanks for your reply and suggestions, the actual TAG number is less than 20 chars in length and will not increase, but maybe i can just put the buffer size up to 64 or 128, i have about 6kb of free SRAM according to the compiler.

Also are you suggesting i change the code to look for either the 0x0A or 0x0D terminators? i never thought of that.
thanks for your suggestions

As you are using MEGA, you may follow the following connection diagram and the sketch.

Connection Diagram:
uartEsZ.png

Sketch:

void setup()
{
   Serial.begin(9600);    //UART0 Bd for communicating with Serial Monitor
   Serial2.begin(9600);  //enter correct Bd = Baud Rate of your Weighing Scale
}

void loop()
{
   byte n = Serial2.available();
   if(n != 0)
   {
       char x = Serial2.read();  
       Serial.print(x);                //just print as the characters/data are coming form scale.
   }
}

uartEsZ.png

GolamMostafa:
As you are using MEGA, you may follow the following connection diagram and the sketch.

Connection Diagram:
uartEsZ.png

Sketch:

void setup()

{
  Serial.begin(9600);    //UART0 Bd for communicating with Serial Monitor
  Serial2.begin(9600);  //enter correct Bd = Baud Rate of your Weighing Scale
}

void loop()
{
  byte n = Serial2.available();
  if(n != 0)
  {
      char x = Serial2.read(); 
      Serial.print(x);                //just print as the characters/data are coming form scale.
  }
}

Hello
Thank you for the reply.
I can connect the Weigh scale directly to the Arduino. I am using that exact RS-232 to USB converter.
I am currently testing the arduino with connected to my laptop using the RS-232 to USB converter I have with the code i posted in my original post.
I have this wired slightly differently. i have pin 5 on both devices e.g. GND <--> GND connected.
On my RS-232 to TTL connected my Arduino i have its Pin 3 connected to Pin 2.
The annoying and strange this is that i can leave the terminal open on my laptop without letting it go to sleep (the laptop) i can manually type a TAG number myself and it gets displayed on the LCD.
I can also do this repeatedly and the LCD shows the EID number.
The only other thing is that i am not typing FR"EIDVID" and ?, i am directly typing the long TAG number so id type 969 000123456789 and hit return and it shows up on the LCD. also when the TAG is detected i can type in the other number in line 3 e.g. 22-1212 and it also saves in the CSV file I create in the SD card and also uploads to the server.
Im not sure why my desktop USB-RS232 to my arduino works but not with the weigh scale.

Also in my Arduino IDE terminal i have it set for "Newline"
I've been testing simulating the data from the Scale by sending;
line 1 data e.g. FR"EIDVID"
then line 2 "?"
then line 3, an ear tag number e.g. 123-45
and finally the long EID TAG number e.g 969 12345678903
this seems to work all the time.

This is my current setup for testing, it works but i have to be careful moving the serial cables as i just have the GNDs and TX to RX jumped with duPont cables.