Jump to content

Serial Port /COM Port UDF


martin
 Share

Recommended Posts

Hi Martin,

Looks like you've made a pretty awesome script!

Thanks.

I'm a newbie to autoit and COM communication am desperately trying to communicate with some hardware of mine. I have a laser micrometer that is set to measure diameters of different objects and then puts their profiles into AutoCAD. I've been able to automate the importation into AutoCAD and everything but have failed in communicating with my micrometer using autocad. The original owner of the micrometer had it set up to hyperterminal but that software is not useful for my application. Right now I am trying to just sucessfully communicate but in theory I want to store the data read from the com port into an array. I can do that but gettting data into a variable from the comm port is my problem.

Right now when reading the lasermicrometer manual it reads this for serial port communication:

The number I want to send it is 68 (which is to read the average diamater) and at this moment I have a code that creates a gui and when I press a button it should return the measurement but it is not working. I don't understand what I should put as a linefeed or carriage return and maybe that is the problem. But here is my script right now.

If anyone could help me understand why my data is not being returned correctly their help would be greatly appreciated.

Thanks,

J

The SendString function only sends exactly what you ask it to. If you need a CR or line feed added then you must add it like this

I'm not sure why you have [b]<A>[/b] when the manual says 68. I would have expected [b]<68>[/b]. Or if you think the Ascii code is needed then [b]<65>[/b].
 _CommSendString("?J0/<A>" & @CR)

The _CommSetPort needs to have a variable for the second parameter. If there is an error then this variable will contain the error message. The documentation needs to be improved here because I state that this parameter is a string whereas I should have said a variable for holding the error string. (I show it as a variable). I will improve the description of this.

The laser manual says <#> but, unless you are sure on this point, I would try without the angle brackets as well in case the author meant <#> to represent the number.

I'm not sure why you have <A> when the manual says 68. I would have expected <68>, or if you think the Ascii code is needed then <65>.

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

How can virtual COM ports be made with this? ...if it's possible.

No, it only connects to existing COM ports as seen in device manager under Ports.
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

cant get it working. The example program runs an error.

I guess I am not able to access the dll. I cannot get the version or list ports.

I am using windows xp pro 64 bit OS multicore - Should it be a problem?

Thanks

Koushik

Link to comment
Share on other sites

cant get it working. The example program runs an error.

I guess I am not able to access the dll. I cannot get the version or list ports.

I am using windows xp pro 64 bit OS multicore - Should it be a problem?

Thanks

Koushik

What errors do you get?

I don't think it should be a problem running on xp pro 64 bit but I have not tested it on that OS. It runs on Vista 64 bit as a 32 bit application.

You cannot mix 64 bit and 32 bit apps in the same process. That is a 64 bit application cannot use a 32 bit dll AFAIK.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Having trouble getting things going correctly. Here's a bit of code I'm trying to make work

CODE
#include <CommMg.au3>

Local $ComError

;~ Dialog to request Com port#, i.e. 1 for Com1

$ComPort = InputBox("Comport#", "Enter Com port number")

$ComBaud = 9600

$ComDataBits = 8

$ComParity = 0

$ComStopBits = 1

;~ Configure Com port settings

_CommSetPort($ComPort,$ComError,$ComBaud,$ComDataBits,$ComParity,$ComStopBits,0)

MsgBox(0,'Com Set',"Com"&$ComPort&" @"&$ComBaud&" baud "&$ComDataBits&$ComParity&$ComStopBits)

$Bytes = "0xF4570100B4"

MsgBox(0,'Data to Send',$Bytes)

$Numbytes = BinaryLen(Binary($Bytes))

MsgBox(0,'Data Length',$NumBytes)

$Struct1 = DllStructCreate("byte[" & $Numbytes & "]")

DllStructSetData($Struct1, 1, $Bytes)

MsgBox(0,"DllStruct","Struct Size: " & DllStructGetSize($Struct1) & @CRLF & _

"Struct pointer: " & DllStructGetPtr($Struct1) & @CRLF & _

"Data:" & @CRLF & _

DllStructGetData($Struct1,1))

$ComOut = _CommSendByteArray(DllStructGetPtr($Struct1), $Numbytes, 1)

MsgBox(0,'Data Sent',$ComOut)

All dialogs (There just for debugging purposes) show correct information, but I never get the final dialog for Data sent. Instead, the script stops and I get "Exit code: -1073741819". The best I can tell is the problem has to be in my _CommSendByteArray line. Anybody see what I did wrong there? Or is the issue that the _CommSetPort isn't working properly? I'm testing it with Com5 which is a virtual Com that is available. I've connected to it with other terminal without trouble.

