WIP
This commit is contained in:
@@ -210,6 +210,34 @@ There are several features that are supported by the digital controller, and the
|
|||||||
|
|
||||||
When a digital operation is pre-empted by the arbiter on ADC2, the ` {sar_sel, ch_sel}` bits in the DMA data indicate this. `1110` is a sample that did not start, `1111` is a sample that did not complete, and the data is valid when those two bits equal the channel number.
|
When a digital operation is pre-empted by the arbiter on ADC2, the ` {sar_sel, ch_sel}` bits in the DMA data indicate this. `1110` is a sample that did not start, `1111` is a sample that did not complete, and the data is valid when those two bits equal the channel number.
|
||||||
|
|
||||||
|
### How SAR (Successive Approximation Register) Works
|
||||||
|
|
||||||
|
Now that we understand the overall architecture for the ESP32's ADC itself, and we know that it uses SAR, we can look into how its actual analog to digital conversion algorithm works. Don't worry, this isn't nearly as thick as everything else.
|
||||||
|
|
||||||
|
We know that ADC is, coarsely, a binary search looking for the correct digital representation of the analog voltage present on an input. We also know, from the Flash ADC breadboard we put together earlier in the project, that we can perform a comparison between two voltages with a comparator circuit; and that by successively dividing the voltage down, we can perform a comparison against a number with a given precision. (We built a 3 bit Flash ADC in our example for values from 0 to 7.) So by implementing a series of bitwise operations and saying "bigger than X?", we can eventually arrive at something that is close enough given our stated precision target. But with Flash ADC, in order to support the same precision we're getting from the ESP32-S3 ADC, we would need (I think) 4096 individual comparators. Plus we would need a precision resistor ladder, encoder logic, etc. It would be an enormous circuit. So Flash ADC is out of the question here.
|
||||||
|
|
||||||
|
SAR ADC solves these problems by using a remarkably small number of components:
|
||||||
|
|
||||||
|
* One comparator with one input and one output
|
||||||
|
* One DAC (Digital to Analog Converter)
|
||||||
|
* A register big enough to hold a value of the precision being calculated
|
||||||
|
* A logic circuit to run a for loop
|
||||||
|
|
||||||
|
The logic circuit, the register, and the DAC are used to drastically shrink the number of comparators that are needed, and to completely eliminate the need for the resistor ladder from the Flash DAC. The way it works is like this (assuming our 12 bit precision):
|
||||||
|
|
||||||
|
* The register gets initialized with zero
|
||||||
|
* For every bit in the register, beginning with the most significant bit and stepping down
|
||||||
|
* Set the current bit to `1`
|
||||||
|
* The register is fed into the DAC
|
||||||
|
* The DAC converts the input value to an output voltage
|
||||||
|
* The comparator receives the DAC's output value, and compares it to the input analog voltage
|
||||||
|
* Is the analog input voltage higher than the DAC voltage?
|
||||||
|
* If yes, then we keep that bit turned on
|
||||||
|
* If no, then we turn that bit off
|
||||||
|
* Proceed to the next bit in the register
|
||||||
|
|
||||||
|
By doing this, we eventually wind up with a series of "less than greater than" comparisons that have toggled a bitfield in a 12 bit value to give us the nearest possible approximation to the input voltage that our register precision will support. It's quite elegantly simple, but not something you can build on a breadboard.
|
||||||
|
|
||||||
## Final notes on the ESP32-S3 ADC
|
## Final notes on the ESP32-S3 ADC
|
||||||
|
|
||||||
Aaaaaand I'm spent.
|
Aaaaaand I'm spent.
|
||||||
|
|||||||
Reference in New Issue
Block a user