When can we set a bit of a tag, like getBit?

Unless I’m missing something, I don’t see a function to set a specific bit in a word via scripting.

I mean, it’s just pretty simple. Change the “g” to an “s” for the “getBit” function.
Can’t see why we can’t have that within the next couple of hours, right? :slight_smile:

Hi Kraenbring,

Welcome to the forum.

Make sense about what you want to do. The expression functions return values. They don’t normally set values directly, instead they return new values that replace old values.

You can use the binEnc expression function to return the bits for an integer/word.

Seems like there could be an expression function that lets you change one bit in a word and return the word as a new value. That seems like it would be useful. This is what you are asking for right?

Or you can write a python script to set individual bits: stackoverflow.com/questions/1217 … -in-python

Best,

The expression functionality includes bitwise operators. Perhaps you can use those to set any individual bit.

Here’s examples of using bitwise operators to set bits: stackoverflow.com/questions/4798 … bit-in-c-c
Best,

You can use the expression bitwise operators to set the bits.

Yes, the following sets the 4th bit in the word/integer to 1. Just change the 3 to specify which bit in the word that you want to change to 1.

{Root Container.Numeric Text Field 1.intValue} | 1 << 3

This can be used to clear a bit. Replace the 3 with the bit position to set to 0.

{Root Container.Numeric Text Field 1.intValue} & ~(1 << 3)Best,

Thanks, Nick.
I do get the difference between using getBit in an expression vs an action. I was just using getBit as an example of format. I could write logic to break the word into bits, set the one I want, then turn bits back to a word and write it down, but in the end, I am still writing a word, not a bit. That’s a huge difference and could be potentially dangerous.

By the time I execute my logic and write the whole word value down, the rest of the bits on the word could be stale. The PLC word value would be overwritten with my stale word value. Not good. I would want a function that I knew was only writing the bit I was intending to write.

Now, I could write a script that takes a tag, get the tag’s word address (say N19:34), create a temporary tag dynamically for the bit (N19:34/9), write the bit, then destroy the dynamic tag. That would work, albeit slowly, but seems like overkill.

Where this is stemming from is working with a PLC5 and trying to keep comms to a minimum.

This is one of the things I really feel needs to be addressed in Ignition. Allow direct read/write access to bits in an integer tag like ever other SCADA system can do. I actually had to create tags for every bit in a word I needed because I had to write to it. Which probably added an additional 40-50,000 tags to my project versus other SCADA packages. Made an impact on my comms as you would expect. Doing this exponentially increases your tags.

For every valve, motor, analog input device I have, I have a status word. Well, adding 32 bit tags to the respective UDT allowing read/write access makes a big difference as you scale the system up.

100 Valve tags, require 3200 bit tags for my status word.
1000 Valves ->32,000 bit tags.

There is tremendous value in being able to read/write tags simply by appending
integerTag.00
integerTag.01

2 Likes

Amen to that! While I do hear that Ignition can handle mass quantities of tags, think of the poor PLC5 that’s being asked for every little bit. Unless Ignition’s OPC server is smart enough to combine requests of bits and words into blocks, but I’m not hopeful of that.

To keep comms down for read-only bits, I’ve resorted to creating one word as an OPC tag and then several Expression tags referencing that OPC Tag and using the getBit function to give me the bit I want.

I’d also love to be able to read blocks of words as arrays, but that’s for another post. :slight_smile:

Have you considered using system.opc.writeValue() and friends? You could have just the full word values as SQLtags, but append bit notation to that tag’s item path to feed into an OPC direct write.
Then again, from what I’ve seen in actual traffic patterns, most OPC servers are smart enough to serve tags of word values and multiple bits of those words without duplicate reads and writes.
It’s good that you are thinking about sources of bit manipulation within a single word. It is a very difficult problem, and most technologies simply cannot make that reliable. In other words, try to design your systems such that bits from your UI are in a separate word from bits to your UI.

[quote=“Paullys50”]This is one of the things I really feel needs to be addressed in Ignition. Allow direct read/write access to bits in an integer tag like ever other SCADA system can do. I actually had to create tags for every bit in a word I needed because I had to write to it. Which probably added an additional 40-50,000 tags to my project versus other SCADA packages. Made an impact on my comms as you would expect. Doing this exponentially increases your tags.
[/quote]

You’re partly correct. It certainly does increase the number of tags you need in Ignition. It does not put any additional increase on the communication load though, at least with our drivers. The reads should be happening at the word level and then a mask is applied.

Followup: we’re throwing around some ideas here about how to get better bit read/write support into our tag system. Maybe for 7.9?

Was this feature ever added to ignition? I am trying to do the same thing. I don’t see why there wouldn’t be a function in ignition to write to a specific bit in a word?

If they have, they’re keeping it secret! I haven’t found it yet either. We’ve resorted to just having individual tags setup for each bit. And we’ve had to make sure our devices/scanclasses/tags are optimized so that we’re not crushing anything. Bit writes are set a little faster, bit reads are a little slower.

What they ultimately need is not to write to bits, but to dynamically write/read to any address quickly. Give it a full path through the device and a value and just write it or read it in script.

I’ve now got a bunch of PLC UDT elements that are in an array that I now have to create tags for all of them even though I only need to work with one at a time. So if i could dynamically write and read (just like that Quick Client stuff in the Gateway pages to test devices), that would solve both issues.

I’ve done the code where you can dynamically create a tag and read/write with it. It just takes a very long time to execute.

Sounds like the system.opc.readValue and system.opc.writeValue functions might be what you are looking for. At least for the dynamic reads and writes you are talking about. No need to actually create a tag to talk to a PLC on a one-off basis.

1 Like

I am poking this again... since I was also looking for a setBit() function.

Here's my scenario:
I would like to get/set individual bits in another (integer) tag. It appears I cannot do this directly with a reference tag, as I would like. (i.e. [.]_reference/AlarmEnable.5 - or some variation) It seems the only direct bit access is available via an OPC item path (unless you can go through Ignition's OPC to access other tags within Ignition - which sounds kludgy).

Thus, I am using a derived tag. The following is my solution, albeit, not very elegant. I would much prefer defining the bit to access within said integer via the tag path, or at least have a setBit() function. I would like to have both of these items added to Ignition's wish list. Thank you.

image

You really should not be doing this if the target device can handle writes to bits of integers natively. Otherwise this is super racy. But if you must, what you have is about the best you can do. Do be sure to use "optimistic writes" or multiple bit updates will clash with each other. And make sure you aren't writing to the target word with PLC code. Write from one direction only.

Thanks for the tip on "optimistic writes." I don't see it being an issue, but who knows!? Also, this is unidirectional.