Jump to content

Serial Port /COM Port UDF


martin
 Share

Recommended Posts

serghei002,

if dtat is being received then it is shown in th eedit box. If you want to stop th eedit box showing what has been receievd then you could simply send the recieved datta to a hidden edit and only copy lines to the shown edited when allowed.

There would be something different needed if you want to stop data being sent to you so if tat's what you want then you would need to play with the hardware handshaking lines.

 

Thanks Martin,

finally I chose an easier solution, I just put a disconnect and reconnect button like in HyperTerminal.

Thanks for the help and UDF

Link to comment
Share on other sites

  • 3 weeks later...

Hi Martin

I will post here some questions. I know some are answered elsewhere, but I beg for your patience,  it can be a good resume for others interested: o:)

  1. when I have more than 1 channel, the other channels (the ones that are not the _CommSwitch one) still receives in internal buffer or they loose the received bytes while they are not the selected one?
  2. what´s the diference betwen _CommGetstring() and _CommReadByteArray?  (please, see next question)
  3.  ".. memory starting at address $pAddress" in  CommReadByteArray , means that  it´s an array $x[...]? If yes, each received byte will be at $x[0], $x[1]...? But as Au3 defines the "type" of variable on the fly, what´s the type of variable you suggest, and how to declare them at Global, Local, etc?  And if $pAddress is a string, each received byte will be a "char" at the string? I suppose the string must have a defined size before call _CommSendString? If so, what´s the diference for  _CommGetstring()?
  4. maybe same question of 2 above, what´s the diference betwen  _CommSendString and _CommSendByteArray
  5. there is a way to not stop receiving if 0x00 arrives in the middle of a message?
  6. I suppose that we can send 0x00 with _CommSendString without any problem (supposing the receiver is a PIC or whatever and don´t worry about receiving 0x00, and I converted my "bytes" to "char" -> $x= chr(0) ).
  7. About 64 bits, means that dll works in a 64 bits systems (win7, XP),  with au3 compiled as a 32 bits application and do not work with au3 compiled as a 64 bits application?
  8.  on 03 Nov 2010 - 7:30 PM, you tell about possible protection issues into have the dll in the same folder than the compiled .exe in win7. There is anything we must do at the target win7 or xp PC about this "protection issue" or it does not exists, I mean, just copy the .exe and .dll to same folder and it will work ok? Even if the logged user is not administrator?

Thanks in advance

Jose

Edited by joseLB
Link to comment
Share on other sites

Hi Martin, Thanks for the great UDF

I've got a small problem with my script.

I've made a sort of ping of live to my Arduino.

A autoit script sent a character every 30 loops to my arduino, if my arduino won't get the character in a few second he knows the PC is down/stand by or in hibernate.

The script and the Arduino works fine but when the pc has been for a while in standby (and start it up) I get a message that the device connect it to the comport won't work (in a small window with a window title “Autoit3”).

When I click on Ok everything works fine.

Now I've build the script to a services and after standby I never get this message (what is normal for a services) and the script won't react anymore.

I think it's a script error, or a error checking problem in my script but I don't know how to solve it, can you help me?

It's starts in the "Func _code()" all the rest is for the services

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=ktip.ico
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Res_Language=1043
#AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <include\CommMG.au3>
#include <include\Services.au3>

Global $sServiceName = "Pc Tools"
Global $commport = 3

If @Compiled = 1 Then
    If _Service_QueryType($sServiceName) = 0 Then
        InstallService()
        Exit
    EndIf
Else
    _code()
EndIf

If $cmdline[0] > 0 Then
    Switch $cmdline[1]
        Case "-i"
            InstallService()
        Case "-u"
            RemoveService()
        Case "-r"
            _Service_Stop($sServiceName)
            Sleep(2000)
            _Service_Stop($sServiceName)
            Sleep(1000)
            _Service_Start($sServiceName)
        Case Else
            Exit
    EndSwitch
Else
    _Service_init($sServiceName)
    Exit
