# Extracting boolean variables with buffer-parser

**URL:** <https://discourse.nodered.org/t/extracting-boolean-variables-with-buffer-parser/80451>\
**Category:** General\
**Created:** [10 August 2023 07:08 UTC](https://discourse.nodered.org/t/extracting-boolean-variables-with-buffer-parser/80451 "2023-08-10T07:08:50Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![OriolFM](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/oriolfm/32/30710_2.png) [@OriolFM](https://discourse.nodered.org/u/OriolFM)\
**Post date:** [10 August 2023 07:08 UTC](https://discourse.nodered.org/t/extracting-boolean-variables-with-buffer-parser/80451/1 "2023-08-10T07:08:50Z")

</div>

So I have managed to read a whole buffer from a Mitsubishi PLC with the mcprotocol node, and I'm trying to parse the variables with buffer-parser.

Integers do not seem to be an issue, I just add the proper offset and I get an integer (16 or 32 bit).

Now I find myself having to read two booleans from the same word. I checked [this thread](https://discourse.nodered.org/t/how-to-extract-nibble-data-in-buffer-parser/73870) where reading nibbles was discussed. However, nibbles are small integers, not booleans.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/2/5/258aed9368b3a010d42ff1ef5c0e80780022461b.png)

In my example, I must read two of the bits. I set up a binary mask to read bits 3 and 4, considering that the LSB is bit 0 and the MSB is bit 15. The result I'm getting is 8 in one of the bits and 16 in the other.

Now, I was thinking of using the scaling function to convert them to either 1 or 0 (with the filter, I shouldn't have any other result), but the variable will still be an integer.

Is there any way to specify the output to be of a certain type (boolean, in my case)?

Thanks!

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [10 August 2023 07:52 UTC](https://discourse.nodered.org/t/extracting-boolean-variables-with-buffer-parser/80451/2 "2023-08-10T07:52:09Z")

</div>

The simplest is to use the bool type

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/1/6/1628cef21b20c69bbc4f6b5606c86e3a47bb1381.png)

however if you want to use bit masks (or more commonly hex masks) then you will get the answer as a masked result (e.g. a mask of `0000 0000 0001 0000` WILL result in a the number 8) so you will need to RIGHT SHIFT the result 3 places.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/a/8/a8870d9b3e0cee631fdd5ada272057e3f3cfcb81.png)

Example:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/9/5/957e4181b2b84310b818a6f2d2ce1fc50b45030a.png)

Flow

```auto
[{"id":"abde808441497640","type":"inject","z":"6429d72ae185e590","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":1310,"y":80,"wires":[["96d8281ed160c22d"]]},{"id":"96632d5a3b49e49e","type":"debug","z":"6429d72ae185e590","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1820,"y":80,"wires":[]},{"id":"96d8281ed160c22d","type":"buffer-maker","z":"6429d72ae185e590","name":"Dummy PLC Data (fill with 0b10101010)","specification":"spec","specificationType":"ui","items":[{"name":"item1","type":"byte","length":1,"dataType":"num","data":"0b10101010"},{"name":"item2","type":"byte","length":1,"dataType":"num","data":"0b10101010"},{"name":"item3","type":"byte","length":1,"dataType":"num","data":"0b10101010"},{"name":"item4","type":"byte","length":1,"dataType":"num","data":"0b10101010"}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","x":1560,"y":80,"wires":[["96632d5a3b49e49e","710ea0a0bb20302a"]]},{"id":"818748a08ae25cce","type":"buffer-parser","z":"6429d72ae185e590","name":"Easy (using bool)","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"bool","name":"byte2_bit3","offset":2,"length":1,"offsetbit":3,"scale":"1","mask":""},{"type":"bool","name":"byte2_bit4","offset":2,"length":1,"offsetbit":4,"scale":"1","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":1490,"y":160,"wires":[["6b458a2a6fdcd277"]]},{"id":"6b458a2a6fdcd277","type":"debug","z":"6429d72ae185e590","name":"debug 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1820,"y":160,"wires":[]},{"id":"233349320631f9b2","type":"debug","z":"6429d72ae185e590","name":"debug 3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1820,"y":240,"wires":[]},{"id":"d06b537d7b7991a7","type":"buffer-parser","z":"6429d72ae185e590","name":"using byte with mask","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"uint8","name":"byte2HexMask_bit3","offset":2,"length":1,"offsetbit":5,"scale":"1","mask":"0x08"},{"type":"uint8","name":"byte2HexMask_bit4","offset":2,"length":1,"offsetbit":5,"scale":"1","mask":"0x10"},{"type":"uint8","name":"byte2HexMaskToBool_bit3","offset":2,"length":1,"offsetbit":5,"scale":"!!","mask":"0x08"},{"type":"uint8","name":"byte2HexMaskToBool_bit4","offset":2,"length":1,"offsetbit":5,"scale":"!!","mask":"0x10"},{"type":"uint8","name":"byte2HexMaskShifted_bit3","offset":2,"length":1,"offsetbit":5,"scale":">> 3","mask":"0x08"},{"type":"uint16be","name":"byte2HexMaskShifted_bit4","offset":2,"length":1,"offsetbit":5,"scale":">> 4","mask":"0x10"},{"type":"uint8","name":"byte2BinMaskRaw_bit3","offset":2,"length":1,"offsetbit":5,"scale":"1","mask":"0b00001000"},{"type":"uint8","name":"byte2BinMaskRaw_bit4","offset":2,"length":1,"offsetbit":5,"scale":"1","mask":"0b00010000"},{"type":"uint8","name":"byte2BinMaskShifted_bit3","offset":2,"length":1,"offsetbit":5,"scale":">> 3","mask":"0b00010000"},{"type":"uint8","name":"byte2BinMaskShifted_bit4","offset":2,"length":1,"offsetbit":5,"scale":">> 4","mask":"0b00010000"}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":1500,"y":240,"wires":[["233349320631f9b2"]]},{"id":"710ea0a0bb20302a","type":"junction","z":"6429d72ae185e590","x":1330,"y":160,"wires":[["818748a08ae25cce","d06b537d7b7991a7"]]}]

```

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [10 August 2023 08:01 UTC](https://discourse.nodered.org/t/extracting-boolean-variables-with-buffer-parser/80451/3 "2023-08-10T08:01:44Z")

</div>

For reference - from the [docs](https://flows.nodered.org/node/node-red-contrib-buffer-parser)

> - Final values can be masked (e.g. a MASK of `0x7FFF` could be used to remove the MSB or `0b1000000000000001` to keep only MSB and LSB)
> - Binary and Octal masks only available in **V3.1** onwards
> 
> - Final values can be have a Scale value or a simple Scale Equation **(New in V3.1)** applied...
> - e.g. Entering a Scale value of `0.01` would turn `9710` into `97.1`
> - e.g. Entering a Scale value of `10` would turn `4.2` into `42`
> - e.g. Entering a Scale Equation of `>> 4` would bit shift the value `0x0070` to `0x0007`
> - e.g. Entering a Scale Equation of `+ 42` would add an offset of 42 to the final value **(New in V3.1)**
> - Supported Scaling Equations are...
> - `<<` e.g. `<<2` would left shift the parsed value 2 places
> - `>>` e.g. `>>2` would right shift the parsed value 2 places
> - `>>>` e.g. `>>>2` would zero-fill right shift the parsed value 2 places (returns a 32bit unsigned value)
> - `+` e.g. `+10` would add 10 to the parsed value
> - `-` e.g. `-10` would deduct 10 from the parsed value
> - `/` e.g. `/10` would divide the parsed value by 10
> - `*` e.g. `*10` would multiply the parsed value by 10
> - ` **` e.g. `** 2` would raise the parsed value to the power of 2
> - `^` e.g. `^0xf0` would XOR the parsed value with 0xf0
> - `==` e.g. `==10` would result in `true` if the parsed value was equal to 10
> - `!=` e.g. `!=10` would result in `false` if the parsed value was equal to 10
> - `!!` e.g. `!!` would result in `true` if the parsed value was `1` (same as `!!1 == true`)
> - `>` e.g. `>10` would result in `true` if the parsed value was greater than 10
> - `<` e.g. `<10` would result in `true` if the parsed value was less than 10
> 
> - NOTE: the scale/equation is applied AFTER the mask

---

<div class="post-metadata">

**Author:** ![OriolFM](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/oriolfm/32/30710_2.png) [@OriolFM](https://discourse.nodered.org/u/OriolFM)\
**Post date:** [10 August 2023 08:46 UTC](https://discourse.nodered.org/t/extracting-boolean-variables-with-buffer-parser/80451/4 "2023-08-10T08:46:48Z")

</div>

In the end, and since the bits I need are in the same word, I used filtering, int scaling with boolean conversion.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/6/9/694ad1ac8414faa8b78e520ba2278b043bc21103.png)

If not, I could have probably used the ==8 or ==16 to get a boolean.

Thanks for all the help, it's been extremely useful 🙂

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [10 August 2023 10:37 UTC](https://discourse.nodered.org/t/extracting-boolean-variables-with-buffer-parser/80451/5 "2023-08-10T10:37:06Z")

</div>

> [@OriolFM](#):
>
> since the bits I need are in the same word, I used filtering, int scaling with boolean conversion.

That is not really relevant. It would be pretty much the same amount of work under the hood to use the bool type, even with the same offset. In fact, it is less work to use the bool type since it does not have to perform the scaling equation!

> [@OriolFM](#):
>
> ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/6/9/694ad1ac8414faa8b78e520ba2278b043bc21103.png)

The double bang `!!` scaling equation does **not** have parameters.

Since ANDing a VALUE & MASK returns the masked value (e.g. `0xFFFF & 0x0010 === 0x0010 === 8`), using `!!` (without the number) means "invert invert value" i.e. Since the result of `VALUE & MASK` is `8` (the number 8 is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy)) therefore `! true` is `false`, `!! true` is `true` BUT you should NOT be adding the value to the double bang in the equation - the equation is applied to the result of the masked value:

> the scale/equation is applied AFTER the mask

in other words, `!!0.125` is wrong.

* * *

My advice in order of recommendation:

1. Use the bool type as described and demoed in my previous post.  
OR
2. Use a mask with a scale equation of `==8` (or whatever the result of `VALUE & MASK` is)  
OR
3. Use a mask with a scale equation of `!!`  
OR
4. Use a mask with a scale equation of `>0`

---

<div class="post-metadata">

**Author:** ![OriolFM](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/oriolfm/32/30710_2.png) [@OriolFM](https://discourse.nodered.org/u/OriolFM)\
**Post date:** [17 August 2023 15:00 UTC](https://discourse.nodered.org/t/extracting-boolean-variables-with-buffer-parser/80451/6 "2023-08-17T15:00:20Z")

</div>

That was solved, option (2) seems to be the easiest.

Now my battle is with the vendor, since they spread the data I need all over the PLC memory, and I'm not sure if all the memory addresses they use in their program are properly labelled, or, on the other side, they forgot to label certain memory positions that are used, and overwriting them will break stuff.

Basically, they had variables to read between positions D228 and D16800 or something like that. Trying to read more than 3600 positions will give a timeout/quality problem as a return message.

I don't know how the MCProtocol works internally, but would it be possible to include only the needed variables in the buffer in a single read, similar to what the S7 module does? I know the node doesn't allow it at the moment, but is it limited by hardware, or it could be done but it's not coded?

Thanks!

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [17 August 2023 15:09 UTC](https://discourse.nodered.org/t/extracting-boolean-variables-with-buffer-parser/80451/7 "2023-08-17T15:09:45Z")

</div>

MC protocol does have multi read function but I can't remember if I implemented it in src. What does the help say again?

All I can suggest for now is make as many grouped reads as possible.

For example, say you need d10, d124, d125, d9000, d9007, d9110, d20000 d20002 d20055 then read them in 3 lots of

D0 [126]  
D9000 [111]  
D20000 [56]

Then use buffer parser to pluck out the elements of interest.

Just remember, it takes a handful of milliseconds more to read 100 items than it does to read 1 item. So if you end up doing 100 reads instead 1 larger read, you would end out unnecessarily flooding the network and it would take approx 99times longer. And you data would be completely inconsistent by around 50 PLC scans from the first to the last item (unless you have a collection buffer in the PLC)

---

<div class="post-metadata">

**Author:** ![OriolFM](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/oriolfm/32/30710_2.png) [@OriolFM](https://discourse.nodered.org/u/OriolFM)\
**Post date:** [21 August 2023 11:06 UTC](https://discourse.nodered.org/t/extracting-boolean-variables-with-buffer-parser/80451/8 "2023-08-21T11:06:27Z")

</div>

> MC Read
> 
> Read data from an MITSUBISHI PLCs using MC Protocol
> 
> ### [Inputs](http://noderedu1.unimicron.int:1880/#)
> 
> ConnectionDF1 Connection  
> The PLC connection  
> Addressnumber | string | payload  
> PLC Memory Address
> 
> _INFO: To open / close the MC Protocol connection, send boolean `true` in `msg.connect` or `msg.disconnect`. Alternatively, send string `connect` or `disconnect` in `msg.topic` to the any mc read / mc write node._
> 
> ### [Outputs](http://noderedu1.unimicron.int:1880/#)
> 
> payloadarray | object  
> the values read from the PLC.  
> _To view additional details of the PLC read result, use a debug node to inspect the data_
> 
> ### [Details](http://noderedu1.unimicron.int:1880/#)
> 
> If an error occurs the output of this node may still be triggered. In this case, the payload will be `null` but the `mcWriteDetails` will contain additional information about the problem.
> 
> Address format [DS] DEV [DT] DN [.BIT] [,CNT] [:OPTS]...
> 
> 1. [1] DS - {string} Digit specifier (e.g. K4) [optional]
> 2. [2] DEV - {string} Device (Y|X|D|F|W|B|R|etc)
> 3. [3] DT - {string} Data type (REAL|FLOAT|STR|WORD|DWORD|DINT|UINT) [optional]
> 4. [4] DN - {int} Device number
> 5. [5] BIT - {int} Bit number [optional]
> 6. [6] CNT - {int} Count of items [optional]
> 7. [7] OPTS - {JSON} Options for specifying network and station e.g. {N:2,S:3} would attempt to route the message to station 3 on network 2 [optional]
> 
> _Notes...  
> DS and DT should not be used together.  
> if CNT is omitted, then `1` is assumed.  
> DN may be DEC or HEX depending on the notation of the Device e.g. YA, X1E, WBA4, B3D_
> 
> data returned will match the address specified e.g...
> 
> | Address Example | Data Type | Notes |
> | --- | --- | --- |
> | K4Y0 | int | −32,768 to 32,767 |
> | DSTR0,10 | string | Up to 10 chars long |
> | DUINT0,10 | UINT[10] | 10 WD array containing values 0 to 65535 |

As far as I can see, it does not mention it.

I tried passing some variable addresses separated by commas, and also an array of addresses. In the first case it says the address is not correct, on the second it returns only the value for the first address in the array.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [4 September 2023 11:06 UTC](https://discourse.nodered.org/t/extracting-boolean-variables-with-buffer-parser/80451/9 "2023-09-04T11:06:49Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