Also, while I'm here... I plan to use _CommReadByteArray to read the response data back from the buffer. Below is the code I intended to use, but can't test as my code isn't getting that far. Anyone see issues with it:

CODE
$WaitingForData = 1

MsgBox(0,'Ready to recieve','Send data now')

While $WaitingForData = 1

$NumBytes = _CommGetInputCount() ;Count number of characters in buffer

if $NumBytes > 0 then $WaitingForData = 0

WEnd

$Struct2 = DllStructCreate("byte[" & $Numbytes & "]")

DllStructSetData($Struct2, 1, $Bytes)

MsgBox(0,"DllStruct","Struct Size: " & DllStructGetSize($Struct2) & @CRLF & _

"Struct pointer: " & DllStructGetPtr($Struct2) & @CRLF & _

"Data:" & @CRLF & _

DllStructGetData($Struct2,1))

$ComIn = _CommReadByteArray(DllStructGetPtr($Struct2), $Numbytes, 1)

MsgBox(0,'Response recieved',$ComIn)

$Struct2= 0

My goal here is to send hex bytes, wait a moment, and grab the response into a variable. The command will generally be only 5-10 bytes, the response will be 60-70 bytes. I'd like to use SendByteArray and ReadByteArray as dealing with single bytes at a time is too cumbersome. Thanks for any help I can get!

Edited by DrJeseuss
Link to comment
Share on other sites

As an update the code below is working. The script waits for characters in buffer, then grabs the bytes. The bytes are checked as valid, if not wait again, if valid respond back with bytes. It appears the issue I was having was due to a quick rewrite of CommMg to allow for a nonstandard baud. I've notified Martin of this, though he is on holiday, so I'll have to wait.

CODE
#include <CommMg.au3>

Local $ComError

$Version = _CommGetVersion(1)

MsgBox(0,'DLL Version',$Version)

;~ Dialog to request Com port#, i.e. 1 for Com1

$ComPort = InputBox("Comport#", "Enter Com port number")

;~ $ComPort = 1

$ComBaud = 9600

$ComDataBits = 8

$ComParity = 0

$ComStopBits = 1

;~ Configure Com port settings

_CommSetPort($ComPort,$ComError,$ComBaud,$ComDataBits,$ComParity,$ComStopBits,0)

;~ COM should be open now. Begin Rx/Tx loop

;~ Wait to recieve command

$NotChecked = 1

While $NotChecked = 1

$WaitingForData = 1

While $WaitingForData = 1

$NumBytes = _CommGetInputCount() ;Count number of characters in buffer

if $NumBytes > 0 then $WaitingForData = 0 ;if characters exist continue

WEnd

$Struct2 = DllStructCreate("byte[" & $Numbytes & "]") ;create struct2 based on buffer size

$ComIn = _CommReadByteArray(DllStructGetPtr($Struct2), $Numbytes, 1)

$ComIn = DllStructGetData($Struct2,1)

MsgBox(0,'Data recieved',$ComIn) ;display bytes received

$Struct2= 0 ;clear struct2 from memory

if $ComIn = "0xF4570100B4" then $NotChecked = 0

WEnd

;~ Bytes recieved, now respond

;~ The code below uses SendByteArray to allow an entire string to be sent at once

$Bytes = "0xF4950124810B0C35000040000035001C81A68A1D4D19020040D4E19680E8A0A202007F841B07A10040044D3600000

0004000E565FF0E5D00106C00005A000005FE6FBE"

$Numbytes = BinaryLen(Binary($Bytes))

$Struct1 = DllStructCreate("byte[" & $Numbytes & "]")

DllStructSetData($Struct1, 1, $Bytes)

$ComOut = _CommSendByteArray(DllStructGetPtr($Struct1), $Numbytes, 1)

$Struct1 = 0 ;clears struct from memory

;~ Command sent. Start listening to get response

;~ At end of Rx/Tx session, close port to release

_Commcloseport()

Link to comment
Share on other sites

As an update the code below is working. The script waits for characters in buffer, then grabs the bytes. The bytes are checked as valid, if not wait again, if valid respond back with bytes. It appears the issue I was having was due to a quick rewrite of CommMg to allow for a nonstandard baud. I've notified Martin of this, though he is on holiday, so I'll have to wait.

The dll I made for DrJeseuss to test special baud rates had no byte array functions! Whoops. New version uploaded overwriting the previous one.

