Reading a potentiometer, push button or other resistive sensor via USB is a priori not very complicated. By the way, the Yocto-Knob is one of the very first modules we put for sale more than ten years ago. However, depending on the applications, the needs are not always the same. Therefore, over time we added new settings in order to refine the measures. Let's see this in details...
If you look at the Related articles and application examples section on the Yocto-Knob page, you realize the diversity of the applications of this module. Originally designed to read physical buttons, we also used it for timekeeping, for rotative position measures, to create a light barrier...
The common point to all of these applications is the reading of a resistive input. The principle is simple: the Yocto-Knob creates a voltage divided on the basis of the resistance that you connect to one of the module input and to an internal resistance, and measures the voltage at the middle point of the divider. You can find the measured value in the rawValue of each AnButton: it can go from 0 when the input contact is closed to 4095 when the contact is open.
To read the raw value of the voltage divider, you can use:
int rawVal = anButton.get_rawValue();
Based on the midpoint voltage, the Yocto-Knob can estimate the value of the connected resistance. As it can guess the maximum resistance that you want to measure, it offers an input calibration procedure which enables you - on the basis of the highest and lowest observed resistances - to normalize the measured analog value so that it varies linearly between 0 and 1000 on the potentiometer use range. It's the value that you find in calibratedValue.
You can perform calibration using the module configuration window in the VirtualHub. If you want to do it programmatically, use the following piece of code:
// move the input between its two extremes
Alternatively, you can also configure the calibration on the basis of known min and max raw values:
To read the calibrated and linearized value on the measuring range, use:
int inputVal = anButton.get_calibratedValue();
When you have all the time in the world, you can do with the method described above, which enables you to obtain by poling at most a few measures per second. But if you want a more reactive behavior, you had best use the value change callback method (see our previous post on this topic).
To read the calibrated and linearized value by callback, use rather:
int inputVal = int.Parse(value);
// use the value here
//Install the callback on the wanted input
// Note: regularly call YAPI.HandleEvents()
In reactive mode, the callback is called each time the calibrated value changes. Knowing that the measures are performed at a 1kHz frequency, if the Yocto-Knob were to simply forward each measure, the USB communication and the application would soon be submerged by measures. For example, when the input signal is slightly noisy, you would receive values constantly varying just a tiny bit. To avoid this, the module forwards only an average value every 32[ms] as long as the measure is stable. But, so as not to lose in reactivity, as soon as a significant change is detected on the basis of the latest three samples, then it instantaneously forwards the median value between the three samples, which reduces the latency to 2[ms] for change detection. This hybrid analog measuring mode is a specificity of the anButton functions, which enables you to design efficient and reactive analog interfaces.
You can configure a threshold above which a measure is considered as a "significant change" with the following code:
A higher value introduces a higher tolerance to changes before leaving the averaged mode. The default value is a 5 point difference sensitivity.
Differentiated measuring modes
- The Analog fast mode is the default, described above
- The Analog smooth mode is a mode purely averaged on 32[ms], without adaptation to the changes. It is useful when stability is more important than reactivity.
- The Digital4 is designed to read on/off inputs and is described below
To modify the measuring method of an input, you either use the module configuration window in the VirtualHub, or use the following code:
Reading on/off buttons
To read on/off buttons, we introduced in 2020 a specific working mode which enables you to multiplex up to four buttons pen analog input (see also the post explaining the multiplexing method). Even if you use only one on/off button, you will probably want to use this mode.
This mode is as reactive as the Analog fast mode, but it has the advantage of directly performing the decoding of the measured value to determine the position of the binary inputs. In this mode, calibration is not necessary anymore; the calibrated value is always a number between 0 and 15, which once converted in base 2 directly gives you the state of the multiplexed buttons.
If you need less than four multiplexed buttons, here is how to proceed;
- For a single on/off button, the simplest way is to connect it directly on the analog input. The returned value is zero when the button is open and 15 when it is closed.
- Another possibility for a single on/off button: if you solder a 10kΩ resistance in parallel to the button, the returned value is 7 when the button is open, 15 when it is closed, and zero if you have a connection failure between the Yocto-Knob and the button.
- For two on/off buttons: as described in the post mentioned above, solder a 10kΩ resistance in parallel to the first button and another 4.7kΩ resistance in parallel to the second button. The returned vale is 3 when the two buttons are open, 11 or 7 when one or the other of the two buttons are closed, 15 when both are closed, and zero if you have a connection failure between the Yocto-Knob and the buttons.
- And so on for three on/off buttons
The following code will help you decode these binary values:
bool bouton2_pressed = ((inputVal & 4) != 0);
bool bouton3_pressed = ((inputVal & 2) != 0);
bool bouton4_pressed = ((inputVal & 1) != 0);
If you use less than 4 buttons and if you put a resistance on the buttons you used, you can add:
Using with NPN type sensors
As described in this other post, you can connect a sensor with an NPN output to a Yocto-Knob as if it were an on/off button. This applies in particular to Hall effect sensors of which we talked last week.
In this use case, a few additional method are useful:
- The get_pulseCounter() method enables you to return the number of detected pulses since the last reset to zero. Note however that the sampling frequency of this module is only of 1kHz, it is reliable only if the pulses last at least a few milliseconds
- The get_lastTimePressed() and get_lastTimeReleased() methods enable you to read the exact timing of the latest transition in each direction. It can be useful for example to build a cheap light barrier...
Alternatives to the Yocto-(Maxi)Knob
Even if it is rather flexible, the Yocto-Knob remains a simple product with limitations, such as the low measuring voltage, which makes it relatively sensitive to electromagnetic perturbations, and the absence of isolation, which usually limits its use to the inside of a device or of a control panel.
For applications requiring remote measures, it's better to use one of the following modules, which are slightly more expensive but more robust and above all equipped with electrical isolation:
- You can perform analog measures by using higher voltages with a Yocto-0-10V-Rx, or even via a current loop with a Yocto-4-20mA-Rx.
- For eight binary inputs with higher voltages, the Yocto-MaxiIO-V2 is ideal.
- To count fast pulses, aim for the Yocto-PWM-Rx which can even detect pulses below the microsecond.