Machsupport Forum
Mach Discussion => Mach4 General Discussion => Topic started by: brianthechemist on March 06, 2023, 11:33:00 AM
-
For some reason, I can't get any registers to update (in any of my coding...?)
Here is the problem du jour:
I trigger this function via a SW toggle switch. The code is running so it is reading the register correctly the first time (I get the "Joystick Jogging Enabled (Toggle)" logging message) but it is not able to read back the register to toggle off.
Is there something strange about 1 and 0, true and false? Perhaps I am doing my booleans wrong?
function JJogEnToggleBrSp()
local inst = mc.mcGetInstance()
local JogEnH=mc.mcRegGetHandle(inst,"iRegs0/JJog/Enable");
local JogEn=mc.mcRegGetValue(inst,JogEnH);
if (JogEn == 0) then
mc.mcRegSetValue(JogEnH, 1);
mc.mcCntlSetLastError(inst, "Joystick Jogging Enabled (Toggle)") -- BS Debug
end
if (JogEn == 1) then
mc.mcRegSetValue(JogEnH, 0);
mc.mcCntlSetLastError(inst, "Joystick Jogging Disabled (Toggle)") -- BS Debug
end
end
-
HI,
the code looks good to me. Just as a matter of interest try enclosing the 1 or 0 in quotes.....it cant hurt to try.
mc.mcRegSetValue(JogEnH, "1");
Craig
-
ok. will check.
I've been reading up on the unconventional way that LUA handles Booleans. Is there a more reliable way to test for the conditions held in the registers? (in C++, 1 and true are interchangeable, it seems not the case in LUA)
-
Hi,
not to my knowledge. Lua has an incredibly small code burden and is blazing fast, one of the fastest scripting languages and not that very far behind C,
but it does take some big shortcuts. It dose not have a Boolean, for instance, in fact it one and only one type of variable, a table. Even a single value is in fact a table
with just one entry. The entries in a table are type free.....ie no Boolean.
Craig
-
HI,
I've often had code cock-ups and one of the common themes is Lua storing a string when I expected a number or vice versa.
I don't know if you've had a chance to play with Lua String functions. At first glance you'd say that these so few and so basic functions to render them less than useful.
But then you start using them and you realise they can in fact do about anything and compare closely to POSIX compliant string functionality....and yet the string function
table (yes all the functions are members of a table) is only about 5kB!!!! Lua surprises that despite its simplicity is as flexible as it is.
Craig
-
Unfortunately, treating the entries as strings like you suggested didn't work.
One interesting observation, however is that i can get this script error when I try to save a string, yet I can't seem to compare to the readback value of the register as a number.
I have started getting a bit more liberal with my use of tonumber() to prevent accidental strings from getting in the way.
Is it possible that reading a "number" register isn't a numerical value? hurts my head.
-
Hi,
well it was worth a try, as I say I've had errors of that type before. It the definite downside of a language with seeming variable typing rules where C is typed up the yazhoo!
Craig
-
incidentally, I'm 90% finished with my analog joystick jogging code. I have everything working except for the final command to jog.
Here is the last clean version before I started shredding it up to debug. The logic and everything is all there... :(
--Analog Joystick jogging code chunk
--[[
X axis potentiometer connected to pin 43
Y axis potentiometer connected to pin 44
The following registers are necessary
"iRegs0/JJog/Enable" -- connected to a toggle switch to enable joystick jogging
"iRegs0/JJog/EnLast" -- Flag to prevent millions of announcements
"iRegs0/JJog/safeZEn" -- connected to a toggle switch to first move to safe Z before jogging
"iRegs0/JJog/atSafeZ" -- Register to hold at safe z flag
"iRegs0/JJog/stickCtr" -- center joystick position value (decimal fraction of 1)
"iRegs0/JJog/stickHyst" --center position hysteresis value (decimal fraction of 1)
"iRegs0/JJog/velLim" -- positive limit (fraction of maximum velocity)
"iRegs0/JJog/jogDirX" -- Readback for direction (pos, neg)
"iRegs0/JJog/jogVelX" -- Readback for jog velocity
"iRegs0/JJog/jogDirY" -- Readback for direction (pos, neg)
"iRegs0/JJog/jogVelY" -- Readback for jog velocity
]]
--[[
If you follow the format from the ini file:
[iReg15]
Name=JJog/Enable
Desc=Enable Joystick Jogging
InitialValue=0
Persistent=0
[iReg16]
Name=JJog/EnLast
Desc=jog enable flag
InitialValue=0
Persistent=0
Value=0
[iReg17]
Name=JJog/safeZEn
Desc=Enable Safe Z before Jogging
InitialValue=1
Persistent=1
Value=1
[iReg18]
Name=JJog/atSafeZ
Desc=at safe z flag
InitialValue=0
Persistent=0
Value=0
[iReg19]
Name=JJog/stickCtr
Desc=center joystick position value
InitialValue=.52
Persistent=1
Value=.52
[iReg20]
Name=JJog/stickHyst
Desc=center position hysteresis
InitialValue=.1
Persistent=1
Value=.1
[iReg21]
Name=JJog/velLim
Desc=Velocity Limit fraction
InitialValue=.8
Persistent=1
Value=.8
[iReg22]
Name=JJog/jogDirX
Desc=Readback for X direction (pos, neg)
InitialValue=0
Persistent=0
Value=0
[iReg23]
Name=JJog/jogVelX
Desc=Readback for X jog velocity
InitialValue=0
Persistent=0
Value=0
[iReg24]
Name=JJog/jogDirY
Desc=Readback for Y direction (pos, neg)
InitialValue=0
Persistent=0
Value=0
[iReg25]
Name=JJog/jogVelY
Desc=Readback for Y jog velocity
InitialValue=0
Persistent=0
Value=0
]]
--Function to read value from analog register
function ReadRegister(device, analogPin)
local inst = mc.mcGetInstance()
local hreg = mc.mcRegGetHandle(inst, string.format("%s/Analog input %s", device, analogPin))
return mc.mcRegGetValueString(hreg)
end
--Function to set Jog value
function JoystickJog(analogX, analogY)
local inst = mc.mcGetInstance()
local safeZenH=mc.mcRegGetHandle(inst,"iRegs0/JJog/safeZEn")
local safeZen=mc.mcRegGetValue(inst,safeZenH)
local atSafeZH=mc.mcRegGetHandle(inst,"iRegs0/JJog/atSafeZ")
local atSafeZ=mc.mcRegGetValue(safeZenH,atSafeZ)
local stickCtrH=mc.mcRegGetHandle(inst,"iRegs0/JJog/stickCtr")
local stickCtr=mc.mcRegGetValue(inst,stickCtrH) --Read center position value (fraction)
local stickHystH=mc.mcRegGetHandle(inst,"iRegs0/JJog/stickHyst")
local stickHyst=mc.mcRegGetValue(inst,stickHystH) --Read center position hysteresis value (fraction)
local velLimH=mc.mcRegGetHandle(inst,"iRegs0/JJog/velLim")
local velLim=mc.mcRegGetValue(inst,velLimH) -- Read positive limit
local xAxisDirection=mc.MC_JOG_STOP -- MC_JOG_POS,1 for positive, MC_JOG_STOP,0 to stop, MC_JOG_NEG,2 for negative
local yAxisDirection=mc.MC_JOG_STOP
local jogVelX=0.0
local jogVelY=0.0
mc.mcCntlSetLastError(inst, "analogX")
mc.mcCntlSetLastError(inst, analogX)
stickHyst=tonumber(stickHyst) -- Make any accidental strings into numbers
stickCtr=tonumber(stickCtr)
velLim=tonumber(velLim)
analogX=tonumber(analogX)
analogY=tonumber(analogY)
-- Check to see if it is necessary to move to safe Z before jogging
if safeZen == 1 and atSafeZ == 0 then
GoToSafeZBrSp() -- function to move to a predetermined safe Z position
end
-- *********** X Axis ***********
if analogX > (stickCtr + stickHyst) and analogX < velLim then
-- If greater than .5 + stickhyst, go positive
-- velocity value is 2*analog for positive,
xAxisDirection=mc.MC_JOG_POS
local ijogVelX=(2*(analogX-stickCtr))
if ijogVelX < velLim then
jogVelX=ijogVelX
else
jogVelX=velLim
end
end
if analogX < (stickCtr + stickHyst) and analogX > (stickCtr - stickHyst) then
-- if within .5 +/- stickhyst,
--write 0 to jog velocity register
--rc = mc.mcJogVelocityStop(mInst, axis); --Stop the axis movement
xAxisDirection=mc.MC_JOG_STOP
jogVelX=0
end
if analogX < (stickCtr - stickHyst) then
-- If less than .5 - stickhyst, go negative
-- 1-(2*analog) for negative
xAxisDirection=mc.MC_JOG_NEG
local ijogVelX=(2*(stickCtr-analogX))
if ijogVelX > velLim then
jogVelX=ijogVelX
else
jogVelX=velLim
end
end
-- *********** Y Axis ***********
if analogY > (stickCtr + stickHyst) and analogY < velLim then
-- If greater than .5 + stickhyst, go positive
-- velocity value is 2*analog for positive,
yAxisDirection=mc.MC_JOG_POS
local ijogVelY=(2*(analogY-stickCtr))
if ijogVelY < velLim then
jogVelY=ijogVelY
else
jogVelY=velLim
end
end
if analogY < (stickCtr + stickHyst) and analogY > (stickCtr - stickHyst) then
-- if within .5 +/- stickhyst,
--write 0 to jog velocity register
--rc = mc.mcJogVelocityStop(mInst, axis); --Stop the axis movement
yAxisDirection=mc.MC_JOG_STOP
jogVelY=0
end
if analogY < (stickCtr - stickHyst) then
-- If less than .5 - stickhyst, go negative
-- 1-(2*analog) for negative
yAxisDirection=mc.MC_JOG_NEG
local ijogVelY=(2*(stickCtr-analogY))
if ijogVelY > velLim then
jogVelY=ijogVelY
else
jogVelY=velLim
end
end
--Output Values to registers for diag
local jogDirXH=mc.mcRegGetHandle(inst,"iRegs0/JJog/jogDirX");
mc.mcRegSetValue(jogDirXH,xAxisDirection); -- Write jog direction to register
local jogVelXH=mc.mcRegGetHandle(inst,"iRegs0/JJog/jogVelX");
mc.mcRegSetValue(jogVelXH,jogVelX); -- Write jog velocity to register
local jogDirYH=mc.mcRegGetHandle(inst,"iRegs0/JJog/jogDirY");
mc.mcRegSetValue(jogDirYH,yAxisDirection); -- Write jog direction to register
local jogVelYH=mc.mcRegGetHandle(inst,"iRegs0/JJog/jogVelY");
mc.mcRegSetValue(jogVelYH,jogVelY); -- Write jog velocity to register
--Jog Axes accordingly
rc = mc.mcJogSetRate(inst, 1, jogVelX);
rc = mc.mcJogVelocityStart(inst, 1, xAxisDirection);
rc = mc.mcJogSetRate(inst, 2, jogVelY);
rc = mc.mcJogVelocityStart(inst, 2, yAxisDirection);
end
function GoToSafeZBrSp()
-- function to execute safe Z move or call built-in function to do the same.
end
function JJogEnToggleBrSp()
local JogEnH=mc.mcRegGetHandle(inst,"iRegs0/JJog/Enable");
local JogEn=mc.mcRegGetValue(inst,JogEnH);
if (JogEn == 0) then
mc.mcRegSetValue(JogEnH, 1);
mc.mcCntlSetLastError(inst, "Joystick Jogging Enabled (Toggle)") -- BS Debug
end
if (JogEn == 1) then
mc.mcRegSetValue(JogEnH, 0);
mc.mcCntlSetLastError(inst, "Joystick Jogging Disabled (Toggle)") -- BS Debug
end
end
function JJogSafeZEnToggleBrSp()
local safeZEnH=mc.mcRegGetHandle(inst,"iRegs0/JJog/safeZEn");
local safeZEn=mc.mcRegGetValue(inst,safeZEnH);
if (safeZEn == 0) then
mc.mcRegSetValue(safeZEnH, 1);
mc.mcCntlSetLastError(inst, "SafeZ Enabled (Toggle)")
end
if (safeZEn == 1) then
mc.mcRegSetValue(safeZEnH, 0);
mc.mcCntlSetLastError(inst, "SafeZ Disabled (Toggle)") -- BS Debug
end
end
-
It appears that anything that goes into or out of a register becomes an issue. Lots of NILs from read back registers and no updating in the RegDiag screen.
Did I perhaps not set some hidden parameter of the registers correctly? It appears that that Mach has a number of register types but it isn't clear how to indicate which you are wanting to use/make.
-
--Jog Axes accordingly
rc = mc.mcJogSetRate(inst, 1, jogVelX);
rc = mc.mcJogVelocityStart(inst, 1, xAxisDirection);
rc = mc.mcJogSetRate(inst, 2, jogVelY);
rc = mc.mcJogVelocityStart(inst, 2, yAxisDirection);
What values do you have for jogVelX and jogVelY as mc.mcJogSetRate is a % of maximum motor velocity?
Also, you have the values for the X and Y axis incorrect. X axis is 0 and Y axis is 1. Alternatively you can use mc.X_AXIS and mc.Y_AXIS
-
Hi,
I hope I'm not belabouring the point or trying to 'teach my Grandmother to suck eggs' but we have a perfect example of one of Lua's strengths right here.
All Lua variables are a table. The syntax for addressing a table is the name of the table followed by a period followed by the name of the entry in that table.
I'm more familiar with FORTRAN and C and the elements of an array are sequentially numbered integers 0,1,2, etc. In Lua however an entry name may be a number or
a string and any mixture thereof.
As an example:
mc = the name of the table
X_AXIS = Name of an entry in the table
mcJogSetRate() = Name of an entry in the table.
Note the one entry, namely X_AXIS equates to just a number. in this case 0. The other entry, namely mcJogSetRate() is a function. Thus the entries in any given table
my be a mixture of strings, numbers or functions. Compare that to C where all elements in the array must be of the same type, say float.
This is a perfect example of the principle of 'a function as a first class value', that is to say a function can be bandied about as if its just a number.....extremely handy
and much of Lua's flexibility comes from use and re-use of that property.
The 'mc' table must be huge. Think of all the APIs like mc.mcJogSetRate() and the many hundreds like it, mc.X_AXIS and many dozens of other numeric assignments
including mc.ISIG_INPUT43 for example.
Again apologies for hijacking the thread but this property of Lua intrigues me greatly.
Craig
-
--Jog Axes accordingly
rc = mc.mcJogSetRate(inst, 1, jogVelX);
rc = mc.mcJogVelocityStart(inst, 1, xAxisDirection);
rc = mc.mcJogSetRate(inst, 2, jogVelY);
rc = mc.mcJogVelocityStart(inst, 2, yAxisDirection);
What values do you have for jogVelX and jogVelY as mc.mcJogSetRate is a % of maximum motor velocity?
Also, you have the values for the X and Y axis incorrect. X axis is 0 and Y axis is 1. Alternatively you can use mc.X_AXIS and mc.Y_AXIS
Good catch!! I was using a fraction (.50 instead of 50) for the jogVelX as the analog inputs from the Pokeys are automatically scaled to a max of 1 and a midpoint (if potentiometer) of .5. That should be an easy test to fix.
For the X and Y axes, I have used a number of variations of mc.X_AXIS, numbers and mc.mc.X_AXIS in various tests. My intention was to get mc.X_Axis to work. let me look at my code again
-
Hi,
I hope I'm not belabouring the point or trying to 'teach my Grandmother to suck eggs' but we have a perfect example of one of Lua's strengths right here.
All Lua variables are a table. The syntax for addressing a table is the name of the table followed by a period followed by the name of the entry in that table.
I'm more familiar with FORTRAN and C and the elements of an array are sequentially numbered integers 0,1,2, etc. In Lua however an entry name may be a number or
a string and any mixture thereof.
As an example:
mc = the name of the table
X_AXIS = Name of an entry in the table
mcJogSetRate() = Name of an entry in the table.
Note the one entry, namely X_AXIS equates to just a number. in this case 0. The other entry, namely mcJogSetRate() is a function. Thus the entries in any given table
my be a mixture of strings, numbers or functions. Compare that to C where all elements in the array must be of the same type, say float.
This is a perfect example of the principle of 'a function as a first class value', that is to say a function can be bandied about as if its just a number.....extremely handy
and much of Lua's flexibility comes from use and re-use of that property.
The 'mc' table must be huge. Think of all the APIs like mc.mcJogSetRate() and the many hundreds like it, mc.X_AXIS and many dozens of other numeric assignments
including mc.ISIG_INPUT43 for example.
Again apologies for hijacking the thread but this property of Lua intrigues me greatly.
Craig
Exactly, I like this property myself, especially if dealing with data from a variety of sensors or inputs. Building data structure arrays is a time consuming process in C.
As the thread initially states, I have been unsuccessful at reliably writing anything to registers (obviously due to some flaw in my code/understanding of the mach registers)).
Are the registers (iRegs, etc...) actually also simply entries in a LUA table as well? Or are they global variables? They seem too flexible to be actual firmware registers to me, but then again that level of detail is past my knowledge.
-
Hi,
Are the registers (iRegs, etc...) actually also simply entries in a LUA table as well? Or are they global variables?
They are certainly global variables and the only way to export data from one Lua chunk to another chunk. What I cannot tell you is whether they are a fixed location,
I suspect they are. As you know most Lua variables are dynamically allocated and throughout a session will be created and destroyed many times. As such the
'handle' for a given variable will vary, however my guess is that registers are fixed.
Craig
-
Hi,
Are the registers (iRegs, etc...) actually also simply entries in a LUA table as well? Or are they global variables?
They are certainly global variables and the only way to export data from one Lua chunk to another chunk. What I cannot tell you is whether they are a fixed location,
I suspect they are. As you know most Lua variables are dynamically allocated and throughout a session will be created and destroyed many times. As such the
'handle' for a given variable will vary, however my guess is that registers are fixed.
Craig
Then i am definitely either doing something wrong, or my user registers are corrupted. Is it possible that there are duplicated handles? The register diagnostics shows a value, but if i read it back it gives nil.
I had identical problems with a number of my VFD registers. It almost looks like some of them got duplicated (below the handle abstraction level).
Do you have a code snippet that writes to and reads back from a register that i can try (on a new register and an existing one)?
I’m wondering where the definitive list of registers is. I checked the machine.ini and there is only one entry for each register.
-
Hi,
I have attached a couple of screen shots from my machine. The first are entries in the SigLib table where a given input, a servo alarm for instance, will cause an Estop
but also write to a register. The second shot is of the Register Diagnostics. Note that the servo alarms are so seldom, if ever, triggered are not especially interesting,
but the AXIS1, AXIS2 reflect the status of the axis select switch on my pendant, which in turn informs Mach of the axis to jog and puts that in another register
just call AXIS and has a number, 0,1 or 2 depending on the axis to be jogged. Note that these values are live, that is to say whenever I flick the three position toggle
switch to select an axis to jog the registers update. I've been using this scheme for months and it works perfectly. If the registers were misbehaving then my pendant would be
misbehaving also,yet it is not.
Craig
-
Hi,
sorry the excerpt from the SigLib table is not a screen shot but rather a text file.
Craig
-
Hi,
sorry the excerpt from the SigLib table is not a screen shot but rather a text file.
Craig
Cool, thanks. I’m definitely thinking that i did something wrong somewhere. As a wise electrical engineer once told me “the electrons always to to the right place, maybe just not where you wanted them to!”
-
hmm,
I don't see anything different about how you are doing the register access than me. Perhaps my registers got corrupted somehow. Is there a way to rebuild the registers (like from the ini file or something?)
-
following along the "corrupt registry" thought, here is my machine.ini file
-
Hi BrianTheChemist or the other experts!
Sorry for rekindling an old post and asking another question instead of providing an answer!
I have the same problem!!
code and .ini file attached...
I'm in Brazil and I even thought that the problem could be the OS number format settings (Windows 10). I changed the settings, restarted everything!... and nothing!!
Did you find a relevant reason?
Thanks for reading!
See you later! I hope!