EDIT: 14th July. DrJeseuss reports that it now works in initial tests.

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Martin and All,

I have successfully used a custom baud rate and connected properly! I have Byte data going to and from the Com without any issues at all. I'm still working on getting the code cleaned up for speed and clarity. As soon as that's done, I'll post a copy. Thanks again Martin!

Link to comment
Share on other sites

  • 1 month later...

I'm having trouble reading Chr(0) using _CommReadByte(). I've modified the example, but it continuously has 0. How can I read Chr(0) or is there a better way of doing this? Thanks

While 1
    
   ;gets characters received returning when one of these conditions is met:
   ;receive @CR, received 20 characters or 200ms has elapsed
   ;$instr = _CommGetstring()
    $instr = _CommReadByte()
   ;$instr = _CommReadChar()
   ;$scroll = StringInStr($instr,@CR)
    If $instr > -1 Then;if we got something
       ;$instr = Hex($instr,2) & " "
        if $instr < 32 Then
            $instr = "[" & Hex($instr,2)& "]"
        Else    
            $instr = Chr($instr)
        endif
        If GUICtrlRead($Checkbox1) = $GUI_CHECKED Then $instr = StringReplace($instr, @CR, @CRLF)
        $lines = GUICtrlRead($Edit1)
        $charcount = StringLen($lines)
        _GUICtrlEdit_SetSel($Edit1, $charcount, $charcount)
        If $charcount > 10000 Then GUICtrlSetData($Edit1, StringRight($lines & $instr, 8000))
        _GUICtrlEdit_ReplaceSel($Edit1, $instr,False)
        _GUICtrlEdit_Scroll($Edit1, $SB_SCROLLCARET)
       ;If $scroll Then _GUICtrlEditLineScroll($edit1,0,_GUICtrlEditGetLineCount($edit1) - 14)
    EndIf
    
WEnd
Link to comment
Share on other sites

I'm having trouble reading Chr(0) using _CommReadByte(). I've modified the example, but it continuously has 0. How can I read Chr(0) or is there a better way of doing this? Thanks

While 1
    
  ;gets characters received returning when one of these conditions is met:
  ;receive @CR, received 20 characters or 200ms has elapsed
  ;$instr = _CommGetstring()
    $instr = _CommReadByte()
  ;$instr = _CommReadChar()
  ;$scroll = StringInStr($instr,@CR)
    If $instr > -1 Then;if we got something
      ;$instr = Hex($instr,2) & " "
        if $instr < 32 Then
            $instr = "[" & Hex($instr,2)& "]"
        Else    
            $instr = Chr($instr)
        endif
        If GUICtrlRead($Checkbox1) = $GUI_CHECKED Then $instr = StringReplace($instr, @CR, @CRLF)
        $lines = GUICtrlRead($Edit1)
        $charcount = StringLen($lines)
        _GUICtrlEdit_SetSel($Edit1, $charcount, $charcount)
        If $charcount > 10000 Then GUICtrlSetData($Edit1, StringRight($lines & $instr, 8000))
        _GUICtrlEdit_ReplaceSel($Edit1, $instr,False)
        _GUICtrlEdit_Scroll($Edit1, $SB_SCROLLCARET)
      ;If $scroll Then _GUICtrlEditLineScroll($edit1,0,_GUICtrlEditGetLineCount($edit1) - 14)
    EndIf
    
WEnd
I don't really understand. The function _ComReadByte returns a string not a number so that might have confused you. So if you receive a byte of value 0 the function returns trhe string '0'. The reason I did that was so that is not so clear to me now but it was supposed to get round some problem.

Can you receive other characters ok?

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

I don't really understand. The function _ComReadByte returns a string not a number so that might have confused you. So if you receive a byte of value 0 the function returns trhe string '0'. The reason I did that was so that is not so clear to me now but it was supposed to get round some problem.

Can you receive other characters ok?

After receiving your reply, I looked further and found 2 problems. 1)I was using the standard Hyperterminal to send the characters to this. I would paste the chr(0) etc into it to transmit but found that it would send all other characters except chr(0). 2) Understanding better what you said, I changed the condition to compare as as string with "".

If $instr <> "" Then;if we got something

So I did a serial loopback instead and made the application send and receive the control characters and it worked properly. Wow! thanks for this wonderful serial port application. I can use it when I need to do some quick testing of serial devices. Thanks again for your help.

Link to comment
Share on other sites

  • 1 month later...

Hi Martin,

First of all, thanks for the udf !

