Skip to main content

Counting and time functions

Signal shaping

Dirac impulse "dirac"

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

p = dirac();

Dirac impulse

note

As this function is generally used for logical functions, the return value as <bool> is directly false or true. So that for a "real" Dirac pulse the integral condition

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

is correct, 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 provides a pulse or the corresponding time stamp periodically at the defined points in time.

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
// a unique configuration from interval or a
// (*) element to define the event times.
PropertyValueDescription
interval<dbl>Time interval at which an event is triggered.
grid<bool>If this option is set, 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, the timestamp is output instead of a 1 nanosecond pulse at the event time, uin64 in UTC nanoseconds since 1.1.1970.
minute<str>crontab syntax for defining the event times
hour<str>crontab syntax for defining the event times
day<str>crontab syntax for defining the event times
month<str>crontab syntax for defining the event times
weekday<str>crontab syntax for defining the event times

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

For each entry in the sequence minute, hour, day, month, weekday, the following specification is possible (based on the crontab syntax):

SpecificationMeaning
not specifiedis '*' if all following elements are not defined, otherwise '0'
'*'always / for each
'*/n'in the interval of n
'a-e'in the range from a to e inclusive
'a,b,c'comma-separated list of any single values
execution around/at a, b and c

Instead of numbers, short names can also be used for weekdays and months that correspond to the first three letters of the English name: e.g. "mon", "thu", "apr", "jun", "dec", ... .

The counting of the weekdays starts on Sundays "sun" with 0.

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

ExamplePulse time ...
{minute: 30, hour: 4}daily at 4:30 a.m., "after close of business"
{day: 1}on 01.01. of a month at 0: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 function timer() is used to generate a memory pulse at a fixed time (end of operation).

Delay "delay"

The following formulas are used to filter and delay the edges of a signal

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

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

edge delay

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

With a true at the reset input, the initial 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 defined how the past of the input signal is handled and whether an edge is to be detected immediately at the start and thus a waiting time triggered. The startup property is used for this:

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

  • <bool>: The input and the output are assumed to have this signal value (true, false) in the past before system start. 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 of duration duration (similar to a 74HC121 or 74HC122 mono flop). The output is reset to false and held with a true at the reset parameter. 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:<double>
, 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 new 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 start, you must define how the past of the signal input is handled and whether an edge is to be detected immediately at the start and a pulse triggered. The startup property is used for this:

  • inf: the first signal sample determines the value in the past before system start, so an edge is not triggered with the first sample.

  • <bool>: The input is accepted with this signal value (true, false) in the past before system start. This may trigger an edge 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 set to true. The signal shape is defined by the mode property. The output rate is set with the global discrete sample 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 course 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 the signal curve 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 the signal output, the signal curve is continued bumplessly at the current output position (*).

Even if the selection of the period duration and output rate is not initially subject to any restrictions, sensible values must 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 the next start and is only then reset.

  • 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 are output with the time values [0.0...period[[0.0 ... period[ in seconds

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

The output is a sawtooth-shaped [0.0..1.0..0.0[[0.0 .. 1.0 .. 0.0[ progression, where control =[0..1]=[0..1] represents the relative position of the 1.0 peak in the period time period. 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 results from the configured generator, the parameter period is ignored.

On the internal 64-bit shift register, NXOR returns are provided at the locations 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 retrieved as feedback for the lengths 2 ... 12 bit can be retrieved.

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

Counting and measuring

Counter "counter"

The following formulas count positive edges in different 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 are counted upwards on up and downwards 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 of this with the dir input of type <dbl> (similar to 74HC191). If dir > 0.0 (or true), counting is upwards, otherwise with dir <= 0.0 (or false) downwards. Default is 1.0 or true (upwards). Using the type <dbl> for the direction allows the use of an analog speed measurement value (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 rotational movements or the direction-dependent counting of objects that are guided past a counting station.

In countincr mode, the count increment is added to the register via the incr input of type <int> with a rising edge on count. The default is 1 (upwards). The order of magnitude of incr must be adapted to the set counter width, counter limits, etc. as appropriate.

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 with 4-fold resolution ("quadrature encoder"). For this, the edges should be exactly the same distance apart.

mode: qencoder

The following counting scheme results for the arrangement shown in the picture:

ABclockwise rotation
incrementing
counterclockwise rotation
decrementing
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 the fourth argument.

The counting 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 the clock signals A, B are counted depending on the direction
start<int>Start value with start of smartCORE
preset<int>reset value with true to parameter r
loweroff/<int>counter 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 boundary values to 0
storage<str>Name of a persistent memory for the internal state. This means that after a system restart, the output receives the last saved value. The content of this memory cannot be used anywhere else in 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 to the following positive edge on end. The measurement always begins 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 input reset sets the stopwatch and output to 0.0 and keeps it 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 with the controlling edges (def.)
false: Continuous output of the rising measurement time
period<bool>true: Measurement between two rising edges at input pulse
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 completed.
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 takes place and the measurement is aborted. (def.: off)

In the first form, only a pulse signal pulse is used. The following diagram shows various configurations and output options for measuring 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 base point on the left 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 base point on the left for the period measurement with the ascending, dashed ramps. Finally, in orange or blue, the output of the stopwatch() function depending on the latch or upper properties.

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, whereby the distance from the last rising edge to the edge at end is measured. In this operating mode, the output of intermediate times can be misleading. In the following diagram, the property latch = true is set to enable the output of intermediate times.

Timing Begin Lap End

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

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

note

stopwatch() only measures the length of a single event. The integrate(x, {...}) function is useful for determining the summed duty cycle of a unit (heater, compressor, etc).

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.