On Thu, 22 Jul 1999, Russell McMahon wrote: > Summary: Using a very cheap op-map ($US0.16 in true volume) and a few > relatively cheap parts and an (internal to uP) comparator an Analog > to Digital conveter with 9+ bits accuracy is achieved. Better > accuracy will be achieveable with longer conversion times. The > technique is slow but cheap to implement. > > > Must be time to stop playing with this. > Results keep getting better. > Many things that people say don't seem to be true! The optimistic things or the pessimistic things? If optimistic, then I have some lies to tell. I've made some measurements of the 2-I/O line sigma delta A/D converter and have been able to obtain fairly good results. I made measurements over the range of about 0 to 1.4 volts and found that the maximum linearity error was only 0.033% (assuming the data spans the full 4096 counts, which it doesn't - I really need to measure over the full range to get an accurate estimate of the linearity). This corresponds to about 1.3 counts on a 12bit A/D converter. Here's the raw data I measured: -0.0098 803 0.0484 831 0.0876 852 0.1133 867 0.1480 883 0.1827 89e 0.2000 8ac 0.2411 8cd 0.2871 8f2 0.3085 903 0.3450 920 0.3924 945 0.4385 96a 0.4708 984 0.5227 9ad 0.5620 9cd 0.5840 9de 0.6329 a05 0.6827 a2e 0.7086 a42 0.7654 a70 0.8133 a97 0.8783 aca 0.9158 ae8 0.9566 b08 0.9915 b24 1.0388 b4a 1.0822 b6d 1.1259 b8f 1.1756 bb8 1.2197 bdc 1.2454 bf1 1.3044 c1f 1.3332 c37 1.3895 c62 I also ran your (Russell's) data through the octave program and got similar results. Which is to say, that the linearity is quite good! The latest thing I added was a simple low pass filter that averages the last four samples. This routine is useful for other things too (such as that median filter algorithm we beat too death a while back): ;---------------------------------------------------- ; fir_average - find the average of the last n 16-bit ; samples ; ; C: ; ; int m[SAMPLES]={0,0,0,0 ... }; ; int ; sample_number=0, ; sum = 0; ; ; int fir_average(int new_sample) ; { ; int w; ; ; /* Find difference between the new sample and ; * the one we are about to replace */ ; ; w = m[sample_number] - new_sample; ; ; /* Subtract this difference from the old sample. ; * This places the new sample into the array. ; * e.g. w = x - y followed by x = x - w will replace ; * x with y. ; */ ; ; m[sample_number] -= w; ; ; /* Subtract this difference from the total too. */ ; sum -= w; ; if(++sample_number > SAMPLES) ; sample_number = 0; ; ; return(sum/SAMPLES); ; } ; ;inputs: ; INDF points to &sample[sample_number] fir_average: movf x_lo,w subwf INDF,W skpnc decf sum_hi,f subwf INDF,f subwf sum_lo,f skpnc incf sum_hi,f incf FSR,f movf x_hi,w subwf INDF,w subwf INDF,f subwf sum_hi,f return This routine is used like so: incf sample_number,w andlw 0x03 ;only four samples movwf sample_number addwf sample_number,w addlw s0l ;Start of sample array movwf FSR call fir_average > > Latest trial uses 2 transistors to act as current sources to drive > the integrating capacitor. > > Here's some shocking ASCII art (I hope)(I can see it - YMMV) > > ______________________ Vcc > | | > R R > R R Re-hi > | | > | E > PIC Output --.-RRR--.---B Q1 - PNP > | C > | | Rin > | -------------RRRR--- <-- Vinput > | | | > | Rbi-lo C | > .-RRR--.---B Q2 --- Cint > | E NPN --- > | | | > R R Re-lo | > Rbg-lo R R | > | | | > ------------------------------------- Gnd If you're using the LM324 as a buffer amplifier (which I think is necessary for almost every application [the amp not the 324 per se]) then why not do something like so: | /| | /+|----------<< Vin | / | +----< | | \ | P | \-|--+ I | \| | C | | | | +--/\/\/\---+ | | | === | | | --- | /// The 324 is being configured as a comparator. If Vin is greater than the DC voltage on the capacitor, then the 324's output is high. The only problem I see with this approach is that the voltage on the capacitor is a function of the PIC's supply voltage - which may be too noisy or too inaccurate for a 12-bit A/D converter. (This problem exists with the 1 and 2 I/O line a/d converters too, btw.) The programmable current source that you show above addresses this issue if it's powered from a voltage reference or perhaps a well filtered version of the power supply. It's possible to also design a precise current source using a LM324. Scott