EndIf

Func _main($iArg, $sArgs)
    If Not _Service_ReportStatus($SERVICE_RUNNING, $NO_ERROR, 0) Then
        _Service_ReportStatus($SERVICE_STOPPED, _WinAPI_GetLastError(), 0)
        Exit
    EndIf

    _code()

    _Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, 1000)
    DllCallbackFree($tServiceMain)
    DllCallbackFree($tServiceCtrl)

    _Service_ReportStatus($SERVICE_STOPPED, $NO_ERROR, 0)
    DllClose($hAdvapi32_DLL)
    DllClose($hKernel32_DLL)
EndFunc   ;==>main

Func _code()
    local $result, $comm, $teller
    $bServiceRunning = True ; REQUIRED

    $comm = _CommSetport($commport, $result, 9600, 8, 'none', 1, 1)
    _comm_arduino()
    
    While $bServiceRunning
        #region --> insert your running code here
        $teller = $teller + 1
        If $teller > 30 Then
            $teller = 0
            _comm_arduino()
        EndIf
        _Sleep(100)
        #endregion  --> insert your running code here
    WEnd
EndFunc

Func _comm_arduino()
    _CommSendString("Ÿ")
    If @error = -1 Then
        ConsoleWrite("error" & @CRLF)
    EndIf
EndFunc

Func _Sleep($delay)
    Local $result = DllCall($hKernel32_DLL, "none", "Sleep", "dword", $delay)
EndFunc ;==>_Sleep

Func InstallService()
    #RequireAdmin
    _Service_Create($sServiceName, $sServiceName, $SERVICE_WIN32_OWN_PROCESS, $SERVICE_AUTO_START, $SERVICE_ERROR_SEVERE, '"' & @ScriptFullPath & '"')
    If @error Then
        ConsoleWrite("InstallService(): Problem installing service, Error number is " & @error & @CRLF & " message : " & _WinAPI_GetLastErrorMessage() & @CRLF)
    Else
        ConsoleWrite("InstallService(" & $sServiceName & "): Installation of service successful" & @CRLF)
    EndIf
EndFunc   ;==>InstallService

Func RemoveService()
    _Service_Stop($sServiceName)
    _Service_Delete($sServiceName)
EndFunc   ;==>RemoveService

Func logprint($text, $nolog = 0)

EndFunc
Edited by nend
Link to comment
Share on other sites


while in standby (and start it up) I get a message that the device connect it to the comport won't work (in a small window with a window title “Autoit3”).

 

Can you tell me more about this message? A screen shot might help.

Why do you run the script as a service? Is it because you want it to run regardless of the user?

I have looked at your script but I don't see anything which looks like it should cause a problem. I'll try experimenting with hibernating to see if I can find anything, but I have no experience with running scripts as services.

It might be that you need to detect hibernating and close the port, then when the PC wakes up open the port again.

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.when I have more than 1 channel, the other channels (the ones that are not the _CommSwitch one) still receives in internal buffer or they loose the received bytes while they are not the selected one?

Any channels opened remain open untill closed. While they are open they receive and send data even if they are not the selected channel. Selecting a channel only means you have specified which channel, or COM port, your script will be dealing with.

If a channel is recieving data and the script doesn't attend to it then depending on the handshaking, or lack of it, data could be lost if the buffer becomes full. See post 366.

2. what´s the diference betwen _CommGetstring() and _CommReadByteArray?  (please, see next question)

Strings are in fact only ASCII strings in this UDF. A string is a sequence of ASCII characters terminated by 0x00.  If you want to send and recieve data which might include 0x00 then you cannot use _CommGetString or _CommSendString. You must instead use _CommRead/Sendbyte or _CommRead/SendByteArray. In most cases ReadByte or SendByte will work ok and is the simplest method. However, if you need to deal with a lot of binary data and speed is important then the byte array functions are very much faster.

You need to cretae a DllStruct to use the byte array functions

