Computers and modern gadgets

Often, when operating a microcontroller device, there is a need to count “anthropomorphic” time - how many fractions of a second the LED should glow, the maximum period of double-click time, etc. In general, count not only nano- and microseconds, but also tens of milliseconds, or even seconds , minutes and even hours (I'm afraid to say about days...).
At the same time, in microcontrollers it is often necessary to simultaneously deal with microseconds - pulse periods, anti-bounce waiting, etc.
There are also devices that operate continuously for many hours and even days - aviation equipment, automobile equipment, downhole devices (sometimes we are talking about continuous operation for several days). In these cases, overflow of timers and 8-bit variables is unacceptable.
I would like to combine all this into one elegant and universal solution - to have a means of measuring time with microsecond accuracy that does not overflow for several days.
Why not? I suffered for some time and came up with a solution for 8-bit AVR microcontrollers. To do this, I used an 8-bit timer-counter and a 4-byte variable. I don’t currently work with PICs and AT89, and I’m not familiar with other embedded platforms. However, if readers help, I’ll do it for them too.
Advantages – the code is highly repeatable (I’m already making the 5th device with it); ease of operation (interrupts are not used for the client part of the work); the client part of the code is conditionally platform-independent; in the interrupt - one summation operation (but, however, for a 4-byte value); there is no external device - a real time timer.
I found only one drawback - one such useful and always needed timer is busy...
The article will be of interest primarily to beginners - I didn’t discover America here.

Theory

So, I have at my disposal a device based on Atmega16A with 12MHz quartz. Let's take its timer-counter 0. This is an eight-bit timer - that's enough for us. Why? We count:
  1. we take 12 MHz from the quartz and take the division factor by 8 - we get a frequency of 1500 KHz;
  2. We take the CTC mode (reset on coincidence) and set the interrupt to coincide with 150 - we get the interrupt frequency of 10 KHz;
  3. on this very interrupt we increment the variable (an increment is obtained every 0.1 milliseconds);
  4. if it is an unsigned 32-bit value, it will overflow after approximately
    • 429496729.6 milliseconds;
    • 42949.7 seconds;
    • 7158.3 minutes;
    • 119.3 hours;
    • 4.97 days.
In other words, this solution creates a timer with an accuracy of 0.1 milliseconds for (almost) 5 days (we must, however, take into account that real quartz has an error - more on that later). And if you also analyze the value of timer 0 itself - it is incremented every 2/3 microseconds - then you can get a counter with an accuracy of 0.67 microseconds.
Enough? Behind my eyes. Using a 0.1 millisecond counter, in my projects I:
  • I count the duration of glow and pauses between LEDs;
  • I take into account timeouts when working with UART, USB;
  • I set all sorts of situations in the test equipment - complex spatio-temporal combinations;
  • I maintain specified time intervals when polling the ADC and other sensors;
  • I tell the computer the time of my (the device’s) operation and transmit information at a given time interval;
  • Taking into account the counter down to the microsecond, I carry out anti-bounce control when pressing keys, analyzing pulses in long lines.
And all this easily fits into ONE ATmega16 CONTROLLER! Moreover, this is not Assembler, but cross-platform C! And no external real-time counter!
Not bad, right?

Setting up for AVR

How to do all this in AVR?
First of all, we create an external variable, which I call “DeciMilliSecond”:
// in main.h typedef unsigned long dword; // unsigned 32-bit integer extern volatile dword dmsec; // 0.1msec // in main.c volatile dword dmsec;
As @no-smoking correctly noted, this variable must be volatile so that the compiler does not try to optimize it.
I initialize this variable in a function:
dmsec = 0;
Next, I set the operating mode of timer 0:
// . timer 0 – 0.1msec Timer0_Mode (TIMER_Mode_CTC | TIMER0_Clk_8); Timer0_Cntr(149); Timer_Int(Timer0_Cmp);
At the same time, in some MCU_init.h I declare everything that is needed:
// in mcu_init.h #include // . TIMSK #define Timer0_Cmp (1<< 1) // совпадение таймера 0 // . TCCRn #define WGM1 (1 << 3) #define CS1 (1 << 1) // . источник сигнала для таймера 0 #define TIMER0_Clk_8 CS1 // предделитель 8 // . режим работы таймера #define TIMER_Mode_CTC WGM1 // CTC (сброс при совпадении) // . настройка таймера #define Timer_Int(Mode) TIMSK = (Mode) #define Timer0_Mode(Mode) TCCR0 = (Mode) #define Timer0_Cntr(Cntr) OCR0 = (Cntr)
Well, then, when possible, I enable interruptions:
#asm("SEI")
It remains to describe the interruption. This is easier than everything before:
#include interrupt Timer0_Compare (void) ( ++dmsec; )
That's it, the timer is described, configured and running!

Setting for PIC

Here's what dear PIC fans told me:

At peaks this can be easily repeated using the Timer2 module. It has a similar interrupt function by coincidence.

PR2 = 75 - the value at which the timer will reset and generate an interrupt
T2CON.T2CKPS = 2 - prescaler 1:16
T2CON.T2OUTPS = 0 - without postscaler
T2CON.TMR2ON = on - timer is enabled

IPR1.TMR2IP = 1 --high priority interrupt
PIR1.TMR2IF = off -- reset the interrupt flag
PIE1.TMR2IE = on -- enable interrupt when TMR2 and PR2 coincide
INTCON.GIE = ​​on -- enable interrupt processing

As you can see, the prescaler here is 2 times larger, therefore PR2 is 2 times smaller.
These settings will generate interrupts with a frequency of 10 kHz at a system frequency of 48 MHz (the timer is set to Fosc/4) - the standard frequency for USB Full Speed.

Usage

The code for the client of this timer is cross-platform (except for accessing the value of timer 0 in AVR).
Here is a snippet of the USB sharing code:
#include "main.h" // here is the dmsec variable, next_USB_timeout #include "FT245R.h" // here are functions for working with the USB module #include "..\Protocol.h" // here is the microcontroller-computer exchange protocol // * * // ** Analyze USB packets // ** void AnalyzeUSB (void) ( #define RECEIVE_BYTE(B) while (!FT245R_IsToRead)\ ( if (dmsec > end_analyze) return; )\ B = FT245_ReadByte (); #define RECEIVE_WORD(W) // similar for 2 bytes #define RECEIVE_DWORD(W) // similar for 4 bytes dword end_analyze, d; NewAnalyze: if (!FT245R_IsToRead) // no packets? return; end_analyze = dmsec + max_USB_timeout; // timeout for the current analysis next_USB_timeout = dmsec + MaxSilence_PC_DEV; // timeout for general exchange RECEIVE_BYTE (b) // packet header switch (b) ( case SetFullState: RECEIVE_DWORD (d); // read the word is_initialized = 1; // process ChangeIndicator () ; break; ) // switch (pack) goto NewAnalyze; #undef RECEIVE_BYTE // cancel #define #undef RECEIVE_WORD #undef RECEIVE_DWORD )
The macro functions RECEIVE_BYTE, RECEIVE_WORD, RECEIVE_DWORD implement reading procedures taking into account the timeout for a given exchange phase. As a result, if something hangs on the other side, the microcontroller will not go into hibernation. Please note - WatchDog is not needed! And all thanks to the variable/constant max_USB_timeout, which sets the timeout with an accuracy of 0.1 milliseconds.
The analysis of “silence on air” using the next_USB_timeout variable is implemented in the same way. This allows the microcontroller 1) to know that the computer has disappeared somewhere, 2) to signal this somehow (in my case, the “error” LED lights up). The constant/variable MaxSilence_PC_DEV allows you to vary the concept of “silence” within the widest range – from a fraction of a millisecond to several days.
All other points are implemented similarly.
If you need to use a microsecond counter, then a comparison function appears there:
#define GetUSec(A,B) ( #asm ("CLI"); A = dmsec; B = TCNT0; #asm ("SEI"); ) // ** // ** Time difference between events accurate to 2/3usec // ** dword Difference (dword prev_dmsec, byte prev_usec) ( dword cur_dmsec; byte cur_usec; ​​dword dif; // . note the current time GetUSec (cur_dmsec, cur_usec); // calculate the difference dif = cur_dmsec - prev_dmsec; dif<<= 8; if (cur_usec < prev_usec) dif += 255 + (dword) cur_usec - prev_usec; else dif += cur_usec - prev_usec; return dif; }
The function is passed the previous point in time - the previous value of dmsec and timer 0.
First, we use the GetUSec macro to stop interrupts so that the value of dmsec and the counter are not corrupted at the time of copying. And copy the current time.
Next, we convert the time difference to a 2/3 microsecond format, taking into account overflow.
Well, let's return this time.
And then we use this in a regular if to control anti-bounce and other measures. Just don’t forget to also pause interrupts when marking the current moment in time - or better yet, use the GetUSec macro.

