Properties... DTRENable = .T. Enabled= .F. Handshaking = 2 InputMode = 0 RTSENable= .T. RTTHreshold= 1 SThreshold= 0 Settings= {whatever you need - im using} 9600, n, 8, 1 Init Event... THIS.CommPort= 2 THIS.interval= 55 OnComm Event... * I'm doing my on double buffering, hope you get the idea... WITH THISFORM .recbuffSMDR= .recbuffSMDR + THIS.input * look for you terminating chr... IF ! .processing AND AT(CHR(10), .recbuffSMDR)>0 .processing= .T. THISFORM.ledSMDR.backcolor= RGB(255, 0, 0) * double buffer... .buff= .recbuffSMDR .recbuffSMDR= "" .procBuffSMDR .processing= .F. THISFORM.ledSMDR.backcolor= RGB(128, 0, 0) ENDIF ENDWITH form.procBuffSMDR... #DEFINE k_EOL CHR(10) WITH THISFORM LOCAL nl, cs, cStr nl= RAT(k_EOL, .buff) cs= CHRTRAN(LEFT(.buff, m.nl), CHR(13), "") IF m.nl < LEN(.buff) * send the leftovers back to the beginning of the original buffer! .recBuffSMDR= SUBSTR(.buff, m.nl+1) + .recBuffSMDR ENDIF * parse cs FOR m.ii = OCCURS(k_EOL, m.cs) TO 1 STEP -1 IF m.ii = 1 nStart= 1 ELSE nStart= AT(k_EOL, m.cS, m.ii-1)+1 && just after previous EOL ENDIF nEnd= AT(k_EOL, m.cS, m.ii) cStr= SUBSTR(m.cs, m.nStart, m.nEnd-m.nStart) * cStr is now your single record data string * call a function here to do whatever with it ENDFOR ENDWITHThe Oncomm event doesn't need a timer, it just fires off whenever it feels like it :-) !!!