But (here comes the but) it seems I am running into some hard limitations of it.

I am trying to communicate with a system of which at a given moment I request a memory dump via the command "D2 F0040000 100"

The response looks like

D2 F0040000 100 (each entered char is echoed, after the CR, the response follows immediately)

> f0040000: 0000 ffff 0000 0000 0000 0000 0000 0000

> f0040010: 000a 00f5 0000 0000 000a 00f5 0000 0000

> f0040020: 000a 00f5 0000 0000 0000 0000 0000 0000

[...]

> f00401f0: 0000 0000 0000 0000 0000 0000 0000 0000

-

No matter what I try to do (_CommGetString or _CommGetLine), I always only manage to get the first 3 lines and the last -.

Is it possible the problem is related to the fact that some internal buffer gets filled up because commg is not reading it out soon enough ?

I've created a log from the communication interaction with teraterm vs commg which you can find at marie.dommel.be/SerialProblem.zip

The behaviour is totally different, with teraterm readin out the info as soon as its available, while commg seems to wait for a read api to be called before it does an IRP_MJ_READ.

However, I in my latest attemp to deal with the problem I immediately start polling after sending the last letter of the command, and still I only get the first 3 lines. The difference between the write and the read is 30ms for terraterm and 60ms for commg which is more are less comparable so I am assuming teraterm does some more tricks to grab everything.

One thing I see in the teraterm logs and not in the commg ones is IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_WAIT_ON_MASK).

( I am not familiar with these IRP calls)

Apart from that, there are a few more less important quirks/bugs in commg

- It seems that if you specify a wait time for reading a line (eg $sReceivedData = _CommGetLine(@CR, 0, 3000) ), he happily starts to busy wait ! (1 CPU core is completely occupied by commg)

- _CommSwitch does not take into account the fact that the DLL may not yet be opened.

- Even if you make sure the dll is opened by another call (eg _CommGetVersion), _CommSwitch fails if no port has been set yet.

- _ComClosePort closes the dll ! It does not take into account that you may be using several ports.

- Maybe it would be cleaner to foresee a _commg init/uninit pair to deal with opening/closing the dll, and just return an error when a call is made before _commg_init

* Error behaviour needs some cleaning up (the mechanism (@error vs return value) + the error values (success is sometimes 1, sometimes 0) ). (make set of consts to abstract the concrete values eg _COMMMG_SUCCESS, ... )

As a reference, I have added the test code to check for the first issue (note: I add a delay between sending the individual keys, because the target sometimes does not follow):

$l_bEnablePolling = 1
        
        ; I don't care, used as init call
        _CommGetVersion()
        
        if ( _CommSwitch( 1 ) == -1 ) Then
            MsgBox ( 0, "Error", "comswitch" )          
        EndIf

        $l_sErr = ""
        If ( _CommSetPort(1, $l_sErr, 115200, 8, 0, 1, 0) == 0 ) Then
            MsgBox ( 0, "Error", "Com port creation failed :" & $l_sErr )           
        EndIf
        
        if ( _CommSwitch( 2 ) == -1 ) Then
            MsgBox ( 0, "Error", "comswitch" )          
        EndIf
        
        $l_sErr = ""
        If ( _CommSetPort(4, $l_sErr, 115200, 8, 0, 1, 0) == 0 ) Then
            MsgBox ( 0, "Error", "Com port creation failed :" & $l_sErr )           
        EndIf
                    
        if ( _CommSwitch( 1 ) == -1 ) Then
            MsgBox ( 0, "Error", "comswitch" )          
        EndIf
        
        $l_sCommand = "D2 F0040000 100"
        while (1)           
            $l_sCommand = InputBox("Giveth thy command", "...", $l_sCommand)                
            
            $l_sCommand = $l_sCommand & @CRLF
            msgbox (1, "info", "[" & $l_sCommand & "] -> " & string(StringLen($l_sCommand) ))
            
            $l_nCommandLength = StringLen( $l_sCommand )
            $l_nCharIndex = 1
            $l_nIntermediateResult = $COMMGDRIVER_SUCCESS
            while   (   ($l_nIntermediateResult == $COMMGDRIVER_SUCCESS ) _
                    and ( $l_nCharIndex <= $l_nCommandLength ) _
                    )
                $l_nIntermediateResult = _CommSendByte( Asc(StringMid($l_sCommand, $l_nCharIndex ,1)), 1)
                if ( $l_nIntermediateResult <> $COMMGDRIVER_SUCCESS) Then
                    MsgBox(0, "info", "nok")
                Else
