====== Counter ======
{{ :files:img_warning-line_b.png?nolink |}}
{{:en:hw:08_safety-instructions_pseudo-ISO-7010-info.png?nolink |(i)}}
This function works only for following Inputs & Outputs:
* **digital inputs**
===== How it works =====
The **counter** is a software-independent, high-speed counter of rising edges of changing signal on the **digital input**. In simple words, it can count fast changing signals very precisely.
**Counter inputs** are suitable especially for collecting data from energy meters, water meters, gas meters and other pulse meters installed in HVAC systems. They are also useful for reading engine revolutions. For this purpose, Unipi units feature 32-bit registers. When the maximum value of the counter (4 294 967 295) is exceeded, the counter resets to 0. **Counter inputs** can be used at up to 10 kHz frequency. In the Mervis IDE library devices, they are labelled as ''CNT'' inputs.
The ''CNT'' input variables are read-only. If you want to change the counter you must use ''CNT_set'' variable.
==== Hardware vs Software counter ====
The speed of Mervis programs is not enough for detecting quick changes of **digital inputs** traditionally (with the "Pulse counter (BD30)" FUPLA box for example). If you have a [[https://en.wikipedia.org/wiki/Slot_car|slot car track]] and you want to count the number of passes of slot cars, you wouldn't be able to detect it, since the length of pulses from the "pass" sensors will be in units of milliseconds. Speed of the slot car is up to 80 kmph and with the length of the car about 10 cm is the pass of the whole car above the sensor about 4.5 ms.
/* */
To demonstrate how slow is the software counting, look at this program in debugging mode:
{{ .:counter:counter_00-counter-hw-vs-sw-demo.png?direct |}}
As you can see, we are counting the rising edge events on the ''Patron_S167_DI_1.01'' through ''Pulse counter (BD30)'' function block, and reading the HW counter of the same input via the ''Patron_S167_CNT_1.01'' variable. Afterwards, we compare those two variables in ''eq'' function block, and if they are equal, we will turn the ''X2'' LED on the controller ''ON''. Once the two counters are not equal, the LED will be ''OFF''. /* spíše není nutné psát, že LED v této ukázce trošku při rychlém mačkání poblikává, protože delay mezi HW a SW countrem */
The debugging started with both counter values at 0. We connected a momentary switch to the ''DI1.1'' input and start pressing the switch very quickly. As you can see, the software counter detected only 76 presses, but the hardware counter detected 81. The difference seems small, but in more practical applications like reading speed of rotor the impulses can overwhelm the SW counter very easily.
===== Using input counter =====
{{ :files:img_warning-line_b.png?nolink |}}
{{ :en:hw:08_safety-instructions_pseudo-ISO-7010-info.png?nolink |(i)}}
**Note:** \\
The HW counter depends on the [[.:description-of-debounce-hidden|debounce]] settings. Therefore the **Debounce** has to be set to lower value than is the expected length of the pulses to count.
Each **digital input** is equipped with **counter** and you don't need to set anything to use it. The **counter** is available through a global variable. For the input named ''Patron_S167_DI_1.01'' we have **counter variable** named ''Patron_S167_CNT_1.01''.
==== Changing value of the Counter ====
The **counter variables** are read-only, therefore you cannot set or reset them directly from the program or the variable browser in debugging mode. You can set or reset the variables via the "set" variable. For the ''Patron_S167_CNT_1.01'' the "set" variable is called ''Patron_S167_CNT_1.01_set''. For example, changing ''Patron_S167_CNT_1.01_set'' variable to value 23 will set the ''Patron_S167_CNT_1.01'' counter to 23.
=== Reseting the Counter ===
To reset the **counter**, the "set" variable need to have different value than your desired starting point, then you can change the "set" variable to your desired starting point. This works fine in debug mode, but if you want to reset the **counter** with fbd/st you should use different way.
To be able to work with following variables you need to set the [[en:sw:01-mervis:autogen-hidden|autogen settings]] to include attributes.
This method also uses the "set" variable, but only to copy the value. First make sure the "set" variable has the desired value. Next you can reset the **counter** by rising edge on ForceComm variable, in this case the variable would be ''Patron_S167_NCnt1.01_wr_woch_forcecomm''. Shortly the ''Patron_S167_CNT_1.01'' **counter** should be set to same value as ''Patron_S167_CNT_1.01_set'' variable.
{{ :files:img_warning-line_b.png?nolink |}}
{{ :en:hw:08_safety-instructions_pseudo-ISO-7010-info.png?nolink |(!)}}
**Note:** \\
In simple terms the ForceComm variable can copy the value from set variable to Counter.