Accessing Individual Bits of a Modbus Word on LOGO! 8

David Krause16 min read
ModbusSiemensTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Accessing Individual Bits of a Modbus Word on Siemens LOGO! 8.FS4

The Siemens LOGO! 8.FS4 is a compact logic module that has no native bit-count, population-count, or bitwise-shuffle instruction. Engineers migrating from S7-1200, S7-300, or third-party PLC platforms frequently look for a way to count the number of set bits inside a 16-bit analog word delivered over Modbus, or to expose individual flag bits inside a single Modbus register. This reference documents the LOGO! 8 memory model, the network input / network output (NI / NQ) mapping, the marker byte layout, and the practical workarounds available inside LOGO!Soft Comfort V8.3.

1. Problem Statement

When a Modbus master writes a 16-bit holding register to the LOGO! 8, the firmware loads the value into a network input word inside the VM area (VW0 through VWn, depending on the slave address table). Each bit of that word can represent a Boolean flag, but LOGO!Soft Comfort V8.3 has no native instruction set to perform the following tasks:

  • Count the number of set bits (popcount / Hamming weight).
  • Shift the word right or left by N positions to inspect the LSB or MSB in turn.
  • Decode the word into a Boolean fan-out of 16 parallel triggers.

The two most common field use cases are: (a) a single Modbus register that conveys 16 alarm flags from a remote device (sensor block, energy meter, or sub-PLC) into the LOGO!, and (b) building a status word on the LOGO! side that aggregates 16 local conditions and exposes them as one register to the Modbus master. Neither case requires a popcount, but the question of "how many alarms are currently active" is the natural follow-up — and that is where the bit-count request originates.

2. Why LOGO! Differs from S7-1200 and S7-300

The S7-1200 (TIA Portal) instruction set includes the AND, OR, XOR word logic operations, the SHR / SHL shift instructions, and dedicated bit-test operations such as DBx.MyWord.%X0. The LOGO!Soft Comfort V8.3 toolbox is intentionally reduced: it targets relay-replacement applications and small automation cells. There is no STL editor, no FBD math library beyond basic arithmetic, and no formal data word with bit-masking in the contact / coil field. The "analog flag" (AM1 – AM64) in LOGO! is a 16-bit storage cell, not a flag word in the S7 sense, and it does not support bitwise addressing through a contact graphic.

The two capabilities that do exist — and that solve roughly 90 % of the field requirements — are the network input (NI) and network output (NQ) terminals on the FBD canvas, and the marker byte (MB) grouping of digital flags. Mastering these is the key to bit-level work in LOGO! 8.

3. LOGO! 8.FS4 Memory Model

The LOGO! 8.FS4 (Siemens order number family 6ED1052-xxx08-0BA1, firmware 1.88.x and later for the FS4 variant) partitions user memory as follows:

Area Count Width Access mechanism
Digital markers M1 – M64 64 1 bit Direct contact / coil
Analog markers AM1 – AM64 64 16 bits (word) Analog input / output only
Network inputs NI1 – NI64 64 1 bit Direct contact (read-only)
Network outputs NQ1 – NQ64 64 1 bit Direct coil (write-only)
VM area V0.0 – V1023.7 1024 bytes 1 bit / 1 byte / 1 word Block parameters (VW0, V0.0, VB0)

Within the VM area, bit addressing Vx.y maps byte x, bit y. Network inputs NI1 – NI8 share the first byte (V0.0V0.7) and network inputs NI9 – NI16 share the second byte (V1.0V1.7). This is the gateway for accessing the individual bits of a 16-bit Modbus word VW0. Refer to the LOGO! 8 System Manual (edition 06/2021) for the canonical memory map.

4. Marker Byte Layout and Reserved Bits

Eight digital markers are grouped into a marker byte for ease of programming and for direct Modbus access through holding register 4xxxx when byte-level access is desired. The mapping is:

Byte Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
MB1 M8 * M7 M6 M5 M4 M3 M2 M1
MB2 M16 M15 M14 M13 M12 M11 M10 M9
MB3 M24 M23 M22 M21 M20 M19 M18 M17
MB4 M32 M31 * M30 * M29 * M28 * M27 * M26 * M25 *
MB5 M40 M39 M38 M37 M36 M35 M34 M33
MB6 M48 M47 M46 M45 M44 M43 M42 M41
MB7 M56 M55 M54 M53 M52 M51 M50 M49
MB8 M64 M63 M62 M61 M60 M59 M58 M57
Reserved markers (asterisked in the table). M8 is the LOGO! TD / TDE backlight flag. M25 starts the analog comparator function block outputs. M26 – M31 are used by the analog threshold trigger (AT) function blocks. Writing to these bits from a contact or coil is silently ignored by the LOGO! 8 firmware, so they read back as 0 in the marker byte. Do not use them as free flags for Modbus bit mapping.

