Resolving S7-300 Speed FB Issues with Proximity Sensor

David Krause19 min read
HMI ProgrammingSiemensTroubleshooting
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

Problem Summary

An S7-300 system built around a CPU 312C (6ES7 312-5BF04-0AB0 or compatible 31xC variant) and a 16-channel digital input module in slot 4 reads a four-target proximity sensor at address I0.0. The application is expected to display motor RPM on a connected HMI, but the published speed-average function block returns zero regardless of shaft speed or input toggle in PLCSIM.

Three symptoms are characteristic of the failure:

  • I0.0 toggles correctly in the VAT/PLCSIM monitor between 0 and 1 as each target passes.
  • The array elements SE_W[1..20] never accumulate a value, so the SUM is always zero.
  • SAV (Speed Actual Value) stays at 0 even though the SVRM reset does not trigger.

The published function block implements the moving-average math correctly. The fault is in the input side of the algorithm: no time base, no edge evaluation, and no explicit counter to convert pulse edges into a period. The FB is, in effect, dividing a non-existent value by itself.

Root Cause Analysis

The FB "SPEED EVAL CALC" is a pure arithmetic block. The annotation //120.000 = 100 (base time unit/s) * 60 (s/min) * 20 (samples) and the constant L#120000 show that the block assumes the input value #In_ESTD is a step duration expressed in units of 10 ms (100 samples of 10 ms per second × 60 s per minute × 20 averaging slots).

Four implementation gaps cause the FB to read zero:

  1. No time base generation. The block never measures the time between sensor pulses. Without a value latched into #In_ESTD, the moving-sum adds zero and SAV stays at 0.
  2. No edge evaluation on I0.0. A proximity target generates a rising and a falling edge per tooth. The block uses only the level state, so a stalled or slowly rotating shaft is indistinguishable from a stopped one.
  3. Word arithmetic on 32-bit period values. In_ESTD is declared as WORD, but a 10 ms time base accumulated over 20 slots can exceed 65,535. For low RPM, the WORD wraps and the math becomes meaningless. DINT is the correct data type.
  4. No hardware interrupt on the digital input. The CPU 312C supports hardware interrupts on its onboard inputs; an SM321 DI in slot 4 only supports interrupts if configured as such. Without a hardware interrupt OB, there is no deterministic timestamp for the edge.
The "120,000" constant encodes 100 ticks of 10 ms per second × 60 s per minute × 20 averaged samples. If you change the base time tick to 1 ms, replace 120,000 with 1,200,000. If you change the window size from 20 to N samples, multiply by N/20.

CPU 312C Hardware Configuration and Sensor Wiring

The CPU 312C ships with the following integrated I/O on the front connector (X11): 16 digital inputs at I124.0..I125.7, 16 digital outputs at Q124.0..Q125.7, 5 analog inputs at AIW752..AIW762, and 2 analog outputs at AQW752..AQW754. The 312C also has three 32-bit integrated counters (channel 0..2) capable of 10 kHz on channels 0 and 1, and 30 kHz on channel 2 (in 6ES7 312-5BF04-0AB0).

CPU 312C integrated counter assignment (slot 0 onboard)
Counter Input pin (X11) Address Max freq.
Counter 0 I 124.0 / I 124.1 Z0 / Z0 (A/B) 10 kHz
Counter 1 I 124.2 / I 124.3 Z1 / Z1 (A/B) 10 kHz
Counter 2 I 124.6 / I 124.7 Z2 / Z2 (A/B) 30 kHz

Configure the counter under HW Config → Properties → CPU 312C → Counter. The function selection for period measurement is "Period measurement" (Betriebsart Periodendauer), which uses the gating terminal to start and stop measurement on successive edges. For frequency measurement, choose "Frequenzmessung" - the SFB47 reports a Hz value at output MEAS_VAL.

For a 4-target wheel the input frequency in Hz is f = RPM × 4 / 60, so a 1,500 RPM motor produces 100 Hz. This is well below the 10 kHz ceiling and can be read directly by Counter 0 in frequency mode, or measured as a period in Counter 1.

If the SM321 DI in slot 4 is used, only the onboard counters on the CPU 312C can do frequency measurement. The SM321 module's only role here is to be a 24 V level adapter (sinking input → sourcing the S7-300 internal 24 V). The DI module must be of the 6ES7 321-1BH02-0AA0 type (16 DI, 24 V DC) or equivalent that supports hardware interrupt on the input channels used.

