Scan time, missed pulses, and fast inputs

The Core Idea

A programmable logic controller (PLC) program observes inputs at particular update times rather than watching every physical change continuously. A pulse can occur between those observations, so the relationship between signal duration and update timing matters.

What you will learn

  • Explain why an input pulse shorter than the scan time can be missed completely: the program sees an input only when a scan reads it.

  • Change the scan time and predict roughly how many short pulses an up counter (CTU) will count.

  • Count each part exactly once, whatever the scan time, by counting the moment the sensor turns ON rather than every scan it is ON.

  • Recognize when a pulse is too short or too fast for ordinary scanned inputs, so a high-speed counter input or an interrupt input is needed.

Why it matters

A counter can only react to an event it receives. Understanding the observation timing helps you distinguish missing input information from a wrong counting instruction.

The problem

A photo-eye at the end of a conveyor counts finished parts. Each part blocks the beam for 30 ms as it passes, and about one part passes every second. An up counter adds one each time the photo-eye input turns ON.

SignalMeaning
PART_SENSORTRUE while a part blocks the photo-eye beam; each part keeps it TRUE for 30 ms. This is a digital input.
RESET_PBTRUE while the Reset pushbutton is pressed. This is a digital input.
PART_COUNTAn up counter (CTU). Its accumulated value is the number of parts counted, in parts. The COUNTED display shows it.

The scan lesson showed that the controller reads every input once, at the start of each scan, then executes the program and writes the outputs. Between two input reads, the program works from the values it read last time.

In the lesson simulator, a pulse generator plays the parts. It turns PART_SENSOR ON for 30 ms out of every 1030 ms, so a part passes about once a second. The spacing is deliberately not a whole number of scans, so parts arrive at different points in the scan, just as real parts do. The simulator starts with a 100 ms scan, and the Scan time selector changes it from 20 ms to 500 ms. Real controllers often scan in a few milliseconds to a few tens of milliseconds, and the time changes as the program grows and as the controller handles communication. The slow scan here makes the effect easy to see.

Predict

Leave the scan time at 100 ms and watch for about ten seconds, which is about ten parts. The SENSOR light shows the input the way the program read it, so it lights only for the parts a read caught, for one scan each. The elapsed time in the scan stepper tells you how many parts have passed: one every 1.03 s.

Try it

Keep using the demo above. Change the scan time, hold RESET for a moment, and count the parts that pass in the next ten seconds or so. Write down COUNTED for each setting:

Scan timeParts counted out of about 10
20 ms?
50 ms?
100 msabout 3
200 ms?
500 ms?

Show the counts you should see

Scan timeParts counted out of about 10
20 msAll 10
50 msAbout 6
100 msAbout 3
200 ms1 or 2
500 msUsually 0, sometimes 1

At 20 ms every part counts, because a 30 ms pulse is longer than the 20 ms between reads, so a read always falls inside it. Once the scan is longer than the pulse, the longer the scan, the more parts slip through between reads.

At 500 ms, try tapping RESET quickly instead of holding it. A tap shorter than the scan can be missed too. An operator's press normally lasts far longer than a real controller's scan, which is why pushbuttons work fine; short sensor pulses are the ones that get lost.

Look closer

Pause the demo and think about the second part. It blocks the beam from 1030 ms to 1060 ms. With a 100 ms scan, the program reads the sensor at 0 ms, 100 ms, 200 ms, and so on:

Input read atThe beam is…The program reads PART_SENSOR as
1000 msclear; the part arrives 30 ms laterFALSE
1100 msclear; the part left 40 ms earlierFALSE

No read happened between 1030 ms and 1060 ms, so no scan ever saw that part. The counter did nothing wrong. It counts every OFF-to-ON change in the input it is given, and in this input nothing changed. Now take the fourth part, from 3090 ms to 3120 ms: the read at 3100 ms lands inside it, SENSOR lights for that one scan, and COUNTED goes up by one.

So two things must happen for every part to count. A read must fall inside every pulse, which needs the ON time to be at least as long as the scan. A read must also fall in every gap between pulses, so the counter sees the input turn OFF before the next part arrives, which needs the OFF time to be at least as long as the scan as well.

