Go Down

Topic: (updated)Help on Serial communication between Arduino and PC!! (Read 1 time) previous topic - next topic

cosailer

Apr 30, 2012, 12:00 am Last Edit: May 02, 2012, 10:38 am by cosailer Reason: 1
----------------------original post-------------------------------------------------------
I want to transfer a pack of data from arduino to PC, which has multiple data types.
However, when I try to receive the data from the PC side, sometimes data seems to be lost.

below is the code I used on Mega, it worked perfectly.

Code: [Select]

#pragma pack (2)

class SensorData
{
   public:
   
   byte tag;
   byte length;
   
   int intData[3];
   
   SensorData()
   {}
   
   void readSensor()
   {
       tag = 11;
       length = 22;
       
       for(int i = 0; i < 3 ; i++)
       {
           intData[i] = i;
       }
       
   }
   
};

class SensorData SD0;

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

void loop()
{
   SD0.readSensor();
   
   Serial.write((byte *)&SD0, sizeof(SD0));
   Serial.flush();
   
   delay(100);
}



On the PC side, I used a loop to print whatever I receive out:

Code: [Select]

       while((nread = read(fd, BUFF, 50)) > 0)
       {
             cout << ">> ";
             for(int i = 0; i < 50; i++)
             {
                cout << (int)BUFF[i] << "-";
             }
             cout << endl;


The problem is, if you change  intData[3] into  intData[20], to add more data in the data structure
some data are some how lost, output is shown below:[more can be found here:https://docs.google.com/open?id=0B-PlSu8oC8g-U0NrT3MyNXk3UWc]

>> 0-4-0-5-0-6-0-7-0-8-0-9-0-10-0-11-0-12-0-13-0-14-0-15-0-16-0-17-0-18-0-19-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-
>> 11-4-0-5-0-6-0-7-0-8-0-9-0-10-0-11-0-12-0-13-0-14-0-15-0-16-0-17-0-18-0-19-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-

where the correct output should be:

>> 11-22-1-0-2-0-3-0-4-0-5-0-6-0-7-0-8-0-9-0-10-0-11-0-12-0-13-0-14-0-15-0-16-0-17-0-18-0-19-0-0-0-0-0-0-0-0-0-0-0-

some help, please??  >_<

Nick Gammon

I would try dropping the baud rate a bit. 115200 is quite fast, the PC might not be keeping up.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

cosailer


I would try dropping the baud rate a bit. 115200 is quite fast, the PC might not be keeping up.


Sorry, already tried that, didn't work.
It seems that the first few bytes were just been cut off, really weird.

Nick Gammon

Each time, or the first time? What version of the IDE are you using?
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

skyjumper

You have a 100mS delay in the transmission. What does read() on the PC side return of there is no data waiting to be read? Perhaps the opposite of what Nick suggested is happening, that the PC is reading fast enough to empty the UART on the receive side, causing read() to return 0, and therefore exiting your loop...

Nick Gammon

Good point. I didn't focus on the PC code. Still, he says it works on one device but not the other.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

skyjumper


Good point. I didn't focus on the PC code. Still, he says it works on one device but not the other.


I think he meant to say the code on the Mega worked, but that on the PC does not. If he referenced a different Arduino device that is sending data then I missed it in his post. I think his issue is that the more data there is, the greater the odds that his receive code is going to empty the buffer before it all done being transmitted by the Mega.

Whatever the ultimate issue is, I would suggest that he (1) compute some minimal checksum to send with the data, (2) invent some kind of flag to mark the end of the data stream/packet of data and (3) compute the checksum of the received data and make sure the transmitted checksum matches. Exactly how to best do this will depend on the nature of the data he is sending.

Of course Nick knows all this, I am posting for the benefit of the original poster and the general audience.



Nick Gammon

I was about ready to suggest he got rid of this line:

Code: [Select]
    Serial.flush();


But I can't quite prove to my satisfaction that it is the cause of it.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

skyjumper


I was about ready to suggest he got rid of this line:

Code: [Select]
    Serial.flush();


But I can't quite prove to my satisfaction that it is the cause of it.


I think he should eliminate that and the delay(100). Especially if he is using 1.0 which has interrupt driven serial transmission. All those lines do is slow down the sending. But even if he leaves them in, I think the receive code needs to be robust enough to cope with things like unexpected delays, bit errors that happen enroute and so on. That means he needs at least a minimal protocol.

He didn't show us enough of the receive code to to eliminate more ordinary programming errors though.

You're right that if he is on a pre-1.0 environment, that will clear the send buffer, meaning perhaps some data gets killed before it is sent. If he is on a 1.0 environment, all it will do is wait until the buffer is empty. No point to that or the delay();



dxw00d

Quote
on a pre-1.0 environment, that will clear the send buffer


Wrong buffer...

From http://arduino.cc/en/Serial/Flush:
Quote
Waits for the transmission of outgoing serial data to complete. (Prior to Arduino 1.0, this instead removed any buffered incoming serial data.)




dxw00d

The 'which IDE?' question hasn't been answered yet, so we don't know what the Serial.flush() is doing.

PaulS

Code: [Select]
class SensorData SD0;
I don't know exactly what this is doing, but I do not think that it is doing what you expect. It is not the correct syntax for declaring an instance of the SensorData class.

A class instance has data and methods.

Code: [Select]
    SD0.readSensor();
   
    Serial.write((byte *)&SD0, sizeof(SD0));

Sending the whole instance, data and methods, hardly seems useful. What is the receiver going to do with the methods?

With no length sent, or start and end markers, how can you expect to know when the complete packet has been received?

Nick Gammon

I was wondering that too, but he said it worked OK.

Quote
below is the code I used on Mega, it worked perfectly.


So who am I to argue with the OP?
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Nick Gammon


Sending the whole instance, data and methods, hardly seems useful. What is the receiver going to do with the methods?


I'm not sure the class data holds the methods per se, but what it does hold is probably implementation-defined.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Go Up