;~                  MsgBox(0, "info", "ok")
                endif
                if ($l_nCharIndex <= $l_nCommandLength) then
                    sleep( $COMPORT_INTERCHARDELAY_MS )
                endif
                $l_nCharIndex = $l_nCharIndex + 1
            WEnd
            
            if ($l_bEnablePolling == 0) then
                sleep(5000)         
                $l_sReturnedResponse = _Commgetstring()
            Else
                for $l_nRetryCount = 1 to 100
                    ;sleep(10)          
                    $l_sReturnedResponse = $l_sReturnedResponse & _Commgetstring()
                next
            endif
            if (@error == 0) then
                msgbox (1, "info", "[" & $l_sCommand  & "] -> " & $l_sReturnedResponse )            
            Else
                msgbox (1, "info", "Error detected " & @error & "with [" & $l_sCommand  & "] -> " & $l_sReturnedResponse )          
            endif
        wend
        ; seems to kill all serial ports
        _CommClosePort()

Thanks

Bram

Link to comment
Share on other sites

Hi Martin,

First of all, thanks for the udf !

But (here comes the but) it seems I am running into some hard limitations of it.

I am trying to communicate with a system of which at a given moment I request a memory dump via the command "D2 F0040000 100"

The response looks like

D2 F0040000 100 (each entered char is echoed, after the CR, the response follows immediately)

> f0040000: 0000 ffff 0000 0000 0000 0000 0000 0000

> f0040010: 000a 00f5 0000 0000 000a 00f5 0000 0000

> f0040020: 000a 00f5 0000 0000 0000 0000 0000 0000

[...]

> f00401f0: 0000 0000 0000 0000 0000 0000 0000 0000

-

No matter what I try to do (_CommGetString or _CommGetLine), I always only manage to get the first 3 lines and the last -.

Is it possible the problem is related to the fact that some internal buffer gets filled up because commg is not reading it out soon enough ?

I've created a log from the communication interaction with teraterm vs commg which you can find at marie.dommel.be/SerialProblem.zip

The behaviour is totally different, with teraterm readin out the info as soon as its available, while commg seems to wait for a read api to be called before it does an IRP_MJ_READ.

However, I in my latest attemp to deal with the problem I immediately start polling after sending the last letter of the command, and still I only get the first 3 lines. The difference between the write and the read is 30ms for terraterm and 60ms for commg which is more are less comparable so I am assuming teraterm does some more tricks to grab everything.

One thing I see in the teraterm logs and not in the commg ones is IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_WAIT_ON_MASK).

( I am not familiar with these IRP calls)

Apart from that, there are a few more less important quirks/bugs in commg

- It seems that if you specify a wait time for reading a line (eg $sReceivedData = _CommGetLine(@CR, 0, 3000) ), he happily starts to busy wait ! (1 CPU core is completely occupied by commg)

- _CommSwitch does not take into account the fact that the DLL may not yet be opened.

- Even if you make sure the dll is opened by another call (eg _CommGetVersion), _CommSwitch fails if no port has been set yet.

- _ComClosePort closes the dll ! It does not take into account that you may be using several ports.

- Maybe it would be cleaner to foresee a _commg init/uninit pair to deal with opening/closing the dll, and just return an error when a call is made before _commg_init

* Error behaviour needs some cleaning up (the mechanism (@error vs return value) + the error values (success is sometimes 1, sometimes 0) ). (make set of consts to abstract the concrete values eg _COMMMG_SUCCESS, ... )

As a reference, I have added the test code to check for the first issue (note: I add a delay between sending the individual keys, because the target sometimes does not follow):

