Machsupport Forum
Mach Discussion => Mach4 General Discussion => Topic started by: thespindoctor on December 18, 2016, 09:54:39 PM
-
i note in the screen for probing for Measure Z that Prb.SingleSurfZ is the function called but in
the probing module it is called Probing.SingleSurfZ How can that be?
THanks
Keith
-
Prb is a derived class (or module for lua) of Probing.
when requiring a module the module name is replaced by what we tell it, in this case its prb, so although you will see Prb.SingleSurfZ its actually running Probing.SingleSurfZ.
seems weird but look at it this way, lets take a module that creates a button called btnCreate and within that module there is a function btnCreate.createButton(coords etc)
we need 3 buttons so we can do this
local btn1 = require btnCreate
local btn2 = require btnCreate
local btn3 = require btnCreate
btn1.createButton(coords etc)
btn2.createButton(coords etc)
btn3.createButton(coords etc)
so btn1 -2 and 3 becomes derived classes/modules of btnCreate.
DazTheGas
-
Ok, so to call a function in a module from a script, we would be correct for instance to call Probing.SingleSurfZ in the probing module to use mcProbing.SingleSurfZ in a screen button? but here they have used require to switch mcProbing to prb.
Looking at mcTouchOff.lua module, the functions are named without a probing or Touch prefix. This is confusing. function TouchOffZNeg0 would be called from a button script by mcTouchOff.TouchOffZNeg0 Or we could use
local TO = require "mcTouchOff"
then call TO.TouchOffZNeg0 in the script
Is that correct?
Appreciate the help!!
-
Daz, the module has a name like mcTouchOff.lua Within the module are functions with names. In the Probing module they put Probing. in front of every function. In the mcTouchOff.lua module they just name the functions without a prefix. What is the proper way to call a function in a module versus calling a function in my own script like load script or plc script.
Thanks
Keith
-
Let me try to help and hopefully Daz will correct any mistakes I make.
The reason mcTouchOff's functions do not have a prefix (mcTouchOff.) is because none of its functions are called or available for use from outside the module. The only one that is, is the Dialog which is called from outside the module. It opens the dialog or user interface. Any other functions are only called form it. Not that the functions could not be used from outside the UI but from a support stand point its not something we wanted to do.
I did this example a few days ago. Its a very simple module that simply pops up a message box and displays the message parameter you pass it. You have 5 things to do to see all of.
1) Create and save a module.
2) Load the module with the screen so it can be used form screen elements.
3) Load the module with the macros so it can be called from macros (Mcodes).
4) Call the module passing it your message from a button.
5) Call the module passing it your message form a custom Mcode (m110 in the example).
Play with it. Break it, fix it, add to it and have some fun.
--This is the mcUserScript.lua module that goes in the modules folder
local mcUserScript = {}
function mcUserScript.UserMessage(Message)
if (Message == nil) then --No message was passed
Message = "No message passed" --If no message is passed this will be the default message
end
wx.wxMessageBox(Message)
end
return mcUserScript -- Module End
--This is what loads the module above.
--Add this to the modules load section of the screen load script so you can call its functions from buttons on the screen.
--Add this to the load_modules.mcs file in the macros folder of the profile that will be using it so you can call its functions from M codes.
package.loaded.mcUserScript = nil
us = require "mcUserScript"
--Put this in a buttons clicked script and when you click it a message box will pop up that says... No message passed
us.UserMessage() --This is not passing a message for the Message parameter so the message will be the default
--m110 goes in the macros folder of the profile that will be using it
function m110()
us.UserMessage("This is my message")
end
if (mc.mcInEditor() == 1) then
m110()
end
-
Nice example ;-)
Simple way to put it is Private and Public Functions
No prefix = Private function being used internally by the module and cannot be run from outside of the script
With prefix = Public function that can be run/called externally using the prefix you gave it during requiring.
DazTheGas
-
That helps very much. I will work with it. As I have said in the past, so much to learn! But once learned, so much power over the machine! Satisfying when it works!
Keith
-
I made a lua file in the mach4hobby/modules directory called mcUserScript.lua containing the script below--
local mcUserScript = {}
function mcUserScript.UserMessage(Message)
if (Message == nil) then --No message was passed
Message = "No message passed" --If no message is passed this will be the default message
end
wx.wxMessageBox(Message)
end
return mcUserScript -- Module End
Flummoxed right off the bat...
Keith
Then when mach4 loads there is an error that no such module exists
-
You will need to make sure the path to the module is included before the require, this is already set in the screen load script but still ok to put again
local profile = mc.mcProfileGetName(inst)
local path = mc.mcCntlGetMachDir(inst)
package.path = path .. "\\Profiles\\" .. profile .. "\\Modules\\?.lua;" .. path .. "\\Modules\\?.lua;"
when using require it will look in these path locations for the module
DazTheGas
-
Got it now. I had mc.UserScript instead of mcUserScript
Thanks!
-
I have it working in a screen button .
Now I don't know how to get it to work in the m110 macro m110 in mdi causes an error expecting a number
Tired to make a file load.modules.mcs in the macros directory of the profile containing
local profile = mc.mcProfileGetName(inst)
local path = mc.mcCntlGetMachDir(inst)
package.path = path .. "\\Profiles\\" .. profile .. "\\Modules\\?.lua;" .. path .. "\\Modules\\?.lua;"
package.loaded.mcUserScript = nil
us = require "mcUserScript"
-
Where are you defining the inst variable your using in the first 2 calls?
inst = mc.mcGetInstance()
-
Change the filename to load_modules.mcs
DazTheGas
-
Changed file to load_modules.mcs
Added inst = mc.mcGetInstance() to load_modules.mcs
Still not running with m110 in MDI
-
This is where I have place files
C:\Mach4Hobby\Modules\mcUserScript.mcs
local mcUserScript = {}
function mcUserScript.UserMessage(Message)
if (Message == nil) then --No message was passed
Message = "No message passed" --If no message is passed this will be the default message
end
wx.wxMessageBox(Message)
end
return mcUserScript -- Module End
both the m110.mcs and load_modules.mcs goes in your profiles own macro directory
load_modules.mcs
local inst = mc.mcGetInstance()
local profile = mc.mcProfileGetName(inst)
local path = mc.mcCntlGetMachDir(inst)
package.path = path .. "\\Profiles\\" .. profile .. "\\Modules\\?.lua;" .. path .. "\\Modules\\?.lua;"
package.loaded.mcUserScript = nil
us = require "mcUserScript"
m110.mcs
function m110()
us.UserMessage("This is my message from m110")
end
if (mc.mcInEditor() == 1) then
m110()
end
This is working within the mdi no problem but still debugging why its not working when called from within gcode, my bet is its something to do with the messagebox not being able to show in the gui from gcode. when running gcode its run within another lua instance that does not have access to the lua instance that is within the gui.
DazTheGas
-
Yep changing the code to below without the messagebox worked fine using mc.mcCntlSetLastError(inst,Message) instead
local mcUserScript = {}
local inst = mc.mcGetInstance()
function mcUserScript.UserMessage(Message)
if (Message == nil) then --No message was passed
Message = "No message passed" --If no message is passed this will be the default message
end
--wx.wxMessageBox(Message)
mc.mcCntlSetLastError(inst,Message)
end
return mcUserScript -- Module End
with this now working it should give you something to play with ;-)
DazTheGas
-
Thanks, it works for me.
I appreciate the follow through. Learning!
Keith
-
Only difference is
C:\Mach4Hobby\Modules\mcUserScript.mcs should be
C:\Mach4Hobby\Modules\mcUserScript.lua ??
Thanks
Keith ???
-
When I create a gcode file with one line m110 it bombs out the gui?
-
Gcode FILE with
G0 X0Y0
M110
G0 X1Y0
works fine
-
Works fine in all instances button script, g code, mfunction, even with wx.wxMessageBox(Message)
Keith
-
Great! Can you give us a summary of why that wasn't the case on the first try? This helps make adjustments to samples, docs, etc.
-
Next post is correct I believe
-
I think your original code was successful except for the filename change to load_modules.mcs from load.modules.mcs
Daz suggestions changed the message method and
C:\Mach4Hobby\Modules\mcUserScript.mcs should be
C:\Mach4Hobby\Modules\mcUserScript.lua
Changes from Daz quote made below
This is where I have placed files
C:\Mach4Hobby\Modules\mcUserScript.lua
local mcUserScript = {}
function mcUserScript.UserMessage(Message)
if (Message == nil) then --No message was passed
Message = "No message passed" --If no message is passed this will be the default message
end
--wx.wxMessageBox(Message)
mc.mcCntlSetLastError(inst,Message)
end
return mcUserScript -- Module End
both the m110.mcs and load_modules.mcs goes in your profiles own macro directory
load_modules.mcs
local inst = mc.mcGetInstance()
local profile = mc.mcProfileGetName(inst)
local path = mc.mcCntlGetMachDir(inst)
package.path = path .. "\\Profiles\\" .. profile .. "\\Modules\\?.lua;" .. path .. "\\Modules\\?.lua;"
package.loaded.mcUserScript = nil
us = require "mcUserScript"
m110.mcs
function m110()
us.UserMessage("This is my message from m110")
end
if (mc.mcInEditor() == 1) then
m110()
end
DazTheGas
[/quote]
-
I am confused. Unless I am misunderstanding you, in the script I originally posted both of those are correct.
I think your original code was successful except for the filename change to load_modules.mcs from load.modules.mcs
C:\Mach4Hobby\Modules\mcUserScript.mcs should be
C:\Mach4Hobby\Modules\mcUserScript.lua
The reason I point this out is because it really shines a light on the old saying, garbage in is garbage out. To us humans those are very simple mistakes and easily overlooked. But to a computer your talking about different planets all together. I plan on using this as an example many will see over time and I want to make sure it is 100% accurate. I know it works here, I have tested it many times but if exactly what I posted does not work on your end I need to figure out why.
-
Those were my mistakes and happened because I did not have the file naming conventions correct. I think it is correct now. The way Daz posted it was easier for me to see where to save each file type and how to name each file. I will proof it again tonight after the first day
of skiing Copper Mountain now. Not sure why Daz had trouble in a G code file.
Keith
-
A big oooooops from me ??? ??? ??? ??? :o :o :'(, just had a rather interesting debug session and yep all works well.
It all boils down to forgetting what you did previously, I already have a macro functions file in my macro directory and forgot so by adding the load_modules.mcs file overwrites my "package.path" with the one containing the .lua extension.
my package.path normally consists of both mcs and lua
package.path = path .. "\\Profiles\\" .. profile .. "\\Modules\\?.lua;" .. path .. "\\Modules\\?.lua;"
package.path = package.path ..path .. "\\Profiles\\" .. profile .. "\\Modules\\?.mcs;" .. path .. "\\Modules\\?.mcs;"
DazTheGas
-
Awesome feedback guys! Thanks!
Have fun skiing! Makes me jealous. ;D
Thats a good find Daz. That could have taken a very long time to find especially if you did not have intimate knowledge of your setup. No shame in it either. This is what happens. To me it is another perfect example. This is why once folks start customizing any little part, they own it all and have to. This is why we ask all testing be done with all things default. Now with this example no way to do it because we are helping to customize but folks need to always start with a profile (copied) that has all things default, change a little and test. That way its easy to back out till you find the error if you run into one.
It also lets folks see that even the best run into issues at times and just have to dig in and figure out whats going on. Sometimes knowing what doesn't work is as valuable as knowing what does. I remember a bit of code stumping me not so long ago. The problem............ inst was not defined. Another fella spotted it right off. Obviously I understand its importance but being imperfect comes natural. ;D
I may be wrong but I think topics like this one will be priceless for those starting out and willing to follow.