$Numbytes1 = 16;say we have 16 bytes
$Struct1 = DllStructCreate("byte[" & $Numbytes1 & "]")

For $n = 1 To Numbytes1 ;put some random numbers in the struct
    DllStructSetData($Struct1, 1, Random(0, 255, 1), $n)
Next

;send the bytes
_CommSendByteArray(DllStructGetPtr($Struct1), $Numbytes1, 1)
if @error then MsgBox(0, 'ERROR', '_CommSendByteArrray failed')

3.  ".. memory starting at address $pAddress" in  CommReadByteArray , means that  it´s an array $x[...]? If yes, each received byte will be at $x[0], $x[1]...? But as Au3 defines the "type" of variable on the fly, what´s the type of variable you suggest, and how to declare them at Global, Local, etc?  And if $pAddress is a string, each received byte will be a "char" at the string? I suppose the string must have a defined size before call _CommSendString? If so, what´s the diference for  _CommGetstring()?

See the previous answer and example.

4. maybe same question of 2 above, what´s the diference betwen  _CommSendString and _CommSendByteArray

Sendstring is for sending an ASCII string. Say $stringToSend = "LetMeOutOfHere!". Sendbyte.. is for sending 8 bit bytes with a value from 0, which cannot be included in a string, up to 255.

5. there is a way to not stop receiving if 0x00 arrives in the middle of a message?

Not if you receive using GetString. You can keep using GetByte and add the bytes to an array if you don't know how many bytes are coming, or use _CommGetByteArray with wait set to 0 so that it will return with however many bytes are in the input buffer.

6. I suppose that we can send 0x00 with _CommSendString without any problem (supposing the receiver is a PIC or whatever and don´t worry about receiving 0x00, and I converted my "bytes" to "char" -> $x= chr(0) ).

No.

0x00 marks the end of a string and is not sent so your PIC, Arduino or whatever will never get it. You have to use the byte functions

7. About 64 bits, means that dll works in a 64 bits systems (win7, XP),  with au3 compiled as a 32 bits application and do not work with au3 compiled as a 64 bits application?

The dll is 32 bit and will only work with 32 bit applications. They don't have to be AutoIt. It could be a PHP scripts, but it still has to be 32 bit.

8.  on 03 Nov 2010 - 7:30 PM, you tell about possible protection issues into have the dll in the same folder than the compiled .exe in win7. There is anything we must do at the target win7 or xp PC about this "protection issue" or it does not exists, I mean, just copy the .exe and .dll to same folder and it will work ok? Even if the logged user is not administrator?

I think that was just an example where a customer has the dll removed sometimes and I assume it's his virus protection but I don't know. He simply keeps a copy of the dll somewhere and copies it back when needed. I don't know why a dll in the script folder should be a problem. If I seach for dll's on your PC you will find many applications have them in their program folders.

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

Hi Martin,

Thanks for the reply.

Your right about services on different users.

this script must allways on as long as the pc is on regarding witch user has logged on, even when no user is logged on. 

I think that the computer wakes-up some microsecond before the arduino is waken up and the _commsendstring send the character before the arduino can react.

I found on this forum a serial communication UDF (without DLL) and that one works create.

For me is that script a/the solution.

I don't think that the error message come direct from your udf/dll because the text is in Dutch (the language from my win7).

A simple translation of the error message is “the device connect it to the comport won't work”

In the title bar it's said “Autoit3” and there is a Ok button (looks like a msgbox)

I only gets this message when I run this script as a normal script not as a services.

If I run this as a services the services stops and won't react anymore.

I only gets this message when I run this script, without everything works fine.

I haven't got any screen shot because I re script the script with the other udf.

I've you really want to have the screen shot I can reproduce the error to put back the other script witch use your UDF/DLL.

 

Can you tell me more about this message? A screen shot might help.

Why do you run the script as a service? Is it because you want it to run regardless of the user?

I have looked at your script but I don't see anything which looks like it should cause a problem. I'll try experimenting with hibernating to see if I can find anything, but I have no experience with running scripts as services.