$l_bEnablePolling = 1
        
        ; I don't care, used as init call
        _CommGetVersion()
        
        if ( _CommSwitch( 1 ) == -1 ) Then
            MsgBox ( 0, "Error", "comswitch" )          
        EndIf

        $l_sErr = ""
        If ( _CommSetPort(1, $l_sErr, 115200, 8, 0, 1, 0) == 0 ) Then
            MsgBox ( 0, "Error", "Com port creation failed :" & $l_sErr )           
        EndIf
        
        if ( _CommSwitch( 2 ) == -1 ) Then
            MsgBox ( 0, "Error", "comswitch" )          
        EndIf
        
        $l_sErr = ""
        If ( _CommSetPort(4, $l_sErr, 115200, 8, 0, 1, 0) == 0 ) Then
            MsgBox ( 0, "Error", "Com port creation failed :" & $l_sErr )           
        EndIf
                    
        if ( _CommSwitch( 1 ) == -1 ) Then
            MsgBox ( 0, "Error", "comswitch" )          
        EndIf
        
        $l_sCommand = "D2 F0040000 100"
        while (1)           
            $l_sCommand = InputBox("Giveth thy command", "...", $l_sCommand)                
            
            $l_sCommand = $l_sCommand & @CRLF
            msgbox (1, "info", "[" & $l_sCommand & "] -> " & string(StringLen($l_sCommand) ))
            
            $l_nCommandLength = StringLen( $l_sCommand )
            $l_nCharIndex = 1
            $l_nIntermediateResult = $COMMGDRIVER_SUCCESS
            while   (   ($l_nIntermediateResult == $COMMGDRIVER_SUCCESS ) _
                    and ( $l_nCharIndex <= $l_nCommandLength ) _
                    )
                $l_nIntermediateResult = _CommSendByte( Asc(StringMid($l_sCommand, $l_nCharIndex ,1)), 1)
                if ( $l_nIntermediateResult <> $COMMGDRIVER_SUCCESS) Then
                    MsgBox(0, "info", "nok")
                Else
;~                  MsgBox(0, "info", "ok")
                endif
                if ($l_nCharIndex <= $l_nCommandLength) then
                    sleep( $COMPORT_INTERCHARDELAY_MS )
                endif
                $l_nCharIndex = $l_nCharIndex + 1
            WEnd
            
            if ($l_bEnablePolling == 0) then
                sleep(5000)         
                $l_sReturnedResponse = _Commgetstring()
            Else
                for $l_nRetryCount = 1 to 100
                    ;sleep(10)          
                    $l_sReturnedResponse = $l_sReturnedResponse & _Commgetstring()
                next
            endif
            if (@error == 0) then
                msgbox (1, "info", "[" & $l_sCommand  & "] -> " & $l_sReturnedResponse )            
            Else
                msgbox (1, "info", "Error detected " & @error & "with [" & $l_sCommand  & "] -> " & $l_sReturnedResponse )          
            endif
        wend
        ; seems to kill all serial ports
        _CommClosePort()

Thanks

Bram

Bram,

I'l have a look at some of your points when I have more time than now, but the lost lines might be because you are not using any handshaking.

I hadn't realized my returns for errors were inconsistent, but I can believe it; the dll started as an experiment to learn how to write a dl and use it, and commg.au3 was my first attempt at a udf so I know I made mistakes.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Bram,

I'l have a look at some of your points when I have more time than now, but the lost lines might be because you are not using any handshaking.

Hi,

It is of course correct there is no handshaking. The target (an embedded system) I am talking to only has TX/RX wires.

But I was kinda hoping my 3 ghz dual core PC could keep up with the 66 Mhz target talking over a 115kbps line >:P.

For this issue I have been able to work around the problem by requesting smaller dumps.

If I ever come in a situation where I don't have control over the amount of information sent to me, I think I will start begging for the sources of the dll to include some internal buffering ;p (or have a look at the mscomm ocx solution, but that one also seems to have it's share of troubles ).

Cu

Bram

Link to comment
Share on other sites

Hi,

It is of course correct there is no handshaking. The target (an embedded system) I am talking to only has TX/RX wires.

But I was kinda hoping my 3 ghz dual core PC could keep up with the 66 Mhz target talking over a 115kbps line >:P.

For this issue I have been able to work around the problem by requesting smaller dumps.

If I ever come in a situation where I don't have control over the amount of information sent to me, I think I will start begging for the sources of the dll to include some internal buffering ;p (or have a look at the mscomm ocx solution, but that one also seems to have it's share of troubles ).

Cu

Bram

Can you use XOX/XOFF?

The input buffer size is 4kb so I'm surprised you loose so much data. I could increase it but I'll check that I'm right first.

Whoops, I see I'm wrong. The default flow of 0 is hardware flow control. It should be set to 2 for no flow control. See if that makes any difference.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Martin,

First, Thanks for the great UDF. I was trying to get on board with NetComm or MSComm neither of which I am able to handle a 0 with.

I am trying to use your Readbytearray function. Here is some output after converting the returned characters over several reads to 2 character hex values :

CODE
FF02020000000200A01106A50EDCEE5A73294502A5FD4B7FBA90060A1001FF02000000A500A01100A50EDCAEC42

EBF6404A71C1CED87992D8DF6FF01020000000100A01106000000AABBCCDD01000000414243440CE38C00000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002FF02000

