Sign in to follow this  
Followers 0
zadu

Outer function has no return value

20 posts in this topic

Hi,

There is my problem: I'm using an object to call functions.

This object is for PLC monitoring (I'd like to see the value of M7000 in PLC).

And I want to use a function.

$Control = ObjCreate("ActMulti.ActMLEasyIF")

$Ret = $Control.GetDevice("M7000", $ReturnData)

$Ret is the return state of function (Succes or not).

$Returndata = {MY TARGET} but this never gets value (why?).

Maybe there is no "=", there is a parameter?

How can I get this value?

Thanks

Getdevice2.au3

Share this post


Link to post
Share on other sites



I cleaned up your code a but.

Have to know more about GetDevice to answer your question. I can see no reason why it should not changed, be used as the return value.

HotKeySet("{ESC}", "Terminate")

Global $o_Control = ObjCreate("ActMulti.ActMLEasyIF") ;Create MX Control object for PLC (Melsoft MX-Change Software for Mitsubishi PLC)
If @error Then Exit

While Not @error ;Main loop
    $Contact = GetDevice(1, "M7000")
    MsgBox(0, "Result:", $Contact)
    If $Contact = -1 Then ExitLoop
    Sleep(1000)
WEnd

Func GetDevice($Logical_station, $device)
    Local $i_ReturnData = -1 ; Default value of PLC contact (Error state)
    With $o_Control
        .ActLogicalStationNumber = $Logical_station ; Set PLC communication mode
        .Open() ; Open control
        .GetDevice($device, $i_ReturnData) ; [Error Code] = GetDevice ([PLC device name] , [Return Value])  <-- !!! The return value is not coming !!! Why?
        .Close() ; Close control
    EndWith
    Return $i_ReturnData
EndFunc   ;==>GetDevice

Func Terminate()
    Exit
EndFunc   ;==>Terminate

Post your code because code says more then your words can. SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y. Use Opt("MustDeclareVars", 1)[topic="84960"]Brett F's Learning To Script with AutoIt V3[/topic][topic="21048"]Valuater's AutoIt 1-2-3, Class... is now in Session[/topic]Contribution: [topic="87994"]Get SVN Rev Number[/topic], [topic="93527"]Control Handle under mouse[/topic], [topic="91966"]A Presentation using AutoIt[/topic], [topic="112756"]Log ConsoleWrite output in Scite[/topic]

Share this post


Link to post
Share on other sites

Thanks the answer,

The problem persists...

I attached the page of the programming manual.

I cleaned up your code a but.

Have to know more about GetDevice to answer your question. I can see no reason why it should not changed, be used as the return value.

HotKeySet("{ESC}", "Terminate")

Global $o_Control = ObjCreate("ActMulti.ActMLEasyIF") ;Create MX Control object for PLC (Melsoft MX-Change Software for Mitsubishi PLC)
If @error Then Exit

While Not @error ;Main loop
    $Contact = GetDevice(1, "M7000")
    MsgBox(0, "Result:", $Contact)
    If $Contact = -1 Then ExitLoop
    Sleep(1000)
WEnd

Func GetDevice($Logical_station, $device)
    Local $i_ReturnData = -1 ; Default value of PLC contact (Error state)
    With $o_Control
        .ActLogicalStationNumber = $Logical_station ; Set PLC communication mode
        .Open() ; Open control
        .GetDevice($device, $i_ReturnData) ; [Error Code] = GetDevice ([PLC device name] , [Return Value])  <-- !!! The return value is not coming !!! Why?
        .Close() ; Close control
    EndWith
    Return $i_ReturnData
EndFunc   ;==>GetDevice

Func Terminate()
    Exit
EndFunc   ;==>Terminate

post-57144-12705372100173_thumb.jpg

Share this post


Link to post
Share on other sites

I found the complete manual: Programming manual

I cleaned up your code a but.

Have to know more about GetDevice to answer your question. I can see no reason why it should not changed, be used as the return value.

HotKeySet("{ESC}", "Terminate")

Global $o_Control = ObjCreate("ActMulti.ActMLEasyIF") ;Create MX Control object for PLC (Melsoft MX-Change Software for Mitsubishi PLC)
If @error Then Exit

While Not @error ;Main loop
    $Contact = GetDevice(1, "M7000")
    MsgBox(0, "Result:", $Contact)
    If $Contact = -1 Then ExitLoop
    Sleep(1000)
WEnd

Func GetDevice($Logical_station, $device)
    Local $i_ReturnData = -1 ; Default value of PLC contact (Error state)
    With $o_Control
        .ActLogicalStationNumber = $Logical_station ; Set PLC communication mode
        .Open() ; Open control
        .GetDevice($device, $i_ReturnData) ; [Error Code] = GetDevice ([PLC device name] , [Return Value])  <-- !!! The return value is not coming !!! Why?
        .Close() ; Close control
    EndWith
    Return $i_ReturnData
EndFunc   ;==>GetDevice

Func Terminate()
    Exit
EndFunc   ;==>Terminate

Share this post


Link to post
Share on other sites

According to the attachment, 3 args are requried. (iRet, sDevice, iData) yet only two are provided.

I would see what the return value is then check it against the error codes section.

Added check against the return value.

HotKeySet("{ESC}", "Terminate")

Global $o_Control = ObjCreate("ActMulti.ActMLEasyIF") ;Create MX Control object for PLC (Melsoft MX-Change Software for Mitsubishi PLC)
If @error Then Exit

While Not @error ;Main loop
    $Contact = GetDevice(1, "M7000")
    MsgBox(0, "Result:", $Contact)
    If $Contact = -1 Then ExitLoop
    Sleep(1000)
WEnd

Func GetDevice($Logical_station, $device)
    Local $i_ReturnData = -1 ; Default value of PLC contact (Error state)
    With $o_Control
        .ActLogicalStationNumber = $Logical_station ; Set PLC communication mode
        .Open() ; Open control
        .GetDevice($device, $i_ReturnData) ; [Error Code] = GetDevice ([PLC device name] , [Return Value])  <-- !!! The return value is not coming !!! Why?
        .Close() ; Close control
    EndWith
    If $i_ReturnData <> 0 Then ; Not 0 indicates abnormal termination
        SetError(1, 0, 0) ;
    EndIf
    Return $i_ReturnData
EndFunc   ;==>GetDevice

Func Terminate()
    Exit
EndFunc   ;==>Terminate

Post your code because code says more then your words can. SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y. Use Opt("MustDeclareVars", 1)[topic="84960"]Brett F's Learning To Script with AutoIt V3[/topic][topic="21048"]Valuater's AutoIt 1-2-3, Class... is now in Session[/topic]Contribution: [topic="87994"]Get SVN Rev Number[/topic], [topic="93527"]Control Handle under mouse[/topic], [topic="91966"]A Presentation using AutoIt[/topic], [topic="112756"]Log ConsoleWrite output in Scite[/topic]

Share this post


Link to post
Share on other sites

$iRet=$o_Control.GetDevice($device, $i_ReturnData)

The return value is "0"

The function is OK but there is no right value in $i_ReturnData...

HotKeySet("{ESC}", "Terminate")

Global $o_Control = ObjCreate("ActMulti.ActMLEasyIF") ;Create MX Control object for PLC (Melsoft MX-Change Software for Mitsubishi PLC)

If @error Then Exit

While Not @error ;Main loop

$Contact = GetDevice(1, "M7000")

MsgBox(0, "Result:", $Contact)

If $Contact = -1 Then ExitLoop

Sleep(1000)

WEnd

Func GetDevice($Logical_station, $device)

Local $i_ReturnData = -1 ; Default value of PLC contact (Error state)

$o_Control.ActLogicalStationNumber = $Logical_station

$o_Control.Open() ; Open control

$iRet=$o_Control.GetDevice($device, $i_ReturnData)

msgbox(0,"Error Flag: ", $iRet)

$o_Control.Close() ; Close control

Return $i_ReturnData

EndFunc ;==>GetDevice

Func Terminate()

Exit

EndFunc ;==>Terminate

Share this post


Link to post
Share on other sites

$iRet=$o_Control.GetDevice($device, $i_ReturnData)

The return value is "0"

The function is OK but there is no right value in $i_ReturnData...

There may be COM errors, so try adding a COM error handler. Something like
; define globals
Global $fEventError = 0 ; to be checked to know if com error occurs. Must be reset after handling
Global $oComErr = ObjEvent("AutoIt.Error", "ComErr") ; Install a custom error handler

; com error handler
Func ComErr()
    $ErrorOutput = @LF & "COM Error in " & @ScriptName _
         & @LF & "Line = " & $oComErr.Scriptline _
         & @LF & "Hex = " & Hex($oComErr.Number, 8) _
         & @LF & "Numb = " & $oComErr.Number _
         & @LF & "WinDesc = " & StringStripWS($oComErr.WinDescription, 2) _
         & @LF & "Desc = " & StringStripWS($oComErr.Description, 2) _
         & @LF & "Src = " & $oComErr.Source _
         & @LF & "HlpFile = " & $oComErr.HelpFile _
         & @LF & "HlpContx = " & $oComErr.HelpContext _
         & @LF & "LastDllErr = " & $oComErr.LastDllError
    MsgBox(262144 + 16, @ScriptName, $ErrorOutput)
    $fEventError = 1 ; something to check for when this function returns
EndFunc ;==>ComErr

Share this post


Link to post
Share on other sites

Ok. I included the error handling. How can I use it?

Should I call the ComErr() func. or monitor the $fEventError ?

After using GetDevice()?

There may be COM errors, so try adding a COM error handler. Something like

; define globals
Global $fEventError = 0 ; to be checked to know if com error occurs. Must be reset after handling
Global $oComErr = ObjEvent("AutoIt.Error", "ComErr") ; Install a custom error handler

; com error handler
Func ComErr()
    $ErrorOutput = @LF & "COM Error in " & @ScriptName _
         & @LF & "Line = " & $oComErr.Scriptline _
         & @LF & "Hex = " & Hex($oComErr.Number, 8) _
         & @LF & "Numb = " & $oComErr.Number _
         & @LF & "WinDesc = " & StringStripWS($oComErr.WinDescription, 2) _
         & @LF & "Desc = " & StringStripWS($oComErr.Description, 2) _
         & @LF & "Src = " & $oComErr.Source _
         & @LF & "HlpFile = " & $oComErr.HelpFile _
         & @LF & "HlpContx = " & $oComErr.HelpContext _
         & @LF & "LastDllErr = " & $oComErr.LastDllError
    MsgBox(262144 + 16, @ScriptName, $ErrorOutput)
    $fEventError = 1 ; something to check for when this function returns
EndFunc ;==>ComErr

Share this post


Link to post
Share on other sites

Ok. I included the error handling. How can I use it?

Should I call the ComErr() func. or monitor the $fEventError ?

After using GetDevice()?

You don't directly call the error handler. Any COM errors should automatically call the handler and you will get a msgbox with error info. In some cases just the WinDesc text will tell you why the call failed.

Share this post


Link to post
Share on other sites

You don't directly call the error handler. Any COM errors should automatically call the handler and you will get a msgbox with error info. In some cases just the WinDesc text will tell you why the call failed.

I had a quick look at the manual using the link in an earlier post and I think you are using the function GetDevice incorrectly. The second parameter is a pointer to an integer.

So your GetDevice function should be more like this I think

$Contact = GetDevice(1,"M700")
MsgBox(0, "Result:", $Contact)
If $Contact = -1 Then ExitLoop
Sleep(1000)
WEnd

Func GetDevice($Logical_station, $device)
 Local $i_ReturnData = -1 ; Default value of PLC contact (Error state)
 $o_Control.ActLogicalStationNumber = $Logical_station
 $o_Control.Open() ; Open control
 Localk $sPLC = DllStructCreate("int")
 $iRet=$o_Control.GetDevice($device, DllStructGetPtr($sPLC))
 $i_ReturnData = DllStructGetData($sPLC) 
 msgbox(0,"Error Flag: ", $iRet)
 $o_Control.Close() ; Close control
 Return $i_ReturnData
EndFunc ;==>GetDevice

Func Terminate()
 Exit
EndFunc ;==>Terminate

I'm not sure about the device name, so "M700" might not be correct, or at least it's not obvious to me from the manual.


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.

Share this post


Link to post
Share on other sites

Thanks your reply,

I'll try your code (I have problem with it now, with syntax).

There are some error with using DllStruct commands...

I use the M7000. It is in PLC ladder so its Ok.

I attached the original VBScript code. This code is working well.

This code was the base.

I had a quick look at the manual using the link in an earlier post and I think you are using the function GetDevice incorrectly. The second parameter is a pointer to an integer.

So your GetDevice function should be more like this I think

$Contact = GetDevice(1,"M700")
MsgBox(0, "Result:", $Contact)
If $Contact = -1 Then ExitLoop
Sleep(1000)
WEnd

Func GetDevice($Logical_station, $device)
 Local $i_ReturnData = -1 ; Default value of PLC contact (Error state)
 $o_Control.ActLogicalStationNumber = $Logical_station
 $o_Control.Open() ; Open control
 Localk $sPLC = DllStructCreate("int")
 $iRet=$o_Control.GetDevice($device, DllStructGetPtr($sPLC))
 $i_ReturnData = DllStructGetData($sPLC) 
 msgbox(0,"Error Flag: ", $iRet)
 $o_Control.Close() ; Close control
 Return $i_ReturnData
EndFunc ;==>GetDevice

Func Terminate()
 Exit
EndFunc ;==>Terminate

I'm not sure about the device name, so "M700" might not be correct, or at least it's not obvious to me from the manual.

Sample_M7000.html

Share this post


Link to post
Share on other sites

Thanks your reply,

I'll try your code (I have problem with it now, with syntax).

There are some error with using DllStruct commands...

I use the M7000. It is in PLC ladder so its Ok.

I attached the original VBScript code. This code is working well.

This code was the base.

The error is because I missed the element out of this line

$i_ReturnData = DllStructGetData($sPLC)

it should be

$i_ReturnData = DllStructGetData($sPLC,1)


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.

Share this post


Link to post
Share on other sites

Thanks again but my problem is the DllStructGetPtr($sPLC)

" ==> The requested action with this object has failed.: "

The error is because I missed the element out of this line

$i_ReturnData = DllStructGetData($sPLC)

it should be

$i_ReturnData = DllStructGetData($sPLC,1)

Share this post


Link to post
Share on other sites

Thanks again but my problem is the DllStructGetPtr($sPLC)

" ==> The requested action with this object has failed.: "

Oh, I don't understand that. Looking at the manual again I see that a 2 byte value is set in the return variable so I assume it should be UShort not int. (But I don't find the manual easy to understand.)