It might be that you need to detect hibernating and close the port, then when the PC wakes up open the port again.

Edited by nend
Link to comment
Share on other sites

ok nend, if you have a solution then won't worry about it because it is an unusual problem. Thanks for your update.

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

grashopper,

what version dll are you using? Version 2.81 removed those messages (or should have). If you are using an earlier version you can download the latest from the fiirst post in this thread.

Hi Martin

I start to test your routines. At this moment I do not have a serial port on my note (win7, 64 bits, dll-2.81, as informed by _CommGetVersion() - I just donwloaded your udf and dll.

I´m receiving the message

autoit 3

can´t perform this operation on a closed port

port=COM1

channel=1

it hapend when:

1- I do not have a serial port

2- it hapens in a command like _CommSendString("test",0), not seting @error (=0)

3- I guess, maybe after a command like _CommClosePort(). But this I must investigate yet.

but, by sure , there is still a msg box elsewhere in your dll that displays that message. Further, _CommSendString("test",0) on this situation returns @error=0...

I tested the command _CommSendString("test",0) as the first line of the script and it works ok even withour any serial port, I mean, it does not open the msg box above. I could not determine yet what changes it behavior on my script, to make the message to appear.

I will post here when I found what makes it change behavior.

Regards

Jose

Edited by joseLB
Link to comment
Share on other sites

Hi Martin

I think I tracked what is going on.

Main consideration is that I do not have any serial port on my note, so, errors are the expected behavior.

Follows the code executed, as first commands in my Au3 (I give "Go" to execute).

$x= _CommSendString("test",0)
MsgBox(1,1,_CommGetVersion() &@cr&@error)
$comRS232 =  _CommSetport(1,$msgErroSerial,2400,8,0,1,2,0,0)
MsgBox(1,2, $msgErroSerial &@cr& @error )
$x= _CommSendString("test",0)
MsgBox(1,3, $msgErroSerial &@cr& @error )
$x= _CommSendString("test",0)
MsgBox(1,4,@error)

If I connect a prolific usb por (COM 6) and change the comsetprot to 6, all works ok (I mean, no more error messages or autoit3 messages. Even yhr 1st line returns ok (@error=0 and no error messages.

**by the way, this is just to report you how it works if there is no attached port. I´m still converting my 1st program and soon will report here. Up to now things are going well.

attached is the sequence of printscreens for each step of the above commands without serial port.

post-9220-0-36207800-1385048403_thumb.jp

Edited by joseLB
Link to comment
Share on other sites

Hi Martin

I´m finish my first porting for your UDF....

What else can I say, besides they really very good, works like a charm and are very solid....

I tried a lot to "crash" them and up to now was unsucessful (hopefully :sweating: ).  And I´m known as the "programers hapiness killer" down here...

The points mentioned in my earlier post are still there, but if we circumvent them, we can go, as I did.

I would like to thanks you for sharing this fantastic piece of code, and have just to complain to not have ported before...

Congratulations and thanks again

Jose

*** but don´t relax, if I find something else, I will post here, don´t worry o:)

Link to comment
Share on other sites

.. *** but don´t relax, if I find something else, I will post here, don´t worry

]

 

I was afraid of that.

But I'm glad you've found the UDF helpful. :)

EDIT:

I will look at the point in your previous posts #569 and #570 in a couple of days.

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

  • 4 weeks later...

I've been using CommMG.au3 for years and it works great!

It controlled a relay-card and an Arduino DMX-controller.

Now i added another Arduino which controls a RGB-Pixel-Strip and all goes belly up  :geek:

I found out that changing the port (_CommSwitch) takes 20ms, that is just waaaay to long for constantly switching between DMX and RGB-strip.

Is there a easy solution for "streaming" over two ports?

While searching this thread i read about making a dedicated program for each port, but keeping two ports open would sure make things easier.

Link to comment
Share on other sites

I tested using _CommSwitch 200 times like this on my creaky old laptop