Change it

A pulse shorter than the scan gets missed. A pulse longer than the scan is read by several scans in a row, which causes a different problem when the program counts the wrong thing. In this version the parts are slower: each holds PART_SENSOR ON for 250 ms, still one part every 1.03 s. Its single rung adds one to PART_TOTAL, an integer in parts shown on TOTAL, on every scan that reads the sensor ON.

  1. At 100 ms, watch TOTAL. Each part adds 2 or 3.

  2. Change the scan time to 20 ms. Each part now adds 12 or 13. The total depends on the scan time, not on the parts.

  3. Change the normally open PART_SENSOR contact to a rising-edge contact (P in the palette). It passes only during the one scan in which the sensor turns ON. This is rising-edge detection, the same job R_TRIG does.

  4. Compare 20 ms, 100 ms, and 200 ms again. Each part now adds exactly one. Then try 500 ms: the 250 ms pulse is shorter than the scan, and about half the parts are missed again. Run the checks.

Show the guided change

Replace the normally open PART_SENSOR contact with a rising-edge contact and keep the add instruction. The contact passes in the scan where PART_SENSOR changes from FALSE to TRUE and blocks in every later scan while the part is still there, so one part adds one however many scans read it. Counting when the part leaves, with a falling-edge contact, also gives one count per part and passes the checks. An up counter works the same way: it only counts when its rung turns from false to true, which is why the demo's counter never counted a part twice.

Check yourself

Build a batch counter from an empty program. BATCH_DONE (the BATCH DONE lamp) must turn on when five parts have been counted and stay on until RESET is pressed. Pressing RESET also starts the count again from zero. The tags are PART_SENSOR, RESET_PB, PART_COUNT (an up counter), and BATCH_DONE.

Press PART to play a part. The checks play parts that last several scans, parts with only one scan between them, and one part whose pulse starts and ends between two input reads. You can also try the scan time selector here: at 500 ms, a quick tap on PART is missed, just like a short pulse. Run the checks as often as you need.

Hint 1

Which instruction adds one each time its rung turns from false to true, and keeps the total from scan to scan?

Hint 2

Use an up counter on PART_COUNT with a preset of 5. Which of the counter's bits turns on when the accumulated value reaches the preset?

Hint 3

Drive BATCH_DONE from PART_COUNT.Done with an ordinary output coil, and add a rung where a normally open RESET_PB contact feeds a timer/counter reset on PART_COUNT.

Show the worked solution

Three rungs:

  1. Normally open PART_SENSOR contact → up counter PART_COUNT, preset 5.

  2. Normally open PART_COUNT.Done contact → ordinary output coil BATCH_DONE.

  3. Normally open RESET_PB contact → timer/counter reset on PART_COUNT.

The counter adds one for each new part, however many scans it lasts, and its done bit turns on at 5. The reset clears the accumulated value and the done bit, so the ordinary coil turns BATCH_DONE off. Comparing the accumulated value with 5 (greater than or equal) instead of using the done bit also passes.

The check with the part from 503 ms to 507 ms passes because no program could count it. The checks read the inputs every 10 ms, at 500 ms and at 510 ms. That part came and went between those two reads, so the input never changed in any scan, and the batch needed a sixth part.

Now explain one of those checks. The checks read the inputs every 10 ms. In one of them, the fifth part blocks the beam from 503 ms to 507 ms, and the batch is not done until a sixth part arrives.

Last, decide when scanned inputs are not enough. The controller's scan takes 5 to 15 ms, depending on what it is doing.

  • A. An operator's Start pushbutton, pressed for at least 200 ms.

  • B. A photo-eye that boxes block for 300 ms each, about one box per second.

  • C. A shaft encoder that makes 3,000 pulses per second, each 0.15 ms long.

  • D. A registration-mark sensor on a fast labeling machine: a 2 ms pulse that the program must act on within 1 ms.

What happened and why

