Jump to content

CommAPI - Serial and parallel communication with Windows API


therealhanuta
 Share

Recommended Posts

3. Pls share your func: "I had to write  a  function to replace  _CommGetLine($sEndChar = @CR, $maxlen = 0, $maxtime = 0) found in CommMG.au3. I'll post it if requested."

Below is promised code. Append this function to CommInterface.au3:

 

Hello Marcsf73,

I have added a similar function, now.

An example you can find here: http://www.autoitscript.com/wiki/CommAPI_Examples#Separator

1. You are right. I have an old comminterface from 10/2013. Newer is fom 3/2014

The information what is newer and what is older should be a little more commucative organized.

 

Hello adom,

here you can find the changelog: http://www.autoitscript.com/wiki/CommAPI#Changelog

Link to comment
Share on other sites

CommAPI Examples
 

Hi TheRealHanuta, concerning Sample Script "Slow Devices" I have following Question:

Do I have to use _CommAPI_ChangeCommTimeoutsElement($hFile, "ReadTotalTimeoutMultiplier", 100)

before every call of _CommAPI_ReceiveData

or

is it necessary only once while initializing ComPort?

THX

Thanks! :bye:

Greetings

Andrew

 

Link to comment
Share on other sites

Hi TheRealHanuta,

Any direction or example for the use of _CommAPI_WaitCommEvent? Whatever I do on the opened port, that function returns 0.

I'm using it in the GUIGetMsg loop to call the concerned func when a character is pending on COM1.

Thanks,

Thoms

OS:WIN_7/Service Pack 1  CPU:X64 OS:X64

AutoIt3 V 3.3.10.2

Link to comment
Share on other sites

Hi,

Another question: I'm trying to connect on COM10. No way. Even no way to connect on ports higher than COM9.

The _WinAPI_GetLastErrorMessage reports "Bad parameter".

Any clue?

Thx

Thoms

 

Try to initialize these comports you want with a simulation: http://www.232analyzer.com/232default.htm.

To find out if they are already occupied.

Thanks! :bye:

Greetings

Andrew

 

Link to comment
Share on other sites

Hi adom,

I guess these comports are free : I'm using com0com to make 2 bridges (COM9<->COM10 and COM11<->COM12) and Realterm on each side (COM10 and COM12). I'm in the middle conditioning  data from COM9 to COM11 and vice-versa.

RealTerm can connect on any virtual comport, ie. COM10 or whatever, but NOT on busy ports.

Given that the first com0com bridge is between COM9 and COM10, I've to connect to COM9. If I try the other direction : RealTerm on COM9 and me on COM10, I get the error message. About the other side: COM11 or COM12, I'm really expecting something that works.

Is there something else I can check?

Thx

Thoms

Link to comment
Share on other sites

Hi adom,

I guess these comports are free : I'm using com0com to make 2 bridges (COM9<->COM10 and COM11<->COM12) and Realterm on each side (COM10 and COM12). I'm in the middle conditioning  data from COM9 to COM11 and vice-versa.

RealTerm can connect on any virtual comport, ie. COM10 or whatever, but NOT on busy ports.

Given that the first com0com bridge is between COM9 and COM10, I've to connect to COM9. If I try the other direction : RealTerm on COM9 and me on COM10, I get the error message. About the other side: COM11 or COM12, I'm really expecting something that works.

Is there something else I can check?

Thx

Thoms

Next ideas:

1. Check if you have the newest Inludes from http://www.autoitscript.com/w/index.php?title=CommAPI&oldid=12340 #Scripts

2. Use GetCOMPorts Func to see it what commAPI will find comports

3. If you want pls explain what you mean by Bridge? What does it exactly?

I am new with comAPI and doing currently my first comm APP. So feel free to ask the community if my ideas are not helpful.

Thanks! :bye:

Greetings

Andrew

 

Link to comment
Share on other sites

Any direction or example for the use of _CommAPI_WaitCommEvent? Whatever I do on the opened port, that function returns 0.

