Path: Home => AVR-EN => Applications => Hysteresis   Diese Seite in Deutsch: Flag DE Logo

Hysteresis voltages of AVRs

Here you can learn,
  1. what hysteresis is,
  2. for what you can use it, and
  3. how you can measure that.
All schematics and pictures are, like always, as LibreOffice-Draw-file here, all calculations as Calc-file here.

1 What is hysteresis?

1.1 Inverter without hysteresis

Back-feeded inverter without hysteresis Let us assume, we couble the output of an inverter via a RC combination back to its input pin. At start-up, when the capacitor is unloaded, the inverter's output is high, because it's input is low. After the capacitor's voltage reaches the trigger level of the input, the output goes low. Now the low output unloads the capacitor via the resistor. This restarts the whole again: load, then re-load.

The delay in between loading and unloading is caused by the Propagation Delay Time (tPD), because the inverter input needs some time time to switch the output transistors. This tPD is usually between 10 and 200 ns, depending from the Family of the inverter (TTL, LS-TTL, HC-TTL, CMOS, CMOS-TTL). The frequency of the inverter oscillator, f = 1 / tPD / 2, therefore is in the range between 2.5 and 50 MHz. How large R and C are, is irrelevant here, only the tPD determines the frequency.

ICs of that inverter types are 74LS04 in LS-TTL and 4069 in CMOS.

1.2 Inverter with hysteresis

Back-feeded inverter with hysteresis Not so, if the upper (low-to-high) and the lower (high-to-low) voltage differ slightly. Then the inverter gets this symbol on its body, which signals that both voltages are at different levels. The voltage difference between both is called hysteresis voltage. This voltage is usually rather small, but the effect can clearly be seen in the diagram: extended load- and unload-times cause the voltage to swing between both levels. And are longer than simple tPDs.

Input voltages at 5V with 50mV hysteresis Now the load-/unload-curve is a little bit different, and R and C determine the frequency. With a resistor of 10kΩ and a capacitor of 1,000µF the two up's and down's need 0.41 seconds, a frequency of 2.4 Hz results.

Increased hysteresis voltage reduces the frequency as well. The product of R and C here is 10, the formula for calculating the frequency is f = 24.4 / (R * C). Of course, the 50 mV hysteresis voltage are hidden in the 24.4 factor.

Typical inverter ICs providing hysteresis are 74LS14 in LS-TTL or 40106 in CMOS.

2 For what do we need hysteresis?

Of course, that is simple: to built digital oscillators. But that is not all.

2.1 Hardware debouncing of keys and switches

Let us assume we'd like to debounce a key, that is attached to an AVR pin with a pull-up resistor. If the key is pressed, it should take some time until the pin's state changes from high to low. If the key is released, the state change shall occur after an additional while. Good keys bounce within a few milli-seconds, old and worn-out keys need up to 20 ms.

Key on an AVR input pin Of course, we can build a Mercedes-solution around each of our keys, with edge-triggered Monoflops, to achieve these delays exactly and reliably. But we can simplify that by an R and a C and by profiting from the AVR's hysteresis voltage, like shown here.

The input pins of any AVR have an hysteresis voltage, so we can simply connect a capacitor to such an input. No matter how slow or fast the voltage rises or drops on this input, no multiple input signals occur, if your source of noise remains well below this voltage. So the hysteresis voltage here is not a Mercedes but a Volkswagen.

At start-up the capacitor is loaded by the internal pull-up resistor of the I/O pin. We can switch that on by setting the PORT bit to one and by clearing the direction bit of this pin. This resistor has roughly 50kΩ.

If the key or switch is closed then, this unloads the capacitor, while the pull-up still pulls it high. But less high: the external resistor should be small enough to unload the capacitor to below the guaranteed VIL. Which is defined as 0.3 * Vop, at 5V this is at 1.5V.

When the key or switch is released, the internal pull-up re-loads the capacitor. After the voltage is larger than the upper hysteresis voltage, the input pin goes high again.

2.2 Voltages and times during pressing and releasing the key

Voltages on the input when pressing and releasing the key These here are the voltages and times with an external resistor of 12kΩ and a C of 2.2µF. When pressed/closed it lasts roughly 20 ms (red curve) until the input goes low (rosy curve).

The blue curve shows the voltage on the capacitor after releasing the key. This voltage starts with the resistor divider's voltage (50k to plus, 12k to minus). The voltage increase is slower that the decrease due to the larger pull-up resistor. After roughly 50 ms the input pin goes high.

This is the theory, but in reality AVR inputs are not switching at half the operating voltage. Those who want to do the calculation more exact, measure these voltages and fill them into the LibreOffice sheet "avr-I/O" here.

