serial port

BlitzMax Forums/BlitzMax Programming/serial port

allos(Posted 2006) [#1]
can someone help me to learn how to send a signal via COM port from a blitzmax software?
I need to interface a portable computer with another device and need to send a trigger to exactly mark the time of an event (keypress, for instance) in the second computer (equipped with a dedicated slot which can receive digital signals via COM port)

...yes, I never learned assembler

thank you
allos


MattVonFat(Posted 2006) [#2]
I'm not really savvy when it comes to what ports are what. I have got this code though which uses the Inpout32 DLL which can be downloaded from somewhere. I was using a 25 pin serial port and that seemed to work.

Global IOP = LoadLibraryA("Inpout32")
Global Out32(Port:Int,Value:Int)=getprocaddress(IOP,"Out32")

Global Lpt1 = $9800

Out32(Lpt1,1)


I used a tutorial someone posted to be able to load the DLL and the function.

The second value in Out32 is a binary value which will trigger the pins. Lpt1 is the port number. I think that should work for everyone.

If you can't find the DLL on the internet I will upload to my website for you.

[edit] I found the DLL: http://www.logix4u.net/inpout32.htm [/edit]


allos(Posted 2006) [#3]
thank you, but I think this code (and related web page) are about parallel port, not serial port
bye
allos


Charrua(Posted 2008) [#4]
Hi
I'm plannig to move to BlitzMax, but first I need to know if
the communication between blitzmax and ports (both serial and paralell) are posible.
Have you found the way to stablish the link between blitzmax and the serial port??

By the way, if you have a usart in your pc (not via a usb to serial hardware), then you just do a Out to the base port of the usart (usually 0x3F8, see the hardware properties of your comm) that`s all for start a serial communiation. To change the speed and other parameter`s is more complicated. To read to, but if you are interested could talk later

Juan


plash(Posted 2008) [#5]
There is a com module around here somewhere..


Nigel Brown(Posted 2008) [#6]
wxMAX will supply you with multi platform serial capability, and checkout my webpage for Parallel I/O under the BlitzMAX section look for DLPortIO. p.s. Click the name for link.


Charrua(Posted 2008) [#7]
Thank's

I already use DLPortIO with Blitz3D and some .decls for kernel32.dll. I have no problem using any ono of them. My quesiton is, how I do a similar thing with BlitzMax. I dont have BlitzMax, and probably move me to thath plataform, but I want to know before if it's posible to handle port's and how.


plash(Posted 2008) [#8]
checkout my webpage for Parallel I/O under the BlitzMAX section look for DLPortIO. p.s. Click the name for link.


That's the one I was thinking of!


Nigel Brown(Posted 2008) [#9]
@Odriozola Almeida, something like this:

Global	DllHandle=LoadLibraryA("DLPORTIO.dll")

Global	DlPortReadPortUchar:Byte( port:Int )"Win32"=GetProcAddress(DllHandle,"DlPortReadPortUchar")
Global	DLPortReadPortUshort:Short( port:Int )"Win32"=GetProcAddress(DllHandle,"DLPortReadPortUshort")
Global	DLPortReadPortUlong:Int( port:Int )"Win32"=GetProcAddress(DllHandle,"DLPortReadPortUlong")

Global	DlPortReadPortBufferUchar( port:Int, buffer:Byte Ptr, count:Int )"Win32"=GetProcAddress(DllHandle,"DlPortReadPortBufferUchar")
Global	DlPortReadPortBufferUshort( port:Int, buffer:Short Ptr, count:Int )"Win32"=GetProcAddress(DllHandle,"DlPortReadPortBufferUshort")
Global	DlPortReadPortBufferUlong( port:Int, buffer:Int Ptr, count:Int )"Win32"=GetProcAddress(DllHandle,"DlPortReadPortBufferUlong")

Global	DlPortWritePortUchar( port:Int, value:Byte )"Win32"=GetProcAddress(DllHandle,"DlPortWritePortUchar")
Global	DlPortWritePortUshort( port:Int, value:Short )"Win32"=GetProcAddress(DllHandle,"DlPortWritePortUshort")
Global	DlPortWritePortUlong( port:Int, value:Int )"Win32"=GetProcAddress(DllHandle,"DlPortWritePortUlong")

Global	DlPortWritePortBufferUchar( port:Int, buffer:Byte Ptr, count:Int )"Win32"=GetProcAddress(DllHandle,"DlPortWritePortBufferUchar")
Global	DlPortWritePortBufferUshort( port:Int, buffer:Short Ptr, count:Int )"Win32"=GetProcAddress(DllHandle,"DlPortWritePortBufferUshort")
Global	DlPortWritePortBufferUlong( port:Int, buffer:Int Ptr, count:Int )"Win32"=GetProcAddress(DllHandle,"DlPortWritePortBufferUlong")




Charrua(Posted 2008) [#10]
GUAU!

(in spanish sound like WOW, most like dog's do)

Thank's a lot

I'll have the evaluation blitzmax, so tray and pray (as always)

I supose that this is for all registered dll's??

best regards!

Juan


Charrua(Posted 2008) [#11]
Rem

	My "Hellow World" in BlitzMax!

		A simple application that sends 1000 count values a second to the base port
	of LPT and read 4 times a second the status port (base+1)
	
	Just for test DLPORTIO.dll, thank´s Nigel Brown for your help!

End Rem

Strict

Graphics 640,480,0


Global	DllHandle=LoadLibraryA("DLPORTIO.dll")
Global	DlPortReadPortUchar:Byte( port:Int )"Win32"=GetProcAddress(DllHandle,"DlPortReadPortUchar")
Global	DlPortWritePortUchar( port:Int, value:Byte )"Win32"=GetProcAddress(DllHandle,"DlPortWritePortUchar")

Global Pasada
Global Vueltas
Global Lectura


Const PuertoDatos   = $378	'base LPT adress in my machine, 8 bits (output)
Const PuertoEstado  = $379	'status port 5 most significant bits used (input)
Const PuertoControl = $37A	'4 bits (thre of them inverted) bit 5 stablish the 
							'direction of data port, by default bit cleared
							'data port is output.

Delay 10

Pasada = 0
Vueltas = 0

While Not KeyHit(KEY_ESCAPE)
	
	DlPortWritePortUchar(PuertoDatos,Pasada)		'write nex value to the port
	Pasada = Pasada + 1
	Delay 1
	'1 ms BitTime in Bit0 of LPT data port = 500 Hz square signal (pin 2 of the DB25 male connector)
	'2 ms BitTime in Bit1 of LPT data port = 250 Hz square signal (pin 3)
	'and so on... in powers of 2
	'128 ms BitTime in Bit7 of LPT data port (pin 9)


	If Pasada=250 Then
		Pasada=0
		Vueltas=Vueltas+1
		'read status pins four times a second
		Lectura = DlPortReadPortUchar(PuertoEstado) ~ $80	'msb is inverted
		Cls
		DrawText "Vueltas: "+Vueltas,20,20
		DrawText "Lectura: "+Right(Bin(Lectura),8),20,40	'show just 8 bits
		DrawText "Lectura: "+Lectura,20,60
		Flip
	End If
Wend

DlPortWritePortUchar(PuertoDatos,0)

End



plash(Posted 2008) [#12]
Just a note: you can use {code}Print "Hey!"{/code} (replace the {} with []) to get code in a codebox.


Charrua(Posted 2008) [#13]
thank's Plash

(i'm new in this thing's)

some one knows how to translate to blitz max this??

.lib "Kernel32.dll" 

RtlMoveMemory%(Destination*,Source,Length) : "RtlMoveMemory" 
RtlMoveMemory2%(Destination,Source*,Length) : "RtlMoveMemory" 

apiCreateFile%(lpFileName$, dwDesiredAccess, dwShareMode, lpSecurrityAttributes, dwCreationDistribution, dwFlagsAndAttributes, hTemplateFile) : "CreateFileA" 
apiSetupComm%(hFile, dwInQueue, dwOutQueue) : "SetupComm" 
apiGetCommState%(hFile, lpDCB*) : "GetCommState" 
apiSetCommState%(hFile, lpCDB*) : "SetCommState" 
apiSetCommMask%(hFile, dwEvtMask) : "SetCommMask" 
apiCloseHandle%(hObject) : "CloseHandle" 
apiEscapeCommFunction%(hFile, dwFunc) : "EscapeCommFunction" 
apiWriteFile%(hFile, lpBuffer*, nNumberOfBytesToWrite, lpNumberOfBytesWritten*, lpOverlapped) : "WriteFile" 
apiSetCommTimeouts%(hFile, lpCommTimeouts*) : "SetCommTimeouts" 
apiClearCommError%(hFile, lpErrors*, lpStat*) : "ClearCommError" 
apiReadFile%(hFile, lpBuffer*, nNumberOfBytesToRead, lpNumberOfBytesRead*, lpOverlapped) : "ReadFile"


specially those who reference poniters ("*")


plash(Posted 2008) [#14]
Extern "win32"
	Function RtlMoveMemory(Destination:Byte Ptr, Source:Int, Length:Int) = "RtlMoveMemory@12" 
	Function RtlMoveMemory2:Int(Destination:Int, Source:Byte Ptr, Length:Int) = "RtlMoveMemory@12" 
	
	Function apiCreateFile:Int(lpFileName:String, dwDesiredAccess:Int, dwShareMode:Int, lpSecurrityAttributes:Int, dwCreationDistribution:Int, dwFlagsAndAttributes:Int, hTemplateFile:Int) = "CreateFileA@28" 
	Function apiSetupComm:Int(hFile:Int, dwInQueue:Int, dwOutQueue:Int) = "SetupComm@12" 
	Function apiGetCommState:Int(hFile:Int, lpDCB:Byte Ptr) = "GetCommState@8" 
	Function apiSetCommState:Int(hFile:Int, lpCDB:Byte Ptr) = "SetCommState@8" 
	Function apiSetCommMask:Int(hFile:Int, dwEvtMask:Int) = "SetCommMask@8" 
	Function apiCloseHandle:Int(hObject:Int) = "CloseHandle@4" 
	Function apiEscapeCommFunction:Int(hFile:Int, dwFunc:Int) = "EscapeCommFunction@8" 
	Function apiWriteFile:Int(hFile:Int, lpBuffer:Byte Ptr, nNumberOfBytesToWrite:Int, lpNumberOfBytesWritten:Byte Ptr, lpOverlapped:Int) = "WriteFile@20" 
	Function apiSetCommTimeouts:Int(hFile:Int, lpCommTimeouts:Byte Ptr) = "SetCommTimeouts@12" 
	Function apiClearCommError:Int(hFile:Int, lpErrors:Byte Ptr, lpStat:Byte Ptr) = "ClearCommError@12" 
	Function apiReadFile:Int(hFile:Int, lpBuffer:Byte Ptr, nNumberOfBytesToRead:Int, lpNumberOfBytesRead:Byte Ptr, lpOverlapped:Int) = "ReadFile@20"
End Extern

That should do it, though I'm not 100% positive I got the :Byte Ptr thing right.

EDIT: The <func>@<num> part is used because apiReadFile does not exist in kernel32.dll, its basically telling the compiler to call ReadFile, through apiReadFile.
The @<num> part of that is just <num> = number of parameters * 4.


Nigel Brown(Posted 2008) [#15]
Or as a module, create a brown/comm.mod in modules and use this:



[Admin Note: Please use the [codebox] tags instead of [code] when posting large pieces of code.] What are the forum codes?


Charrua(Posted 2008) [#16]
Thank's again both

A nice piece of code, I hope to understand it soon, let me read about modules and will try some things.

I'm not a programmer, ellectronics is my area, I like software and I read an play mostly with Pascal (3.0 .. 6.0)
I read some C (djgpp) and assembler 8086 (I work with microcontrollers). Basic of course. For a year in my free times i'm learning Blitz3D for a project I supose some day will finish.

I write some thing's enterely by instinct.

Starting with the definitions I saw in DLPORTIO and the one's you sent me, I try to write some thing like your's, but I find that the string definition:

apiCreateFile:Int(lpFileName:String, dwDesiredAccess:Int, dwShareMode:Int, lpSecurrityAttributes:Int, dwCreationDistribution:Int, dwFlagsAndAttributes:Int, hTemplateFile:Int) = "CreateFileA"


At first I receive an error when I call that function, then I saw that the definition start with "apiCreateFile" and end with "CreateFileA" I decide to declare:

global apiCreateFile:Int(lpFileName:String, dwDesiredAccess:Int, dwShareMode:Int, lpSecurrityAttributes:Int, dwCreationDistribution:Int, dwFlagsAndAttributes:Int, hTemplateFile:Int)"Win32"=GetProcAddress(DllHandle,"CreateFileA")


I didn't get an error

when the compiler doesn't recongnize the "*"

I defined the pointers as Byte Ptr, and I reveive no error message

so

I rewrite the functions in SERIALIO.BB the way I think they should work (FREEBANK doesn't exists but seems thah BlitzMax is intelligent enaugh to free all the things one leave with out use!??)

but CreateFile doesn't seems to work properly, didn`t return other value than -1 (having a port free in my machine).

I put Varptr nameVar whenever shoul be a pointer but still doesn' wor, really I don't know why!

Thank's again


plash(Posted 2008) [#17]
I don't think you can send Varptr variables to external functions, other then that I would have to see what your code is actually doing to figure out why createfile returns -1.


Charrua(Posted 2008) [#18]
Well, I try to use your EXTERNS declares but the compiler seems to have a trouble with the @12 in the apiSetCommTimeOuts, so I tried Niegel's module.
Work's!
After some wrong writing command's the BMK build the mod

I suppose, I forgotten something because from a new bmx file doesen't see the type TComm. Do I have to do something else to mod's other than bmk?

Any way, I comment (') the module's declarations and use all of the code in a .bmx, plus some code to test the metod's and work fine.

Thank's both for your help
Be patient with me, for each answer I resolve, I got 100 new question's, but keep walking (like jhonny)


Danny(Posted 2010) [#19]
Here is an example serial port reader based on Nigel Brown's module (post #15).

I used it to communicate with my parralax USB RFID reader. It works flawlessly! Just swipe the RFID tags over the reader and the code will display the Tag ID's.

Cheers,

Danny