Does this still give an error? I'm not optimistic.

Func GetDevice($Logical_station, $device)
 Local $i_ReturnData = -1 ; Default value of PLC contact (Error state)
 $o_Control.ActLogicalStationNumber = $Logical_station
 $o_Control.Open() ; Open control
 Local $sPLC = DllStructCreate("USHORT"), $ptemp
 $ptemp = DllStructGetPtr($sPLC)
 $iRet=$o_Control.GetDevice($device, $ptemp)
 $i_ReturnData = DllStructGetData($sPLC,1) 
 msgbox(0,"Error Flag: ", $iRet)
 $o_Control.Close() ; Close control
 Return $i_ReturnData
EndFunc ;==>GetDevice

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.

Share this post


Link to post
Share on other sites

I tried a lot but there were error only. I'll give up...

Maybe DllCall() ?

I don't understand the Excel VBA is OK, the VBScript is OK but Auto It not...

Oh, I don't understand that. Looking at the manual again I see that a 2 byte value is set in the return variable so I assume it should be UShort not int. (But I don't find the manual easy to understand.)

Does this still give an error? I'm not optimistic.

Func GetDevice($Logical_station, $device)
 Local $i_ReturnData = -1 ; Default value of PLC contact (Error state)
 $o_Control.ActLogicalStationNumber = $Logical_station
 $o_Control.Open() ; Open control
 Local $sPLC = DllStructCreate("USHORT"), $ptemp
 $ptemp = DllStructGetPtr($sPLC)
 $iRet=$o_Control.GetDevice($device, $ptemp)
 $i_ReturnData = DllStructGetData($sPLC,1) 
 msgbox(0,"Error Flag: ", $iRet)
 $o_Control.Close() ; Close control
 Return $i_ReturnData
