Machsupport Forum
Mach Discussion => Mach4 General Discussion => Topic started by: gorf23 on November 10, 2017, 09:45:33 PM
-
I have a script that is calling mc.mcCntlGcodeExecuteWait at least that where the problem seems to be..
if i enable mach4 and load the script with the script editor the script runs fine no errors the Dro moves to the set value and stops...
now if I try to use the script with a button press the Dro doesn't move and mach4 locks up
So I can't seem to debug it in the editor I get no errors when I step thought the code or even if I run it. only error's when I use the code with a button press..
Is there certain code you cannot use with a button press in mach4.. I am creating a dialog box with some radio buttons and text input...
Thanks gary
-
Perhaps post the code so it can be checked...
DazTheGas
-
Here's the code daz have to forgive me i'm new to lua so there is a lot of extra junk in there while I was testing...
like I said just seems to crash when run from a button press script
Gary
[-------------------------------------------------------------------------=---
-- Name: Mach4 caclulate
--
-- Author: Gary
-------------------------------------------------------------------------=---
inst = mc.mcGetInstance()
function GetNextID()
next_id = next_id+1
return next_id
end
WhatAxis = {
XaxisButton = { 'X' , "Motor0", 0 },
YaxisButton = { 'Y' , "Motor1", 1 },
ZaxisButton = { 'Z' , "Motor2", 2 },
AaxisButton = { 'A' , "Motor3", 3 },
BaxisButton = { 'B' , "Motor4", 4 },
CaxisButton = { 'C' , "Motor5", 5 },
}
next_id = 0
-- IDs of the controls in the dialog
ID_AUTOCALCUATE_BUTTON = GetNextID() -- NOTE: We use the fact that the textctrl ids
ID_AUTOCALCUATE_TEXTCTRL = GetNextID()
ID_ABOUT_BUTTON = GetNextID()
ID_CLOSE_BUTTON = GetNextID()
ID_SAVE_TEXTCTR = GetNextID()
ID_SAVE_BUTTON = GetNextID()
ID_ABORT_TEXTCTR = GetNextID()
ID_ABORT_BUTTON = GetNextID()
ID__MAX = GetNextID() -- max of our window ids
WhereAreWe = 0
-- Create the dialog
dialog = wx.wxDialog(wx.NULL, wx.wxID_ANY, "Mach4 Auto Caculate Motor Counts Per Units",
wx.wxDefaultPosition, wx.wxDefaultSize)
-- Create a wxPanel to contain all the buttons
panel = wx.wxPanel(dialog, wx.wxID_ANY)
-- Layout all the buttons using wxSizers
local mainSizer = wx.wxBoxSizer(wx.wxVERTICAL)
local staticBox = wx.wxStaticBox(panel, wx.wxID_ANY, "Axis Calculater")
local staticBoxSizer = wx.wxStaticBoxSizer(staticBox, wx.wxVERTICAL)
local flexGridSizer = wx.wxFlexGridSizer( 3, 3, 5, 0 )
local radioGridSizer = wx.wxFlexGridSizer( 3,6,0, 0 )
flexGridSizer:AddGrowableCol(1, 0)
-- Make a function to reduce the amount of duplicate code.
function AddConverterControl(name_string, button_text, textCtrlID, buttonID)
local staticText = wx.wxStaticText( panel, wx.wxID_ANY, name_string)
local textCtrl = wx.wxTextCtrl( panel, textCtrlID, "00.00", wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxTE_PROCESS_ENTER )
local button = wx.wxButton( panel, buttonID, button_text)
flexGridSizer:Add( staticText, 0, wx.wxALIGN_CENTER_VERTICAL+wx.wxALL+wx.wxST_NO_AUTORESIZE, 5 )
flexGridSizer:Add( textCtrl, 0, wx.wxGROW+wx.wxALIGN_CENTER+wx.wxALL, 5 )
flexGridSizer:Add( button, 0, wx.wxGROW+wx.wxALIGN_CENTER+wx.wxALL, 5 )
return textCtrl, button, staticText
end
CalculateTextCtrl, Calculate, staticTextCTRL = AddConverterControl("Enter Distabce to move Axis ", "Travel Diatance", ID_AUTOCALCUATE_TEXTCTRL, ID_AUTOCALCUATE_BUTTON)
SaveTextCtrl, Savebutton, SavestaticTextCTRL = AddConverterControl("Save ", "Save Units", ID_SAVE_TEXTCTR, ID_SAVE_BUTTON)
AbortTextCtrl, Abortbutton, AbortstaticTextCTRL = AddConverterControl("Abort ", "Abort Save", ID_ABORT_TEXTCTR, ID_ABORT_BUTTON)
flexGridSizer:Hide(Abortbutton)
flexGridSizer:Hide(Savebutton)
flexGridSizer:Hide(SavestaticTextCTRL)
flexGridSizer:Hide(AbortstaticTextCTRL)
flexGridSizer:Hide(SaveTextCtrl)
flexGridSizer:Hide(AbortTextCtrl)
staticBoxSizer:Add( flexGridSizer, 0, wx.wxGROW+wx.wxALIGN_CENTER+wx.wxALL, 5 )
mainSizer:Add( staticBoxSizer, 1, wx.wxGROW+wx.wxALIGN_CENTER+wx.wxALL, 5 )
local buttonSizer = wx.wxBoxSizer( wx.wxHORIZONTAL )
local aboutButton = wx.wxButton( panel, ID_ABOUT_BUTTON, "&About")
local closeButton = wx.wxButton( panel, ID_CLOSE_BUTTON, "E&xit")
buttonSizer:Add( aboutButton, 0, wx.wxALIGN_CENTER+wx.wxALL, 5 )
buttonSizer:Add( closeButton, 0, wx.wxALIGN_CENTER+wx.wxALL, 5 )
mainSizer:Add( buttonSizer, 0, wx.wxALIGN_CENTER+wx.wxALL, 5 )
function AddRadioControl(name_string)
local ID = GetNextID()
local sizer = wx.wxBoxSizer(wx.wxHORIZONTAL )
local Ctrl = wx.wxRadioButton( panel, ID, name_string, wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxTE_PROCESS_ENTER ,wx.wxTextValidator(wx.wxFILTER_NUMERIC))
radioGridSizer:Add( sizer, 0, wx.wxALIGN_CENTER_VERTICAL+wx.wxALL+wx.wxALIGN_RIGHT, 5)
radioGridSizer:Add( Ctrl, 0, wx.wxGROW+wx.wxALIGN_CENTER+wx.wxALL+wx.wxALIGN_LEFT, 5)
return Ctrl, ID
end
-- make the check boxs
--m_Test = AddCheckControl("Check me")
X_Axis = AddRadioControl("X Axis")
Y_Axis = AddRadioControl("Y Axis")
Z_Axis = AddRadioControl("Z Axis")
A_Axis = AddRadioControl("A Axis")
B_Axis = AddRadioControl("B Axis")
C_Axis = AddRadioControl("C Axis")
--mainSizer:Add( flexGridSizer, 0, wx.wxALIGN_CENTER+wx.wxALL, 2 )
staticBoxSizer:Add( radioGridSizer, 0, wx.wxGROW+wx.wxALIGN_CENTER+wx.wxALL, 5 )
panel:SetSizer( mainSizer )
mainSizer:SetSizeHints( dialog )
--Check what radio button is clicked if any and return all the axis info needed or nul
function CheckAxisButton()
if X_Axis:GetValue() == true then
return WhatAxis.XaxisButton[1], WhatAxis.XaxisButton[2], WhatAxis.XaxisButton[3]
elseif Y_Axis:GetValue() == true then
return WhatAxis.YaxisButton[1], WhatAxis.YaxisButton[2], WhatAxis.YaxisButton[3]
elseif Z_Axis:GetValue() == true then
return WhatAxis.ZaxisButton[1], WhatAxis.ZaxisButton[2], WhatAxis.ZaxisButton[3]
elseif A_Axis:GetValue() == true then
return WhatAxis.AaxisButton[1], WhatAxis.AaxisButton[2], WhatAxis.AaxisButton[3]
elseif B_Axis:GetValue() == true then
return WhatAxis.BaxisButton[1], WhatAxis.BaxisButton[2], WhatAxis.BaxisButton[3]
elseif C_Axis:GetValue() == true then
return WhatAxis.CaxisButton[1], WhatAxis.CaxisButton[2], WhatAxis.CaxisButton[3]
end
return nul
end
function AxisMove()
--wx.wxMessageBox("Here = "..WhereAreWe)
-- CalculateTextCtrl:SetValue("00.000")
-- staticTextCTRL:SetLabel("Enter Distance to move Axis")
-- Calculate:SetLabel("Travel Diatance")
AxisLetter, AxisName, AxisNumber = CheckAxisButton()
if AxisLetter == nul then return
end
AxisEnteredDistance = CalculateTextCtrl:GetValue() --Distance to move the axis
-- wx.wxMessageBox( 'Distanced = ' .. AxisEnteredDistance )
mc.mcAxisSetPos(inst, AxisNumber, 0); --"Zero Dro (0 is x, 1 y, and so on)
mc.mcCntlGcodeExecuteWait(inst, 'G01 '.. AxisLetter .. AxisEnteredDistance..'F4'); --G31. Machine will stop on probe strike or go to distance set
return 1
end
function AxisCalculate(AxisEnteredDistance)
--distance, rc = mc.mcAxisGetPos(inst ,0); --"Zero Z" (0 is x, 1 y, and so on)
--Steps, rc = mc.mcProfileGetDouble(inst,"Motor0", "CountsPerUnit", 0)
--Steps, rc = mc.mcProfileGetDouble(inst,"Motor0", "CountsPerUnit", 2000)
AxisDistanceTraveled = CalculateTextCtrl:GetValue()
--local distance = distance_travled
Steps = 1800
--local dro_pos = Distance_to_travel
local traveled = (AxisEnteredDistance * Steps)
local NewUnits = (traveled / AxisDistanceTraveled)
wx.wxMessageBox('Newsteps = ' ..tostring(NewUnits) .. '\nDistanced steps travled = ' .. tostring(AxisDistanceTraveled))
return NewUnits
end
function SaveUnits()
staticTextCTRL:SetLabel("Save units")
-- CalculateTextCtrl:SetValue("0.0023 ")
Calculate:SetLabel("Save")
--flexGridSizer:Hide(button)
AxisDistanceTraveled = CalculateTextCtrl:GetValue() --Distance to move the axis
wx.wxMessageBox( "Travel Distance = " .. AxisEnteredDistance .. "\nDistance Treveled = " ..AxisDistanceTraveled)
return 2
end
function AbortSaveUnits()
staticTextCTRL:SetLabel("Abort units")
CalculateTextCtrl:SetValue("0.000 ")
Calculate:SetLabel("Abort") --Distance to move the axis
HideItems()
return 3
end
function HideItems()
flexGridSizer:Hide(Abortbutton)
flexGridSizer:Hide(Savebutton)
flexGridSizer:Hide(SavestaticTextCTRL)
flexGridSizer:Hide(AbortstaticTextCTRL)
flexGridSizer:Hide(SaveTextCtrl)
flexGridSizer:Hide(AbortTextCtrl)
--CalculateTextCtrl:SetValue(" ")
--Calculate:SetLabel("Save")
return 0
end
function ShowItems()
flexGridSizer:Hide(Abortbutton)
flexGridSizer:Hide(Savebutton)
flexGridSizer:Hide(SavestaticTextCTRL)
flexGridSizer:Hide(AbortstaticTextCTRL)
flexGridSizer:Hide(SaveTextCtrl)
flexGridSizer:Hide(AbortTextCtrl)
--CalculateTextCtrl:SetValue(" ")
--Calculate:SetLabel("Save")
--CalculateTextCtrl:SetValue("0.0025 ")
return 0
end
--HideItems()
-- ---------------------------------------------------------------------------
-- Connect a handler for pressing enter in the textctrls
dialog:Connect(wx.wxID_ANY, wx.wxEVT_COMMAND_TEXT_ENTER,
function(event)
-- Send "fake" button press to do calculation.
-- Button ids have been set to be -1 from textctrl ids.
dialog:ProcessEvent(wx.wxCommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, event:GetId()-1))
end)
-- ---------------------------------------------------------------------------
-- Connect a central event handler that responds to all button clicks.
-- NOTE: Since we Connect() the about and close buttons after this they will be
-- called first and unless we call event:Skip() in their handlers the
-- events will never reach this function. Therefore we don't need to
-- check that the ids are only from buttons.
dialog:Connect(wx.wxID_ANY, wx.wxEVT_COMMAND_BUTTON_CLICKED,
function(event)
-- NOTE: A wxID_CANCEL event is sent when the close button on the
-- dialog is pressed.
if event:GetId() >= ID__MAX then
event:Skip()
return
end
-- We know that the textctrl window ids are +1 from the button ids
Number = tonumber(dialog:FindWindow(event:GetId()+1):DynamicCast("wxTextCtrl"):GetValue())
if Number == nil then
wx.wxMessageBox("The input is invalid, enter a number.",
"Error!",
wx.wxOK + wx.wxICON_EXCLAMATION + wx.wxCENTRE,
dialog)
else
-- Create a "case" type statement
local AutoCalculate = {
[ID_AUTOCALCUATE_BUTTON] = function() if (WhereAreWe == 0 and CheckAxisButton() ~= nul) then AxisMove()
staticTextCTRL:SetLabel("Enter Distance Axis has Traveled")
Calculate:SetLabel("Calculate")
CalculateTextCtrl:SetValue("") return 1
elseif (WhereAreWe == 1 and CheckAxisButton() ~= nul) then NewUnits = AxisCalculate(AxisEnteredDistance)
CalculateTextCtrl:SetValue(tostring(NewUnits))
Calculate:SetLabel("Save")
staticTextCTRL:SetLabel(" New Motor Counts Per Units = ".."\nDistance= " .. AxisEnteredDistance.. " Distance Traveled= " ..AxisDistanceTraveled)
return 2
elseif (WhereAreWe == 2 and CheckAxisButton() ~= nul) then SaveUnits()
staticTextCTRL:SetLabel("Enter Distance to move Axis")
CalculateTextCtrl:SetValue("00.00")
Calculate:SetLabel("Travel Diatance") return 0
end
end
}
-- call the "case" statement
WhereAreWe = AutoCalculate[event:GetId()]()
end
end)
-- ---------------------------------------------------------------------------
-- Attach an event handler to the Close button
dialog:Connect(ID_CLOSE_BUTTON, wx.wxEVT_COMMAND_BUTTON_CLICKED,
function(event) dialog:Destroy() end)
dialog:Connect(wx.wxEVT_CLOSE_WINDOW,
function (event)
dialog:Destroy()
event:Skip()
end)
-- ---------------------------------------------------------------------------
-- Attach an event handler to the About button
dialog:Connect(ID_ABOUT_BUTTON, wx.wxEVT_COMMAND_BUTTON_CLICKED,
function(event)
wx.wxMessageBox("Mach4 Axis Calulate Motor Units.\n",
"\n",
wx.wxOK + wx.wxICON_INFORMATION,
dialog)
end)
dialog:Connect(ID_SAVE_BUTTON, wx.wxEVT_COMMAND_BUTTON_CLICKED,
function(event)
SaveUnits()
end)
dialog:Connect(ID_ABORT_BUTTON, wx.wxEVT_COMMAND_BUTTON_CLICKED,
function(event)
AbortSaveUnits()
end)
-- ---------------------------------------------------------------------------
-- Send a "fake" event to simulate a button press to update the textctrls
--dialog:ProcessEvent(wx.wxCommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED,ID_AUTOCALCUATE_BUTTON))
-- ---------------------------------------------------------------------------
-- Centre the dialog on the screen
dialog:Centre()
-- Show the dialog
dialog:Show(true)
-- Call wx.wxGetApp():MainLoop() last to start the event loop,
-- MainLoop is already running or will be started.
wx.wxGetApp():MainLoop()
/code]script...
-
The problem you have is as you say is the mc.mcCntlGcodeExecuteWait, there is no bug in the command. one thing you have to remember is when using mc.mcCntlGcodeExecuteWait within the gui you are also making the gui wait so it then becomes unresponsive. mc.mcCntlGcodeExecute runs the script fine as it doesnt block the gui. If you change your FeedRate of F4 to say F500 then set your travel distance to say just 1 and select X using the mc.mcCntlGcodeExecuteWait
mc.mcCntlGcodeExecuteWait(inst, 'G01 '.. AxisLetter .. AxisEnteredDistance..'F500')
you will find this will run the script fast enough that it doesnt make the gui unresponsive proving the mc.mcCntlGcodeExecuteWait is working.
DazTheGas
-
Thanks daz
I tried mc.mcCntlGcodeExecuteWaitwith the feed rate stepped up to 500 then 1000 didn't make a difference still crashed
but mc.mcCntlGcodeExecute did work so I guess I will have to go with what works...
Thanks again
Gary
-
Have another problem have a check in code for cycle start, if off I turn on then of after mc.mcCntlGcodeExecute
Problem seem to be it runs right though and shuts of cycle start before the axis starts to move so endless there is
another way to do it, then if I want to check for cycle start and turn on and off I would then have to use mc.mcCntlGcodeExecuteWait
but that crashes mach4..
any other ideas ?
Thanks gary
-
Have another problem have a check in code for cycle start
I have been all over the script and cannot find anything to do with cycle start??? the script confuses me in that it looks like its part of the dialog example from github and you are trying to do an axis steps optimizer but yet there are comments about G31 which is for probeing. If it is a steps calculator there is a basic one within the wizards.
DazTheGas
-
Sorry Daz
there is no cycle start it I may have copied some code from another one of my scripts
its suppose to be to turn enable on or off not cycle start....
The script seem to run fine turning on or off enable is a problem I am thinking the code is running to fast, it will turn it on if its turned off before it runs the
mc.mcCntlGcodeExecute(inst, 'G90 G0'..AxisLetter .. AxisEnteredDistance..'F500') and I call it again to turn it off ii wasn't turned on when the script
was first run but like I said I think without being able to run mc.mcCntlGcodeExecuteWait(inst, 'G90 G0'..AxisLetter .. AxisEnteredDistance..'F500') the
script runs so fast when it hit the code to turn off the enable it doesn't turn it off, what I am looking to get working is when
mc.mcCntlGcodeExecute(inst, 'G90 G0'..AxisLetter .. AxisEnteredDistance..'F500') is run it doesn't continue running thought the script..
I would like it to finish moving the axis to the entered distance then continue from there.
The way its running when it runs the mc.mcCntlGcodeExecute(inst, 'G90 G0'..AxisLetter .. AxisEnteredDistance..'F500') then right away its on to the next
function changing the buttons and text asking for the next input info..
Does this make better sense?
Thanks gary
-
Hi Daz..
I think I found away to do it but I will have to, most likely rewrite the bulk of the code
I ended up trying to use coroutine .. I ran mc.mcCntlGcodeExecute then in a function button event
I put a while do loop and run local pos = mc.mcAxisGetPos(inst, 0) in the loop till the dro is at the
correct distance,
The script seems to run fine with a button press no more lockup or crashes so I guess the GUI is fine
with the coroutine script... but guess I will have to rewrite most of the script...
Gary