Skip to main content

Counting and timing functions

Signal shaping

Dirac pulse "dirac"

The function outputs a 0-1-0 pulse with a length of 1 ns using the global discrete sampling time discreteSampleTimeMs. The return type is <bool>.

p = dirac();

Dirac impulse

note

Since this function is typically used for logical functions, the return value as <bool> is directly false or true. For a "real" Dirac impulse, the integral condition

δ(f)=δ(τ)f(τ)dτ=f(0)\delta(f) = \int\delta(\tau)f(\tau)d\tau = f(0)

is satisfied, dirac() would have to be multiplied by 10910^{-9}.

tip

To sample a signal with the discrete sampling time discreteSampleTimeMs, use the function sample(x).

Timer "timer"

The following formula periodically returns a pulse or the corresponding timestamp at the defined times.

pulse = timer({ interval: <dbl>   // mandatory, unless at least one (*) is defined
, grid: <bool>
, readTime: <bool>
, minute: <str> // (*)
, hour: <str> // (*)
, day: <str> // (*)
, month: <str> // (*)
, weekday: <str> // (*)
});
// The configuration object is mandatory in order to define
// a unique configuration from interval or a
// (*) element to define the event times.
PropertyValueDescription
interval<dbl>Time interval in which an event is triggered.
grid<bool>If this option is set, the interval is based on 00:00:00 of the day, regardless of the start time of the calculation.
readTime<bool>If this option is set, instead of a 1 nanosecond pulse at the event time, the timestamp is output, uin64 in UTC nanoseconds since January 1, 1970.
minute<str>crontab syntax for defining event times
hour<str>crontab syntax for defining event times
day<str>crontab syntax for defining event times
month<str>crontab syntax for defining event times
weekday<str>crontab syntax for defining event times

If the parameters hour, minute, day, month, and/or weekday are used instead of interval, explicit trigger times (UTC) can be specified.

The following information is possible for each entry in the order minute, hour, day, month, weekday (based on crontab syntax):

SpecificationMeaning
No specificationis '*' if all subsequent elements are not defined, otherwise '0'
'*'always / at any time
'*/n'at intervals of n
'a-e'in the range from a to e inclusive
'a,b,c'comma-separated list of any individual values
Execution at/on a, b, and c

For weekdays and months, short names corresponding to the first three letters of the English name can be used instead of numbers: e.g., "mon," "thu," "apr," "jun," "dec," ... .

The counting of weekdays starts on Sunday "sun" with 0.

Pulses can be used to reset sums or integrals or to transfer corresponding values to a latch register.

ExamplePulse time ...
{minute: 30, hour: 4}daily at 4:30 a.m., "after closing time"
{day: 1}on January 1 of each month at 12:00 a.m.
{minute: '*/15'}every 15 minutes, x:00, x:15, x:30, x:45
{hour: 2, weekday: 'sun'}weekly on Sunday at 2:00 a.m.
{day: 15, month: 'apr-sep'}on the 15th of the months April to September at 0:00 a.m.
{hour: '6,9,14,18'}daily at 6, 9, 14, and 18 o'clock

Example

In Example 1b, the timer() function is used to generate a memory pulse at a fixed time (end of operation).

Delay

The following formulas are used to filter and delay signal edges

delayed1_s = delay(signal, {...});
delayed2_s = delay(signal, reset, {...});
// The configuration object is mandatory.
delayedX_s = delay(..., { delayOn:<dbl>
, delayOff:<dbl>
, restart:<bool>
, startup: inf|<bool>
});
PropertyValueDescription
delayOn<dbl>Time in seconds for delaying the positive edge
delayOff<dbl>Time in seconds for delaying the negative edge
restart<bool>Subsequent edges during the wait time restart the time interval
startupinf/<bool>Start condition for edge detection, see description below

The behavior depends on the output signal state. If this is false, only positive edges on the input signal signal and the time parameter delayOn are taken into account. If the state is true, negative edges and the time parameter delayOff are taken into account.

Edge delay

Time measurement begins with the first arriving edge and can optionally be restarted with subsequent edges (restart: true). The output state only changes if the input signal is in the opposite state when the time expires. This means that only short signal changes are filtered and signal changes are only passed on after the signal has stabilized.

With a true at the reset input, the output state is reset to false and held.

The function can be used to filter and stabilize a "bouncing" switching signal.

For the system start, it must be specified how the past of the signal input is to be handled and whether an edge should be detected immediately at start-up, thereby triggering a waiting time. The startup property is used for this purpose:

  • inf: the first signal sample determines the value in the past and thus the output before system startup; an edge is therefore not triggered with the first sample.

  • <bool>: The input and output are assumed with this signal value (true, false) in the past before system startup. This may trigger an edge with the first sample of the input and start a delay time.