EndFunc ;==>GetDevice

Share this post


Link to post
Share on other sites

I tried a lot but there were error only. I'll give up...

Maybe DllCall() ?

I don't understand the Excel VBA is OK, the VBScript is OK but Auto It not...

What were the errors?

I can't test the code since I don't know what else you are using, but I'm interested to know how this works so I could use it myself on a Mitsubishi PLC.


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.

Share this post


Link to post
Share on other sites

There are two types of errors:

1. When I use the function of the MX object: GetDevice("char", "ptr").

So this way the Autoit compiler gives me this error constantly:

" ==> The requested action with this object has failed. "

I've tried already different types pointer struct: int, long, short, ushort etc.

2. When I use without pointer: GetDevice("char", "int") /or long, short, ushort etc./.

There is no error (@Error = 0), but no return value too, "null".

After I installed the MX Components, I found sample progs in the install directory.

There are for Excel, Access, Vbscript, VB and C++. I could try the first three type

and all were good. I don't know VB and C++ so I tried with Autoit but no success.

My first thought was the Autoit cannot give value for a variable without "=".

What were the errors?

I can't test the code since I don't know what else you are using, but I'm interested to know how this works so I could use it myself on a Mitsubishi PLC.

Share this post


Link to post
Share on other sites

There are two types of errors:

