Scaling Modbus Tag Data in Groov

I want to take my raw data from a Modbus tag and multiply it by 0.10. I looked at the Scaler in the tag setup but not being a math wiz I couldn’t figure out how the formula for that particular tool was going to give me what I want.

Seems like it should be an easy thing to do.



Search is your friend?

Mary is out of the office till Thursday, but if you have any questions, post them here, my math is weak, but there are plenty of lurkers…

I did search but that explanation is way over my head. All I want to do is multiply one number by another. Hopefully the math wizs will come forward shortly. :slight_smile:



Yeah, I wondered if you had found it… It is going to take me a few minutes to dig into it as well, might get time tomorrow.

You using a text gadget, or a dial gadget? If its the dial, you might be able to use the scaling on that gadget? If its a text gadget, then yeah, calling all math lurkers… Help. Need a little help.

Multiply by 0.1 is the same as divide by 10, so I’d keep it simple and put the raw high/low as 0 and 10 with scaled high/low as 0 and 1 to cause to shrink to that 10%. Make sense?

It doesn’t make any sense but I took your word for it and it took my raw number of 292 and now it displays 29. What I want is 29.2. Getting closer but still no cigar.

When you use scaling in Modbus you’re asked to specify an output type. It looks like yours is set to an Integer type, which is why the output will be truncated to 29. Double-check that you’re asking for a Float or Double as your output type?

(In hindsight, we arguably should have named those types Decimal Number, or something to that effect.)

Float and Double give me 0. My output in the Modbus device is an unsigned integer. In that device, I’m able to divide by 10 which gives me a value of 29.2. I just want to be able to do the same in Groov. Which begs the question: If this number wasn’t coming from a Modbus device and it was just a plain old integer with a value of 292, how would I get it to scale to 29.2?



In the general case, you can’t scale a number in groov right now. There are a few special cases where you can do it, Modbus being one of them. A couple gadgets allow it is well: the Round Gauge and Range Indicators off the top of my head.

The Linear mapper on Modbus tags works by interpolating a value from the Input range to one in the Scaled Result range. It’s best if you know the full range of values that will show up in your Input, but it should work without.

In this case, if you know your input value is going to range from 0 - 300 or so, you’d set that as the Input Range Limit in your Modbus tag configuration, and figure out what your output range is based on that. In your case, the output value is 1/10th of your input value, so you can just divide your output range limits by 10, giving you 0 - 30.

I went ahead and double checked this locally. I have a SNAP-PAC-R1 at my desk that I’m configuring as a Modbus device: I’m just using its scratchpad area as a place to stick values that I can read via our Modbus scanner.

I added a Modbus device to my groov project using my SNAP-PAC-R1’s IP address, and Slave ID 110. (Mapping the scratchpad’s memory locations into Modbus’s address space is a little confusing, involving doing some math from an MMP location into a Modbus Slave ID + register number combination.) I turned off 1-based addressing in my configuration, and then added 2 tags to the device.

First, a 32-bit integer (doesn’t matter whether signed or unsigned for now) at holding register number 2048. (That’s the first address in the integer scratchpad area space.)

Then, another 32-bit integer at the same register number, but this one I enabled scaling on. I turned on the Linear scaler, selected Float as my output type, set my Raw Input Limits from 0 - 300 (to fit 292 in the range we’re mapping from) and my Scaled Result limits to 0 - 30.

Closed out the device configuration stuff, created a new page with 2 gadgets on it: a Text Box pointing to that first plain 32-bit integer, and a Value gadget pointing to the scaled one. The Text Box gadget needed it’s acceptable values bumped up to let me type in 292.

Save my pages, switch to View, look at the new page I made. I entered 292 in the Text Box pointing to the plain integer, and the Value box now reads 29.20.

Did everything you suggested including setting up two gadgets. Keep in mind that I’m using a third-party Modbus device, not an Opto22 one. Secondly the holding registers are only 16-bit, not 32. In any case, when comparing the two registers (which now read 122. This is a live device) the scaled one reads 12, the unscaled one 12.

At this point I’m ready to concede defeat because it’s not working. This is a deal killer for the app we’re considering using Groov for, because if we can’t do simple scaling like this, we won’t be able to present data in the form necessary for our app.

Bother. Would you be up for sharing your Modbus tag configuration? There’s an “Export” button in the Modbus tag editor that will let you download a CSV file containing all the configured tags. Mine looks like this right now:

Raw Integer,32-bit Unsigned Integer,402048,Read/Write
Scaled Float,32-bit Unsigned Integer,402048,Read/Write,"Linear,Float,0,300,0,30,false"

The first column is the tag name, followed by data type, register address (the leading 4 means Holding Register), whether to allow gadgets that will write to it, and the scaler configuration.

Secondly the holding registers are only 16-bit, not 32.

Yeah, we support reading/writing multiple registers at once to store values larger than Modbus’ register size. I just grabbed 32-bit at random for the above test.

Sure. Here it is:

Z-Axis Peak Freq,16-bit Unsigned Integer,400059,Read/Write,Linear,Float,0,300,0,30,false
Control,16-bit Unsigned Integer,400059,Read/Write


One more thing. These values are displayed in a Text Area gadget in Groov. Could that be an issue? It was the only way I could get a value in Groov Build without a tag label associated with it.

Aha! The Text Area might explain it: what does your formatting string look like? A single # will truncate to an integer, while #.# will give you one digit after the decimal point. Add more # for as many decimal points as you like.

Oh, and you should be able to get rid of the label on any gadget by just deleting the default string that’s there.

The #.# works like a champ!

Thanks for all your help. Simple fix for what was going to be a big problem for me. :relaxed:


I followed all of this and got my own scaling working mostly. My value from the modbus device is in absolute pressure and I need to scale it to gauge pressure (subtract 14.7) The complete scale formula would be ((x/10)-14.7) How would I do that? I tried to simply subtract it in the scale area, but that doesn’t work.

I figured out the correct scaling, but it drops my decimal during input… Also, if I am not paying attention, the tag editor wants to re-assign and save this as a float value.

You may want to try putting the Raw Low to 0 and the Limit Low to -14.7 if you need to be able to read vacuum.

If I do that, it reads correctly, but the input is not correct ie. if I enter “30.5” the compressor updates to “29.5”. It is displayed correctly, but the output doesn’t match the input.

Video of behavior