Jump to content

CommAPI - Serial and parallel communication with Windows API


therealhanuta
 Share

Recommended Posts

Can anybody explain to me which meaning has the parameter 15:

_CommAPI_PurgeComm($hFile, 15)

And

What is the meaning of "5000" ?

Local $sResult = _CommAPI_ReceiveData($hFile, IniRead($sFileINI, "Timeout", "IDSR", 5000))

 

15 is sum of PURGE_TXABORT, PURGE_RXABORT, PURGE_TXCLEAR and PURGE_RXCLEAR.

More details you can find here: http://msdn.microsoft.com/en-us/library/aa363428(v=vs.85).aspx

5000 means a max timeout of 5 seconds.

error: _CommAPI_ReceiveData() called with wrong number of args.

[...]

Func _CommAPI_ReceiveData(Const $hFile) ; only one Parameter!!!!!!!!!!!!!

[...]

Has anybody knowledge to clarify this?

 

I think you are using an old version. One month ago I changed timeout handling.

How can I recognize these <CR> with Local $sResult = _CommAPI_ReceiveData($hFile) ?

 

You have to use build in String functions like StringRegExp or StringInStr.

Link to comment
Share on other sites

15 is sum of PURGE_TXABORT, PURGE_RXABORT, PURGE_TXCLEAR and PURGE_RXCLEAR.

More details you can find here: http://msdn.microsoft.com/en-us/library/aa363428(v=vs.85).aspx

5000 means a max timeout of 5 seconds.

 

I think you are using an old version. One month ago I changed timeout handling.

 

You have to use build in String functions like StringRegExp or StringInStr.

 

therealhanuta thanks for your quickly responding.

Some becomes clear now.

But sorry I need a little more input in find the <CR> in the telegram to get the end of a telegram.

StringInString clear so far. But what exactly is the thing I have to search with it?

Is this Char or DEC or HEX? And how I recognize what type it is?

Would you pls write a line for solving it with methode StringInString?

 

BTW:

CommAPIConstants.au3 has to change INDEX header from ; Name ..........: CommAPIStructures.au3 to ; Name ..........: CommAPIConstants.au3

Thanks for taking time to me.

Best regards

Andrew

Thanks! :bye:

Greetings

Andrew

 

Link to comment
Share on other sites

Is this Char or DEC or HEX? And how I recognize what type it is?

Please, have a look into documentation:

; Name ..........: _CommAPI_ReceiveData
; Description ...: Receives data (RxD/RX/RD) to a specified communications device.
; Syntax ........: _CommAPI_ReceiveData(Const $hFile[, $iTimeout = 0])
; Parameters ....: $hFile               - [in] A handle to the communications device.
;                  $iTimeout            - [in] An integer value for total read timeout in milliseconds.
; Return values .: Success - Received string
;                  Failure - Empty string
; Author ........:
; Modified ......:
; Remarks .......: If the result contains Chr(0), you should convert the result with function Binary().

Would you pls write a line for solving it with methode StringInString?

Local Const $sToken = "<CR>"
Local $sResult = ""
Local $iPosition = 0
Do
    $sResult &= _CommAPI_ReceiveData($hFile)
    $iPosition = StringInStr($sResult, $sToken)
    If $iPosition > 0 Then
        MsgBox(0,0,StringLeft($sResult,$iPosition-1))
        $sResult = StringMid($sResult,$iPosition+StringLen($sToken))
    EndIf
Until Not $sResult And $iPosition
Link to comment
Share on other sites

  • 2 weeks later...

Hello,

I'm a first time poster and a long time AutoIt user. I'm having trouble sending and receiving data via a configured serial port.

Software

Editor: SciTE 2.2.8

AutoIt 3.3.8.1 

Computer running Windows XP SP3

A USB to Serial port converter is fitted with a loop back plug (RD --> TD, CTS --> RTS)

When the  Port was configured with Hyperterminal , it worked with both  "no handshaking" and "hardware flow control" modes. Successful operation was  confirmed by the echoed typed Characters.