1. When I use the function of the MX object: GetDevice("char", "ptr").

So this way the Autoit compiler gives me this error constantly:

" ==> The requested action with this object has failed. "

I've tried already different types pointer struct: int, long, short, ushort etc.

2. When I use without pointer: GetDevice("char", "int") /or long, short, ushort etc./.

There is no error (@Error = 0), but no return value too, "null".

After I installed the MX Components, I found sample progs in the install directory.

There are for Excel, Access, Vbscript, VB and C++. I could try the first three type

and all were good. I don't know VB and C++ so I tried with Autoit but no success.

My first thought was the Autoit cannot give value for a variable without "=".

The C++ example miight be easier and closer to the way AutoIt works. Can you post that or pm it to me? Or tell me where I can get the MX Components.

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.

Share this post


Link to post
Share on other sites

The C++ example miight be easier and closer to the way AutoIt works. Can you post that or pm it to me? Or tell me where I can get the MX Components.

I'll attach the C++ sample as soon as possible (I'm not at work now).

With using the Melsoft MX Component you can connect to the PLC through an active-x component.

I use this software at my company, it's not mine (I don't have the install CD).

But I can send you the DLL files (maybe you need register them ?).

Or purchase: Essential Automation

Another: the device write is OK, it works well:

WriteDevice(1,"M7000",1)

Func WriteDevice($Logical_station, $Device, $Value)

 Local $o_Control = ObjCreate("ActMulti.ActEasyIF")

  With $o_Control
       .ActLogicalStationNumber = $Logical_station
       .Open()
       .WriteDeviceRandom($Device,1,$Value)
       .Close()
  EndWith

EndFunc

Share this post


Link to post
Share on other sites

I'll attach the C++ sample as soon as possible (I'm not at work now).

With using the Melsoft MX Component you can connect to the PLC through an active-x component.

I use this software at my company, it's not mine (I don't have the install CD).

But I can send you the DLL files (maybe you need register them ?).

Or purchase: Essential Automation

Another: the device write is OK, it works well:

WriteDevice(1,"M7000",1)

Func WriteDevice($Logical_station, $Device, $Value)

 Local $o_Control = ObjCreate("ActMulti.ActEasyIF")

  With $o_Control
       .ActLogicalStationNumber = $Logical_station
       .Open()
       .WriteDeviceRandom($Device,1,$Value)
       .Close()
  EndWith

EndFunc

I didn't know well: the sample is VC, not C++

I attached it.

vc_sample.zip

Share this post


Link to post
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
Sign in to follow this  
Followers 0