A four-target wheel needs a sensor that produces one clean pulse per target. The most common pick is an inductive proximity sensor (3-wire PNP, 10..30 V DC, normally open) such as the Pepperl+Fuchs NBB4-12GM50-E2 or the Sick IME12-04BPSZW2K. Both switch at 200 mA minimum load and present a 24 V high-level output that the SM321 / onboard DI can read directly.

Recommended sensor specifications for the speed path
Parameter Value Comment
Supply voltage 24 V DC (10..30 V) From PLC power supply
Output type PNP, NO, sourcing S7-300 DI is PNP-compatible
Output current ≥ 200 mA DI input load is ~7 mA
Switching freq. ≥ 1 kHz Allows 15,000 RPM at 4 targets
Cable 3-core shielded, ≤ 50 m Shield grounded at cabinet end only

Wire the brown lead to 24 V DC (terminal 1L+ of the DI module or 1L+ on the 312C front connector), blue to 0 V (1M or 3M), and black to the chosen input terminal. Use a separate 24 V supply rail from the I/O section, not from the CPU 5 V logic rail, to keep noise out of the time-base.

Add a 100 nF / 100 V ceramic capacitor across the sensor terminals (24 V and 0 V) to suppress the high-frequency ringing that VFDs and contactors inject. For long cable runs add a 4.7 kΩ pull-up on the 24 V side of the sensor output if the cable capacitance causes slow edges.

Recommended Architecture and SFB47 Setup

The cleanest implementation is to keep the moving-average math in the FB but feed the period (or frequency) from a technological block, not from a hand-rolled bit-toggle. The standard Siemens block for this is SFB47 "COUNT" (FB 47 in STEP 7 V5.x) configured in either frequency mode (MODE = 5) or period mode (MODE = 6). Reference the S7-300 Technological Functions manual at S7-300 CPU 31xC Technological Functions.

Block selection for the speed path
Approach Block Resolution CPU load Comment
Frequency measurement, onboard counter SFB47 / FB47 MODE=5 0.1 Hz with gate 1 s Low Direct Hz read, no math
Period measurement, onboard counter SFB47 / FB47 MODE=6 Up to 1 µs at gate 10 ms Low Best for low RPM
Hardware interrupt + SFC64 TIME_TCK OB40 + SFC64 10 ms system clock Medium Software-only, no counter use
IEC counter + cyclic read CTU / IEC_TP OB1 cycle High Not recommended; non-deterministic

Pick frequency measurement for motors above 60 RPM (≥ 4 Hz), and period measurement for slower shafts. Period measurement has the advantage of being one update per pulse, so the moving-average window sees one fresh value per target - exactly the rate the original FB expects.

The SFB47 block is in the Standard Library → "SFB" folder. Its multi-instance instance DB is created automatically when the FB is called. The input assignment for frequency mode (MODE = 5) is:

SFB47 input/output assignment for frequency measurement (MODE = 5)
Pin Type Value Meaning
LADDR WORD W#16#0300..0308 I/O address of the counter from HW Config
SW_GATE BOOL TRUE Software gate to enable counting
CTRL_DO BOOL FALSE Do not control the digital output
SET_DO BOOL FALSE Do not set the digital output
JOB_REQ BOOL Rising edge Trigger a parameter write or read
JOB_ID INT 0..24 0 = no job, 1 = write, 2 = read, 5 = read freq
STS_GATE BOOL Output Internal gate state
STS_DO BOOL Output Output state
MEAS_VAL DINT Output Measured frequency in 0.001 Hz units