Free Serial Port Monitor V3.31 also confirms port was opened and shows the transmission and reception of typed characters via the loopback connector when using Hyperterminal

When the same port is configured with commands CommAPI, the  Serial Port Monitor V3.31 confirms the port opens.

With the open port, the Below commands successfully toggle the RTS and DTR lines from the CommAPI configured port using a script containing the following commands:

_CommAPI_SetOnRTS($hFile, True)
_CommAPI_SetOnRTS($hFile, False)
 
_CommAPI_SetOnDTR($hFile, True)
_CommAPI_SetOnDTR($hFile, False)
 
The problem is when I run the First Example Scrip from http://www.autoitscript.com/wiki/CommAPI_Examples
 
The command  _CommAPI_TransmitData($hFile, $sCommand) is not sending the string assigned to $sCommand and _CommAPI_ReceiveData($hFile, 5000) is not receiving the string.
 
Serial Port Monitor V3.31 confirms the serial port was opened by the program but no characters were transmitted after the execution of _CommAPI_TransmitData($hFile, $sCommand)
 
The command _CommAPI_ClosePort($hFile) successfully closes the port as reported by the serial port monitor.
 
Any Ideas why the data is not being sent? 
 
Thanks,
Marc

 

Link to comment
Share on other sites

 Andrew,

Thanks for the response. Unfortunately turning off handshaking did not work. 

Problem solved!

To fix the problem, I had to delve into the CommInterface.au3 script and modify the function _CommAPI_OpenPort(Const $sMode).  It appeared that,  on my system, the  file with handle $hFile could not be accessed.

To allow file access, I had to modify  the following statement  in the function  _CommAPI_OpenPort(Const $sMode) 

 

From:

Local $hFile = _WinAPI_CreateFile($sFileName, 2, $GENERIC_ALL)

Where:

$iCreation set to 2 - Opens a file. The function fails if the file does not exist 

 

To:

Local $hFile = _WinAPI_CreateFile($sFileName, 3, 2+4,2+4
 
Where:
 
_WinAPI_CreateFile($sFileName, $iCreation [, $iAccess = 4 [, $iShare = 0 [, $iAttributes = 0 [, $pSecurity = 0]]]])
 
$iCreation set to 3 - Opens a file. If the file does not exist, the function creates the file
$iAccess and $iShare set to 2+4; Both 2 - Read and 4 - Write 
----------------------------------------------------------------------------------------------------------------------------------------
Hardware handshaking also works. 
 
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.
 
 
Does anyone know if the CommAPI works running  Windows 7 and 8?
 
Marc

 

Link to comment
Share on other sites

Hey Marcsf73,

    I have been tyring to receive characters from my Arudino leonardo using CommAPI but I get an "Access denied" error. It look you have solved the problem. Could you post the replacement you did for the _CommGetLine function? I hope this will finally work for the arduino.

    Thanks!

Cheers!

Atyab

Link to comment
Share on other sites

Hello Marc!

THX for sharing your ideas.

Got 2 questions:

1. I parsed orig func Local $hFile = _WinAPI_CreateFile($sFileName, 2, $GENERIC_ALL)

I didn't find the $GENERIC_ALL Var .

 

I found: Local $hFile = _WinAPI_CreateFile($sFileName, 2, 6)

Is this correct?

2. In my tests I got no problems with acces of $sFileName. Could it be it is different from system to system?

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."

Thank you again sharing your results.

Thanks! :bye:

Greetings

Andrew

 

Link to comment
Share on other sites

Hi Andrew,

   Thanks for the comments. :) Can it be that since the Aurdino already has the port open AutoIT can't access it? But then how do I make my Arduino talk with AutoIT if they don't communicate on the same port?

Cheers!

Atyab

Link to comment
Share on other sites

Hi Atyab,

an access denied can't come from Arduino's RS232. I am not familiar with Arduino. But sofar, you have to think in Master Slave. PC is the MAster.

Your Arduino have to wait for a Telegram from PC. Your Arduino SW have to wait for Telegrams to get the next Telegram.

If you want you can simulate Slave for debugging. For simulating a counterpart I found: http://www.232analyzer.com/232default.htm.

