Code archives/User Input/COM-Port II

This code has been declared by its author to be Public Domain code.

Download source code

COM-Port II by Vertex2005
File% = OpenCommPort%(0-255) ; -1 = Error
Succes% = CloseCommPort%(File%)
Size% = WriteComm%(File%, Bank%, Size%)
Size% = ReadComm%(File%, Bank%, Size%)
Succes% = SetComm%(File%, "Settings")
Succes% = SetCommTimeouts%(File%, ReadMillisecs%, WriteMillisecs%)

SetComm: http://msdn.microsoft.com/library/en-us/devio/base/buildcommdcb.asp?frame=true
For example "baud=9600 parity=N data=8 stop=1":
Sets baudrate to 9600 bits per second, no paritybit, 8 databits and 1 stopbit.

Example:
File% = OpenCommPort(1)
SetComm(File%, "baud=9600 parity=N data=8 stop=1")
SetCommTimeouts(File%, 500, 500)

Repeat
	Message$ = Input("Message: ")
	If Message$ = "end" Then
		Exit
	ElseIf Message$ = "cls" Then
		Cls
		Locate 0, 0
		Message$ = ""
	EndIf
	
	SendMessage(File%, Message$+Chr$(13)+Chr$(10))
	
	Message$ = RecvMessage(File%)
	If Message$ <> "" Then Print Message$
Forever

CloseCommPort(File%)
End

Function SendMessage%(File%, Command$)
	Local Buffer%, Offset%, Succes%
	
	Buffer% = CreateBank(Len(Command$))
	For Offset% = 0 To Len(Command$)-1
		PokeByte Buffer%, Offset%, Asc(Mid$(Command$, Offset%+1, 1))
	Next
	
	Success% = WriteComm(File%, Buffer%, Len(COmmand$))
	FreeBank Buffer%
	
	Return Success%
End Function

Function RecvMessage$(File%)
	Local Buffer%, Offset%, Count%, Message$
	
	Buffer% = CreateBank(1024)
	Count% = ReadComm(File%, Buffer%, 1024)
	If Count% > 0 Then
		For Offset% = 0 To Count-1
			Message$ = Message$+Chr$(PeekByte(Buffer%, Offset%))
		Next
		Return Message$
	Else
		FreeBank Buffer%
		Return ""
	EndIf
End Function


Just put your old modem on port 1, write "AT" (AT = Attention) press Return. Now you can communicate with your modem. For example "ATDT1234567" (D = Dail, T = Tone) or Hangup with ATH0.

You just need the following comport.decls :
.lib "kernel32.dll"


apiCreateFile%(FileName$, DesiredAccess%, ShareMode%, pSecurrityAttribute%, CreationDistribution%, FlagsAndAttributes%, TemplateFile%) : "CreateFileA"
apiCloseHandle%(Object%) : "CloseHandle"

apiWriteFile%(File%, pBuffer*, NumberOfBytesToWrite%, pNumberOfBytesWritten*, pOverlapped%) : "WriteFile"
apiReadFile%(File%, pBuffer*, NumberOfBytesToRead%, pNumberOfBytesRead*, pOverlapped%) : "ReadFile"


apiGetCommState%(File%, pDCB*) : "GetCommState"
apiSetCommState%(File%, pDCB*) : "SetCommState"
apiBuildCommDCB%(Def$, pDCB*) : "BuildCommDCBA"
apiGetCommTimeouts%(File%, pCommTimeouts*) : "GetCommTimeouts"
apiSetCommTimeouts%(File%, pCommTimeouts*) : "SetCommTimeouts"


cu olli
Const GENERIC_READ          = $80000000
Const GENERIC_WRITE         = $40000000
Const OPEN_EXISTING         = 3
Const FILE_ATTRIBUTE_NORMAL = $80
Const INVALID_HANDLE_VALUE  = -1

Function OpenCommPort%(Port%)
	Local File%

	If (Port < 0) Or (Port > 255) Then Return -1
	
	; Open CommPort
	File% = apiCreateFile("COM"+Port%, GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0)
	If File% = INVALID_HANDLE_VALUE Then
		Return -1
	Else
		Return File%
	EndIf
End Function

Function CloseCommPort%(File%)
	Return apiCloseHandle(File%)
End Function

Function WriteComm%(File%, Buffer%, Size%)
	Local Count%, Count2%

	If Size% > BankSize(Buffer%) Then Return 0
	
	Count% = CreateBank(4)
	
	If apiWriteFile(File%, Buffer%, Size%, Count%, 0) = 0 Then
		FreeBank Count%
		Return 0
	Else
		Count2% = PeekInt(Count%, 0)
		FreeBank Count%
		Return Count2%
	EndIf
End Function

Function ReadComm%(File%, Buffer%, Size%)
	Local Count%, Count2%
	
	If Size% > BankSize(Buffer%) Then Return 0
	
	Count% = CreateBank(4)
	
	If apiReadFile(File%, Buffer%, Size%, Count%, 0) = 0 Then
		FreeBank Count%
		Return 0
	Else
		Count2% = PeekInt(Count%, 0)
		FreeBank Count%
		Return Count2%
	EndIf
End Function

Function SetComm%(File%, Settings$)
	Local DCB%
   
	DCB% = CreateBank(28)
   
	; Get States
	If apiGetCommState(File%, DCB) = 0 Then
		FreeBank DCB%
		Return False
	ElseIf PeekInt(DCB%, 0) <> 28
		FreeBank DCB%
		Return False
	EndIf
	
	; Build DCB
	If apiBuildCommDCB(Settings$, DCB%) = 0 Then
		FreeBank DCB%
		Return False
	EndIf
   
	; Set States
	If apiSetCommState(File%, DCB%) = 0 Then
		FreeBank DCB%
		Return False
	Else
		FreeBank DCB%
		Return True
	EndIf
End Function 

Function SetCommTimeouts%(File%, ReadTime%, WriteTime%)
	Local TimeOuts%
	
	; Get timeouts
	Timeouts% = CreateBank(40)
	If apiGetCommTimeouts(File%, Timeouts%) = 0 Then
		FreeBank Timeouts
		Return False
	EndIf
	
	PokeInt Timeouts%,  8, ReadTime%  ; ReadTotalTimeoutConstant
	PokeInt Timeouts%, 16, WriteTime% ; WriteTotalTimeoutConstant
	
	; Set Timeouts
	If apiSetCommTimeouts(File%, Timeouts%) = 0 Then
		FreeBank Timeouts
		Return False
	Else
		FreeBank Timeouts
		Return True
	EndIf
End Function

Comments

Nigel Brown2005
Have done a MAX module of this if anyone interested? Havenot tested it yet seems to be ok.


Neochrome2005
hey this works!!!!!
even works with home brew RS232 buffers!


Lane2006
Thanks this seems to work, after adding the API stuff to my Kernal32.decl

some of the declarations already existed with api_ as show below
Yours : apiSetCommState%(File%, pDCB*) : "SetCommState"
Mine: api_SetCommState% (hCommDev%, lpDCB*) : "SetCommState"


Mr. Bean2007
I was searching for a Terminal, to test my At89S8252-processor, found a lot, but nothing good. Then I saw this, compiled and everything works now.
Thanks


schilcote2008
Exactly how do we use it? (I'm not great with advanced concepts like memory banks and stuff)


Litobyte2008
Hey Vertex, thanks for sharing.

I tried and it wooooorks!


Danny2010
@Nigel Brown, yes I'm very much interested in a BMax version. Do you still have it?

Cheers,
Danny


markcw2010
Nigel Brown's com module is here.

Also see Brucey's wxCTB.


Code Archives Forum