Property startup

Pulse "pulse"

The following formulas convert a selectable input edge on signal into a rectangular Boolean pulse with a duration of duration (similar to a 74HC121 or 74HC122 mono flip-flop). With a true at the reset parameter, the output is reset to false and held. All parameters are interpreted as <bool> .

p1 = pulse(signal, {...});
p2 = pulse(signal, reset, {...});
p3 = pulse(signal, reset, duration, {...});
// The configuration object is mandatory.
px = pulse(..., { edge:<int>
, duration:<dbl>
, restart:<bool>
, startup: inf|<bool>
});
PropertyValueDescription
edge<int>Selection of the controlling edge:
-1: negEdge,
0: anyEdge,
+1: posEdge (default)
duration<dbl>Duration of the pulse in seconds
restart<bool>Extension of the pulse with renewed edge possible
startupinf/<bool>Start condition for edge detection, see description below

The following example shows the behavior for the restart property for edge = +1:

Pulse Signal

For the system startup, it must be specified how the past of the signal input is to be handled and whether an edge should be detected immediately at startup, thereby triggering a pulse. The startup property is used for this purpose:

  • inf: the first signal sample determines the value in the past before system startup; an edge is therefore not triggered with the first sample.

  • <bool>: The input is assumed to have this signal value (true, false) in the past before system startup. This may allow an edge to be triggered with the first sample.

Property startup

Function generator "periodic"

The function periodic() can be used as a function generator and generates a periodic signal with the period duration period as long as the input enable is held at true. The signal shape is determined by the mode property. The output rate is determined by the global discrete sampling time discreteSampleTimeMs or the set output rate fOut.

