Reading bool array from S7 DB

Hi,

In my setup i have the following
Ignition : 8.0.3
Siemens controller : S7-1212C fw 3.0.2 (192.168.13.30)
PC : 192.168.13.40

I have created an array of boolean tags(10) in my data block DB1. The address spans from 4.0 to 5.1. I am able to read/write the tags individually when i create a new opc tag like

dummy1 (address [test]DB1,X4.0)
dummy2 (address [test]DB1,X5.1) etc

but this does not seem to work when i create a new data type and use the parameter value to provide the index.

index = 1
new tag (address [test]DB1,X{index*0.1+4.0})

when I try the above for the tag data, I am receiving data from DB1 address 4.7 instead. The above approach works well for a int and real data array.

Attached is a captured wireshark trace, where i tried changing the Boolean address from 4.1 to 5.1 in Ignition . In the trace the request seems to be for a complete byte instead of a bit.

bool_tag_5_1.rar (13.4 KB)

Saurabh Menon

I'm a little surprised that your UDT works at all. With index = 1 your parameter expression is (1*0.1+4.0). The floating point numbers (0.1 and 4.0) are treated as integer, that result in (1*0+4)=4 so the final opc address is [test]DB1,X4.
To use your parameter as bit address, the parameter expression should be [test]DB1,X4.{index}.
If you want to use bit numbers > 7 with offset X4.0, the expression
[Test]DB1,X{4+index-index%8}.{index%8}
should do the trick.

Even when you only want to read a single bit, the driver will always request the full byte.

@chi

Thanks for the help. I had to slightly tweak the equation to [Test] DB1, X{4+index/8}.{index%8} this is good for array index starting with 0.

My array in S7 udt is bool[1 to 30]

You could just address the DWORD with the data type set to array of bools and then you would have each bit in one element. If i remember correctly the bytes are reversed (little endIan as opposed to big endIan) but we have used this before to read Siemens IO card data into a diagnostics page.

@chi

I am facing a slight problem with the above approach. I am expecting {index/8} to give me a integer value, but there is a rounding off happening that is causing some of the tags to be misaligned. For eg when the index is 6/7. Any ways to overcome this

Try:

[Test] DB1,X{4+(index-(index%8))/8}.{index%8}
1 Like

Ignitions driver uses the legacy S7-300 protocol and knows nothing about the data type definition in the plc. Even a bool[101..130] array would still start at the bit address DB1.DBX4.0.
If you want the parameter in Ignition to match your array index in the plc try

[Test]DB1,X{4+( (index-1) -( (index-1) %8))/8}.{ (index-1) %8}

(i did not test this expression)

@pturmel

Thanks for this, this works.

@AndyP
Thanks for the suggestion. Actually i had thought about this initially, the problem is that in Siemens to access a bit of a word i have to use “variable_name”.%x"bit_number", I cannot assign the bit number as a dynamic variable. This problem is easy to overcome with bool_array.

No Problem. In an earlier project where we were monitoring the Safety Inputs form A Siemens Safety PLC we used a variable for the word then just used Boolean expression tags in the UDT pull out the bit. I know this sounds clumsy but it worked very well in practice. We had 20 odd S7 Safety PLCs to monitor and ended up needing about 100 instance of the UDT. This made the instances very easy to implement. To make it easy for site mods to naming we also loaded all the IO names and descriptions into a data table and used these for displaying rollovers and comments in the diagnostics pages. I’ve attached the UDT if you are interested. It was for Inputs but would work equally well for DBs.

Siemens_UDT.xml (8.1 KB)