Go Down

Topic: reading serial data with timeouts (Read 1 time) previous topic - next topic

alyas

So how is you code?  If you will be using the h/w serial, what I do is use the flexitimer2 library and serial.event.

At each serial.event, at the start I stop flexitimer2 from running.  After the new byte has arrive,  I run flexitimer2.  So as long as new data keeps arriving within the set timeout for flexitimer2, flexitemer2 will never run the function its supposed to run.  If no new data has arrived and timeouts, flexitimer2 then runs the the specified function.

In my specified function, i just raise a flag to indicate that I should already read the buffer.  Hope this helps.  I posted the code in my favorite local forum as my code is related to specifc local product.  In the code, the flexitimer2 is alyastmr2.  Its a modified flexitimer2 tha supports the particular cpu I am using.

http://www.elab.ph/forum/index.php?topic=37118.0

zarobhr

I cannot add start and stop markers to the incomng data since i have no control, the protocol states that i response must be given within 40ms or there is no response and that the time between each byte will not excedd 5ms. there is however a crc added to end that i can check and if its invalid i can reissue command

PaulS

Quote
i used a variation of blink without delay, i still had to put a couple delay(1) in

No. You absolutely did NOT need the delay() in the loop to read the serial data. You DO need to add start and end of packet markers to your packets, rather than diddling around hoping that the whole packet gets there in time.

Then, you read the data as fast as it arrives (no delay()), and only do something when the end of the packet arrives. Like so:
Code: [Select]

#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[80];
byte index;

void setup()
{
   Serial.begin(57600);
   // Other stuff...
}

void loop()
{
  // Read all serial data available, as fast as possible
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}

zarobhr

thanks i used a variation of blink without delay, i still had to put a couple delay(1) in and will try to use they delaymicro in a revison, its been running for about 12 hours so far without a hitch

Code: [Select]
delay(10);
      byte seravcount = 0;
      byte lprtemp[200];
      byte datafound1 = 0;
      byte bytefound1 = 0;
      unsigned long currentMicros = micros();
      delay(1);
      while (micros() - currentMicros < 100000)
      {
        if (Serial.available() >0)
        {
          datafound1 = 1;
          bytefound1 = 1;
          seravcount = seravcount +1;
          lprtemp[seravcount] = Serial.read();
          break;
        }
      }
      delay(1);
      while (bytefound1 == 1)
      {
        currentMicros = micros();
       
        while(micros() - currentMicros < 6000)
        {
          if (Serial.available() > 0)
          {
            seravcount = seravcount +1;
            lprtemp[seravcount] = Serial.read();
            currentMicros = micros();
            delay(1);
            break;
          }
          else
          {
            bytefound1 = 0;
          }
        }
      }

marco_c

You need to use the same technique as the 'Blink without delay' example.

Before you start checking if a characetr is available on the serial port, you store the current value of millis(). You then loop waiting for a character until either a character arrives or the new current millis() value is bigger than the timeout.
Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Go Up