results

This timer turned out to be an extremely convenient solution for me. I think it will be useful to you too. And I used it in my following projects:
  • Switchboard fencing situations. This is a hefty half-meter board with three controllers - ATmega128 as the central one and ATmega64 as two auxiliary ones (right and left sides). There is no galvanic connection between the three controllers and their components - power supply is based on ionistors, communication through optocouplers. The central controller charges groups of some ionistors and at this time powers both sides from other ionistors. Here we had to make a multi-stage algorithm for switching all this in order to minimize the interconnection. In particular, we are talking about the coordinated work of 8 relays - timers work here for 3.3 ms (guaranteed relay response time). Well, in fact, both sides control 10 relays and about half a hundred multiplexers. All this equipment works with clearly defined time characteristics (with an accuracy of 1 ms, maximum duration is 6 seconds). Well, and, in the end, banal timeout for USB, UART.
  • Depth sensor. Here I am solving another problem (a project in progress). There are two conductors (many meters long) that define the situation “shift up by 1 cm” and “shift down by 1 cm”. There are many ways to set a direction. In any case, these are certain combinations of impulses. Using this timer, I determine bounce and the duration of a stable pulse. The maximum permissible bounce time (10 microseconds is enough here), anti-bounce wait, and minimum/maximum pulse duration are set from the computer. Well, there is a debug mode - the sensor becomes a logic analyzer. This allows you to debug the operation of the line and adjust the coefficients. Well, again timeout, LEDs.
  • Analog signal sensor. A banal 8-channel ADC. Here I use a timer to maintain the necessary pauses.
