Serial port polling finished before end of message

I am using an Arduino Due board with an ethernet shield to serve as an intermediate processor in a feedback system. I need the ethernet connection because I want to be able to set the feedback parameters over the network. I do this by issuing a command like “write vx +0.24” or some such thing.

This setup uses ethernet for main communications with the user, but I also have a serial comm available for debugging purposes since that is sometimes easier.

The effect I see is this: when polling the ethernet line for an incoming message from a client, my program accepts the entire message and then proceeds to the parsing and all is good. However, when I poll the serial line for an incoming message I get a very different response - sometimes the polling loop bails after a single character, sometimes after three, sometimes more. This effect is independent of baud rate.

My question is this: how do I modify my code so that I can continuously poll the serial line and only stop when I have received a termination character? I am guessing that sometimes (randomly??) the serial line goes low so that serial.available() returns false and that is causing the polling to bail, but returns again on a subsequent cycle of the loop and picks up where it left off.

Copied below is a reduced version of my code that just shows the serial and ethernet polling. Following is a capture from the serial monitor when I first submit “Hello World!” over serial and then over ethernet.

Thanks!

#include <Arduino.h>
#include <Ethernet2.h>

const unsigned int maxChar = 20;

// Static ethernet connection settings
byte mac[6] = {0x90, 0xA2, 0xDA, 0x10, 0xF1, 0x5F};
byte  ip[4] = {198, 125, 178, 11};

// establish Arduino as a server using port 23
EthernetServer server(23);


// ---------------------------------------------- //
void setup()
{  
 
  // initialize the ethernet device
  Ethernet.begin(mac, ip);
  server.begin();

  Serial.begin(9600);
  while(!Serial)
  {
  }

  Serial.println(F("Serial connection active"));

}


// ---------------------------------------------- //
void loop()
{

  static char Ecmd[maxChar];
  static char Scmd[maxChar];
  boolean EmsgRecd = false;
  boolean SmsgRecd = false;
  static boolean clientConnected = false;

  EthernetClient client = server.available();

  if (client)
  {
    if (!clientConnected)
    {
      // clear the input buffer:
      client.flush();
      Serial.println(F("We have a new client"));
      Serial.println();
      clientConnected = true;
    }


    while (client.available() > 0)
    {
      EmsgRecd = true;
      RecNewByte(client.read(), Ecmd);
    }

    if (EmsgRecd == true)
    {
        // go on to parse command, but for now just print to serial
        Serial.print(F("Ethernet command received: "));
        Serial.println(Ecmd);
    }

  }  //end polling of client



  while (Serial.available() > 0)
  {
    SmsgRecd = true;
    RecNewByte(Serial.read(), Scmd);
  }

  if (SmsgRecd == true)
  {
      // go on to parse command, but for now just print to serial
      Serial.print(F("Serial command received: "));
      Serial.println(Scmd);
  }

    
}


// ---------------------------------------------- //
void RecNewByte (const byte newByte, char *msg)
{
  static unsigned int charIndex = 0;

  switch (newByte)
  {

    // end of text, reset counter
    case '\n':
      msg[charIndex] = '\0';
      charIndex = 0;
      break;

    // discard carriage return
    case '\r':
      break;

    // otherwise, add next character
    default:
      if (charIndex < (maxChar - 1))
        msg[charIndex++] = upCase(newByte);
      break;

  }  // end of switch
}

//===============================================//
char upCase(char ch)
{

  return (ch - 32 * ((ch >= 97) && (ch <= 122)));

}

output from serial monitor

Serial connection active
Serial command received: H
Serial command received: HE
Serial command received: HEL
Serial command received: HELL
Serial command received: HELLO
Serial command received: HELLO WORLD!
We have a new client

Ethernet command received: HELLO WORLD!

  while (Serial.available() > 0)
  {
    SmsgRecd = true;
    RecNewByte(Serial.read(), Scmd);
  }

This will read bytes only until the serial buffer is empty. You can empty the buffer far faster than you can fill it from the serial stream. One fix would be to have a character that indicates the end of the input. Typically that is the newline character:

  while (Serial.available() > 0)
  {
    char input = Serial.read();
    if (input == '\n') {
      SmsgRecd = true;   // Received newline so input is complete
      break;   // End the while loop early, in case the start of a second message is already in the buffer
    } else {
      RecNewByte(input, Scmd);   // accumulate non-newline characters
    }
  }

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

The 2nd and 3rd examples are specifically designed to avoid the problem you mention.

...R

Thanks guys! Big help here. Simple solution, I was suspecting that was the issue.

One question for you: transmission over ethernet should be way faster than serial, but I'm wondering if it is wise to build a similar message catcher for the ethernet communications in case there should be a similar lull. I assume that is unlikely, but the more relevant question seems to be, is it possible that the ethernet line would similarly go quiet, perhaps with a really long message?

Thanks!
Eric

I don't have an Ethernet shield so cannot help with the details. Of course it is possible for Ethernet to fail. Whether it is sufficiently likely to need special protection depends on a lot of things. If it is getting data from the public internet then I reckon that protection would be necessary. But maybe there are suitable timeouts built into the Ethernet library or whatever you use.

...R