On analog pin change?

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
User avatar
Posts: 3
Joined: Thu Jan 11, 2018 1:24 pm
Location: Berlin, Germany, Europe, Earth

Re: On analog pin change?

Post by hase » Thu Jan 11, 2018 2:33 pm

[quote=philwilkinson40 post_id=23928 time=1513432540 user_id=3399]
Should I investigate using digital Schmitt triggers in this example?

No. And yes.
To me, this sounds like a use case for a Schmitt Trigger.
But perhaps not a "digital" one like the 74xx14.

The term Schmitt trigger seems to intimidate you.
It should not.

It is just a device with an input that has some hysteresis - like the temperature controller in your clothes iron:
- on the up-slope (the iron is heating up), the temperature controller turns off the heating element at T1
- on the down-slope the heating is turned on at T2
with T2<T1.
The value T1-T2 is the hysteresis of the trigger.

Schmitt triggers do the same for a digital input.
While the input is low (so the next slope is an up-slope), the trigger level is a bit higher that when the input is high. Again the difference is the hysteresis.

The usual implementation is to use a comparator like the LM339 or use an OpAmp like the LM324.
"Comparator" is really a nifty word for an OpAmp that has very high amplification and shitty linearity :-)
Unlike any OpAmp, the LM339 has Open Collector outputs, which is really only useful in comparator applications.

The basic operation of an comparator is to compare two input voltages (hence the name, get it?).
The inputs are designated "+" and "-" (plus and minus).
When the voltage on the + pin is higher than the voltage on the - pin, the output is high, otherwise it is low.
Check out https://www.elektronik-kompendium.de/si ... 311271.htm for a (german) explanation and a basic schematic.

Open-Collector outputs have only one transistor.
This transistors collector is connected to the output pin (the emitter is on ground, the base controlled by the chip and the transistor type is NPN).
So the chip can only output "low" and "nothing". Any "high" value is created by an external pullup resistor.
This is handy if you want to connect multiple signal sources: OC outputs can be simply wired together; anything pulling the signal low will not interfere with anything else on this "bus".
This technique is used frequently for Reset signals: one pullup, multiple sources for "low" like voltage monitors, pushbuttons or NPN-transistors driven by the DTR line of the usb-uart chip on your ESP-12, NodeMCU or suchlike.

Back to comparators.
By feeding a reference voltage to the minus-pin and your signal to a resistor to the plus-pin, you compare the two voltages.
The reference could simply come from a (precision-)potentiometer, so it is adjustable.

The resistor feeding the output value back to the plus-pin (aka positive feedback) adds something to the input voltage.
And this creates the hysteresis of the circuit:
Lets start with the input signal below the reference voltage (on the - pin).
Plus pin below minus pin => output is low.
The feedback resistor is therefore connected to a low signal.
So the input signal is divided by the input and feedback resistor, the voltage on the + pin is therefore lower than the actual signal.
In other words: the signal mus be above the reference plus the hysteresis before the trigger switches to "high" state.

Starting on high, the operation is reversed: the feedback is connected to high, so the + pin sees the voltage from the signal puls some feedback.
Therefore the signal must go below reference minus feedback for the trigger to trip to "low" state again.

This all is *very* useful when feeding noisy signals to the digital domain.
So it should be your general practice :-)
And therefore it is a good idea to invest a few hours looking into Schmitt triggers, yes.

The digital Schmitt triggers in the 74xx14 ICs have a fixed hysteresis and their reference voltage is fixed to 0.5 Vcc (iirc, not checking the datasheet now).
This is useful some times. I still prefer the LM339, even though it has a higher part count (needs some resistors etc.
The LM339 is cheap, handles voltages well above the 5V, 3.3V or 2.5V domains we are working with nowadays and I can make that into a window comparator as well.
(just to spike your curiosity: a window comparators digital output tells us, whether an input voltage is inside or outside a defined window.
This is a logical and between "above lower threshold" and "below upper threshold". Which needs only 2 of the 4 comparators inside an LM339 IC).

Use a comparator and poll the input if you need fast response or use the ESP8266 interrupt if your application can live with the 500us latencies.


User avatar
Posts: 59
Joined: Tue Nov 14, 2017 3:11 am
Location: Perth, Australia

Re: On analog pin change?

Post by philwilkinson40 » Sat Feb 17, 2018 7:46 am

I just rembered this post from a while back and thought I must finish it up if other forum users search up similar questions.

Many thanks @hase, @pythoncoder and @roberthh for the help and encouragement to dabble into Schmitt triggers. I spent some time reading about them and then realised that these electronic circuits are already present in many of our cheap sensor devices to prevent constant bouncing.

So I grabbed a very cheap rain sensor unit, detached the rain sensor from the control module and connected it to the output of a MXP5100DP measuring a change in air pressure as a cyclist passes over a hollow rubber tube. I then played with the potentiometer until a got a clear pin state change. The one I used was great as it has an analog pin output too.
In conclusion, I didn't try to trigger an interrupt on an analog pin change, instead I ran the analog signal through a schmitt trigger to obtain a reliable digital output and ran an interrupt from that.
My terrible code is below.
Obvious next steps are to place two rubber tube sensors a known distance apart and identify only bicycles, count bicycles by direction, calculate speed, etc, etc.

Code: Select all

##MPX5010DP sensing dP through a hollow rubber tubing

import machine
import utime

interruptCounter = 0
totalInterruptsCounter = 0
connectedPin = 5 

def callback(pin):
    global interruptCounter
    interruptCounter = interruptCounter + 1

digital = machine.Pin(connectedPin, machine.Pin.IN)
digital.irq(trigger=machine.Pin.IRQ_FALLING, handler=callback)

while True:
    if interruptCounter > 0:
        state =  machine.disable_irq()
        interruptCounter = interruptCounter - 1
        utime.sleep(0.5)  #note this is optimised for my specific use case

        totalInterruptsCounter = totalInterruptsCounter + 1
        print (str(totalInterruptsCounter), " cyclists have passed.")

IMG_20180217_28391.jpg (86.01 KiB) Viewed 585 times

Post Reply