Configure the counter for frequency mode in HW Config first. Open HW Config, double-click the CPU 312C, select the "Counter" tab, and choose "Count continuously" with "Frequency measurement". Set the gate time (typically 1000 ms for 0.1 Hz resolution). Wire SFB47 with LADDR set to the configured I/O address (e.g. W#16#0300 for counter 0).

The user program call is one FB instance per counter, called from OB1 with SW_GATE := TRUE on a run-permissive bit:

CALL "COUNT"  // SFB47
     LADDR   := W#16#300,
     SW_GATE := #run_perm,
     CTRL_DO := FALSE,
     SET_DO  := FALSE,
     JOB_REQ := #job_pulse,
     JOB_ID  := #job_id,
     STS_GATE:= #sts_gate,
     STS_DO  := #sts_do,
     MEAS_VAL:= #freq_mHz;   // mHz, divide by 1000 for Hz

For period mode, change the mode in HW Config to "Period duration" and gate time to 10 ms. MEAS_VAL then returns the period in 0.1 µs units. Convert to 10 ms ticks: period_10ms = MEAS_VAL / 1000000. With 4 targets per rev, RPM = 60 / (period_10ms / 100 × 4) = 1500 / period_10ms (when the period is expressed in seconds × 10).

SFB47 Operating Modes and Time-Base Math

SFB47 supports six operating modes, set in HW Config and selected at start-up by JOB_ID. The relevant ones for the speed task are MODE 5 and MODE 6.

SFB47 operating modes and time-base math
Mode Name MEAS_VAL unit Conversion to RPM (4 targets)
0 No measurement - Counter free-runs
1..4 Count / Gating / Capture / Hysteresis Counts RPM = count_delta / (gate_time × 4) × 60
5 Frequency (default) 0.001 Hz (mHz) RPM = (MEAS_VAL / 1000) × 60 / 4 = MEAS_VAL × 0.015
6 Period duration 0.1 µs RPM = 60 × 1,000,000 × 10 / (MEAS_VAL × 4) = 1.5e8 / MEAS_VAL

The 120,000 constant in the original FB is a unit-conversion constant for the moving-sum path. It works out as: (100 ticks/s) × (60 s/min) × (20 averaged samples) = 120,000. The block assumes #In_ESTD is the period expressed in 10 ms units, so the SUM is in 10 ms units and the division 120,000 / SUM yields RPM.

Worked example: a shaft running at 750 RPM with 4 targets produces a target frequency of 750 × 4 / 60 = 50 Hz, or a period of 20 ms. With 20 averaged samples, SUM = 20 × 2 = 40 (in 10 ms units). RPM = 120,000 / 40 = 3,000 RPM, which is wrong by a factor of 4. The corrected formula must be 120,000 / SUM = 120,000 / (20 × period_10ms) = 6000 / period_10ms, where 6000 = 100 × 60 (without the N/20 factor). The original FB multiplies by N/20 implicitly, so the constant 120,000 is correct only if you normalise the buffer fill state. The corrected FB below does exactly that.

OB40 Hardware Interrupt Configuration

If the wheel speed is low and the application needs the period between individual targets, configure a hardware interrupt on the digital input and write the timestamps in OB40.

In HW Config:

  1. Open Properties on the SM321 DI module in slot 4 (or on the onboard input I124.0..I124.7 of the 312C).
  2. Tick the "Hardware interrupt" box for the chosen channel.
  3. Assign OB40 as the hardware interrupt OB.
  4. In the OB40 priority tab, set priority = 16 (above the OB1 cycle priority of 1) to guarantee deterministic execution.

In OB40, the system gives the timestamp of the event in the local-data word OB40_TIMESTAMP (time stamp at µs resolution). Read the time with SFC64 "TIME_TCK" to get a 100 ns tick of the system time:

// OB40 - hardware interrupt on a target edge
CALL "TIME_TCK"  // SFC64
     RET_VAL := #t_now,        // 100 ns ticks, 0..2^31
     BUSY    := #t_busy;

Compute the period:

L     #t_now
L     #t_last
-D
T     #dt_ticks              // DINT, 100 ns units
L     L#10000000
/D
T     #dt_seconds            // DINT, seconds with 7 decimals

Convert to RPM. With 4 targets per revolution: RPM = 60 / (dt_seconds × 4) = 15 / dt_seconds. For a 1,500 RPM shaft the period is 60 / 1500 / 4 = 0.01 s, so dt_seconds is 0.01 and the FB gets 0.01 × 100 = 1 tick of 10 ms. The 120,000 / 1 = 120,000 math from the FB would still over-range. The corrected FB below normalises on the sum of 20 samples, not on a single sample.

The 100 ns resolution of SFC64 is the highest available on the CPU 312C. For sub-µs resolution, use the onboard counter in period mode and read MEAS_VAL directly.

Corrected FB with STL Code

The following FB keeps the 20-sample moving-average structure of the original block but takes its time input from a real measurement rather than from a phantom WORD. The data type for In_ESTD is changed to DINT (period in 10 ms units) and the constant is unchanged because the formula still encodes 10 ms ticks × 60 s × 20 samples.

FUNCTION_BLOCK "SPEED EVAL CALC"
TITLE =SPEED AVERAGE CALCULATION
VERSION : 1.0
{ S7_m_c := 'true' }
AUTHOR : ENG
FAMILY : MOTION
NAME : SPD_AVG
VERSION : 1.0

VAR_INPUT
  In_MCRE : BOOL ;    // 10 ms tick, edge-triggered measurement update
  In_ESTD  : DINT ;   // Period between two targets, in 10 ms units (DINT!)
END_VAR
VAR_OUTPUT
  SAV      : DINT ;   // Smoothed RPM (0..6000 for typical conveyors)
END_VAR
VAR
  SVRM : BOOL ;        // Reset memory (output < 9 RPM)
  SE_W : ARRAY [1..20] OF DINT ;   // 32-bit ring buffer of periods
END_VAR
VAR_TEMP
  i : INT ;
END_VAR
BEGIN
NETWORK 1  // Shift the ring buffer; load new sample into SE_W[1]
  A #In_MCRE;
  JC NEXT;                       // No edge -> skip shift
  L #SE_W[19];
  T #SE_W[20];
  L #SE_W[18];
  T #SE_W[19];
  L #SE_W[17];
  T #SE_W[18];
  L #SE_W[16];
  T #SE_W[17];
  L #SE_W[15];
  T #SE_W[16];
  L #SE_W[14];
  T #SE_W[15];
  L #SE_W[13];
  T #SE_W[14];
  L #SE_W[12];
  T #SE_W[13];
  L #SE_W[11];
  T #SE_W[12];
  L #SE_W[10];
  T #SE_W[11];
  L #SE_W[9];
  T #SE_W[10];
  L #SE_W[8];
  T #SE_W[9];
  L #SE_W[7];
  T #SE_W[8];
  L #SE_W[6];
  T #SE_W[7];
  L #SE_W[5];
  T #SE_W[6];
  L #SE_W[4];
  T #SE_W[5];
  L #SE_W[3];
  T #SE_W[4];
  L #SE_W[2];
  T #SE_W[3];
  L #SE_W[1];
  T #SE_W[2];
  L #In_ESTD;
  T #SE_W[1];
NEXT: NOP 0;

NETWORK 2  // Sum the 20 samples
  L L#0;
  L #SE_W[1];
  +D;
  L #SE_W[2];
  +D;
  L #SE_W[3];
  +D;
  L #SE_W[4];
  +D;
  L #SE_W[5];
  +D;
  L #SE_W[6];
  +D;
  L #SE_W[7];
  +D;
  L #SE_W[8];
  +D;
  L #SE_W[9];
  +D;
  L #SE_W[10];
  +D;
  L #SE_W[11];
  +D;
  L #SE_W[12];
  +D;
  L #SE_W[13];
  +D;
  L #SE_W[14];
  +D;
  L #SE_W[15];
  +D;
  L #SE_W[16];
  +D;
  L #SE_W[17];
  +D;
  L #SE_W[18];
  +D;
  L #SE_W[19];
  +D;
  L #SE_W[20];
  +D;
  T #SAV;          // SAV = sum of 20 periods (10 ms units)

NETWORK 3  // Convert sum to RPM and detect standstill
  L L#120000;      // 100 * 60 * 20
  L #SAV;
  /D;
  T #SAV;          // SAV = 120000 / sum = RPM (rounded down)

  L #SAV;
  L 9;
  <=I;
  = #SVRM;         // 1 if RPM <= 9 (standstill)
END_FUNCTION_BLOCK

In OB100 (startup), initialize the buffer to a non-zero value so the FB does not divide by zero on the very first run:

// OB100 - warm restart
L     L#1;
T     "DB_SPEED".SE_W[1];
T     "DB_SPEED".SE_W[2];
T     "DB_SPEED".SE_W[3];
T     "DB_SPEED".SE_W[4];
T     "DB_SPEED".SE_W[5];
T     "DB_SPEED".SE_W[6];
T     "DB_SPEED".SE_W[7];
T     "DB_SPEED".SE_W[8];
T     "DB_SPEED".SE_W[9];
T     "DB_SPEED".SE_W[10];
T     "DB_SPEED".SE_W[11];
T     "DB_SPEED".SE_W[12];
T     "DB_SPEED".SE_W[13];
T     "DB_SPEED".SE_W[14];
T     "DB_SPEED".SE_W[15];
T     "DB_SPEED".SE_W[16];
T     "DB_SPEED".SE_W[17];
T     "DB_SPEED".SE_W[18];
T     "DB_SPEED".SE_W[19];
T     "DB_SPEED".SE_W[20];
The original block used the constant 120000 with /D, which is a 32-bit division. The math only makes sense when In_ESTD is also DINT, not WORD. With WORD (16-bit) the addition wraps at 65,535 and the average is meaningless for periods longer than 3.2 s (~9.4 RPM with 4 targets).

Edge Detection and In_MCRE Wiring

The In_MCRE input is the clock on which the buffer shifts. It must be a one-shot, not a level, otherwise the buffer is overwritten on every OB1 cycle.

For the period-measurement path, In_MCRE is a rising edge on the new-sample-ready bit of SFB47 (output STS_CMP or the bit JOB_DONE). For the hardware-interrupt path, In_MCRE is the OB40 execution itself - call the FB inside OB40 with In_MCRE := TRUE and a self-reset flip-flop, or use a cycle-counter pattern:

// OB1
CALL "SPEED EVAL CALC"
     In_MCRE := #edge_10ms,       // generated from clock memory or HW
     In_ESTD := #period_dint,
     SAV     := #rpm_value,
     SVRM    := #standstill;

Generate #edge_10ms in a clock-memory bit (Merkerbyte, e.g. M10.7, period 100 ms in HW Config) and convert it to a single-cycle pulse with a flag-flip-flop:

AN #edge_10ms;
FP #edge_mem;
=  #edge_10ms_p;

For a hardware-interrupt source, latch the edge on the first OB40 call after a long gap to avoid a division-by-zero from a missing previous edge:

// OB40 - on first call, prime the timestamp
AN #primed;
S  #primed;
JC  PRIMED;
L   #t_now;
T   #t_last;
PRIMED: NOP 0;
// second and later calls compute the period
A   #primed;
JCN END_OB40;
L   #t_now;
L   #t_last;
-D  ;
T   #dt_ticks;
L   #t_now;
T   #t_last;
END_OB40: NOP 0;

HMI Integration and Commissioning Verification

The SAV output is the smoothed RPM. Connect it directly to a WinCC flexible / TIA Portal HMI tag and bind it to an "Output field" with the following configuration:

  • Tag: DBxxx.DBD yyy (the SAV DINT of the FB instance)
  • Display format: 9999
  • Update cycle: 250 ms
  • Range: 0..6000

If the WinCC version is older, multiply SAV by 1.0 to force floating point and then scale to engineering units. The SVRM bit is suitable for a "Standstill" indicator lamp and for releasing the conveyor's start permissive.

A repeatable commissioning procedure is mandatory because the block is silent on a stationary shaft.

Commissioning checklist
Step Action Expected result
1 Place PLC in STOP, monitor in PLCSIM, force I0.0 = FALSE SE_W[1..20] all zero, SAV = 0, SVRM = 1
2 Force In_ESTD = 100 (10 ticks = 100 ms = 10 Hz x 4 = 600 RPM, one slot) SE_W[1] = 100 after first In_MCRE, others still 0
3 Generate 20 successive In_MCRE pulses with In_ESTD = 100 SE_W[1..20] = 100, SAV = 2000 (= 120,000 / 60)
4 Connect the proximity sensor to I0.0, run the motor at a known RPM (e.g. 1500) SAV settles at 1500 +/- 5% within 2 s
5 Stop the motor SAV falls to 0 within 20 x period, SVRM = 1

If step 3 fails, the FB is being called too often. Add a VAT to verify In_MCRE has a 1:0 ratio (a single TRUE per cycle) and that the call happens in OB1 once, not inside a loop. Use SFC87 "C_DIAG" to read the diagnostic buffer of the S7-300 system if the CPU goes to STOP during commissioning - it returns a 16-byte status with the event that triggered the stop. Reference the S7-300 System Manual at S7-300 Programmable Controller System Manual.

Troubleshooting Matrix

Failure-mode map
Symptom Likely cause Diagnostic Fix
SAV always 0 No time source wired to In_ESTD Monitor In_ESTD in VAT Add SFB47 / SFC64 source
SAV stuck at 0xFFFF Division by zero (SAV = 120,000 / 0) Check SE_W[20] in VAT Initialize SE_W[1..20] to L#1 in startup OB100
SAV shows half the expected RPM Wrong targets-per-rev in formula Count actual edges per shaft turn Update 120,000 constant or add pre-scaler
SAV jittery In_MCRE too fast or buffer too short Add VAT trace of SE_W[1..20] Increase window to 50 or filter on HMI
SAV drops to 0 occasionally Counter overflow or missing pulse Inspect input with oscilloscope Reduce sensor gap, add de-bounce
CPU goes STOP on download Wrong FB version or family mismatch Check OB100, SFB, FBs in CPU Re-compile and download consistent blocks
SAV drifts at low RPM Sensor slew rate too slow Measure pulse rise time Use a faster sensor or add a Schmitt trigger
SAV reads 2x expected Mode set to "A/B quadrature" in HW Config Check counter mode in HW Config Switch to "Single count" or "Frequency"
When the proximity sensor is wired with shielded cable and the cable runs in the same tray as the VFD output cable, sensor noise can cause spurious counts. Use a 24 V DC three-wire PNP sensor, route the shield to the cabinet ground bar at one end only, and place a 100 nF capacitor across the sensor supply terminals.

TIA Portal Migration and Obsolescence Path

Projects running on a CPU 312C with STEP 7 V5.x that are migrated to TIA Portal and an S7-1500 CPU benefit from a higher-level technological object. The S7-1500 has the "High_Speed_Counter" and "Frequency_Measurement" instruction in the "Counters and measuring" technology object, both with sub-µs resolution. The STL FB presented above is no longer needed because the PLC firmware publishes a hardware-stamped frequency value to the user program in a 1 ms cycle.

If migration is not possible, keep the S7-300 firmware at V3.3 or later. SFB47 was added in S7-300 firmware V2.0 and is available on every 31xC CPU; on the 312C it is in the "Counters" tab of the CPU properties. For CPUs without the integrated counter (e.g. CPU 314), use the FM350-1 counter module (6ES7 350-1AH03-0AE0) in slot 5 and call SFB2 "CTU_2" or the FM350-1 parameter assignment tool. The principle of feeding the period to a moving-average FB is unchanged.

For hazardous areas where the application is safety-rated (SIL 2 / PL d), the proximity sensor and DI module must be qualified. Use an SM321-1HF01 (fail-safe DI) and route the speed signal through the F-runtime group. The SVRM bit must not be used as a safe standstill indicator; use a separate certified speed monitor such as the 3TK2810-1 from Siemens for safe stop. Reference the S7-300F/FH fail-safe manual at S7-300F/FH fail-safe modules.

Obsolescence note: the 6ES7 312-5BF04-0AB0 is in the standard Siemens product phase of "Active product" but the 6ES7 312-5AC02-0AB0 predecessor is in the "Phase-out" cycle. Always check the latest product status at the Siemens Industry Online Support portal before specifying a new design.

Frequently Asked Questions

Why does the original FB return 0 RPM even though I0.0 toggles in PLCSIM?

The FB only does the math. It never measures time, so In_ESTD is zero, the moving sum is zero, and SAV (120,000 / 0) is clamped to zero. Wire SFB47 in frequency mode, or OB40 + SFC64 for period mode, to feed In_ESTD a real period value.

Can I leave In_ESTD as WORD and just declare it DINT?

No. WORD is 16 bits unsigned and wraps at 65,535, which is shorter than the period of one slow revolution expressed in 10 ms units. DINT (32-bit signed) covers periods up to 2,147,483,647 x 10 ms ~ 7 years. Change the array type to ARRAY OF DINT as well, otherwise the implicit conversion in the +I / +D transition corrupts the sum.

What is the correct constant if my base time tick is 1 ms instead of 10 ms?

Replace 120,000 with 1,200,000. The constant is 100 x 60 x N where 100 is the number of base ticks per second, 60 is seconds per minute, and N is the window size (20). If you also change the window to 40 samples, multiply by 40 / 20 = 2, so 2,400,000 for 1 ms / 40 samples.

Should I use the onboard counter or a digital input + OB40?

Use the onboard counter for high-frequency measurement (above 60 RPM with 4 targets = 4 Hz) because the integrated counter is hardware-based and deterministic. Use OB40 with SFC64 for very low RPM (under 10) where the period between targets is long and a software time stamp is sufficient, and the onboard counter is already used elsewhere.

My HMI shows the value in raw counts, not in RPM. What tag property is wrong?

The HMI tag is bound to the DINT correctly but the format string is set to "99999" integer. The SAV value is already in RPM. Open the HMI tag properties, set the display format to "9999", and confirm the cycle is 250 ms. The HMI does not need a scaling block on top of SAV.

Back to blog