The reserved range M25 – M31 effectively removes MB4 (eight bits) and bit 7 of MB1 (M8) from any 16-bit fan-out. Practical workarounds use M1 – M7, M9 – M24, and M32 – M64, giving 56 freely-usable bits in seven clean bytes plus the top 3 bits of MB4.

5. Solution A: Use Network Inputs to Read Bits of VW0

When the Modbus master writes a holding register to the LOGO! slave, the firmware updates the corresponding VW address inside the VM area. The recommended approach in LOGO!Soft Comfort V8.3 is to reference the bits of that word directly through the network input contacts NI1 – NI16:

  1. In the LOGO! hardware configuration, define the slave's Modbus table (for example, holding register 40001 maps to VW0).
  2. On the FBD canvas, drag NI1 to the first contact of the alarm rung. NI1 = bit 0 of VW0, NI2 = bit 1, continuing through NI16 = bit 15.
  3. Connect each contact's output to the appropriate coil, function block input, or downstream OR rung.

No AND, masking, or shifting is required: the LOGO! runtime already separates the byte into individual Boolean terminals. The result is a clean 16-line flag fan-out from a single 16-bit register, with no block-budget impact and no scan-time penalty.

6. Solution B: Pack Local Flags into a Word with Network Outputs

For the reverse direction (LOGO! → master), connect the coils of NQ1NQ16 to the 16 local conditions. NQ1 corresponds to bit 0 of VW0, which the master reads as the LSB of holding register 4xxxx. The mapping is:

Network pin Bit position Hex mask within VW0 Decimal weight
NQ1 bit 0 (LSB) 0x0001 1
NQ2 bit 1 0x0002 2
NQ3 bit 2 0x0004 4
NQ4 bit 3 0x0008 8
NQ5 bit 4 0x0010 16
NQ6 bit 5 0x0020 32
NQ7 bit 6 0x0040 64
NQ8 bit 7 0x0080 128
NQ9 bit 8 0x0100 256
NQ10 bit 9 0x0200 512
NQ11 bit 10 0x0400 1024
NQ12 bit 11 0x0800 2048
NQ13 bit 12 0x1000 4096
NQ14 bit 13 0x2000 8192
NQ15 bit 14 0x4000 16384
NQ16 bit 15 (MSB) 0x8000 32768

The master's read of that register returns the OR of all 16 NQ coil states. To prevent bit flicker from fast scan updates, drive the NQ coils with latching (S / R) coils rather than standard energise coils.

7. Counting Set Bits: A Pure LOGO! Implementation

LOGO!Soft Comfort V8.3 does not provide a population count. To compute "how many of the 16 bits are 1" in a single scan cycle, build a 16-stage AND / compare cascade. The approach uses the Analog AND (AA) and Analog Threshold Trigger (AT) function blocks:

  1. Connect VW0 to input Ax of an AA block whose Ay parameter is set to 1 (0x0001). The output (A→) holds 0x0001 if bit 0 is set, 0x0000 otherwise.
  2. For each of the remaining 15 bits, add one AA block with Ay = 2^(n-1) (so 2, 4, 8, …, 32768). Configure the AT block downstream with threshold = 1 and gain = 1 to fire a one-cycle pulse when the masked value is non-zero.
  3. Use a chain of Up counters (or an OR-rung into a single Up/Down counter) to sum the 16 boolean pulses. The counter value is the population count, in the range 0 – 16.
The AA + Ay = 2^(n-1) cascade returns the bit value (its positional weight), not the count. To obtain a true population count, compare each masked bit against 0 using an AT block (threshold = 1, gain = 1) and then sum the 16 boolean pulses with an OR-rung + counter. With 16 AA blocks, 16 AT blocks, and one Up/Down counter, the implementation occupies roughly 33 blocks of the 400-block program budget on a LOGO! 8.FS4. A 32-bit popcount (two holding registers) doubles the count to ~66 blocks.

A leaner alternative: instead of counting, use the 16 NI bits to drive 16 individual digital markers (M1 – M7, M9 – M17), then build a priority encoder ladder with mutual-exclusion OR rungs. The encoder produces a single 4-bit output code in VW10 identifying the highest-priority active alarm, which the master reads directly. This consumes roughly 8 blocks, avoids the count overflow problem, and is the approach used in most field installations.

