Extracting MODBUS values from function registers
-
Hey Guys, we have a bunch of Midnite Solar regulators we pull voltages etc from, they are all straight forward registers. However now we want to pull out the status of some aux relay terminals and this is the table the manufacturer has documented..
Is there a simple way to get Mango to extract and store each of the Aux status's in two separate data points, 1 for aux1, 1 for aux2?
If I read the 4165 (4164) register now I get a value of '66'.Any help would be much appreciated, thanks.
Cheers
Dan -
That's a bit of a odd one and I'm not sure I follow 100%. These look like multi state data points to me and there would be two of them. Are they saying that the store the values for both values in a single Modbus register (2 bytes)?
You could probably use a meta data point to extract the correct value but maybe someone else will have a better idea.
-
66 doesn't make sense as that would be bit 1 and bit 6 is set. Are the other bits used for anything else or do you just have to mask with &0xC0 and shift right 6 bits?
If you mask the 66 you get bit 6 set and if then shifted right 7 bits would be a value of 1 indicating Aux 1 AUTO and Aux 2 OFF
Would this be correct?
-
@v8dave said in Extracting MODBUS values from function registers:
66 doesn't make sense as that would be bit 1 and bit 6 is set. Are the other bits used for anything else or do you just have to mask with &0xC0 and shift right 6 bits?
If you mask the 66 you get bit 6 set and if then shifted right 7 bits would be a value of 1 indicating Aux 1 AUTO and Aux 2 OFF
Would this be correct?
That makes a lot of sense, cause the first AUX is controlling a genset it will have been in Auto at the time.
How would I get the Mango system to represent each of the 3 possible values per AUX terminal, per each data point?Cheers
Dan -
Hi Dan,
Possibility 1)
I would think a meta point would be up to the task. You could make it a 2 byte data type (edit: whoops, dunno why i thought 0x66 described 16 bits...), then two meta points like:return (modbusPoint.value & 0xc0) >> 6
Possibility 2)
You could read the registers as 2byte data types (read only one register) and use range renders to handle all this for you, since,
#pseudocode
if registerValue < (1 << 6)
rendering = "Aux Off"
else if registerValue < (2 << 6)
rendering = "Aux Auto"
else if registerValue < (3 << 6)
rendering = "Aux On"
else
rendering - "Aux Unimplemented"But this would be very difficult to work with when it came to setting these point values, if settable. You'd probably want some other point / script as a layer of indirection to set the bit correctly. You can handle the 'else' part in the range rendered by using a very large value (I would steal the value from the 'discard extreme values' box for the positive side, which is the largest finite double).
-
Thanks guys I'll try those options and let you know how we go.
Cheers
Dan -
I just made an edit, don't know what I was thinking saying you need to read 4 bytes, 2 should be fine, and you'll have to think of that in your range renderer for the second point reading the same register, all those bitshifts will be +8 which make may a range renderer impossible for the lower order byte
I would go with the meta strategy, because then the 'set' command will be on the meta, and a pointlink that undoes the bitshifting will set the modbus value.
-
OK I have fair idea what you're getting at, I'll try it with the meta data source and see if I can pick out the required values.
Thanks for that.Cheers
Dan