The program sees the field only at input reads. Between two reads, an input can turn ON and back OFF without the program ever knowing. Whether a pulse shorter than the scan is seen depends on luck: on where its 30 ms fall relative to the reads. That is why the count fell from all 10 parts at a 20 ms scan to about 3 at 100 ms, while the counter worked correctly the whole time.

To see every pulse, a scanned input needs both the ON time and the OFF time of the signal to be longer than the longest scan, plus the input's filter delay (input modules filter their inputs for a few milliseconds to reject electrical noise). Leave a generous margin: a common rule of thumb is at least twice the longest scan for both. When a signal is too short or too fast for that, the choices are:

  • Make the pulse longer at the source. Use a longer target or flag, a sensor with a built-in pulse-stretch or off-delay setting, or a slower line speed.

  • Make the scan shorter. Shorten the program, or run the time-critical logic in a separate task that runs more often. This only helps if the shorter scan stays reliably shorter than the pulse.

  • Use a high-speed counter input. Dedicated input hardware counts pulses on its own, independent of the scan, and the program reads the accumulated count. Encoders, pulse-output flow meters, and fast product counts use these.

  • Use an interrupt input. The controller pauses its scan and runs a short routine as soon as the input changes, for a response that cannot wait for the next scan, such as recording the moment a mark passes.

High-speed counter and interrupt inputs are configured in the controller's hardware settings, and every input has a maximum pulse rate and a minimum pulse width in its specifications. Check those numbers against the signal before choosing an input.

The guided change showed the opposite problem. A pulse longer than the scan is read by several scans in a row, so counting every scan the sensor is ON counts scans, not parts, and the total changes whenever the scan time does. Count the change instead: a counter or a rising-edge contact counts each part once.

Show the math

When a pulse is shorter than the scan, the chance that a read lands inside it is the pulse width divided by the scan time:

Scan timeChance a 30 ms pulse is seenOut of 10 parts
20 ms30 ÷ 20 is more than 1, so every pulse10
50 ms30 ÷ 50 = 0.66
100 ms30 ÷ 100 = 0.33
200 ms30 ÷ 200 = 0.151.5
500 ms30 ÷ 500 = 0.060.6

For a counter to see every pulse, each ON time and each OFF time must last at least one scan, so the fastest pulse train it can follow has a period of two scans. With a 10 ms scan that is 1 ÷ (2 × 0.010 s) = 50 pulses per second at the very most, before any margin or filter delay. The encoder in case C makes 3,000 pulses per second, sixty times faster than that.

Common mistakes

  • Blaming the counter for missing parts. Cause: assuming the counter skipped a count. Symptom: COUNTED is lower than the number of parts, and SENSOR never lit for the missing ones. Fix: compare the pulse width and the gap between pulses with the longest scan time; the counter only counts changes it sees.

  • Counting every scan the sensor is ON. Cause: a normally open contact feeding an add-one instruction. Symptom: the total rises by several per part and changes when the scan time changes. Fix: count the rising edge with a counter or a rising-edge contact.

  • Checking only the ON time. Cause: forgetting that the input must also be seen OFF between pulses. Symptom: two parts close together count as one. Fix: make sure the gap between pulses is also longer than the longest scan.

  • Designing for today's scan time. Cause: measuring the scan once on a small program. Symptom: counts that were right go missing after the program grows or communication increases. Fix: design for the longest scan, with margin, or use a high-speed counter input.

Platform notes

Logix 5000 controllers run logic in tasks. A periodic task runs its routines at a fixed interval, and an event task runs when a configured trigger occurs, such as an input module reporting a change of state. Fast pulse counting uses a high-speed counter module. Most Micro800 controllers also have built-in high-speed counter (HSC) inputs on their embedded input/output (I/O).

High-speed counters (HSC) are available on built-in inputs or technology modules. A hardware interrupt organization block, such as OB 40, runs when a configured input edge occurs, and cyclic interrupt organization blocks run logic at a fixed interval. Digital inputs have a configurable input filter time, which must be shorter than the pulses you need to see.

Enable JavaScript to run the embedded simulator and complete the interactive exercises.