And now? For what was all the hysteresis stuff? It would have worked as well without all that. Yes, it would have, but not around the switching point. Without the hysteresis the voltage on the capacitor would have needed just a few milli-Volts near the switching point, and a whole series of Highs and Lows would have resulted. These milli-Volts are what you get if your mobile phone talks with its base station once in a while. And would have initiated a whole swarm of pulses after you released the key. This is not what you want to tolerate for a hardware-debounced key. With that hysteresis your mobile has to produce at least 50 mV to get over the edge of the hysteresis. Not a simple task for a mobile, if your capacitor is 2.2µF.

Note: always when capacitors are connected to AVR pins, that change their voltage slowly and if switching levels are involved, it is good to have some hysteresis voltage.

3 Measuring the hysteresis voltage of AVR-pins

Measuring hysteresis voltagtes via frequency measurements To measure the hysteresis voltage we have to The result can be seen from the load/unload pin: the higher the hysteresis voltage the lower its switching frequency.

To bring any AVR to swinging in that way requires a short assembler program. As any AVR has at least an INT0- or a PCINT-pin, and as the RC on two pins is simple, the whole measurement results in a frequency measurement. If your measuring equipment allows to measure pulse relations as well, such as my counter here does it, you can also see how far the switching level is from half the operating voltage.

Because the hysteresis voltage is a little bit different at different operating voltages, you should be able to vary this between the minimum and the maximum and to measure the operating voltage as well. My counter has such an input.

4 Calculating the hysteresis voltage from the frequency

Formula for calculating the hysteresis voltage from the measured frequency The formula to calculate the voltage from the frequency is derived in the yellow field.

Two assumptions have been made to simplify calculation:
  1. The switching level is roughly half the operating voltage. If that is not the case, the load- and unload times derived are different, but the sum of both remains the same.
  2. The second assumption is that the hysteresis voltage is small compared to the operating voltage. We can therefore assume that the load and unload current are constants, which simplifies the calculation of load- and unload-times.
First, formula (1) calculates the load and unload current. As these currents are rather small (less than 0.5 mA), we can skip the calculation of the voltage drops of the driver pin in the high and low state. Those who do not believe that can use an R of 100 kΩ or 1 MΩ instead.

The time for loading and unloading Δt with a current of I is shown in formula (2). Formula (3) replaces I with the formula (1).

The frequency f consists of the load and unload times and can be seen in formula (4). Converted to Δt the formula (6) results.

By replacing Δt in formula (3) by Δt in formula (6), yields formula (7). By removing brackets formula (8) results, and finally formula (9) gives the hysteresis voltage VH as Vop / 4 / f / R / C.

Example calculation As an example the green box shows such a case. It assumes that the frequency is 20 Hz. From that a hysteresis voltage of 62.5 Milli-Volt results.

Because it cannot be avoided that switching the load/unload pin on and off are at different times, I assumed that the difference is four clock cycles. That yields an error margin, that is very small and well below the capacitor's and resistor's tolerances.

5 The program for measuring the hysteresis voltage

As the measuring via an INTn- and a PCINTn-pin differs slightly, two versions of the program are published here.

Both programs are written for the ATtiny13A, other AVR types have to be generated on that basis.

Another warning here: if programming pulses are on INTn- or PCINTn-pins, you must not connect the electrolytical capacitor with GND during programming. This would not allow programming, as the capacitor would destroy the programming pulses. So better disconnect it from GND during programming.

5.1 The program for measuring with an INTn-pin

The program assumes that on PB0 of an ATtiny13 the resistor is connected, that loads/unloads the capacitor on the PB1 pin, which is the INT0 pin.

This program is available in assembler format here. The following displays it in the browser.

; *********************************
; * Hysteresis measuring via INT0 *
; * AVR type ATtiny13, Version 1  *
; * (C)2021 by Gerhard Schmidt    *
; *********************************
.include "" ; Define device ATtiny13A
; Hardware
; Device: ATtiny13A, Package: 8-pin-PDIP_SOIC
;            ________
;         1 /        |8
; RESET o--|Reset Vcc|--o +Vop
;  (NC) o--|PB3   PB2|--o (NC)
;  (NC) o--|PB4  INT0|--o RC
;   GND o--|Gnd   PB0|--o R/F
;        4 |_________|5
; **********************************
;   P O R T S   A N D   P I N S
; **********************************
; Ports
.equ pO = PORTB
.equ pD = DDRB
.equ pI = PINB
; Pins
.equ bPB0O = PORTB0
.equ bPB0D = DDB0
.equ bINT0O = PORTB1
.equ bINT0D = DDB1
.equ bINT0I = PINB1
; **********************************
;       R E G I S T E R S
; **********************************
.def rmp = R16 ; Multi purpose Register
; **********************************
;       P R O G R A M 
; **********************************
.org 000000
; **********************************
; R E S E T  &  I N T - V E C T O R S
; **********************************
  rjmp Main ; Reset vector
  rjmp Int0Isr
  reti ; PCIO
  reti ; OVF0
  reti ; ERDY
  reti ; ACI
  reti ; OC0A
  reti ; OC0B
  reti ; WDT
  reti ; ADCC