p1 = periodic(enable, {...});
p2 = periodic(enable, control, {...});
p3 = periodic(enable, control, period, {...});
// The configuration object is mandatory.
px = periodic(..., { period: <dbl>
, mode: <enum>
, reset: <enum>
, control: <dbl>
, fOut: <dbl>
, width: <uint>
, taps: [<uint>]|p##
});
PropertyValueDescription
period<dbl>Constant period duration of the signal curve in seconds, corresponds to input period
Value range: [0.0001..[[0.0001 .. \infty[
mode<enum>Operating mode (def.: ramp)
[rect, pwm, time, ramp, ramp2, sawtooth, 2Pi…]
reset<enum>Reset of the signal waveform with
[stop, start, none]
control<dbl>Constant control value for PWM, corresponds to input control
fOut<dbl>Optional output rate for data points in Hertz
Value range [0.1..[[0.1..\infty[
width<uint>PRBS signal output width
Value range [0..64][0..64]
taps[<uint>]/p##PRBS feedback positions or predefined polynomial p2..p12

The optional inputs control and period have priority over the fixed properties. If the period duration changes during signal output, the signal curve continues smoothly at the current output position (*).

Even though the selection of the period duration and output rate is not initially subject to any restrictions, sensible values should be selected with regard to the function of the smartCORE.

Values for reset:

  • stop: (default) The output value is reset with enable == false.

  • start: The output value remains until restarted and is only reset then.

  • none: The output is only stopped with enable == false, not reset.

A few examples of output modes in conjunction with the period duration period, the output rate fOut, a control signal control, and various reset settings

Periodic signals

Mode: rect

A <bool> 0-1 square wave signal is output, where control [0.0..1.0]\in [0.0..1.0] represents the relative position of the positive edge in the period time period (default: 0.5). Reset state is 0!

Mode: pwm

A <bool> 1-0 square wave signal is output, where control [0.0..1.0]\in [0.0..1.0] represents the relative position of the negative edge in the period time period (PWM, default: 0.5). Reset state is 0!

Mode: time

Ramps with the time values [0.0..period[[0.0 .. period[ in seconds are output.

Mode: ramp (def.)

Ramps are output with the relative position in the interval as a scaling value [0.0..1.0[[0.0..1.0[

Mode: ramp2

Ramps are output with the scaling values [0.0..1.0[,[1.0..0.0[[0.0..1.0[, [-1.0 .. 0.0[, whereby the return to 1.0-1.0 is in the middle of the period duration.

Mode: sawtooth

A sawtooth-shaped [0.0..1.0..0.0[[0.0 .. 1.0 .. 0.0[ curve is output, where control =[0..1]=[0..1] represents the relative position of the 1.0 peak in the period time period. The reset state is 0.0!

Mode: 2pi

The relative position in the interval is output as an angle value [0.0..2π[[0.0 .. 2π[ for downstream angle functions.

wave = 10.0 * sin(periodic(true, { mode : 2pi
, period: 2.0 // Signal period / s
, fOut: 100.0})); // Sample rate

Mode: prbs

Output of a pseudo binary noise signal (pseudo random binary sequence) with the output frequency fOut. The period length is determined by the configured generator; the parameter period is ignored.

NXOR feedback is provided on the internal 64-bit shift register at the positions marked by *taps[]. width (def: 0) is the bit width of the output mask for the shift register in order to use the PRBS to generate pseudo-random amplitudes. With width: 0, only a <bool> sequence is output.

For taps, predefined polynomials p2 .. p12 can also be called up as feedback for lengths 2 .. 12 bits.

The PRBS signal can be used for parameter identification of dynamic systems.

Counting and measuring

Counter "counter"

The following formulas count positive edges in various configurations.

caution

The meaning of the parameters depends on the set operating mode!

c1  = counter(up);
c2 = counter(up, down); // mode: updown
c3 = counter(up, down, reset); // mode: updown
c4 = counter(up, down, reset, preset); // mode: updown
c5 = counter(count, dir);                   // mode: countdir
c6 = counter(count, dir, reset); // mode: countdir
c7 = counter(count, dir, reset, preset); // mode: countdir
c8 = counter(count, incr); // mode: countinc
c9 = counter(count, incr, reset); // mode: countinc
c10 = counter(count, incr, reset, preset); // mode: countinc
c11 = counter(A, B); // mode: qencoder
c12 = counter(A, B, reset);            // mode: qencoder
c13 = counter(A, B, reset, preset); // mode: qencoder
// Optional configuration for all variants
cX = counter(..., { mode: <enum> // mandatory if not 'updown'
, start: <int>
, preset: <int>
, lower: off|<int>
, upper: off|<int>
, range: <uint>
, modulo: <uint>
, storage: <str>
});

In updown mode (default), positive edges count up on up and down on down (similar to a 74HC193). If the edges occur at exactly the same time, +11=0+1-1=0 is counted.

In countdir mode, positive edges are counted at the count input and the direction is specified independently with the dir input of type <dbl> (similar to 74HC191). If dir > 0.0 (or true), counting is upward, otherwise with dir <= 0.0 (or false) downward. The default is 1.0 or true (upward). Using the <dbl> type for the direction allows the use of an analog speed measurement (e.g., in "m/s") to control the counting direction. On the other hand, the input is compatible with <bool> signals.

mode: countdir

Areas of application include position determination for linear or rotary movements or direction-dependent counting of objects passing a counting station.

In countincr mode, the counting increment is added to the register via the incr input of type <int> with a rising edge on count. The default is 1 (upward). The magnitude of incr should be adjusted appropriately to the set counter width, counter limits, etc.

In qencoder mode, all edges on the phase-shifted signals A and B are counted. The use of the two inputs is therefore mandatory. The signal without an edge indicates the counting direction. Areas of application include high-precision position determination for linear or rotary movements in 4x resolution ("quadrature encoder"). For this purpose, the edges should have exactly the same spacing.

mode: qencoder

The arrangement shown in the figure results in the following counting scheme:

ABClockwise rotation
Increment
Counterclockwise rotation
Decrement
00\downarrow A: 0->1\uparrow B: 0->1
10\downarrow B: 0->1\uparrow A: 1->0
11\downarrow A: 1->0\uparrow B: 1->0
01\downarrow B: 1->0\uparrow A: 0->1
00\downarrow A: 0->1\uparrow B: 0->1

With a true at the reset input, the counter is set to preset (def: 0) and held. preset can be passed via the properties or as a fourth argument.

The count register is of type <int64>

PropertyValueDescription
mode<enum>updown: Separate count inputs for up/down (def.)
countdir: Count input and separate direction <dbl> (> 0.0: up)
countincr: Clock input and separate increment as <int>
qencoder: All edges of clock signals A, B are counted depending on direction
start<int>Start value with start of smartCORE
preset<int>Reset value with true on parameter r
loweroff/<int>Count value stops at lower limit,
no overflow
upperoff/<int>Count value stops at upper limit,
no overflow
range<uint>Count value range
[0..range1][0..range-1]
Overflow from the boundary values to 00 or range1range-1
modulo<uint>Count value range count %= modulo with sign
[1modulo..modulo1][1-modulo..modulo-1]
Overflow from the edge values to 0
storage<str>Name of a persistent memory for the internal state. This ensures that the output receives the last stored value after a system restart. The contents of this memory cannot be used anywhere else in the smartCORE.

Stopwatch "stopwatch"

The following formulas represent a stopwatch and measure the length of a pulse pulse or the interval between two positive edges on pulse or between the first positive edge on beg and the subsequent positive edge on end. The measurement always starts with the start condition at t=0.0st=0.0s. An intermediate time can be output with an edge at the lap input (latch = true). True at the reset input sets the stopwatch and output to 0.0 and keeps them in this state. All inputs are interpreted as <bool>. The output is in seconds.

t1 = stopwatch(pulse);        
t2 = stopwatch(beg,end);
t3 = stopwatch(beg,lap,end);
t4 = stopwatch(beg,lap,end,reset);
// Optional configuration for all variants
tx = stopwatch(..., { latch: <bool>
, period: <bool>
, hold: <bool>
, restart: <bool>
, upper: off|<dbl>
});
PropertyValueDescription
latch<bool>true: Output of the time only occurs with the controlling edges (def.)
false: Continuous output of the rising measurement time
period<bool>true: Measurement between two rising edges at the pulse input
false: Measurement of the time for pulse = true
hold<bool>true: The output is only set to the new measured value when the measurement is complete.
false: The output is set to 0 with a new/ongoing measurement.
restart<bool>true: Each rising edge at beg restarts the measurement
false: Only the first rising edge at beg starts the measurement (def.)
upperoff/<dbl>When this time value is reached, the output is made and the measurement is terminated. (def.: off)

In the first form, only one pulse signal pulse is used. The following diagram shows various configurations and output options for measurement on a pulse signal:

Time measurement pulse signal

The first line shows any pulse signal to be measured.

The second line shows the time that has elapsed since the corresponding edge at the left footpoint for the pulse duration measurement with the ascending, dashed ramps. Finally, in magenta, the output of the stopwatch() function for various properties latch, hold or upper.

The third line shows the time that has elapsed since the corresponding edge at the left foot point for period measurement with the ascending, dashed ramps. Finally, in orange or blue, the output of the stopwatch() function depending on the properties latch or upper.

For operation with beg, lap, and end inputs, the output is configured accordingly. With the restart property, an active measurement can start again at 0.0 with each new edge at beg, measuring the distance from the last rising edge to the edge at end. In this mode, the output of intermediate times can be misleading. In the following diagram, the latch property is set to true to enable the output of intermediate times.

Time measurement Begin Lap End

The first three lines show example time curves for the input signals beg, lap, and end. The lap input is optional. In the dashed areas, either a return of the signal to false (green) is possible at any time, since only a rising edge is relevant for the beg input, or the signal may assume any state (red, blue) since the clock has not started.

The bottom line again shows the output of the stopwatch() function for different settings of the restart and hold properties. The ascending, dashed ramps show the time that has elapsed since the corresponding edge at the left foot point.

note

stopwatch() only measures the length of a single event. To determine the total operating time of an aggregate (heating, compressor, etc.), the integrate(x, {...}) function is useful.

total_on_time = integrate(onState, {storage:'myTotalizerX'});

Here, onState is a <bool> status signal that forms the integrand as 0 or 1. Optionally, a reset signal could be used to reset the integrated value.

Conversions

Time conversion "decodeTime" 1

The function decodeTime() takes a scalar timestamp t in UTC and converts it to the corresponding date and time representation using the optional offset tzDif to the local time. Various interpretations and output formats can be set.

TM1 = decodeTime(t);
TM2 = decodeTime(t, tzDif);
// Optional configuration
TMx = decodeTime(..., { scale: <enum>
, epoch: unix|<date>
, tzDif: <int>
, format: <str>
});
PropertyValueDescription
scale<enum>Determines what the integer part of the timestamp describes:
auto: The order of magnitude of the timestamp determines the resolution (def.), or
the integer part of t counts...
d: ... days
s: ... seconds
ms: ... milliseconds
us: ... microseconds
ns: ... nanoseconds
epochunix/<date>The start time of the count is set to the given UTC date,
format: 'yyyy-mm-dd',
optionally with time specification 'yyyy-mm-dd HH:MM'
(def.: unix 1970-01-01)
tzDif<int>Time offset in minutes for outputting local time, example CET: +60, CEST: +120, EST: -300
format<str>Instead of a vector, a formatted date/time string is output. The function uses the C++ function strftime() internally. The formatting of the output is described here.
In addition, the following placeholders can be used:
%FMS: 3 digits milli-seconds
%FUS: 6 digits micro-seconds
%FNS: 9 digits nano-seconds
each with leading zeros

Unless the format property is used to request the output of a formatted date-time text, the result is a vector with the following <uint> values:

// Return of the date-time information as a vector corresponding to
// the following content:
TM = [ year, month, day
, hour, minute, second, nanoseconds
, weekday // 0..6, 0 := Sunday
, yearday];

Footnotes

  1. Available from catalog version 11 onwards.