Dear habra users from other platforms can tell me the initialization code for the corresponding timer, as well as the rules for accessing it - I’ll add it here. It may be necessary to select different times for other platforms. But in any case, it should be something within a few units of microseconds for the timer itself and something a multiple of 100 microseconds for the counter variable. Because, as it turns out, sometimes one millisecond is not enough.

Everyone knows why a microcalculator exists, but it turns out that in addition to mathematical calculations, it is capable of much more. Please note that if you press the “1” button, then “+” and then press “=”, then with each press of the “=” button the number on the display will increase by one. Why not a digital counter?

If two wires are soldered to the “=” button, they can be used as a counter input, for example, a turns counter for a winding machine. And after all, the counter can also be reversible; to do this, you must first dial a number on the display, for example, the number of turns of the coil, and then press the “-” button and the “1” button. Now, each time you press “=” the number will decrease by one.

However, a sensor is needed. The simplest option is a reed switch (Fig. 1). We connect the reed switch with wires parallel to the “=” button, the reed switch itself stands on the stationary part of the winding machine, and we fix the magnet on the movable one, so that during one revolution of the coil the magnet passes near the reed switch once, causing it to close.

That's all. You need to wind the coil, do “1+” and then with each turn, that is, with each turn the display readings will increase by one. You need to unwind the coil - enter the number of turns of the coil on the microcalculator display, and make “-1”, then with each revolution of unwinding the coil, the display readings will decrease by one.

Fig.1. Connection diagram of the reed switch to the calculator.

And, suppose you need to measure a large distance, for example, the length of a road, the size of a plot of land, the length of a route. We take a regular bicycle. That's right - we attach a non-metallic bracket with a reed switch to the fork, and we attach the magnet to one of the spokes of the bicycle wheel. Then, we measure the circumference of the wheel, and express it in meters, for example, the circumference of the wheel is 1.45 meters, so we dial “1.45+”, after which with each revolution of the wheel the display readings will increase by 1.45 meters, and as a result, the display will show the distance traveled by the bike in meters.

If you have a faulty Chinese quartz alarm clock (usually their mechanism is not very durable, but the electronic board is very reliable), you can take a board from it and, according to the circuit shown in Figure 2, make a stopwatch out of it and a calculator.

Power is supplied to the alarm clock board through a parametric stabilizer on the HL1 LED (the LED must have a direct voltage of 1.4-1.7V, for example, red AL307) and resistor R2.

