Hello Guest it is September 28, 2023, 05:24:50 PM

### Author Topic: Doing math to DRO values  (Read 460 times)

0 Members and 1 Guest are viewing this topic.

#### Ironwright

• 17
##### Doing math to DRO values
« on: November 30, 2022, 09:10:09 PM »
I'm trying to take a DRO value from the screen and do some simple comparison math to it.  Apparently the DRO Values are strings and not actual numbers.

I used the tonumber lua command to convert the string to a number,  It completes all of my code then errors anyway giving me a lua error message :number has no integer representation calling back to the function where i read the DRO values.

Is there an easy way to read a DRO value and do simple arithmetic to that value ?

#### joeaverage

• 7,570
##### Re: Doing math to DRO values
« Reply #1 on: November 30, 2022, 10:20:16 PM »
Hi,
a DRO is a visual representation of a numeric quantity in Mach. If you want to do some calculation then get the value, almost certainly stored in a pound variable,
not the visual string in the DRO.

What DRO are you trying to read?

Craig
'I enjoy sex at 73.....I live at 71 so its not too far to walk.'

#### Ironwright

• 17
##### Re: Doing math to DRO values
« Reply #2 on: December 01, 2022, 10:07:57 AM »
A custom DRO on screen for user input.  How do you assign a pound variable to a DRO?

#### joeaverage

• 7,570
##### Re: Doing math to DRO values
« Reply #3 on: December 01, 2022, 12:59:44 PM »
Hi,
pound variables are defined within Mach, you cannot o my knowledge assign a pound variable.
What you can do however is define a register. The register can contain a data variable, either numeric or string.
Your DRO would simply display that value.

Craig
'I enjoy sex at 73.....I live at 71 so its not too far to walk.'

#### joeaverage

• 7,570
##### Re: Doing math to DRO values
« Reply #4 on: December 01, 2022, 02:26:47 PM »
Hi,
to assign a register:
1) Open the Configure/Plugins/Regfile
2) Use the green cross checkmark to generate a new instance register
3) Give it a unique name, an inital value if required and whether you want it persistent. Its a handy feature that means the register is saved in the .ini file
on shutdown and the register is restored when you next start up Mach. Very handy!

To see that the register is properly configured, its value and if you want to manually edit it then:
1) Open Diagnostic/Regfile
2) Expand the instance registers, that is iRegs0 with the '+' checkmark

Generally global data in say the GUI cannot be accessed by the Gcode Interpreter because the GUI and Interpreter are different chunks and only one can be active.
A register on the otherhand can be shared across different chunks and between modules. Registers are the true global variable.

To access the register from code:

Code: [Select]
`local RegHandle=mc.mcRegGetHandle(mInst,"iRegs0/MyRegister")local Value=mc.mcRegGetValue(RegHandle)`
If you have problems with accessing registers it is usually a fault with the string description of the register 'iRegs0/MyRegister' This string has to be exactly right, letter and case
or you will not get a valid handle. Its highly worthy to put a code test after the GetHandle API call to ensure that you have a non-nill handle....or you will crash.

Craig
« Last Edit: December 01, 2022, 02:28:43 PM by joeaverage »
'I enjoy sex at 73.....I live at 71 so its not too far to walk.'

#### pjcevallos@gmail.com

• 19
##### Re: Doing math to DRO values
« Reply #5 on: December 02, 2022, 04:54:44 AM »
Hi

Craig is right, but I am not sure it depends on the Mach4 version. In my case, the Screen Load script already came with a reading and writing registers according to the Lua script manual as below. please check the manual. This means reading and writing registers is straight forward, but please remember they are write and read as strings, not numbers.

Code: [Select]
`function GetRegister(regname)local inst = mc.mcGetInstance()local hreg = mc.mcRegGetHandle(inst, string.format("iRegs0/%s", regname))return mc.mcRegGetValueString(hreg)end`
Code: [Select]
`function WriteRegister(regname, regvalue)local inst = mc.mcGetInstance()local hreg = mc.mcRegGetHandle(inst, string.format("iRegs0/%s", regname))mc.mcRegSetValueString(hreg, tostring(regvalue))end`
That meant that the registers are strings, even though they are numbers. You have to convert them into a number
Code: [Select]
`val = tonumber(val)`
Then you can use the variables to do math.

Something that I did not have time to check is that I could not perform an if the operation (Equal) because the decimals were not the same.
I guess I need to use the following, but I have not had time to do it.

Code: [Select]
`tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", num))`
Silly things happened to me and crashed mach4, but now I learned (literally this week)

Check your register's name: an empty space at the end of the register. I copy/pasted from notepad and didn't check the empty space, which crashed the PLC script because a "new" variable with nil value was being used.

Pablo

#### Ironwright

• 17
##### Re: Doing math to DRO values
« Reply #6 on: December 02, 2022, 11:28:54 AM »
THANK YOU THAT WAS VERY HELPFUL!

#### joeaverage

• 7,570
##### Re: Doing math to DRO values
« Reply #7 on: December 02, 2022, 05:10:51 PM »
Hi,

Quote
but please remember they are write and read as strings, not numbers.

That is not correct. Try experimenting.

There are three APIs to set the value of a register:

mcRegSetValue()      stores a numeric value, I suspect a 32bit floating point IEEE 754
mcRegSetValueLong()      stores an integer value, I suspect 32 bit signed
mcRegSetValueString()      which as the name suggests stores a variable length string.

As an example I tried this piece of code:

Code: [Select]
`local regHandle=mc.mcRegGetHandle(inst,"iRegs0/MyString") local string=mc.mcRegGetValueString(regHandle) local string=string/2.07`
where I stored '6789' as the value of the string. One some occasions the division failed, dividing a string by a numeric value does not really make sense, but on
other occasions the string was re-cast and the division proceeds with a real result, ie a fractional portion. I have yet to discover why Lua sometimes re-casts and sometimes
not.

Another example:

Code: [Select]
`local regHandle=mc.mcRegGetHandle(inst,"iRegs0/MyInteger") local integer=mc.mcRegGetValueLong(regHandle) local integer=integer/2.07`
This time I stored the same number (6789) but as an integer by using SetValueLong(). Note that I tried storing the value 6789.1234 using the same API
but the actual stored value is 6789, ie the fractional portion is lost, ie stored as an integer. Interestingly the division works but returns a real value, ie with
a fractional component. It suggests that the integer value was re-cast as a real number and then the division is completed.

This is a common feature of Lua, being essentially type free, is that re-casts happen behind the scenes often transparently to the user. None the less there are at least three
distinct data types that can be stored in a register. You have to be aware of when Lua re-casts......and that has caused me a little grief from time to time.

Craig
'I enjoy sex at 73.....I live at 71 so its not too far to walk.'