8. Step-by-Step: Decomposing a Modbus Holding Register

  1. Define the connection. Open LOGO!Soft Comfort V8.3 and navigate to Tools → Ethernet Connections. Add a Modbus TCP Slave (or a Modbus RTU Slave when using the LOGO! CMK2000 module). Note the slave ID, the IP, the TCP port (502 default), and the start address of the holding register table (e.g. 0001).
  2. Map the VM area. In the slave configuration, the first four holding registers map to VW0, VW2, VW4, VW6 of the VM area. The registers from 40005 onward map to VW8, VW10, etc. The exact mapping is documented in the LOGO! 8 System Manual, section 4.4.3.
  3. Drop NI contacts on the canvas. Drag the NI1 (bit 0) through NI16 (bit 15) contacts to the rung where each alarm is handled. To reference bits from VW2, use NI17 through NI32.
  4. Assign actions. Connect the contact outputs to coils, function block inputs, or OR rungs that build the application logic.
  5. Simulate locally. In LOGO!Soft Comfort, open Tools → Simulation. Force VW0 = 0x0005. NI1 and NI3 contacts close; the corresponding coils energise. The simulation panel shows the live NI state.
  6. Online test. Transfer the program to the LOGO! 8.FS4 over Ethernet. From the Modbus master, write 0x00A3 to register 40001. Verify with a Modbus scanner (Modbus Poll, CAS Modbus Scanner, or similar) that NI1, NI2, NI6, and NI8 (bits 0, 1, 5, 7) close on the LOGO! HMI display.

9. Limitations of LOGO!Soft Comfort V8.3

  • No bit-shift on analog values. The Shift Register (SR) block is digital only. There is no ROL / ROR / SHL / SHR instruction for the AM or VM word types. This is the primary reason the user request to "shift bytes to look at the LSB or MSB" is not directly satisfiable in this software.
  • No word compare against mask. The Compare block (CMP) supports <, ≤, =, ≥, >, ≠ on analog values, but cannot perform an AND test. The AA block performs AND, not test-against-mask, and the result must be compared to zero with an AT block to recover a Boolean.
  • No bit-test on AM. You cannot address AM1.3 in a contact field. Bit addressing is only available on the VM area (V0.0) and on the special NI / NQ terminals. To work on a single AM, copy it into a VW first.
  • Reserved marker collisions. M8 and M25 – M31 are reserved. Using them in a 16-bit fan-out silently drops those bits to 0 with no diagnostic in the standard compiler output.
  • Block budget. The 0BA8.FS4 base unit provides 400 blocks. A 16-stage popcount consumes 30+ blocks before the first rung of user logic, so reserve at least 50 blocks per popcount instance to leave room for the rest of the application.
  • Modbus update rate. With the default LOGO! 8 cycle time of 10 – 50 ms (CPU type dependent), the network inputs are sampled once per cycle. High-speed bit toggling at the master (> 100 Hz) can be missed.

10. Verification Procedure

  1. Open Tools → Online → Test in LOGO!Soft Comfort. Force VW0 to 0x0000, 0x0001, 0x8000, and 0xFFFF in turn. Watch the NI1 – NI16 contact state indicators flip in the expected pattern.
  2. Set a breakpoint on the AA block (V0.0 AND 0x0001) and confirm the analog value output is 1 when NI1 is high and 0 when NI1 is low.
  3. For the popcount cascade, set VW0 to known values (0x0001 → expect 1; 0x0003 → expect 2; 0x00FF → expect 8; 0xFFFF → expect 16) and verify the counter output against a hand calculation or a PC reference such as __builtin_popcount.
  4. Run the LOGO! in cycle mode for at least 1 hour with VW0 toggled by a Modbus master script (alternating 0x5555 / 0xAAAA every 100 ms). Confirm no watchdog events in the LOGO! diagnostic log (Tools → Diagnostics → Log).
  5. From the LOGO! built-in HMI (TDE or LOGO! 8 with display), open Status → Parameters and verify the live counter value matches the expected population count.

11. Comparison Table: LOGO! 8 vs S7-1200 Bit Operations

Operation LOGO! 8.FS4 (LOGO!Soft Comfort V8.3) S7-1200 (TIA Portal V17+)
Read bit n of a word Use NI(n+1) contact bound to VWx "DB".MyWord.%X0, %X1, …
Count set bits in 16-bit word 16 × AA + 16 × AT + counter (≈33 blocks) Single instruction in SCL or LAD/FBD
Mask a word with 0x00FF AA block, Ay = 255 Word AND, single rung
Shift right by 1 Not directly available on AM / VM SHR instruction
Set bit 5 of VW0 AA between two AMs, OR with old word "DB".MyWord.%X5 := 1
Bit-fan-out to 16 coils 16 NI contacts (0 blocks cost) Slice access with one MOVE
Popcount at scan ~3.5 ms typical at 16 bits (FS4) < 1 µs in SCL