The pulses are generated from the control pulses of the stepper motor of the clock mechanism (the coils must be disconnected, the board is used independently). These pulses travel through diodes VD1 and VD2 to the base of transistor VT1. The alarm board supply voltage is only 1.6V, while the pulse levels at the outputs for the stepper motor are even lower.

For the circuit to work properly, diodes with a low level of forward voltage, such as VAT85, or germanium are required.

These pulses arrive at the transistor switch at VT1 and VT2. The collector circuit VT2 includes the winding of a low-power relay K1, the contacts of which are connected in parallel to the “=” button of the microcalculator. When there is +5V power, the contacts of relay K1 will close at a frequency of 1 Hz.

To start the stopwatch, you must first perform the “1+” action, then turn on the power to the pulse shaper circuit using switch S1. Now, with every second, the display readings will increase by one.

To stop counting, simply turn off the power to the pulse shaper using switch S1.

To have a count for reduction, you must first enter the initial number of seconds on the microcalculator display, and then do the “-1” action and turn on the power to the pulse shaper with switch S1. Now, with every second, the display readings will decrease by one, and from them it will be possible to judge how much time is left until a certain event.

Fig.2. Scheme for turning a Chinese hanger into a stopwatch.

Fig.3. Circuit diagram of an IR beam intersection counter using a calculator.

If you use an infrared photo sensor that works at the intersection of the beam, you can adapt the microcalculator to count some objects, for example, boxes moving along a conveyor belt, or by installing the sensor in the aisle, count people entering the room.

A schematic diagram of an IR reflection sensor for working with a microcalculator is shown in Figure 3.

The IR signal generator is made on an A1 chip of type “555” (integrated timer). It is a pulse generator with a frequency of 38 kHz, at the output of which an infrared LED is switched on. The generation frequency depends on the C1-R1 circuit; when setting up by selecting resistor R1, you need to set the frequency at the output of the microcircuit (pin 3) to close to 38 kHz. The HL1 LED is placed on one side of the passage, putting an opaque tube on it, which must be precisely aimed at the photodetector.

The photodetector is made on the HF1 chip - this is a standard integrated photodetector of the TSOP4838 type for remote control systems for TVs and other home appliances. When a beam from HL1 hits this photodetector, its output is zero. In the absence of a beam - one.

Thus, there is nothing between HL1 and HF1 - the contacts of relay K1 are open, and at the moment of the passage of any object, the relay contacts are closed. If you perform the “1+” action on the microcalculator, then with each passage of an object between HL1 and HF1, the microcalculator display readings will increase by one, and from them you can judge how many boxes were shipped or how many people entered.

Kryukov M.B. RK-2016-01.

Like flip-flops, counters do not necessarily need to be assembled manually from logical elements - today’s industry produces a wide variety of counters already assembled in microcircuit packages. In this article, I will not dwell on each counter chip separately (this is not necessary, and it will take too much time), but will simply briefly outline what you can count on when solving certain problems in digital circuitry. For those who are interested in specific types of counter chips, I can send them to my far from complete reference book on TTL and CMOS chips.

So, based on the experience gained in the previous conversation, we found out one of the main parameters of the counter - bit depth. In order for the counter to count up to 16 (including zero - this is also a number), we needed 4 digits. Adding each subsequent digit will exactly double the counter's capabilities. Thus, a five-bit counter can count up to 32, and a six-bit counter can count up to 64. For computer technology, the optimal bit depth is a multiple of four. This is not a golden rule, but still most counters, decoders, buffers, etc. are built four (up to 16) or eight-bit (up to 256).

But since digital circuitry is not limited to computers alone, counters with very different counting coefficients are often required: 3, 10, 12, 6, etc. For example, to build circuits for minute counters, we need a 60 counter, and it is easy to obtain by connecting a 10 counter and a 6 counter in series. We may also need a larger capacity. For these cases, for example, the CMOS series has a ready-made 14-bit counter (K564IE16), which consists of 14 D-flip-flops connected in series and each output except the 2nd and 3rd is connected to a separate pin. Apply pulses to the input, count and read, if necessary, the counter readings in binary numbers:

K564IE16

To facilitate the construction of counters of the required capacity, some microcircuits may contain several separate counters. Let's take a look at K155IE2 - BCD counter(in Russian – “counter up to 10, displaying information in binary code”):

