This is a multi-part message in MIME format. ------=_NextPart_000_024A_01C0008C.14504440 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit ----- Original Message ----- From: "Michael Rigby-Jones" To: Sent: Friday, August 04, 2000 2:58 AM Subject: Re: [OT] Using Visual Basic with RS232 Read > > -----Original Message----- > > From: Dan Mulally [SMTP:dtcon@RAPIDNET.COM] > > Sent: Friday, August 04, 2000 1:17 AM > > To: PICLIST@MITVMA.MIT.EDU > > Subject: [OT] Using Visual Basic with RS232 Read > > > > Does anyone have Visual Basic code for reading characters from a PC serial > > port. I'm trying to receive data from a PIC. I can see it fine on a simple > > communications modem program (Quick Link II is what I've been using) but > > when I try to read it with visual basic, I get the first few values and > > then > > it stops and I get a "run-time error '5'" message on the line which reads > > the input buffer. I'm using 9600 baud with about 100msec between > > characters. > > I've attached the files if anyone cares to look at them. Thanks in advance > > for any help. > > > > Dan & Tina Mulally > > dtcon@rapidnet.com > > http://rapidnet.com/~dt2000 << File: lloydspc.vbw >> << File: > > lloydspc.vbp >> << File: lloydspc.frm >> > > > Couple of points: > > 1) The RThreshold property of the comm control is set to zero. This > specifies how many characters must be received before firing the OnComm > event. Having a value of Zero disables this event from ever happening. > Instead you seem to be calling the OnComm event directly, effectively > polling the comm control. This is bad because the OnComm event gets called > not only when you recieve a character, but also for a whole range of Comm > events (errors, transmission of character etc) This means you have > effectively made this Sub re-entrant, i.e. the sub could be called while you > are in it. > > 2) Do > DoEvents > Loop Until MSComm1.InBufferCount >= 1 > Value = Asc(MSComm1.Input) > Select Case MSComm1.CommEvent > > What happens if you, say, receive more than one character? The only thing > that can cause runtime error 5 here is trying to perform an ASC o a null > string, which shouldn't in theory happen because of your loop, but because > of point 1), unpredictable things can happen. You need to buffer the data, > either in a string or a byte array. And use events by setting RThreshold to > 1 and read the entire buffer by setting InputLen to 0. You could read out > the buffer one character at a time, but I think it's safer to empty the Comm > buffer ASAP. > > Private Sub MSComm1_OnComm() > > Dim strBuffer as String > Dim intCount as Integer > Dim bytValue as Byte > > Select Case MSComm1.CommEvent > ' Handle each event or error by placing > ' code below each case statement > ' Errors > Case comEventBreak ' A Break was received. > 'Handle your errors here and then Exit Sub. > End Select > > If MSComm1.InBufferCount = 0 Then Exit Sub ' ensure we have some > characters in the buffer > > strBuffer = MSComm1.Input ' read the conects of the Comm buffer into a > string > For intCount = 1 To Len(strBuffer) > bytValue = Asc(Mid$(strBuffer,intCount,1) > DisplayChar(bytBuffer) > Next intCount > > Exit Sub > > Then modify your Display routine so that it does not call the OnComm event > and remove the polling loop. > > Private Sub DisplayChar(Value as Byte) > > If Value = HEADER Then rx_state = 0 'start of packet > Select Case rx_state > Case 1 > lblSensor1.Caption = Value > Case 2 > lblSensor2.Caption = Value > Case 3 > lblSensor3.Caption = Value > Case 4 > lblSensor4.Caption = Value > Case 5 > lblSensor5.Caption = Value > Case 6 > lblSensor6.Caption = Value > Case 7 > lblSensor7.Caption = Value > Case 8 > lblSensor8.Caption = Value > Case 9 > lblSensor9.Caption = Value > Case 10 > lblSensor10.Caption = Value > Case 11 > lblSensor11.Caption = Value > Case 12 > lblSensor12.Caption = Value > Case 13 > lblSensor13.Caption = Value > Case 14 > lblSensor14.Caption = Value > rx_state = 0 > End Select > rx_state = rx_state + 1 > End Sub > > This way the whole serquence of events will be event driven, effectively > working in the background so that your main program can get on and do other > things. It would also make sense to configure all your labels as a control > array., then you could reduce the above code to something like: > > Private Sub DisplayChar(Value as Byte) > > If Value = HEADER Then rx_state = 0 > > Select Case rx_state > Case 1 To 13 > lblSensor(rx_state).Caption = Value > Case 14 > lblSensor(rx_state).Caption = Value > rx_state = 0 > End Select > rx_state = rx_state +1 > > End Sub > > Hope this helps, if you have any more problems email me. > > Mike Thanks Mike, I implemented your suggestions as best I could. It seems to work except for one glitch: If a byte value of zero is sent, the program doesn't seem to recognize it. It seems that any value from 0 to 255 should be valid. Is there something unique about 0 when using strings perhaps? Maybe this was also part of my original problem. I'm also wondering if there is a way to clear MSComm1.CommEvent which is read only. My modified code is attached. Thanks for the useful suggestions. Dan Mulally ------=_NextPart_000_024A_01C0008C.14504440 Content-Type: application/octet-stream; name="lloydspc.vbw" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="lloydspc.vbw" frmForm1 = 66, 66, 455, 339, Z, 44, 44, 433, 317, ------=_NextPart_000_024A_01C0008C.14504440 Content-Type: application/octet-stream; name="lloydspc.vbp" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="lloydspc.vbp" Type=3DExe Form=3Dlloydspc.frm Reference=3D*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\..\W= INDOWS\STDOLE2.TLB#OLE Automation Object=3D{648A5603-2C6E-101B-82B6-000000000014}#1.1#0; MSCOMM32.OCX IconForm=3D"frmForm1" Startup=3D"frmForm1" HelpFile=3D"" ExeName32=3D"lloydspc.exe" Path32=3D"A:\" Command32=3D"" Name=3D"Project1" HelpContextID=3D"0" CompatibleMode=3D"0" MajorVer=3D1 MinorVer=3D0 RevisionVer=3D0 AutoIncrementVer=3D0 ServerSupportFiles=3D0 CompilationType=3D0 OptimizationType=3D0 FavorPentiumPro(tm)=3D0 CodeViewDebugInfo=3D0 NoAliasing=3D0 BoundsCheck=3D0 OverflowCheck=3D0 FlPointCheck=3D0 FDIVCheck=3D0 UnroundedFP=3D0 StartMode=3D0 Unattended=3D0 ThreadPerObject=3D0 MaxNumberOfThreads=3D1 ------=_NextPart_000_024A_01C0008C.14504440 Content-Type: application/octet-stream; name="lloydspc.frm" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="lloydspc.frm" VERSION 5.00 Object = "{648A5603-2C6E-101B-82B6-000000000014}#1.1#0"; "MSCOMM32.OCX" Begin VB.Form frmForm1 Caption = "Lloyd's Resue Robot" ClientHeight = 5190 ClientLeft = 60 ClientTop = 345 ClientWidth = 7440 LinkTopic = "Form1" ScaleHeight = 5190 ScaleWidth = 7440 StartUpPosition = 3 'Windows Default Begin VB.CommandButton cmdClear Caption = "Clear Errors/Events" Height = 375 Left = 5760 TabIndex = 35 Top = 3480 Width = 1575 End Begin MSCommLib.MSComm MSComm1 Left = 6600 Top = 2400 _ExtentX = 1005 _ExtentY = 1005 _Version = 327680 DTREnable = -1 'True End Begin VB.CommandButton cmdStop Caption = "Stop/Exit" Height = 375 Left = 1680 TabIndex = 1 Top = 4560 Width = 975 End Begin VB.CommandButton cmdStart Caption = "Start" Height = 375 Left = 240 TabIndex = 0 Top = 4560 Width = 975 End Begin VB.Label Label17 Caption = "RX Header" Height = 255 Left = 5280 TabIndex = 36 Top = 360 Width = 855 End Begin VB.Label Label16 Caption = "Serial Port Event" Height = 255 Left = 3720 TabIndex = 34 Top = 4800 Width = 1335 End Begin VB.Label Label15 Caption = "Serial Port Error" Height = 255 Left = 3720 TabIndex = 33 Top = 4440 Width = 1335 End Begin VB.Label lblEvent Caption = "No Event" Height = 255 Left = 5280 TabIndex = 32 Top = 4800 Width = 1935 End Begin VB.Label lblHeader Caption = "lblHeader" Height = 255 Left = 6360 TabIndex = 31 Top = 360 Width = 855 End Begin VB.Label lblError Caption = "No Error" Height = 255 Left = 5280 TabIndex = 30 Top = 4440 Width = 1935 End Begin VB.Label Label14 Caption = "Sensor 7" Height = 255 Left = 120 TabIndex = 29 Top = 3960 Width = 1095 End Begin VB.Label Label13 Caption = "Sensor 6" Height = 255 Left = 120 TabIndex = 28 Top = 3360 Width = 1095 End Begin VB.Label Label12 Caption = "Sensor 5" Height = 255 Left = 120 TabIndex = 27 Top = 2760 Width = 1095 End Begin VB.Label Label11 Caption = "Sensor 4" Height = 255 Left = 120 TabIndex = 26 Top = 2160 Width = 1095 End Begin VB.Label Label10 Caption = "Sensor 3" Height = 255 Left = 120 TabIndex = 25 Top = 1560 Width = 1095 End Begin VB.Label Label9 Caption = "Sensor 2" Height = 255 Left = 120 TabIndex = 24 Top = 960 Width = 1095 End Begin VB.Label Label8 Caption = "Sensor 1" Height = 255 Left = 120 TabIndex = 23 Top = 360 Width = 1095 End Begin VB.Label Label7 Caption = "Left Motor Current" Height = 375 Left = 2760 TabIndex = 22 Top = 3840 Width = 1095 End Begin VB.Label Label6 Caption = "Right Motor Current" Height = 375 Left = 2760 TabIndex = 21 Top = 3240 Width = 1095 End Begin VB.Label Label5 Caption = "Sensor 12" Height = 255 Left = 2760 TabIndex = 20 Top = 2760 Width = 1095 End Begin VB.Label Label4 Caption = "Sensor 11" Height = 255 Left = 2760 TabIndex = 19 Top = 2160 Width = 1095 End Begin VB.Label Label3 Caption = "Sensor 10" Height = 255 Left = 2760 TabIndex = 18 Top = 1560 Width = 1095 End Begin VB.Label Label2 Caption = "Sensor 9" Height = 255 Left = 2760 TabIndex = 17 Top = 960 Width = 1095 End Begin VB.Label Label1 Caption = "Sensor 8" Height = 255 Left = 2760 TabIndex = 16 Top = 360 Width = 1095 End Begin VB.Label lblSensor2 BackColor = &H00FFFFFF& Height = 255 Left = 1200 TabIndex = 15 Top = 975 Width = 1095 End Begin VB.Label lblSensor3 BackColor = &H00FFFFFF& Height = 255 Left = 1200 TabIndex = 14 Top = 1605 Width = 1095 End Begin VB.Label lblSensor4 BackColor = &H00FFFFFF& Height = 255 Left = 1200 TabIndex = 13 Top = 2220 Width = 1095 End Begin VB.Label lblSensor5 BackColor = &H00FFFFFF& Height = 255 Left = 1200 TabIndex = 12 Top = 2760 Width = 1095 End Begin VB.Label lblSensor6 BackColor = &H00FFFFFF& Height = 255 Left = 1200 TabIndex = 11 Top = 3360 Width = 1095 End Begin VB.Label lblSensor7 BackColor = &H00FFFFFF& Height = 255 Left = 1200 TabIndex = 10 Top = 3960 Width = 1095 End Begin VB.Label lblSensor1 BackColor = &H00FFFFFF& Height = 255 Left = 1200 TabIndex = 9 Top = 360 Width = 1095 End Begin VB.Label lblSensor8 BackColor = &H00FFFFFF& Height = 255 Left = 3960 TabIndex = 8 Top = 360 Width = 1095 End Begin VB.Label lblSensor9 BackColor = &H00FFFFFF& Height = 255 Left = 3960 TabIndex = 7 Top = 975 Width = 1095 End Begin VB.Label lblSensor10 BackColor = &H00FFFFFF& Height = 255 Left = 3960 TabIndex = 6 Top = 1560 Width = 1095 End Begin VB.Label lblSensor11 BackColor = &H00FFFFFF& Height = 255 Left = 3960 TabIndex = 5 Top = 2160 Width = 1095 End Begin VB.Label lblSensor12 BackColor = &H00FFFFFF& Height = 255 Left = 3960 TabIndex = 4 Top = 2760 Width = 1095 End Begin VB.Label lblSensor13 BackColor = &H00FFFFFF& Height = 255 Left = 3960 TabIndex = 3 Top = 3360 Width = 1095 End Begin VB.Label lblSensor14 BackColor = &H00FFFFFF& Height = 255 Left = 3960 TabIndex = 2 Top = 3960 Width = 1095 End End Attribute VB_Name = "frmForm1" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = False '-------------------------------------------------------- 'Programmer: Dan Mulally 'Date: 8/7/00 'File: lloydspc.vbp ' 'This Program runs on a PC and reads the data from the 'robot unit via the base unit using COM1. The unique 'character HEADER signifies the start of the data. 'Subsequent numeric character values are then displayed 'in their label boxes. Errors or other messages are 'displayed in separate label boxes. '--------------------------------------------------------- Option Explicit Const HEADER As Byte = 112 'denotes start of packet, must match robot software Public Value As Byte Public rx_state As Byte Private Sub cmdClear_Click() lblError.Caption = "No Errors" lblEvent.Caption = "No Events" End Sub Private Sub cmdStart_Click() Do DoEvents Call MSComm1_OnComm 'read serial character Loop End Sub Private Sub cmdStop_Click() MSComm1.PortOpen = False 'disable comm port upon shutdown Unload frmForm1 End End Sub Private Sub Form_Load() MSComm1.PortOpen = True 'enable comm port upon startup End Sub Private Sub MSComm1_OnComm() Dim strBuffer As String Dim intCount As Integer Dim bytValue As Byte Select Case MSComm1.CommEvent ' Handle each event or error by placing ' code below each case statement ' Errors Case comEventBreak ' A Break was received. lblError.Caption = "Break" Case comEventCDTO ' CD (RLSD) Timeout. lblError.Caption = "CD Timeout" Case comEventCTSTO ' CTS Timeout. lblError.Caption = "CTS Timeout" Case comEventDSRTO ' DSR Timeout. lblError.Caption = "DSR Timeout" Case comEventFrame ' Framing Error lblError.Caption = "Frame Error" Case comEventOverrun ' Data Lost. lblError.Caption = "Data Lost" Case comEventRxOver ' Receive buffer overflow. lblError.Caption = "RX Overflow" Case comEventRxParity ' Parity Error. lblError.Caption = "Parity Error" Case comEventTxFull ' Transmit buffer full. lblError.Caption = "TX Full" Case comEventDCB ' Unexpected error retrieving DCB lblError.Caption = "DCB Error" ' Events Case comEvCD ' Change in the CD line. lblEvent.Caption = "CD" Case comEvCTS ' Change in the CTS line. lblEvent.Caption = "CTS" Case comEvDSR ' Change in the DSR line. lblEvent.Caption = "DSR" Case comEvRing ' Change in the Ring Indicator. lblEvent.Caption = "Ring" Case comEvReceive ' Received RThreshold # of ' chars. lblEvent.Caption = "RX Thresh#" Case comEvSend ' There are SThreshold number of ' characters in the transmit ' buffer. lblEvent.Caption = "SThresh in TX" Case comEvEOF ' An EOF charater was found in ' the input stream lblEvent.Caption = "EOF in input" End Select If MSComm1.InBufferCount = 0 Then Exit Sub 'ensure we have some characters in the buffer strBuffer = MSComm1.Input 'read contents of the buffer into a string For intCount = 1 To Len(strBuffer) bytValue = Asc(Mid$(strBuffer, intCount, 1)) DisplayChar (bytValue) Next intCount Exit Sub ' MSComm1.Output = Chr(Value) End Sub Public Sub DisplayChar(Value As Byte) If Value = HEADER Then rx_state = 0 'start of packet lblHeader.Caption = Value End If Select Case rx_state Case 1 lblSensor1.Caption = Value Case 2 lblSensor2.Caption = Value Case 3 lblSensor3.Caption = Value Case 4 lblSensor4.Caption = Value Case 5 lblSensor5.Caption = Value Case 6 lblSensor6.Caption = Value Case 7 lblSensor7.Caption = Value Case 8 lblSensor8.Caption = Value Case 9 lblSensor9.Caption = Value Case 10 lblSensor10.Caption = Value Case 11 lblSensor11.Caption = Value Case 12 lblSensor12.Caption = Value Case 13 lblSensor13.Caption = Value Case 14 lblSensor14.Caption = Value rx_state = 0 End Select rx_state = rx_state + 1 End Sub Private Sub Text1_Change() End Sub ------=_NextPart_000_024A_01C0008C.14504440-- -- http://www.piclist.com hint: The list server can filter out subtopics (like ads or off topics) for you. See http://www.piclist.com/#topics