Machsupport Forum
Mach Discussion => Mach4 General Discussion => Topic started by: pjcevallos@gmail.com on March 09, 2024, 08:37:05 PM
-
Hi
I have been trying to debug a code without success for the PLC script (See below). I want to record X,Y,Z vs time in an external text file activated by an output that will start data acquisition of another hardware.
I can successfully monitor the values I want in registers. However, I get an error as soon as I want to use
file = io.open(MyFile, "a") --open the file in append mode
,
--attempt to index a nil value (global 'file')
--strack traceback
-- in function 'Mach_PLC_script'
I can open, write, save, and close files in Macros, but that is inconvenient.
Does any one have any idea how to approach this problem or what I am doing wrong?
Code that is added to the PLC:
-------------------------------------------------------
-- position Data
-------------------------------------------------------
local val_x = mc.mcAxisGetPos(inst, mc.X_AXIS) -- get X position
local val_y= mc.mcAxisGetPos(inst, mc.Y_AXIS) -- get Y position
WriteRegister("X_pos",val_x) -- to monitor in register diagnostics ok
WriteRegister("Y_pos",val_y) -- to monitor in register diagnostics ok
local LoadCellSignal = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT9 ) -- monitor output 9 activated by macro
local LoadCellSignalState = mc.mcSignalGetState(LoadCellSignal)
if (LoadCellSignalState == 1) then -- if output 9 is activated
local hregTime_LC = mc.mcRegGetHandle(inst, "iRegs0/Time_LC") -- get register Time_LC = 0
local LoadCellTime= mc.mcRegGetValue(hregTime_LC)
if (LoadCellTime==0) then
local Path = GetRegister(Layer_path) -- get File path from register
local MyFile = wx.wxGetCwd() .. Path -- define the file path in Mach4
file = io.open(MyFile, "a") -- open file in append mode
end
LoadCellTime = LoadCellTime+0.05 - follow PLC cycle time as sample rate
WriteRegister("Time_LC",LoadCellTime) -- monitor in register ok
local text = string.format ("%.4f, %.4f, %.4f \n", val_x, val_y, LoadCellTime );
file:write (text ) --Write the Gcode file
file:flush (MyFile) --Save written data
file:close (MyFile) --Close file
end
-
I think you should only close the file when you want to stop recording the data i.e. when output 9 turns off. If you close it after every time you write data you will need to open the file each time, but you are only opening it once when output 9 turns on. Something like this...
-------------------------------------------------------
-- position Data
-------------------------------------------------------
local val_x = mc.mcAxisGetPos(inst, mc.X_AXIS) -- get X position
local val_y= mc.mcAxisGetPos(inst, mc.Y_AXIS) -- get Y position
WriteRegister("X_pos",val_x) -- to monitor in register diagnostics ok
WriteRegister("Y_pos",val_y) -- to monitor in register diagnostics ok
local LoadCellSignal = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT9 ) -- monitor output 9 activated by macro
local LoadCellSignalState = mc.mcSignalGetState(LoadCellSignal)
if (LoadCellSignalState == 1) then -- if output 9 is activated
local hregTime_LC = mc.mcRegGetHandle(inst, "iRegs0/Time_LC") -- get register Time_LC = 0
local LoadCellTime= mc.mcRegGetValue(hregTime_LC)
if (LoadCellTime==0) then
local Path = GetRegister(Layer_path) -- get File path from register
local MyFile = wx.wxGetCwd() .. Path -- define the file path in Mach4
file = io.open(MyFile, "a") -- open file in append mode
end
LoadCellTime = LoadCellTime+0.05 - follow PLC cycle time as sample rate
WriteRegister("Time_LC",LoadCellTime) -- monitor in register ok
local text = string.format ("%.4f, %.4f, %.4f \n", val_x, val_y, LoadCellTime );
file:write(text ) --Write the Gcode file
file:flush() --Save written data
else
if (file ~= nil) then
file:close() --Close file
end
end
[/code
-
Hi swiftyJ
Thanks for your reply, However, It also doesn't work showing the same error.
it thinks "file" is a variable.
If I add a "local" before variable, that line is not the error, but then the error goes to:
- file:write
- if file:write (text) commented, file:close()
I wonder if the PLC script can open and write files.
-
Try this:
-------------------------------------------------------
-- position Data
-------------------------------------------------------
local val_x = mc.mcAxisGetPos(inst, mc.X_AXIS) -- get X position
local val_y= mc.mcAxisGetPos(inst, mc.Y_AXIS) -- get Y position
WriteRegister("X_pos",val_x) -- to monitor in register diagnostics ok
WriteRegister("Y_pos",val_y) -- to monitor in register diagnostics ok
local LoadCellSignal = mc.mcSignalGetHandle(inst, mc.OSIG_OUTPUT9 ) -- monitor output 9 activated by macro
local LoadCellSignalState = mc.mcSignalGetState(LoadCellSignal)
if (LoadCellSignalState == 1) then -- if output 9 is activated
local hregTime_LC = mc.mcRegGetHandle(inst, "iRegs0/Time_LC") -- get register Time_LC = 0
local LoadCellTime= mc.mcRegGetValue(hregTime_LC)
if (LoadCellTime==0) then
local Path = GetRegister(Layer_path) -- get File path from register
local MyFile = wx.wxGetCwd() .. Path -- define the file path in Mach4
file = io.open(MyFile, "a") -- open file in append mode
end
LoadCellTime = LoadCellTime+0.05 -- follow PLC cycle time as sample rate
WriteRegister("Time_LC",LoadCellTime) -- monitor in register ok
local text = string.format ("%.4f, %.4f, %.4f \n", val_x, val_y, LoadCellTime );
file:write(text ) --Write the Gcode file
file:flush() --Save written data
else
if (file ~= nil) then
file:close() --Close file
file = nil
end
end
[/code
-
Hey guys,
Don't try writing to a file each PLC cycle like it's described within this thread.
It's not a great idea also, you can just make a string or table with the information you're trying to write. Append to the string to make it larger and larger as it comes in. Then write that entire string or table after the GCODE is done running.
Meaning you would significantly lower the resources required by the PC / lower the chances for a corruption on a write / unknown failure.
Examples of this are within the Engraving tab in the screen as well as within the FPOST module, I'm sure it's other places as well.