ConsoleWrite("switch time is ")
$t1 = TimerInit()
for $n = 1 to 100
    _Commswitch(0)
    _Commswitch(1)
Next
ConsoleWrite(stringformat("%0.2f mS",timerdiff($t1)/200) & @LF)

 

The output was about the same every time I tried, typically

switch time is 1.07 mS

 

I can't make it any faster than that but it has never been any different as far as I know. How did you decide that it takes 20 mS?

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

Hello , 

CommgExample.au3 , Line 224 , you set com port as:

_CommSetPort($setPort,$sportSetError,GUICtrlRead($CmBoBaud),GUICtrlRead($CmboDataBits),GUICtrlRead($CmBoParity),GUICtrlRead($CmBoStop),$setFlow)

But GUICtrlRead($CmBoParity) returns 'none' , but this value should be '0' , not 'none'

am I right ?

----------------------------------------------------------------------------------------------------------------------

; Function Name: _CommSetport($iPort,ByRef $sErr,$iBaud=9600,$iBits=8,$ipar=0,$iStop=1,$iFlow=0,$RTSMode = 0,$DTRMode = 0)
; Description: Initialises the port and sets the parameters
; Parameters: $iPort - integer = the port or COM number to set. Allowed values are 1 or higher.
; NB WIndows refers To COM10 Or higher`as .com10 but only use the number 10, 11 etc
; $sErr - string: the string to hold an error message if func fails.
; $iBaud - integer: the baud rate required. With commg.dll v2.3 and later any value allowed up to 256000.
; With v2.4 any value??
; If using commg.dll before V2.3 then only allowed values are one of
; 50, 75, 110, 150, 600, 1200, 1800, 2000, 2400, 3600, 4800, 7200, 9600, 10400,
; 14400, 15625, 19200, 28800, 38400, 56000, 57600, 115200, 128000, 256000
; $iBits - integer: number of bits in code to be transmitted
; $iParity - integer: 0=None,1=Odd,2=Even,3=Mark,4=Space
; $iStop - integer: number of stop bits, 1=1 stop bit 2 = 2 stop bits, 15 = 1.5 stop bits
; $iFlow - integer: 0 sets hardware flow control,
; 1 sets XON XOFF control,
; 2 sets NONE i.e. no flow control.

Edited by MichaelXMike
Link to comment
Share on other sites

@MichaelXMike

 Yes, you are correct on both points. Obviously not many people follow my example! :)

Thank you for telling me about that MichaelXMike.

I have fixed it now and I will correct the version in the download soon.

EDIT:

Example attached to the first post has now been corrected.

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

Thank you for your prompt answer .

Another point is that I had 30-40% CPU usage. I mentioned that (into CommMG.au3 ) _CommGetLine  includes a sleep(20)  delay but _CommGetString does not .

So in your (revised) CommgExample.au3 ,  line 91

If $instr <> '' Then;if we got something
...

Endif

changed to

If $instr <> '' Then;if we got something
   ...

Else
   sleep(20) ; Mike - reduce CPU usage

EndIf

Anyway thanks for the great job .

Edited by MichaelXMike
Link to comment
Share on other sites

OK, I have corrected that one too. Don't find any more problems for a few hours - I want to go to bed!

I hope you find a use for the UDF.

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

Func sendsms()
    $to=GUICtrlRead($Input1)
    $message=GUICtrlRead($Edit1)
    ConsoleWrite("Trimit sms-ul catre numarul " & $to &" ,cu mesajul  " & $message)
    _CommSendstring("at+cmgf=1")
    Sleep(100)
    _CommSendString("at+cmgs="&"+407xxxxxx""&")
    Sleep(10)
    _CommSendString($message)
    Sleep(100)
    $string = Chr(26) & @CR
_CommSendString($string,1)
EndFunc

I press a buton and receive sms with at+cmgf=1at+cmgs=$40xxxx"&

SOmething is wrong please help

Edited by abaluta8
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...