The microcircuit contains 4 D-flip-flops, and 1 flip-flop (single-digit counter - divider by 2) is assembled separately - has its own input (14) and its own output (12). The remaining 3 flip-flops are assembled in such a way that they divide the input frequency by 5. For them, the input is pin 1, outputs 9, 8,11. If we need a counter up to 10, then we simply connect pins 1 and 12, apply counting pulses to pin 14, and from pins 12, 9, 8, 11 we remove the binary code, which will increase to 10, after which the counters will be reset and the cycle will repeat. The K155IE2 composite counter is no exception. A similar composition has, for example, K155IE4 (counter up to 2+6) or K155IE5 (counter up to 2+8):

Almost all counters have inputs for forced reset to “0”, and some have inputs for setting them to the maximum value. And finally, I just have to say that some counters can count both back and forth! These are so-called reversible counters, which can switch for counting both to increase (+1) and decrease (-1). So he can, for example, BCD up/down counter K155IE6:

When pulses are applied to input +1, the counter will count forward, pulses at input -1 will decrease the counter readings. If, as the readings increase, the counter overflows (pulse 11), then before returning to zero, it will output a “transfer” signal to pin 12, which can be applied to the next counter to increase the capacity. Pin 13 has the same purpose, but a pulse will appear on it when the count passes through zero when counting in the opposite direction.

Please note that in addition to reset inputs, the K155IE6 microcircuit has inputs for writing an arbitrary number to it (pins 15, 1, 10, 9). To do this, it is enough to set any number 0 - 10 in binary notation at these inputs and apply a write pulse to input C.

Electrical impulse counters

A counter is a digital device that counts the number of electrical impulses. The counter conversion factor is equal to the minimum number of pulses received at the counter input, after which the states at the counter output begin to repeat. A counter is called summing if after each next pulse the digital code at the counter output increases by one. In a subtractive counter, after each pulse at the counter input, the digital code at the output is reduced by one. Counters in which it is possible to switch from summation mode to subtraction mode are called reversible.

Counters can be pre-installed. In such counters, information from the preset inputs is transferred to the counter outputs by a signal at a special preset input. According to their structure, counters are divided into serial, parallel and parallel-serial. A serial binary counter is formed by a chain of counting flip-flops connected in series. In a parallel counter, counting pulses are applied simultaneously to the inputs all digits of the counter. Parallel counters are faster than serial counters. Parallel-serial counters have high speed and high value change of the conversion factor.

Electrical pulse counters are available in both TTL and CMOS series. As an example of a TTL counter, consider the K155IE5 microcircuit. The functional diagram of the K155IE5 counter is shown in Figure 1.51,a, and its symbol on the circuit diagrams is shown in Figure 1.51,b. The K155IE5 counter actually has two counters: with a conversion factor of two (input C0 and output Q 0) and with a conversion factor of eight (input C1 and outputs Q 1, Q 2, Q 3). A counter with a conversion factor of sixteen is easily obtained by connecting output Q0 to input C1, and pulses are applied to input C0. The timing diagram of the operation of such a counter is shown in Figure 1.52.

Figure 1.53 shows connection diagrams that change the conversion factor of the K155IE5 meter. The counter outputs Q 0, Q 1, Q 2, Q 3 have respectively, weighting coefficients 1, 2, 4, 8. By connecting the outputs Q 1, Q 2 with inputs for setting the counter to zero, we get a counter with a conversion factor of six (Fig. 1.53a). Figure 1.53, b shows the connection diagram for obtaining a conversion factor of ten, and Figure 1.53, c - twelve. However, in the circuits shown in Figures 1.53, a - c, there is no possibility of setting the counters to the zero state.

Figures 1.54, a, b show, respectively, counters with conversion factors six and seven, in which an input is provided for setting the counter to the zero state. Analysis of the operation of the circuits shown in Figures 1.53 - 1.54 shows that to obtain a given conversion factor, those counter outputs whose weighting coefficients add up to the required conversion factor are connected to the inputs of the logic element AND.

Table 1.3 shows the states at the outputs of the counter with a conversion factor of ten after the arrival of each next pulse, and the counter was previously set to zero.