I'm using it in the GUIGetMsg loop to call the concerned func when a character is pending on COM1.

 

Hi thoms,

I fixed @error handling, but I can't help you to create an example, because I have never used this function.

Maybe this can help you to create an examples for us: http://www.codeproject.com/Articles/2682/Serial-Communication-in-Windows (Search for WaitCommEvent)

Link to comment
Share on other sites

Another question: I'm trying to connect on COM10. No way. Even no way to connect on ports higher than COM9.

The _WinAPI_GetLastErrorMessage reports "Bad parameter".

 

Hi thoms,

I can't find any error. For me COM10 is working fine.

Are you using function _CommAPI_OpenPort or _CommAPI_OpenCOMPort?

Func _CommAPI_OpenPort(Const $sMode)
    Local $sFileName = "\\.\" & StringLeft($sMode, StringInStr($sMode, ":") - 1)
    Local $hFile = _WinAPI_CreateFile($sFileName, 3, 6)

Line 103 is responsible for COM ports greater than 9.

Link to comment
Share on other sites

Next ideas:

1. Check if you have the newest Inludes from http://www.autoitscript.com/w/index.php?title=CommAPI&oldid=12340 #Scripts

2. Use GetCOMPorts Func to see it what commAPI will find comports

3. If you want pls explain what you mean by Bridge? What does it exactly?

I am new with comAPI and doing currently my first comm APP. So feel free to ask the community if my ideas are not helpful.

Adom,

1. I'm using the later includes dated 03/27/14 downloaded 03/29/14 :thumbsup:

2. I'm using GetCOMPort to fill  a combobox when my program launches. Regarding that GetCOMPort, maybe a WinAPI, GetDefaultCommConfig would give another result. Don't know, need to try but i'm kind of lazy ;)

3. I say bridge, which it is between 2 virtual COM ports; in other words, it's a virtual null modem. This allow my program to communicate with 2 devices that actually are 2 terminals (Hyperterm, Realterm, putty, ...). As I know the langage of the 1st device, I can enter it on the 1s terminal, translate it and send it to the 2nd terminal in the correct langage. Easy, no? :sweating:

Thoms

Link to comment
Share on other sites

Hi thoms,

I fixed @error handling, but I can't help you to create an example, because I have never used this function.

Maybe this can help you to create an examples for us: http://www.codeproject.com/Articles/2682/Serial-Communication-in-Windows (Search for WaitCommEvent)

 

Hi TheRealHanuta,

I still didn't try this one again. I'm only checking if a character was received. As the include allows not to check for only one char, it's a lot more easier. Thx.

But as soon as I can, i'll try it and give some example.

Hi thoms,

I can't find any error. For me COM10 is working fine.

Are you using function _CommAPI_OpenPort or _CommAPI_OpenCOMPort?

Func _CommAPI_OpenPort(Const $sMode)
    Local $sFileName = "\\.\" & StringLeft($sMode, StringInStr($sMode, ":") - 1)
    Local $hFile = _WinAPI_CreateFile($sFileName, 3, 6)

Line 103 is responsible for COM ports greater than 9.

 

I just tried both of them, same result : @error = -1, _WinAPI_GetLastErrorMessage() = Bad parameter.

Maybe that line, but I'm not specialist and don't know how to access that adress .COM and what is there.

Thx

Thoms

Link to comment
Share on other sites

Hi TheRealHanuta,

I still didn't try this one again. I'm only checking if a character was received. As the include allows not to check for only one char, it's a lot more easier. Thx.

But as soon as I can, i'll try it and give some example.

 

I just tried both of them, same result : @error = -1, _WinAPI_GetLastErrorMessage() = Bad parameter.

Maybe that line, but I'm not specialist and don't know how to access that adress .COM and what is there.

Thx

Thoms

 

TheRealHanuta,

Guess what! I changed a physical USB COM2 Port to COM20. It works! So, it's probably an issue with virtual ports  :think:   . I forgott to ask if virtual or physical Port when you said it was working with your COM10 :oops: .

