Files
esp32-learning/07-LM339N-ADC/README.md

141 lines
10 KiB
Markdown
Raw Normal View History

2026-06-11 15:29:01 -04:00
# Breadboard
![breadboard](breadboard.png)
This project uses an LM339N comparator chip, a voltage ladder, a potentiometer and 4 LEDs to create a Flash Analog to Digital Converter.
[Here is a video of it working](https://x.com/AKLabsDotNet/status/2064431239013048425?s=20)
It's worth pointing out that this ADC outputs thermometer code (unary code), not binary. I would have needed to use an additional priority encoder to get it converted down to binary. I didn't have a priority encoder on hand (though I could've built one with quite a few other chips I *did* have on hand), so I just left it at unary output.
# Lessons Learned
* What is a voltage ladder
* How pull up and pull down resistors work
* Breadboards are small finnicky things
* How USB power delivery dummies work
## Voltage ladder
Not a lot to say here. A voltage ladder is a series of connected voltage dividers. Each junction between resistors in the series is a step on the "ladder".
```
Supply
|
R1 220
|
>----- Step 1
|
R2 220
|
>----- Step 2
|
R3 220
|
>----- Step 3
|
R4 220
|
>----- Step 4
|
R5 220
|
GROUND
```
... and so on. The voltage is (assuming an equal dispersion of resistor values) equally divided at every step on the ladder, allowing you to take different voltages at different parts of the ladder. Varying the resistance values in between steps of the ladder will give you different divisions along the ladder.
For this project, I used 220 ohm resistors all the way through, for an equal 25% division at each step.
## Pull Up and Pull Down Resistors
This circuit uses LM339N chips to perform the comparison operations on the input voltage vs the reference voltage at various points along the voltage ladder. The LM339N output pins require a pull up resistor to do their job correctly.
[From the LM339N datasheet](https://www.ti.com/lit/ds/symlink/lm339-n.pdf?ts=1781077876487):
> The output is HIGH when the voltage on the non-inverting (+IN) input is greater than the inverting (-IN) input. The output is LOW when the voltage on the noninverting (+IN) input is less than the inverting (-IN) input
The voltage ladder is going to `-IN` and the potentiometer is going to `+IN`. So when the potentiometer is greater than a given step of the voltage ladder, the output for that step is supposed to be `LOW`; otherwise it should be `HIGH`. However, if we just wire the LEDs up directly to the output pins, we get unpredictable readings on the output pin - I got `0.25v` when I was expecting `5v`.
<center><img alt="Okay but why" src="butwhy.webp" width="320px"/></center>
When working with electronics, you might see something called a "pull up" or "pull down" resistor. For example,
* "... We connect this pin to a pull up resistor which pulls the voltage up to 5v"
* "... We connect this pin to a pull down resistor which pulls the voltage down to 0v"
Electricity, like water, always wants to take the path of least resistance possible. So if there is a resistor of any value in a circuit path, the electrons will prefer to go a different way until the path of least resistance is found. Pull up and pull down resistors use this property of electricity, in cooperation with [transistors](../02-buzzers_with_transistors#transistors), to control the flow of voltage between a supply and a ground.
In lesson 2 I talked about [how transistors work](../02-buzzers_with_transistors#transistors)), having a collector, an emitter, and a base. They work by a charge coming into the base and changing the amount of charge carriers that can pass through depletion zone in the `P/N` materials at the `BC` and `BE` junction. Crudely speaking, the base connector is used like a switch to turn the flow from one side of the transistor to the other (depending on how the transistor is configured) on or off.
If we look at the block diagram for the LM339N [from the datasheet](https://www.ti.com/lit/ds/symlink/lm339-n.pdf?ts=1781077876487), we can see that the integrated circuit is made up of (among other things) a number of transistors, especially transistors that sit right at the output pins:
<center><img alt="TI LM339N block diagram" src="lm339nblock.png"/></center>
This tells us that the output pin is actually one leg of a transistor, and that the transistor is set up as a low side switch. Makes sense - we have comparator that will be HIGH or LOW depending on the operation, so we have an output that will be turned on or off depending on the output of that comparison. The LM339N datasheet further clarifies this:
> The output of the LMx39-N series is the uncommitted collector of a grounded-emitter NPN output transistor.
What they're saying here is that the collector is floating, but the transistor is setup as a low-side switch. *The collector is actually the output pin*; the emitter is going to ground. Remember what I said about low side switching:
> ... with low side switching, the load is always connected to +V and the load just floats when it's turned off.
This is why we see `0.25v` without the pull up resistor. The output is just floating, so when the base goes high, there's no voltage there, because the LM339N isn't actually providing any voltage of its own. It essentially produces unpredictable noise, because the charge from base was allowing charge carriers to move but there were no charge carriers around and they had nowhere to go anyway. I got `0.25v` you might get something else, but either way it's not usable voltage.
So how do we solve this? How do we get 5v out of our pin like we expect? We have to **supply the 5v to the output pin ourself**, and use a `pull up resistor` to make the 5v supply current flow on the output path whenever that transistor is activated.
```
+---------+
| |
| | OUTPUT
| |-----+--> 220R ---> LED
| LM339N | ^
| | |
| | |
| | +--- 10kR <--- +5v
+---------+
```
What this does is weakly connects 5v onto the output pin. When the comparator returns a false result, the transistor provides a strong connection to ground that provides an easier path than for the +5v to travel through the resistor out to the output, and the transistor sinks the `+5v` supply voltage coming from the output pin directly to ground. So we get a `+5v` when the comparator says "your potentiometer is above this step on the voltage ladder", and we get ground reference voltage (`0v`) in the opposite case. However when the comparator returns a true result, the transistor ensures the easiest path for the `+5v` supply voltage is out to the LED rather than back towards ground.
A pull down resistor works in the opposite way.
```
+---------+
| |
| | OUTPUT
| |------+--> 220R ---> LED
+5v --> | DEVICE | |
| | |
| | |
| | +--- 10kR ---> GROUND
+---------+
```
Instead of weakly connecting the output pin to supply voltage, it weakly connects the output pin to ground. When the transistor is open, the pull down resistor keeps the output (which would otherwise float) down at ground reference voltage (`0v`). When the transistor is closed, the `10k` resistor allows only a very small amount of current to flow, which keeps the output at supply voltage (depending on the device).
<center><img alt="That's just on and off with extra steps" src="extrasteps.jpeg" /></center>
Part of the confusion here is not understanding how the LM339N in particular works. The LM339 never outputs a logic 1. It only outputs a logic 0 or "nothing." The pull-up resistor converts that "nothing" state into a valid logic 1 by gently connecting the output to the supply voltage. The datasheet explains this, but if you're like me, that point might WHOOSH past you.
Open collector outputs like you see on the LM339N do have some uses. For example:
* You can combine multiple outputs onto a single pullup resistor to make a `wired-AND` or `wired-OR` (depending on the logic of your particular chip). This way, if any of the comparator outputs go low, they all go low.
* You can pretty easily set different outputs to different voltage levels. For example you can supply the LM339N with 5v but drop the output pins to 3.3v.
And I'm sure there are others besides this.
## Breadboards are small and finicky things
Once you start getting into integrated circuits, a breadboard starts feeling really small really fast. I've seen some folks who have breadboarding setups that are essentially dozens of breadboards glued together, and I'm definitely seeing why. Initially I had planned to use several of these LM339N chips to make a 4-bit ADC, but after seeing how hairy the wiring got on a single one, I quickly ditched that plan.
Also they are not the best at forming strong connections, especially if your components stand proud of the board. If your resistors have long legs, for example, they may bend and move and momentarily lose contact with the breadboard. You may need to poke things to make them work. On simple circuits that's not a huge issue, but even at this level of complexity, there were several times I thought I had a bug in my design only to find I needed to touch a loose resistor or an LED to make things work again.
## How USB power delivery dummies work
This was my first exposure to a USB-C power delivery dummy device. Basically it's just a little USB plug with an IC, a few resistors, a `VCC` and `GND` connection, and (on some models like mine) a switch that tells the IC what output voltage you want.
The device acts by pretending to be a USB device, and asks for the voltage you've requested. If the power delivery device can provide the granted voltage, that's what you get. Otherwise you will get 5 volts. Some devices, no matter what you ask for or what they agree to, will always provide 5 volts and you just have to get bent if you don't like that. But these things were a really neat way to power this board, and I'm sure I'll be using them again soon.
They can be had very cheaply - I'm sure there are cheaper options, but [these are the ones I ordered](https://www.amazon.com/dp/B0FXL6DLB9).