Go Down

Topic: Problems with Serial Bus (Read 936 times) previous topic - next topic

bluefix

Hello,

If I enter the String "W1-1356834120-20-60/2-1356834140-20-60/3-1356834160-20-60/4-1356834120-20-60/5-1356834140-20-60/6-1356834160-20-60/7-1356834120-20-60/8-1356834140-20-60/" to the Serial Monitor, the Arduino return this: "1-1356834120-20-60/2-1356834140-20-60/3-1356834160-20-60/4-135"

My Code:
Code: [Select]

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

void loop()
{
 if (Serial.available())
 {
   char SI = Serial.read();
   if (SI == 'W')
   {
     String Input;
     while (Serial.available())
     {
       Input = Input + char(Serial.read());
     }
   
     Serial.println(Input);
   }
}


Why the Arduino don´t return "1-1356834120-20-60/2-1356834140-20-60/3-1356834160-20-60/4-1356834120-20-60/5-1356834140-20-60/6-1356834160-20-60/7-1356834120-20-60/8-1356834140-20-60/"?

Thank You,
bluefix

tocpcs

Hmm. How much SRAM does your Arduino have?

bluefix

#2
Jan 05, 2013, 01:36 pm Last Edit: Jan 05, 2013, 01:40 pm by bluefix Reason: 1
Arduino Uno rev. 3

SRAM     2KB


My Code is much longer.

Global Variables:

unsigned long end_of_ch[38];
int Channels[8];
boolean IsOpen[8];

wildbill

Your code assumes that once you see a 'W', all the other characters will be delivered back to back. That isn't necessarily so - there may be a time when transmission is in process, but nothing is available to read yet. If that occurs, you'll print what you have at that point and go back to looking for a 'W'. Since there isn't another, no more input will be read.

There's more to it than that I suspect. You're only processing 64 characters, which by a remarkable coincidence is the size of the serial read buffer.

billroy

Concur with wildbill. 

The serial input buffer is 64 characters.  You are only getting the first 64-ish of your 154 characters of input.  So right away we have to think "timing problem with buffer overflow".

The second Serial.available() test seems to have the intention of looking for the end of the line.  But checking Serial.available() is not a reliable way to detect line endings.  

It would be better to loop looking for a line ending character like '\n', and wait on serial available within that loop, if that makes sense.  Accumulate characters to the end of the line, not until random timing gives you serial.available of zero.

-br

wildbill

Ah, that's not all your code. If the missing code does time consuming stuff or has, God forbid, delay in it, then depending on when you send the serial data, it may well overflow the buffer. Try running the code you posted - does it work?

bluefix

With This Code:
Code: [Select]

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

void loop()
{
  if (Serial.available())
  {
    char SI = Serial.read();
    if (SI == 'W')
    {
      String Input;
      char c = char(Serial.read());
      while (c != '\n')
      {
        Input = Input + c;
        c = Serial.read();
      }
      Serial.println(Input);
    }
}


it returns nothing.

If I use this Code (for Debugging):
Code: [Select]

void loop()
{
  if (Serial.available())
  {
    char SI = Serial.read();
    if (SI == 'W')
    {
      String Input;
      char c = char(Serial.read());
      while (c != '\n')
      {
        Input = Input + c;
        Serial.print(c);
        c = Serial.read();
      }
      Serial.println();
      Serial.println(Input);
    }
}


it returns "1-1356834120-20-60/2-1356834140-20-60/3-1356834160-20-60/4-135ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(...)"

tocpcs

The chip isn't receiving \n from you, so doesn't exit the while loop..

billroy

In the inner loop you are doing Serial.read without first assuring that Serial.available is greater than zero.  That's why it doesn't work, and why you get those y-umlaut characters.  They show up when you read when zero characters are ready.

-br


bluefix

Code: [Select]

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

void loop()
{
 if (Serial.available())
 {
   char SI = Serial.read();
   if (SI == 'W')
   {
     String Input;
     char c;
     while (Serial.available() > 0)
     {
       c = Serial.read();
       Input = Input + c;
     }
     Serial.println(Input);
   }
 }
}



I get Nothing back...  =(

billroy

Um, what happened to checking for the end of line?

If you're simply going to thrash around, without trying harder to understand what's going on, you'll get nowhere.  Maybe a little break would help.

One more time.

You need to capture characters up to the end of line.

To capture each character, you must be sure it is there first.


-br


bluefix

#11
Jan 05, 2013, 02:32 pm Last Edit: Jan 05, 2013, 02:37 pm by bluefix Reason: 1
I´m sorry, but i´m really desperate, because i´m sitting on this problem for a week...

Ok.
What is the character for an end of the line, if it isn´t '\n'?

Code: [Select]

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

void loop()
{
  if (Serial.available())
  {
    char SI = Serial.read();
    if (SI == 'W')
    {
      String Input;
      char c = Serial.read();
      while (Serial.available() && c != [end of line character])
      {
        Input = Input + c;
        if (Serial.available)
        {
          c = Serial.read();
        }
      }
      Serial.println(Input);
    }
  }
}


Would it be now correct?

P.S. And Yes a coffee would be the right now ;-)

wildbill

Your problem is that serial communications are very slow compared to the Arduino's ability to process them, especially at 9600 baud. As I said earlier, you cannot depend on the string you are sending all arriving at the same time. I believe that the only reason your original version was close to working was because other parts of your code slowed things down so that the data you sent filled the read buffer and the rest was thrown away. Given that it was then sitting on the arduino ready to be read, you could use your while loop to pull the data without fear that nothing would be there.

Now that does not apply. Before you read each character, you must be sure that one is available. Get rid of your while loop. In loop, if a character is available, read it and then check what it is. If it was 'W', set your collection string to "". If it was '\n' print the string and set it to "". any other character, add it to the string.

That should do it. A switch would be handy for replacing the ifs. Then get rid of String and use char arrays instead. Then add some logic that ignores characters until you see 'W'. Get the absolute minimum working first though.


bluefix

You´re right. The rest of my code (about 500 rows) is very long.
One loop() last about 200ms. But I´ve got an idea how to fix the buffer problem.

Thank you all!
(And sorry for my stupidity  ;) )

PeterH


I´ve got an idea how to fix the buffer problem.


I hope your idea is very very similar to the approach suggested by wildbill.
I only provide help via the forum - please do not contact me for private consultancy.

Go Up