I'll try to bypass that with the physical COM1 (on dock station) already bridged (say connected thru crossover cable) with (now) COM20 on USB :idea: .

Anyway, I follow that topic to see if someone finds another solution concerning (maybe) virtual ports.

Thanks a lot!

Link to comment
Share on other sites

Hi,

Another issue: when receiving data, ie. Chr(0), Chr(1) ... Chr(255) (0x00 to 0xFF), the first half is correct. But, after Chr(127)(0x7F), I receive only Chr(63)(0x3F) and the same character till Chr(255).

I watched the COM with PortMon (SysInternal) so I'm sure the correct data was transmitted.

In the other direction, sending Chr(0) to Chr(255), it's normal.

Any idea? Do I do something wrong? :(

Thx,

Thoms

Link to comment
Share on other sites

Another issue: when receiving data, ie. Chr(0), Chr(1) ... Chr(255) (0x00 to 0xFF), the first half is correct. But, after Chr(127)(0x7F), I receive only Chr(63)(0x3F) and the same character till Chr(255).

I watched the COM with PortMon (SysInternal) so I'm sure the correct data was transmitted.

In the other direction, sending Chr(0) to Chr(255), it's normal.

 

Hi thoms,

please try again with current CommInterface.au3

I have fixed some errors, now.

Link to comment
Share on other sites

Hi,

Yes, I (we) got it! :dance:

What I really wanted was only to get BYTES, not char or else. So the best way was to declare a byte structure and to initialize the returned value as number. $sResult should change to $(?)Result, I don't know the prefix for byte. Of course, the calling function as to know that it will receive a byte (or byte array) instead of a string.

That way can be very useful when you want to receive one byte or char. In case you want several of them, you have to create and return a Byte array. I'll try to write an example, but not now. I need to sleep sometimes.

Here is your modified Func:

Func _CommAPI_ReadOneByte(Const $hFile, Const $iTimeout = 1)
    Local $tBuffer = DllStructCreate("byte")
    Local $hTimer = TimerInit()
    Local $iWritten = 0
    Local $sResult = 0
    While 1
        _WinAPI_ReadFile($hFile, DllStructGetPtr($tBuffer), 1, $iWritten)
        If @error Then Return SetError(@error, @ScriptLineNumber, $sResult)
        If $iWritten Then
            $sResult = DllStructGetData($tBuffer, 1)
            ConsoleWrite("tb=" & hex(DllStructGetData($tBuffer, 1),4) & " sR=" & $sResult & " " & Binary($sResult) & " ")
            Return $sResult
        Else
            If $iTimeout >= 0 And $iTimeout < TimerDiff($hTimer) Then Return SetError(-2, @ScriptLineNumber, $sResult)
        EndIf
    WEnd
    Return $sResult
EndFunc   ;==>_CommAPI_ReadOneByte

So, for my immediate need, this problem is solved. But I'll try to go further with CommAPI, as I'm very often using one or more RS232 ports ; each of them having his own protocol, byte, char, wchar... Nice!

And i'm going to seek deeply in the FileCreate to understand why some softwares can see some ports, and other softwares can see other ports.

Thx for that UDF,

Thoms

Edit: oops! Iforgot to remove the consolewrite line that was only for debug.

Edited by thoms
Link to comment
Share on other sites

What I really wanted was only to get BYTES, not char or else. So the best way was to declare a byte structure and to initialize the returned value as number. $sResult should change to $(?)Result, I don't know the prefix for byte. Of course, the calling function as to know that it will receive a byte (or byte array) instead of a string.

That way can be very useful when you want to receive one byte or char. In case you want several of them, you have to create and return a Byte array. I'll try to write an example, but not now. I need to sleep sometimes.

Hi thoms,

thanks for your solution. I have taken your approach and have made some changes.

I have replaced ReceiveData & ReceiveLine with ReceiveBinary & ReceiveString.

To read only one byte: _CommAPI_ReceiveByte($hFile, 1, 1)

To read a line: _CommAPI_ReceiveString($hFile, 1, 0, @CRLF)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...