Let's look at some of the CMOS series counters. Figure 1.55 shows the symbol for the K561IE8 microcircuit - a decimal counter with a decoder. The microcircuit has an input for setting to the zero state R, an input for supplying counting pulses of positive polarity CP and an input for supplying counting pulses of negative polarity CN.

The counter switches based on the decline of pulses of positive polarity at the CP input, while there must be a logical one at the CN input. The counter will switch based on the decline of pulses of negative polarity at the CN input if the CP input is logical zero. One of the ten counter outputs always has a logical one. The counter is set to zero when a logical one is applied to input R. When the counter is set to zero, output “0” will be set to a logical one, and all other outputs will be set to logical zeros. K561IE8 chips can be combined into multi-bit counters with serial carry, connecting the carry output of the previous chip to the CN input of the next one. Figure 1.56 shows a diagram of a multi-bit counter based on K561IE10 microcircuits.

The industry produces counters for electronic watches. Let's look at some of them. Figure 1.57 shows the symbol for the K176IE3 microcircuit, and Figure 1.58 shows the K176IE4 microcircuit. In these figures, the outputs of the microcircuits are shown for the standard indicator segment designation shown in Figure 1.59. These microcircuits differ from each other by the conversion factor. The conversion factor of the K176IE3 microcircuit is six, and the conversion factor of the K176IE4 chip is ten. Setting the counters in question to zero is carried out by applying a logical one signal to the input R. Switching of counter triggers occurs upon the decline of positive pulses at input C. The microcircuits have a carry output p (pin 2), to which the input of the next counter is usually connected. The voltage drop at this output is formed at the moment the counter transitions from state 9 to state 0. The microcircuits differ in the signals at pin 3. For the K176IE3 microcircuit, a logical one appears at pin 3 when the counter is set to state 2, and for the K176IE4 microcircuit - to state 4. This necessary to reset the clock at 24 hours.

When a logical zero signal is applied to the S input, logical ones at the counter outputs will be on those segments that display the number of pulses received at the counter input. When a logical unit is applied to the S input, the polarity of the output signals changes. The ability to switch the polarity of the output signals makes it quite easy to change the connection diagram of digital indicators.

Figure 1.60 shows a diagram of connecting a luminescent indicator to the outputs of the K176IE4 microcircuit. Connecting the indicator to the outputs of the K176IE3 microcircuit will be similar.

Diagrams for connecting LED indicators to the outputs of the 176IE4 microcircuit are shown in Figures 1.61a and 1.61b. At the S input, a logical zero is set for indicators with a common cathode and a logical one for indicators with a common anode.

A description of the K176IE5, K176IE12, K176IE13, K176IE17, K176IE18, K176ID2, K176ID3 microcircuits and their use in electronic watches can be found in. Microcircuits K176IE12, K176IE13, K176IE17, K176IE18 allow a supply voltage from 3 to 15 V.

COUNTER ON THE MICROCONTROLLER

Many technical and automation devices still have mechanical counters installed. They count the number of visitors, products on the conveyor belt, turns of wire in winding machines, and so on. If it fails, it is not easy to find such a mechanical meter, and it is impossible to repair it due to the lack of spare parts. I propose to replace the mechanical counter with an electronic one using a PIC16F628A microcontroller.

An electronic counter turns out to be too complex if it is built on microcircuits of the K176, K561 series. especially if a reverse account is needed. But you can build a counter on just one chip - the universal PIC16F628A microcontroller, which includes a variety of peripheral devices and is capable of solving a wide range of problems.

So recently a person asked me to make a multi-digit pulse counter. I decided against LED indicators because they take up a lot of space and consume a lot of energy. Therefore, I implemented the circuit on LCD. The counter on the microcontroller can measure input pulses of up to 15 digits. The first two digits are separated by a dot. EEPROM was not used because there was no need to remember the meter state. There is also a countdown function - reverse. Schematic diagram of a simple counter on a microcontroller:

The counter is assembled on two printed circuit boards made of foil fiberglass. The drawing is shown in the figure.

One of the boards has an LCD indicator, the other has 4 buttons, a controller and other parts of the meter, with the exception of the power supply. You can download the boards and the counter circuit in Lay format, as well as the microcontroller firmware on the forum. Material provided by Samopalkin.

If you notice an error, select a piece of text and press Ctrl+Enter
SHARE:
Computers and modern gadgets