Hysteresis of Arduino digital inputs, measurement of

The Arduino Uno has Schmitt Triggers on its input pins, and you can measure the logic and hysteresis levels with your Uno's analogRead().

The Schmitt Trigger shown on this schematic translates the analog readings on the pin to digital levels with hysteresis:

If you connect a potentiometer wiper to two pins, you can read its voltage as both an analog and a digital input:

// hysteresisCheck.ino
// for https://forum.arduino.cc/t/hysteresis-of-arduino-digital-inputs/1127345
// Measure the digital input Schmitt trigger hysteresis on digPin
// against the analog input anaPin to measure the hysteresis

const int anaPin = A0;
const int digPin = A1;

void setup() {
  Serial.begin(115200);
}

void loop() {
  static int lastDig = -1;
  int digital = digitalRead(digPin);
  if(digital != lastDig){
    static int lastAna = -1;
    int analog = analogRead(anaPin);
    Serial.print("Dig:");
    Serial.print(digital);
    
    Serial.print(" Analog:");
    Serial.print(analog);
    Serial.print(" Diff:");
    Serial.print(abs(analog -lastAna));

    Serial.print(" Volts:");
    Serial.print(5.0*(analog+0.5)/1024,3);
    Serial.print(" dVolts:");
    Serial.print((analog -lastAna)*5.00/1024,3);
    Serial.println();
    lastDig = digital;
    lastAna = analog;
  }
}

When connected with the wiper of a 10K pot connected to A0 & A1 the sketch produces this output:

Dig:0 Analog:445 Diff:123 Volts:2.175 dVolts:-0.601
Dig:1 Analog:516 Diff:71 Volts:2.522 dVolts:0.347
Dig:0 Analog:446 Diff:70 Volts:2.180 dVolts:-0.342
Dig:1 Analog:517 Diff:71 Volts:2.527 dVolts:0.347
Dig:0 Analog:448 Diff:69 Volts:2.190 dVolts:-0.337
Dig:1 Analog:514 Diff:66 Volts:2.512 dVolts:0.322
Dig:0 Analog:451 Diff:63 Volts:2.205 dVolts:-0.308
Dig:1 Analog:514 Diff:63 Volts:2.512 dVolts:0.308
Dig:0 Analog:450 Diff:64 Volts:2.200 dVolts:-0.312
Dig:1 Analog:515 Diff:65 Volts:2.517 dVolts:0.317
Dig:0 Analog:449 Diff:66 Volts:2.195 dVolts:-0.322
Dig:1 Analog:513 Diff:64 Volts:2.507 dVolts:0.312

For my Uno's A1 pin, the digital input hysteresis is about 0.3V centered at about 2.35V.

I was curious about the Arduino Uno digital input Schmitt Trigger thresholds and hysteresis, because I wanted to hook up an IR photodiode and bias it so I could read it as a digital input.

1 Like

In the mega328 data sheet the Table 28.2 (page 258) lists the values for Vil and Vih. They are dependent on Vcc.

Vil is for a voltage that is dropping. When the voltage drops through Vil the input will switch from HIGH to LOW. Conversely, with a rising voltage the input will switch from LOW to HIGH at Vih.

2 Likes

Thanks, I was interested in seeing the behavior in the unspecified space between "the highest value where the pin is guaranteed to be read as low" and "the lowest value where the pin is guaranteed to read as high"

If the voltage at the digital input is between 0.3 * Vcc and 0.6 * Vcc at reset the state of the input is indeterminate. The same as floating until the input is set to a known state by raising or lowering the voltage passed the threshold. Is that what you mean?

If the voltage is HIGH to start with, it will remain so until the voltage drops below 0.3 * Vcc. And if it starts LOW it will re.ain so till the voltage rises past Vcc * 0.6.

I think the spec is saying the opposite -- one should design a reliable digital sensor to produce voltages outside the {0.3*Vcc, 0.6*Vcc} range to be reliably read, because it is unreliable in between.

As measured here:

... if the voltage is HIGH to start with, it toggled LOW when the voltage dropped below 2.18/5=0.43 * VCC, and when LOW, it toggled to HIGH when the voltage rose past 2.527/5 = 0.51*VCC.

Yes it’s another chip but a LM339 might be the way to proceed. :thinking:

4 circuits in one chip :slight_smile:

1 Like

I agree with that. If what I wrote was interpreted differently, I apologize. The above is why there are pullup and pulldown resistors, ie to establish a known state for an open or floating input.

1 Like

I was trying to mimic the low-budget hacks in:

from

...but using some stuff from my junk box. I thought if his PIC's Schmitt triggers worked, why not try it with the Arduino's?

With a couple bent up LEDs on a breadboard, and with 150K of series resistance on the LED/photodiode, it works. The Arduino analogReads(A0) as 2 and 680, or 0 and 3.32V, or 0*VCC and 0.66*VCC, or as digitalRead 0 and 1, when the light path is either blocked and unblocked.

The 150K is enough to pull the floating input down to LOW, and when the photodiode conducts, it is enough to pull it up to HIGH.

I think what I was perceiving from your words was that the hysteresis behavior is specified as Vil and Vih, while I was more interested in the behavior the schmitt trigger per these graphs from that datasheet:

1 Like

Your values are really close to what shows on the charts on page 272 ... if you zoom in at 5V and look at the green traces (figures 29-11 and 29-12).

1 Like

Here's a pic of a set of LEDs/photodetectors in a bracket aiming at a stick-built DIY dual photo-interrupter/quadrature encoder.

I cranked the pot up to 250K, and am getting >0.6*VCC signals out of this configuration, but it still toggles cleanly around VCC/2 due to the Schmitt trigger.

The 3d parts are from:

Note to self:

IR photo detector wise, these were good:

https://www.teamwavelength.com/photodiode-basics/

Additionally, the Wokwi simulator does not do Schmitt triggers to transform analog signals into digital signals.

Here is a Wokwi demonstration of a Schmitt Trigger using a Wokwi custom chip:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.