12. Field-Proven Tips

  • Always reserve a free marker byte (M1 – M7 or M9 – M16) for the 16-bit fan-out. Avoid M8, M25 – M31. Document the bit assignment in a tag comment inside LOGO!Soft Comfort (right-click contact → Comment).
  • For a Modbus status word, drive NQ1 – NQ16 with latching (S / R) coils. Standard energise coils can flicker on slow scan times; the latch prevents false clear pulses during cycle overlap.
  • When the bit count exceeds 16 (e.g. 32 alarms in two holding registers), repeat the technique on VW2 and route both bytes through separate rungs. Do not attempt to OR them into a single 32-bit value — LOGO!Soft Comfort V8.3 has no double-word (DWORD) arithmetic.
  • For LOGO! 8.FS4 firmware 1.88.x and later, the LOGO! 8 supports up to 32 network input words and 32 network output words. Earlier 0BA8 firmware 1.81.x is limited to 8 words. Check the firmware via LOGO! menu → Diagnostics → SW Version before commissioning.
  • When using Modbus RTU, add the LOGO! CMK2000 communication module (order number 6ED1055-1MM00-0BA2) or the CM2020 BM (6ED1055-1MC00-0BA2). The mapping of NI / NQ to holding registers is identical between the two transports; the difference is the physical layer (RS-485 vs Ethernet).
  • If the application genuinely needs a 32-bit popcount, migrate to a LOGO! 8 with the S7-LOGO! Modbus/TCP bridge, or step up to a S7-1200 with a TM MODBUS TCP / RS485 communication module.

13. Troubleshooting Matrix

  • AA cascade outputs positional weight; no AT block to convert to Boolean
  • Symptom Likely root cause Fix
    NI1 – NI8 always 0; master writes succeed Register mapped to VW0 but master is writing to register 40002 (offset) Verify the start address in Tools → Ethernet Connections; LOGO! register 40001 = VW0, 40002 = VW2
    Specific NI always 0 (e.g. NI6) Reserved bit in the underlying marker byte; the bit position corresponds to M25 in MB4 Reassign the flag to a free bit (M1 – M7, M9 – M24, M32 – M64)
    NI bits flicker at the scan rate Master is writing faster than the LOGO! scan time Reduce master poll rate to < 10 Hz, or latch at the master side
    Popcount returns the bit weight, not the count Add AT block (threshold = 1) per stage, then sum with an Up counter
    Compile error: "Block limit exceeded" 16-stage popcount consumed > 30 blocks Reduce to priority encoder, or migrate to S7-1200
    Master reads back 0 from VW0 even though NQ1 is high Wire break on RS-485, or slave ID mismatch Verify with CAS Modbus Scanner; check termination resistor (120 Ω) at both ends

    14. Related Siemens Documentation

    How do I access bit 0 of a Modbus holding register on LOGO! 8?

    Map the register to VW0 in the Modbus slave configuration. On the FBD canvas, drop the NI1 contact — NI1 corresponds to bit 0 (LSB) of VW0. NI2 is bit 1, continuing through NI16 for bit 15. No shifting, masking, or auxiliary logic is required.

    Why are M8, M25, M26, M27, M28, M29, M30, and M31 not usable as free flags?

    These markers are reserved by the LOGO! 8 firmware. M8 controls the TD / TDE backlight. M25 starts the analog comparator function block outputs. M26 – M31 are used by the analog threshold trigger (AT) function blocks. Writing to them from a contact or coil is silently ignored. Use M1 – M7, M9 – M24, and M32 – M64 instead.

    Can LOGO!Soft Comfort V8.3 count the number of set bits in a 16-bit word?

    Not directly. The software has no popcount instruction. You can build one from 16 Analog AND (AA) blocks (each masked with 2^n), 16 Analog Threshold Trigger (AT) blocks (threshold = 1), and one Up / Down counter. Expect to consume 30+ blocks of the 400-block program budget on a LOGO! 8.FS4.

    How do I send 16 local conditions to a Modbus master as one register?

    Drive NQ1 through NQ16 from the 16 conditions. The LOGO! runtime ORs these bits into VW0, and the master reads VW0 as holding register 4xxxx. NQ1 is the LSB; NQ16 is the MSB. Use latching (S / R) coils to prevent flicker on fast scan updates.

    Does the LOGO! 8.FS4 support Modbus RTU as well as TCP?

    Yes. The 0BA8.FS4 base unit supports Modbus TCP natively on the Ethernet port (port 502). For Modbus RTU over RS-485, add the LOGO! CMK2000 communication module (6ED1055-1MM00-0BA2) or the CM2020 BM (6ED1055-1MC00-0BA2). The mapping of NI / NQ to holding registers is identical between the two transports.

    What is the difference between NI contacts and the VM area for bit access?

    Both expose the same bit. NI1NI16 are pre-bound contacts that read the first network input word VW0. V0.0V1.7 are general bit references inside the VM area that you can wire to any block parameter. Use NI contacts for clarity in standard logic; use Vx.y references when you need to pass the bit to an analog input of an AA / AT block.

    Back to blog