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();
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
is correct, dirac()
would have to be multiplied by .
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.
Property | Value | Description |
---|---|---|
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):
Specification | Meaning |
---|---|
not specified | is '*' 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.
Example | Pulse 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>
});
Property | Value | Description |
---|---|---|
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 |
startup | inf/<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.
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.
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>
});
Property | Value | Description |
---|---|---|
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 |
startup | inf/<bool> | Start condition for edge detection, see description below |
The following example shows the behavior for the restart property for edge = +1:
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.
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##
});
Property | Value | Description |
---|---|---|
period | <dbl> | Constant period duration of the signal course in seconds, corresponds to input period Value range: |
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 |
width | <uint> | PRBS signal output width value range |
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
Mode: rect
A <bool>
0-1 square wave signal is output, where control 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 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 in seconds
Mode: ramp (def.)
Ramps are output with the relative position in the interval as a scaling value
Mode: ramp2
Ramps are output with the scaling values , whereby the return to is in the middle of the period duration.
Mode: sawtooth
The output is a sawtooth-shaped progression, where control 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 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.
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, 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.
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.
The following counting scheme results for the arrangement shown in the picture:
A | B | clockwise rotation incrementing | counterclockwise rotation decrementing |
---|---|---|---|
0 | 0 | A: 0->1 | B: 0->1 |
1 | 0 | B: 0->1 | A: 1->0 |
1 | 1 | A: 1->0 | B: 1->0 |
0 | 1 | B: 1->0 | A: 0->1 |
0 | 0 | A: 0->1 | 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>
.
Property | Value | Description |
---|---|---|
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 |
lower | off/<int> | counter value stops at lower limit, no overflow |
upper | off/<int> | Count value stops at upper limit, no overflow |
range | <uint> | count value range overflow from the boundary values to or |
modulo | <uint> | count value range count %= modulo with signoverflow 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 . 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>
});
Property | Value | Description |
---|---|---|
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.) |
upper | off/<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:
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.
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.
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.