; **********************************
;  I N T - S E R V I C E   R O U T .
; **********************************
Int0Isr: ; 7 clock cycles for INT0 and RJMP
  sbic pI,bINT0I ; Jump over next if low, +1/2 = 8/9
  cbi pO,bPB0O ; PB0 output off, +2 = 10
  sbis pI,bINT0I ; Jump over next if high, +1/2 = 10/11/12
  sbi pO,bPB0O ; PB0 output on, +2 = 12/13
  reti ; +4 = 7 + 1 + 2 + 2 + 4 or 7 + 2 + 1 + 2 + 4 = 16 clock cycles
; delay of pulse if low: 7 + 2 + 1 + 2 = 12 clock cycles
; delay of pulse if high: 7 + 1 + 2 = 10 clock cycles
; delta delay = 2 clock cycles
; **********************************
;  M A I N   P R O G R A M   I N I T
; **********************************
  ldi rmp,Low(RAMEND)
  out SPL,rmp ; Init LSB stack pointer
  cbi pD,bINT0D ; INT0 as input
  cbi pO,bINT0O ; INT0 output to low (no pull-up)
  sbi pD,bPB0D ; PB0 as output
  sbi pO,bPB0O ; Output to high on start-up
  ; Init INT0
  ldi rmp,(1<<ISC00) ; INT0 at both edges
  out MCUCR,rmp
  ldi rmp,1<<INT0 ; INT0 interrupts enable
  out GIMSK,rmp
  ; Interrupts enable
	sei ; Set I-flag
; **********************************
;    P R O G R A M   L O O P
; **********************************
	rjmp loop
; End of source code
; Copyright
  .db "(C)2021 by Gerhard Schmidt  " ; Source code-readable
  .db "C(2)20 1ybG reahdrS hcimtd  " ; Machine code-readable

The program is rather short, needs only very few flash memory and works well in all AVRs (with small changes) that have an INT0 pin.

5.2 The program for measuring the hysteresis voltage via an PCINTn-pin

The program for measuring via a PCINT pin is only differing slightly from the above program: The program, also written for an ATtiny13A, is available here in assembler-source-code format. Initialization of the PCINT1 is shown here as follows.

  ; Init PCINT1
  ldi rmp,(1<<PCINT1) ; PCINT1, both edges
  out PCMSK,rmp
  ldi rmp,1<<PCIE ; PCINT interrupt enable
  out GIMSK,rmp

5.3 Practical measurements with an ATtiny13A

Measuring an ATtiny13A Measuring at 4.585V Pulse width at 4.579V The electrical set-up for measuring is immediately available on a breadboard. The measurement showed a hysteresis voltage of around 200 mV, as well as at 5V and at 3.3V.

The switching level is slightly below half of the operating voltage. The pulse ratio was 55.3% at 5V and 65.3% at 3.3V.

The frequency counter allowed to measure frequency as well as pulse width as well as operating voltage.

Much success in measuring and calculating your own device on your own operating voltage.

6 The comfort version for measuring VIL and VIH

Those who need the exact voltages where the input goes high and low, if they play a serious role in your application, get the Mercedes version of measurement here.

6.1 Integrated version

Schematic for measuring and displaying hysteresis in an ATtiny24(A) To integrate hysteresis measurement and displaying it on an LCD in only one AVR is not that trivial. The LCD needs e.g. 5 V operating voltage, while the AVR works well even below 2V operating voltage. So we need a translation between these two voltages. An ULN2001, 2002 or 2003 can do that. Using that IC is a little overdone, because of the low currents needed, but can be done simple and fast with that IC.

One consequence of that construction is that the data bus of the LCD cannot be bidirectional. We'll have to drive the LCD in one direction and use wait cycles instead of the Busy flag of the LCD. Keep this in mind when configuring the LCD routines, as provided here as e.g. (description of these routines here).

LCD display of the measurement results So the results of the measurement can appear on the LCD. As measuring uses the whole range of 10 bits or 1,024 stages at the operating voltage, only the last digit of the results are inexact. When calculating the hysteresis voltage the minor 8 bits of the multiplication results can be used, so one further digit is exact.

6.2 Measuring with the ATtiny24-LCD-Module

Here the 5V version of an LCD display with an ATtiny24(A) has been presented. If you have build that, you can use it as well, and you do not need the voltage transfer from xV to 5V. Unfortunately, this version uses the full 5V in ADC measurement, so yields a resolution of 5V / 1,024 = 4.88 mV only.

For attaching the frequency output of the tested AVR to the LCD module (for determining the switching events) you'll need one voltage level changer, which can be a single transistor plus two resistors.

To the top of this page

©2021 by