Thanks! :bye:

Greetings

Andrew

 

Link to comment
Share on other sites

 

 Andrew,

Thanks for the response. Unfortunately turning off handshaking did not work. 

Problem solved!

To fix the problem, I had to delve into the CommInterface.au3 script and modify the function _CommAPI_OpenPort(Const $sMode).  It appeared that,  on my system, the  file with handle $hFile could not be accessed.

To allow file access, I had to modify  the following statement  in the function  _CommAPI_OpenPort(Const $sMode) 

 

From:

Local $hFile = _WinAPI_CreateFile($sFileName, 2, $GENERIC_ALL)

Where:

$iCreation set to 2 - Opens a file. The function fails if the file does not exist 

 

To:

Local $hFile = _WinAPI_CreateFile($sFileName, 3, 2+4,2+4
 
Where:
 
_WinAPI_CreateFile($sFileName, $iCreation [, $iAccess = 4 [, $iShare = 0 [, $iAttributes = 0 [, $pSecurity = 0]]]])
 
$iCreation set to 3 - Opens a file. If the file does not exist, the function creates the file
$iAccess and $iShare set to 2+4; Both 2 - Read and 4 - Write 
----------------------------------------------------------------------------------------------------------------------------------------
Hardware handshaking also works. 
 
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.
 
 
Does anyone know if the CommAPI works running  Windows 7 and 8?
 
Marc

 

 

Hello Therealhanuta,

could you pls review the the read/write issue? Can you confirm what 

Marcsf73

found out?

Thanks! :bye:

Greetings

Andrew

 

Link to comment
Share on other sites

Answers to ADOM's questions
 

Got 2 questions:

1. I parsed orig func Local $hFile = _WinAPI_CreateFile($sFileName, 2, $GENERIC_ALL)

I didn't find the $GENERIC_ALL Var .

I used the current code at:  http://www.autoitscript.com/wiki/CommInterface.au3  See line 116 below 

; #FUNCTION# ====================================================================================================================
; Name ..........: _CommAPI_OpenPort
; Description ...: Opens a specified communications device.
; Syntax ........: _CommAPI_OpenPort(Const $sMode)
; Parameters ....: $sMode               - [in] A device-definition string.
; Return values .: Success - The open handle to a specified communications device.
;                  Failure - 0
; Author ........:
; Modified ......:
; Remarks .......:
; Related .......: _CommAPI_OpenCOMPort, _CommAPI_ClosePort, _CommAPI_SetCommState
; Link ..........: http://msdn.microsoft.com/en-us/library/aa363214(v=vs.85).aspx
; Example .......: No
; ===============================================================================================================================
Func _CommAPI_OpenPort(Const $sMode)
    Local $sFileName = "\\.\" & StringLeft($sMode, StringInStr($sMode, ":") - 1)
    Local $hFile = _WinAPI_CreateFile($sFileName, 2, $GENERIC_ALL)
    If @error Then Return SetError(@error, @ScriptLineNumber, 0)
    If $hFile <= 0 Then Return SetError(-1, @ScriptLineNumber, 0)
 
    Local $tDCB = DllStructCreate($tagDCB)
    Local $tCommTimeouts = DllStructCreate($tagCOMMTIMEOUTS)
 
    _CommAPI_BuildCommDCB($sMode, $tDCB)
    If @error Then Return SetError(@error, @extended, 0)
 
    _CommAPI_SetCommTimeoutsElement($tCommTimeouts, "ReadTotalTimeoutMultiplier", 1)
    If @error Then Return SetError(@error, @extended, 0)
 
    _CommAPI_SetCommTimeoutsElement($tCommTimeouts, "WriteTotalTimeoutMultiplier", 1)
    If @error Then Return SetError(@error, @extended, 0)
 
    If Not _CommAPI_SetCommState($hFile, $tDCB) Then Return SetError(@error, @extended, 0)
    If Not _CommAPI_SetCommTimeouts($hFile, $tCommTimeouts) Then Return SetError(@error, @extended, 0)
 
    Return $hFile
EndFunc   ;==>_CommAPI_OpenPort

 
I found: Local $hFile = _WinAPI_CreateFile($sFileName, 2, 6)
 
Is this correct?
 
Refer to parameters listed:
 http://www.autoitscript.com/autoit3/docs/libfunctions/_WinAPI_CreateFile.htm
 
Local $hFile = _WinAPI_CreateFile($sFileName, 2, 6)
 
$iCreation=2; 2 - Opens a file. The function fails if the file does not exist
This is one of the parameters I changed to make it work on my system
 
$iAccess=6; 6=2+4  this is correct: Bit setting  2-Read (010) + 4-Write(100) = 6 decimal  (110)  
I always write multiple bit settings a sum decimal weighted sum. It is easier to figure out what is specified.
 
2. In my tests I got no problems with acces of $sFileName. Could it be it is different from system to system?
 
Looks like the access bits are correctly set.
 
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:
 
 
 


; #FUNCTION# ====================================================================================================================
; Name ..........: _CommAPI_GetLine
; Description ...: Receives data string (RxD/RX/RD) from a specified communications device ending in $EndChar.
; Syntax ........:  _CommAPI_GetLine(Const $hFile[, $EndChar = @CR[, $MaxLen = 0[, $iTimeout = 0]]])
; Parameters ....: $hFile               - [in] A handle to the communications device.
;                  $EndChar             - [in] terminating character in a string
;                  $MaxLen              - [in] Maximum string length
;                  $iTimeout            - [in] An integer value for total read timeout in milliseconds.
; Return values .: Success - Received string including $EndChar
;                       @error=0
;
;                  Failure - Empty string
;                       @error=1: Timeout ($iTimeout)
;                       @error=2: String exceeded maximum length ($MaxLen)
;                       @error=3: String Terminator ($EndChar) not in valid sized String
;
; Author ........: Marcsf73
; Modified ......: March 26, 2014
; Remarks .......: If the result contains Chr(0), you should convert the result with function Binary().
; Related .......: _CommAPI_TransmitData
; Link ..........:
; Example .......: _CommAPI_GetLine($hFile,";",20,5000) ;get line terminated in ";" 20 characters max, timeout 5 seconds

; ===============================================================================================================================
Func _CommAPI_GetLine(Const $hFile,Const $EndChar = @CR, Const $MaxLen = 0, Const $iTimeout = 0)
    Local $tBuffer = DllStructCreate("char")
    Local $hTimer = TimerInit()
    Local $iWritten = 0
    Local $sLine = ""
    Local $cChar=""
    Local $flgDone=False
    Local $error=0

    While $flgDone=False
        _WinAPI_ReadFile($hFile, DllStructGetPtr($tBuffer), 1, $iWritten)
        $cChar=DllStructGetData($tBuffer, 1)
        Select
            Case TimerDiff($hTimer) >= $iTimeout ;Timeout error condition
                $flgDone=True
                $sLine="" ;Return string for Timeout Error
                $error=1
            Case StringLen($sLine) >= $MaxLen ;String too long error
                $flgDone=True
                $sLine="" ;Return string for String too long Error
                $error=2
            Case $cChar=$EndChar ;$EndChar Detected Finished!
                $sLine &= $cChar ;append $EndChar to string (Delete line if $EndChar unwanted in return string)
                $flgDone=True
            Case $iWritten ;Charater in buffer, Continue building line
                $sLine &= $cChar
            Case Not $iWritten ;No more characters in buffer, $EndChar not found in string
                $flgDone=True
                $error=3
                $sLine="" ;Return String for String without $EndChar
        EndSelect
    WEnd

    SetError($error)
    Return $sLine
EndFunc   ;==>_CommAPI_GetLine

 
 
 
 
 
 
 

Link to comment
Share on other sites

Hello Marcsf73,

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.

2. no I used 2,6 and the old version may be with old version of comminterface other behaviour. Anyway old.

3. Thank you very much for sharing your script!

Edited by adom

Thanks! :bye:

Greetings

Andrew

 

Link to comment
Share on other sites

Hi Marcsf73,

Sth here is wrong. I checked again :

I used the current code at:  http://www.autoitscript.com/wiki/CommInterface.au3  See line 116 below

The code in the Wiki must have been changed since you copied the snipped with line 116.

Your snipped around 116 is now line 84.

I double checked the versions on Wiki. The current one is different to your snipped. It must have been changed without adress it to public.

Are we still on the right rail now?

Is your add on scriptstill valid?

And by the way what is the idea behind your _CommGetLine()

Thanks! :bye:

Greetings

Andrew

 

Link to comment
Share on other sites

Hi Marcsf73,

Sth here is wrong. I checked again :

I used the current code at:  http://www.autoitscript.com/wiki/CommInterface.au3  See line 116 below

The code in the Wiki must have been changed since you copied the snipped with line 116.

Your snipped around 116 is now line 84.

I double checked the versions on Wiki. The current one is different to your snipped. It must have been changed without adress it to public.

Are we still on the right rail now?

Is your add on scriptstill valid?

And by the way what is the idea behind your _CommGetLine()

The line numbers in my post  are relative. I abitrarly chose the start line at 100 in "Code add box" so we can reference statements in both routines in our discussions. Yes, My addon script is valid. AutoIit references a function by name it  doesn't care what line it starts on.

The idea behind my _CommGetLine()?

I needed a drop in replacement for CommMG's function. I just added more error reporting. If I used _CommAPI_ReceiveData() I would have to implement the checking functions in my main program. 6 of one 1/2 dozen of the other..

Link to comment
Share on other sites

Hi Marcsf73,

I can confirm :

>>>>

To fix the problem, I had to delve into the CommInterface.au3 script and modify the function _CommAPI_OpenPort(Const $sMode).  It appeared that,  on my system, the  file with handle $hFile could not be accessed.

To allow file access, I had to modify  the following statement  in the function  _CommAPI_OpenPort(Const $sMode) 

 

From:

Local $hFile = _WinAPI_CreateFile($sFileName, 2, $GENERIC_ALL)

Where:

$iCreation set to 2 - Opens a file. The function fails if the file does not exist 

 

To:

Local $hFile = _WinAPI_CreateFile($sFileName, 3, 2+4,2+4
 
Where:
 
_WinAPI_CreateFile($sFileName, $iCreation [, $iAccess = 4 [, $iShare = 0 [, $iAttributes = 0 [, $pSecurity = 0]]]])
 
$iCreation set to 3 - Opens a file. If the file does not exist, the function creates the file
$iAccess and $iShare set to 2+4; Both 2 - Read and 4 - Write
<<<<<<<<
 
After updating all includes from wiki to current version I got the same issues and had to follow:
Local $hFile = _WinAPI_CreateFile($sFileName, 3, 2+4,2+4).
 
o:)

Thanks! :bye:

Greetings

Andrew

 

Link to comment
Share on other sites

Hi everybody!

1. I parsed orig func Local $hFile = _WinAPI_CreateFile($sFileName, 2, $GENERIC_ALL)

I didn't find the $GENERIC_ALL Var .

 

You can found this constant in file "C:\Program Files (x86)\AutoIt3\Include\FileConstants.au3".

I thought that I could use it for Execute + Read + Write.

But I have just realized that I was wrong.

From:

Local $hFile = _WinAPI_CreateFile($sFileName, 2, $GENERIC_ALL)

Where:

$iCreation set to 2 - Opens a file. The function fails if the file does not exist 

 

To:

Local $hFile = _WinAPI_CreateFile($sFileName, 3, 2+4,2+4
 
Where:
 
_WinAPI_CreateFile($sFileName, $iCreation [, $iAccess = 4 [, $iShare = 0 [, $iAttributes = 0 [, $pSecurity = 0]]]])

 

Now, I have changed this line to increase compatibility for all.

Using of $iShare = 2 + 6 has now effect for serial communication.

The modified line is therefore as follows:

Local $hFile = _WinAPI_CreateFile($sFileName, 3, 6)
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...