Please help with inconsistent serial communication

Im having real trouble achieving consistent communication with two arduino and xbees. Essentially on my sending module I have some pots that I can alter integers with, these values are then sent over the xbees (which is essentially just serial commands), and they are recieved by the reciever module and processed. There is a 12ms window in which these values are processed and about 8ms to recieve them, when the reciever is ready it sends an 'H' to the sender to start the transfer of the next set of values.

The problem is that when I move the pots, I can only see the first value changing on the reciever COM port (the others just remain at the constant they initialise to at the start), and it often starts just printing out the first digit (although the right first digit as they are 3 figure integers and I can still see it changing), or freezing and printing out the same number over and over, or printing out random numbers completely etc etc

Im really stuck and I dont know why this is happening.

My sender code:

...... other code to get variables

   if (Serial.available()) {
    incomingByte = Serial.read();
    if (incomingByte == 'H') {
        Serial.print("<");
        Serial.print(Throttledelay);
        Serial.print(" ");
        Serial.print(Aelerondelay);
        Serial.print(" ");
        Serial.print(Elevatordelay);
        Serial.print(" ");
        Serial.print(Yawdelay);
        Serial.print(" ");
        Serial.print(autoflag);
        Serial.print(">");
        collect = 1;
        }
   }

My receiver code:

// end of 12ms delay, print out integers used and send for next batch
Serial.print('H');
  Serial.print(Throttledelay);
  Serial.print(" ");
  Serial.print(Aelerondelay);
  Serial.print(" ");
  Serial.print(Elevatordelay);
  Serial.print(" ");
  Serial.print(Yawdelay);
  Serial.print(" ");
  Serial.println(autoflag);
}


void loop() { // Main loop to recieve wireless data from pots

while(Serial.available() > 0)
   {
       char aChar = Serial.read();
       if(aChar == '<')
       {
           started = true;
           index = 0;
           inData[index] = '\0';
       }
       else if(aChar == '>')
       {
           ended = true;
       }
       else if(started)
       {
           inData[index] = aChar;
           index++;
           inData[index] = '\0';
       }
   }

   if(started && ended)
   {
       // Convert the string to an integer

        char *token;
        if (token = strtok(inData, " ")) 
        { 
          Throttledelay = atoi(token); 
        }
        if (token = strtok(NULL, " ")) 
        {
          Aelerondelay = atoi(token);
        }
        if (token = strtok(NULL, " ")) 
        {
          Elevatordelay = atoi(token);
        }
        if (token = strtok(NULL, " ")) 
        {
          Yawdelay = atoi(token);
         }
        if (token = strtok(NULL, " ")) 
        {
          autoflag = atoi(token);
        }
     
       // Get ready for the next time
       started = false;
       ended = false;
       index = 0;
       inData[index] = '\0';
   }
}

Any help I greatly appreciate

thanks

Vostro,

I think I see your problem. Here's how the hardware serial port works with the Serial class:

When a character comes in, an interrupt routine adds it to a buffer.
When you do Serial.available(), it tells you how many characters are in the buffer.
When you do Serial.read(), it takes the next character out of the buffer.

Now let's say that one character has been received. Your while loop will loop exactly once, since you can do all of that processing before the next character is received. After it completes the while loop, you reset 'index', which means that you've just lost the one character you've received.

Here's another (untested) version that may get you closer to your goal:

void loop()
{
    char aChar;
    boolean started;
    boolean ended;
    int index;

    started = ended = false;
    index = 0;
    
    while (!ended)
      {
      if (Serial.available() > 0)     // at least one character rec'd
        {
        aChar = Serial.read();
        if (aChar == '<')
          {
         started = true;
         }
       else if(aChar == '>')
         {
         ended = true;
           started = false;
         }
       else if (started)
         {
         inData[index] = aChar;
         index++;
           }
         }
   }

   if (ended)
     {
     inData[index] = '\0';

      // insert conversion code here ...
     }
}

Note that you really should also add a check to be sure that 'index' is always less than the size of 'inData'.

With help form the esteemed AlphaBeta, I've written a routine to make all this easier: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1269302644/2 The routine is called 'lineAvailable'. You'll have to adapt it a bit for your purposes.

Regards,

-Mike

P.S. I believe you misspelled 'aileron' :slight_smile:

Hi thank you for your suggestions. I havent tried it yet but last night I found some more info which makes me think it might be hardware related.

When I print out inData after I collect it all, what is actually inside the array is missing bits of data, so if I sent <1234 456 789>, what actually ends up inside inData when I print it out is "1 34 4 6 789", or something similar. Sometimes its missing more than others. Using a different delimiter doesnt help either. Changing the baud rate also seems to affect the performance, if I remove the strtok and just send one value , say <1234>, if I set the baud rate too high this seems to fail as well, even though that doesnt make sense to me but I had been trying to get this to work for about 14 hours straight yesterday.

I will try your suggestion and also I have found out how to send my values as bits and bytes over serial instead, which I believe may help if I understand correctly. I believe that to send say the number 1500 over serial by just using serial.print as I have, it actually takes up 4 bytes (1 byte for each character), but if I send the number as actual 'bytes' I would only need 2 bytes to make 16 bits? Surely this would be better?

I actually think I have sorted it. I didnt use your code but your point about data not being transmitted fast enough I think was the reason. I just moved the flag that is sent from the reciever to tranmitter to initiate sending data earlier in the loop and it appears to work ok