000A500A01100A50EDCAEC42EBF6404A71C1CED87992D7112FF02020000000200A01106A50EDCEE5A73294502A5FD4B7FBA9

0060A1001FF02000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D8DF6FF01020000000100A01106000000AABBCCD

D01000000414243440CE38C0FFF02000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D04720000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001FF0200000

0A500A01100A50EDCAEC42EBF6404A71C1CED87992D7112FF02020000000200A01106A50EDCEE5A73294502A5FD4B7FBA900

60A1001FF02000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D8DF6FF01020000000100A01106000000AABBCCDD0

1000000414243440CE38C0FFF02000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D0472000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000EDCAEC42EBF6404A71C1CED87992D8DF6FF01020000000100A01106000000AABBCCDD010000004

14243440CE38C01FF02000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D8DF6FF01020000000100A01106000000A

ABBCCDD01000000414243440CE38C02FF020000414243440CE38C0FFF02000000A500A01100A50EDCAEC42EBF6404A71C1CE

D87992D047200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D7112FF020

20000000200A01106A50EDCEE5A73294502A5FD4B7FBA90060A1001FF02000000A500A01100A50EDCAEC42EBF6404A71C1CE

D87992D8DF6FF01020000000100A01106000000AABBCCDD01000000414243440CE38C02FF02000000A500A01100A50EDCAEC

42EBF6404A71C1CED87992D711287992D0472000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

00000000000000000000000000000000000FF02020000000200A01106A50EDCEE5A73294502A5FD4B7FBA90060A1001FF020

00000A500A01100A50EDCAEC42EBF6404A71C1CED87992D8DF6FF01020000000100A01106000000AABBCCDD0100000041424

3440CE38C03FF02000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D552D00A500A01100A50EDCAEC42EBF6404A71

C1CED87992D711287992D0472000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

00000000000000000000000000000000000000000000000000000000000000000000000000000FF00000000A5792001003BD

9DCEE5A73294502A5FD4B7FBA90060A1001FF02000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D8DF6FF0102000

0000100A01106000000AABBCCDD01000000414243440CE38C03FF02000000A500A01100A50EDCAEC42EBF6404A71C1CED879

92D552D00A500A01100A50EDCAEC42EBF6404A71C1CED87992D711287992D047200000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

00000000001FF02000000A500A01100A50EDCEE5A73294502A5FD4B7FBA90060A1001FF02000000A500A01100A50EDCAEC42

EBF6404A71C1CED87992D8DF6FF01020000000100A01106000000AABBCCDD01000000414243440CE38C03FF02000000A500A

01100A50EDCAEC42EBF6404A71C1CED87992D552D00A500A01100A50EDCAEC42EBF6404A71C1CED87992D711287992D04720

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000DCAEC42EBF6404A71C1CED87992D8DF6FF01020000000100A01106000

000AABBCCDD01000000414243440CE38C01FF02000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D8DF6FF0102000

0000100A01106000000AABBCCDD01000000414243440CE38C02FF02000000A500A01100A50EDCAEC42EBF6404A71C1CED879

92D7112FF02020000000200A01106A50EDCEE5A73294502A5FD4B7FBA90060A1001FF02000000A500A01100A50EDCAEC42EB

F6404A71C1CED87992D8DF6FF01020000000100A01106000000AABBCCDD01000000414243440CE38C02FF02000000A500A01

100A50EDCAEC42EBF6404A71C1CED87992D7112FF02020000000200000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

00000000000000000000000000000000000000000000000000000

In this, the zeroes are not really bytes. They are bus idle condition, that for some reason are being returned as data. I did not have this issue with the ReadByte function. I wonder what could be causing this. I also wonder if, by checking return values of your function, I might be able to eliminate this. Right now, I am using

CODE
$receive_length = _CommReadByteArray(DllStructGetPtr($receivebuffer), 255, 0)

If (@ERROR = 0) and ($receive_length > 0) Then;if we got something

to validate that real bytes have been received. Is this not enough?

Link to comment
Share on other sites

Martin,

First, Thanks for the great UDF. I was trying to get on board with NetComm or MSComm neither of which I am able to handle a 0 with.

I am trying to use your Readbytearray function. Here is some output after converting the returned characters over several reads to 2 character hex values :

CODE
FF02020000000200A01106A50EDCEE5A73294502A5FD4B7FBA90060A1001FF02000000A500A01100A50EDCAEC42

EBF6404A71C1CED87992D8DF6FF01020000000100A01106000000AABBCCDD01000000414243440CE38C00000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002FF02000

