Poor man's delta-sigma ADC converter - Page 1
Forum section: electronics / general

author: Picuino
author_rank: Super Contributor
timestamp: November 06, 2021, 11:00:18 am
content: This Application Note from Microchip describes how to make an ADC converter using a microcontroller’s analog comparator.http://ww1.microchip.com/downloads/en/AppNotes/00700a.pdfhttps://www.microchip.com/forums/m242514.aspxIt can reach high input range, high conversion accuracy (at cost of more conversion time)

author: Picuino
author_rank: Super Contributor
timestamp: November 06, 2021, 11:08:11 am
content: I just have found another thread in the forum about this app note:https://www.eevblog.com/forum/projects/sigma-delta-using-arduino/

author: voltsandjolts
author_rank: Unknown
timestamp: November 06, 2021, 01:22:51 pm
content: As a learning exercise, absolutely.But for anything else, you can buy a 24bit delta-sigma adc for like $2, even in low quantity.

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 06, 2021, 05:23:12 pm
content: Why not. If you have CPU time to kill and are absolutely willing to avoid an external ADC.Doing as well as commercial ADCs will still be hard. So if you need high accuracy, you'll probably be better off with an off-the-shelf solution.Note that some modern MCUs have internal digital filters for implementing sigma-delta modulators, so that you can implement this much more efficiently.Some STM32s for instance, with their DFSDM peripheral.https://www.st.com/content/ccc/resource/training/technical/product_training/96/b6/2b/ea/72/3f/4e/d5/STM32L4_System_DFSDM.pdf/files/STM32L4_System_DFSDM.pdf/jcr:content/translations/en.STM32L4_System_DFSDM.pdfI read the Microchip app note quickly and at first sight, it looks like a pretty crude implementation. If you're interested in implementing sigma delta ADCs, you should probably read some more advanced material first.

author: capt bullshot
author_rank: Super Contributor
timestamp: November 06, 2021, 05:32:13 pm
content: Been there, done this. Back in the days when I used an 8051 derivative that had a comparator but not an ADC. Monitoring temperature and battery voltage or similar. So this was basically a "no additional cost" solution if you needed an ADC but your uC didn't have one. Nowadays, even the simplest uC have ADC inputs, so no need to think about these solutions.

author: Picuino
author_rank: Super Contributor
timestamp: November 06, 2021, 06:33:49 pm
content: I remember starting it up with a PIC16F628 to measure temperature. I could get more than 12 bits of resolution that didn't fluctuate from sample to sample, but I don't know how much error.If the error can be kept low, it is also a way to measure slow variables (temperature) with higher resolution than the internal ADC (usually 10 bits).

author: Picuino
author_rank: Super Contributor
timestamp: November 07, 2021, 05:40:19 pm
content: An Schematic with Arduino, just in case someone wants to try this type of ADC.I have used a 1N4148 diode to measure temperature.Measure time is less than 1ms with a clock of 16MHz.The sigma-delta algorithm needs to disable interrupts during measurement and is assembler optimized.Resolution = 1024 steps (0.2ºC approx each step)Arduino program:Code: (C)#define PIN_OUT 2#define PIN_AIN1 7#define PIN_AIN0 6void setup() {pinMode(PIN_AIN0, INPUT);pinMode(PIN_AIN1, INPUT);Serial.begin(9600);ACSR = (1 << ACBG); // Bandgap SelectADCSRB = 0x00; // Clear bits of ADCSRBDIDR1 = 0b00000010;}volatile unsigned int adc_result;void loop() {sigma_delta();Serial.println(adc_result);delay(500);}void sigma_delta(void) {pinMode(PIN_OUT, OUTPUT);PORTD |= (1 << 2);while ( (ACSR & (1 << 5)) != 0);PORTD &= ~(1 << 2);while ( (ACSR & (1 << 5)) == 0);adc_result = 123;asm volatile ("PUSH R24 \n""PUSH R25 \n""PUSH R26 \n""PUSH R27 \n""PUSH R28 \n""CLI \n""LDI R24, 0 \n" // counter = 0;"LDI R25, 0 \n""LDI R26, 0 \n" // result = 0;"LDI R27, 0 \n""L1: \n" // do {"IN R28, %a \n" // if ( (ACSR & (1 << 5)) != 0) {"SBRS R28, 5 \n""RJMP L2 \n""SBI %a, 2 \n" // PORTD |= (1 << 2);"NOP \n""NOP \n""NOP \n""RJMP L3 \n" // }"L2: \n" // else {"CBI %a, 2 \n" // PORTD &= ~(1 << 2);"INC R26 \n" // result++;"BRNE L3 \n""INC R27 \n""L3:\n" // }"INC R24 \n" // counter++;"BRNE L4 \n""INC R25 \n""L4: \n""SBRS R25, 2 \n" // } while (counter != 1024);"RJMP L1 \n""STS (adc_result), R26 \n""STS (adc_result+1), R27 \n""SEI \n""POP R28 \n""POP R27 \n""POP R26 \n""POP R25 \n""POP R24 \n": :  "M" (_SFR_IO_ADDR(PORTD)),  "M" (_SFR_IO_ADDR(ACSR)));pinMode(PIN_OUT, INPUT);}

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 07, 2021, 06:20:58 pm
content: Quote from: Picuino on November 06, 2021, 06:33:49 pmFirst thing to do after implementing your own ADC is to verify it through measurements. Otherwise you're just getting data and however many bits this data is, you don't really know what they are worth.The beauty with sigma-delta is that you can as well implement a 32-bit ADC. But getting even half the ENOB with this kind of implementation would already be a great achievement...So I highly suggest doing your measurements. Since those are low-speed ADCs here, you don't need any fancy setup.In your example, if you think the ENOB of your "hand-made" 12-bit ADC is better than that of the internal 10-bit ADC, you should check that first. Maybe it is, but you don't know, and I wouldn't count on it too much.

author: Picuino
author_rank: Super Contributor
timestamp: November 07, 2021, 07:06:00 pm
content: With Arduino, the measure fluctuate 2 bits of the 10 total bits.Typical samples at 20ºCCode:959961962960957958959961961962958957960958958961960959959963959961960960959958962959960959960957959958960959958961959957959959958960956960961958960959958961960957957962957962960961959959961960958958962961960960959959961959958958959957961960959960957960960963964964963962959961960960960959960960959961958958957958958957964960959962959962958957960960

author: Siwastaja
author_rank: Super Contributor
timestamp: November 07, 2021, 07:18:08 pm
content: If you want lower noise off the AVR's 10-bit SAR ADC, do the following:* Add 100nF capacitor (or larger) directly between the input pin and ground plane (two reasons: input lowpass filter, low impedance for SAR ADC),* Use the CPU sleep mode during measurement,* Average results in software. Even just averaging 4-8 results already is quite significant - and you get more resolution to work with.It's still not a wonderful ADC. Use an external one for better analog performance.

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 07, 2021, 07:23:05 pm
content: And just looking at the output for one input value like this is NOT verifying an ADC. It can tell you something about noise or repeatablity, but doesn't say anything about the ENOB, for instance. This isn't how you do it. It may even be misleading. Some ADC may look to have a more stable output for a given input, yet have much worse ENOB, INL and DNL.