We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpElectronics,  Serial Library › Serial Port write data lost
Page Index Toggle Pages: 1
Serial Port write data lost (Read 1824 times)
Serial Port write data lost
Mar 22nd, 2008, 7:21pm
 
Has anyone else seen this (and hopefully worked around it).  I have a simple processing program that sends a 3-byte string through the serial port to a device and waits for a response from the device.  It seems that occasionally the data I am trying to write just gets lost.  I use a serialEvent to receive data (it sets a flag).  My program looks like

  1. send command
  2. wait for a flag to be set indicating we got data
  3. display the data

My wait loop sometimes just hangs forever (well, until a timeout expires).  I have attached an external terminal to the serial interface and confirmed in those cases no data is transmitted.  After the wait loop times out the next command is sent.

I'm running Mac OS X 10.5.2 (PPC) using a FTDI 232R USB to serial interface.  

  - Processing 0135 Beta
  - RXTX-2.1-7
  - FTDI USBSerialDriver 2.1.7

The program looks like:

/**
* Simple Heart Rate Display
* by Dan Julio.
*
* Send a Get Heartrate command to the HRMI device and
* then display the received heartrate along with
* status flags.
*
* The HRMI device must be configured for serial
* operation with a baud rate of 57,600 baud (default
* with no jumpers).
*
*/


import processing.serial.*;

Serial port;                           // The serial port
byte[] rspCharArray = new byte[32];    // Where we'll put the raw data read from the HRMI device
int[] rspArgArray = new int[3];        // Where we'll put the converted response values
int validData = 0;
int LINE_FEED = 10;                    // <LF> constant
PFont fontA;
int timeout;
int timeoutCount = 0;

void setup() {
 size(200, 200);  // Stage size
 
 // Setup text
 fontA = loadFont("CourierNew36.vlw");
 
 // Open the serial port with the default baud rate of 57600
 // baud.  I know that the FTDI 232R USB to serial interface
 // on my Mac is Serial.list()[2] so I always open that.
 // However the particular entry on your machine may be different.
 // Uncomment out the
 //
//  println(Serial.list());
 //
 // command to identify the port to use.  

 // Hack: Open the known device
 port = new Serial(this, Serial.list()[2], 57600);
 
 // Setup the serialEvent to be called when we receive complete response
 // packets from the HRMI device
 port.bufferUntil(LINE_FEED);
 
}

void draw() {

 // Send a command to get a single heart rate value
 validData = 0;
 port.write('G');
 port.write('1');
 port.write(LINE_FEED);

 // Wait for a response from the HRMI device.
 //
 // Includes a kludge to work around an issue somewhere in the
 // serial software from port.write() to actual hardware.  On my
 // system data I load with port.write sometimes seems to be
 // lost (is never transmitted out the serial port).  This code
 // aborts the response wait after a couple of seconds so the main
 // loop can issue another command.
 timeout = 0;
 while (validData == 0) {
   delay(500);
   timeout += 1;
   if (timeout > 4) {
     print("Timeout "); println(timeoutCount); timeoutCount++;
     validData = -1;
   }
 }
 
 if (validData != -1) {
   // Blank the display area
   fill(102);
   rect(0, 0, 200, 200);
 
   // Display the heart rate
   fill(204);
   textFont(fontA, 56);
   text(rspArgArray[2], 20, 50);
 
   // Display the count
   fill(204);
   textFont(fontA, 14);
   text("Count: ", 20, 100);
   text(rspArgArray[1], 75, 100);
     // Display the status flag information
   fill(10);
   textFont(fontA, 14);
   
   if ((rspArgArray[0] & 0x01) == 0x01) {
     text("Algorithm: Averaged", 20, 120);
   } else {
     text("Algorithm: Raw", 20, 120);
   }
   
   if ((rspArgArray[0] & 0x02) == 0x02) {
     text("No Heartbeat detected", 20, 140);
   } else {
     text("Heartbeat detected", 20, 140);
   }
   
   if ((rspArgArray[0] & 0x04) == 0x04) {
     text("(Re)acquiring Series", 20, 160);
   }
   
   if ((rspArgArray[0] & 0x08) == 0x08) {
     text("Too much bad data", 20, 180);
   }
 }
 
}

// Catch the event from the serial interface.  This event seems to be
// called even when there is no receive data (perhaps for the transmitted
// data) so we make sure there is actually data to read before attempting
// to do any processing.
void serialEvent(Serial port) {
     if (port.readBytesUntil(LINE_FEED, rspCharArray) != 0) {
       // Read bytes until we get to the end of the packet converting
       // each ASCII digit into a number.  We make use of the space
       // character between sets of digits to delimit numbers.
       //    Argument 0: Status Flags
       //    Argument 1: Second Count
       //    Argument 2: Heartrate
       //
       int ArgIndex = 0;
       int CharIndex = 0;
       for (int i=0; i<3; i++) rspArgArray[i] = 0;
       while (rspCharArray[CharIndex] != LINE_FEED) {
         if (rspCharArray[CharIndex] != ((byte) ' ')) {
           rspArgArray[ArgIndex] = (rspArgArray[ArgIndex]*10) + (rspCharArray[CharIndex] - ((byte) '0'));
         } else {
           ArgIndex++;
         }
         CharIndex++;
       }
       validData = 1;
     }
}
Page Index Toggle Pages: 1