000A500A01100A50EDCAEC42EBF6404A71C1CED87992D7112FF02020000000200A01106A50EDCEE5A73294502A5FD4B7FBA9

0060A1001FF02000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D8DF6FF01020000000100A01106000000AABBCCD

D01000000414243440CE38C0FFF02000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D04720000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001FF0200000

0A500A01100A50EDCAEC42EBF6404A71C1CED87992D7112FF02020000000200A01106A50EDCEE5A73294502A5FD4B7FBA900

60A1001FF02000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D8DF6FF01020000000100A01106000000AABBCCDD0

1000000414243440CE38C0FFF02000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D0472000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000EDCAEC42EBF6404A71C1CED87992D8DF6FF01020000000100A01106000000AABBCCDD010000004

14243440CE38C01FF02000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D8DF6FF01020000000100A01106000000A

ABBCCDD01000000414243440CE38C02FF020000414243440CE38C0FFF02000000A500A01100A50EDCAEC42EBF6404A71C1CE

D87992D047200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D7112FF020

20000000200A01106A50EDCEE5A73294502A5FD4B7FBA90060A1001FF02000000A500A01100A50EDCAEC42EBF6404A71C1CE

D87992D8DF6FF01020000000100A01106000000AABBCCDD01000000414243440CE38C02FF02000000A500A01100A50EDCAEC

42EBF6404A71C1CED87992D711287992D0472000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

00000000000000000000000000000000000FF02020000000200A01106A50EDCEE5A73294502A5FD4B7FBA90060A1001FF020

00000A500A01100A50EDCAEC42EBF6404A71C1CED87992D8DF6FF01020000000100A01106000000AABBCCDD0100000041424

3440CE38C03FF02000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D552D00A500A01100A50EDCAEC42EBF6404A71

C1CED87992D711287992D0472000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

00000000000000000000000000000000000000000000000000000000000000000000000000000FF00000000A5792001003BD

9DCEE5A73294502A5FD4B7FBA90060A1001FF02000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D8DF6FF0102000

0000100A01106000000AABBCCDD01000000414243440CE38C03FF02000000A500A01100A50EDCAEC42EBF6404A71C1CED879

92D552D00A500A01100A50EDCAEC42EBF6404A71C1CED87992D711287992D047200000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

00000000001FF02000000A500A01100A50EDCEE5A73294502A5FD4B7FBA90060A1001FF02000000A500A01100A50EDCAEC42

EBF6404A71C1CED87992D8DF6FF01020000000100A01106000000AABBCCDD01000000414243440CE38C03FF02000000A500A

01100A50EDCAEC42EBF6404A71C1CED87992D552D00A500A01100A50EDCAEC42EBF6404A71C1CED87992D711287992D04720

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000DCAEC42EBF6404A71C1CED87992D8DF6FF01020000000100A01106000

000AABBCCDD01000000414243440CE38C01FF02000000A500A01100A50EDCAEC42EBF6404A71C1CED87992D8DF6FF0102000

0000100A01106000000AABBCCDD01000000414243440CE38C02FF02000000A500A01100A50EDCAEC42EBF6404A71C1CED879

92D7112FF02020000000200A01106A50EDCEE5A73294502A5FD4B7FBA90060A1001FF02000000A500A01100A50EDCAEC42EB

F6404A71C1CED87992D8DF6FF01020000000100A01106000000AABBCCDD01000000414243440CE38C02FF02000000A500A01

100A50EDCAEC42EBF6404A71C1CED87992D7112FF02020000000200000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

00000000000000000000000000000000000000000000000000000

In this, the zeroes are not really bytes. They are bus idle condition, that for some reason are being returned as data. I did not have this issue with the ReadByte function. I wonder what could be causing this. I also wonder if, by checking return values of your function, I might be able to eliminate this. Right now, I am using

CODE
$receive_length = _CommReadByteArray(DllStructGetPtr($receivebuffer), 255, 0)

If (@ERROR = 0) and ($receive_length > 0) Then;if we got something

to validate that real bytes have been received. Is this not enough?

You have the last parameter as 0 which means that _CommReadByteArray returns the number of bytes which were available at the time. If you are assuming that $receive_length is 255 then that might explain the extra zeroes.
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

  • 1 month later...

Hi Martin,

First of all thanks for UDF!

And now a question:

I try to create "not standard" protocol, namely 9 bit of data. As soon as I set $iBits = 9, I receive an error -4. I have tried to set value less than 8 (7) and the error is not present. It is a bug or I do something wrong?

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