> I've never tried this approach, but I saw a Philips app note doing some > analysis of a similar method to measure resistance, and they came up with > around 5 bit for the most simple version (one port, one C, and one R), > about 8 bit for a version using two ports and two HC buffers, and around 14 > bit using two comparators. > > Since what you suggest seems to be similar, I think the results might be > similar, too. Do you have any experience with the precision and > repeatability (also over temp range) with this simple circuit? If you have a comparator (either external or 16C62X) you can measure a slowly-changing analog voltage with decent accuracy (if you measure 16 bits, you'll get about 12 good ones) using the following method: Feed one input signal into one comparator input. Feed a PIC output, through a large resistor, into the other comparator input. Also place a nice big cap between this input and ground (see below for info on values). Run the output of the comparator into another PIC port pin. Then run the following code at the fastest continuous rate you can manage (e.g. toss in a timer tick routine or somesuch. Note that this code assumes the PIC's RC is fed into the inverting input of the comparator. If this is not so, reverse the BTFSx instruction as marked. TimerL: ds 1 ; 16-bit timer counts number of subsamples TimerH: ds 1 CountL: ds 1 ; 16-bit counter: how many high comparator reads CountH: ds 1 ReadL: ds 1 ; 16-bit last read value ReadH: ds 1 ... CallMe: btfsc INPUT ; Change to BTFSS if OUTPUT feeds non-invert input goto InputHi InputLo: bcf OUTPUT incfsz CountL goto DoTimer incfsz CountH ; Should never skip, but INCFSZ doesn't hit flags goto DoTimer InputHi: bsf OUTPUT DoTimer: decfsz TimerL goto Done decfsz TimerH goto Done movf CountL,w ; *** movwf ReadL ; *** movf CountH,w ; *** movwf ReadH ; *** clrf CountL ; *** [sets Z flag] clrf CountH ; *** [sets Z flag] Done: ... Note that except in the instructions marked with asterisks, neither W nor PSW is altered in any way. If the above code is used in an ISR, and W and PSW are "live", the asterisked instructions may be replaced with: movwf WSave swapf CountL swapf CountL,w movwf ReadL swapf CountH swapf CountH,w movwf ReadH movlw 0 movwf CountL movwf CountH swapf WSave swapf WSave,w This will save one instruction versus the normal save/restore sequence and also saves a register. Anyway, the way this ADC works is that the processor will, in essence, be outputting a PWM wave with whatever duty cycle is required to make the capacitor voltage match the input. To see why this measurement technique works, imagine that both the input and the capacitor are at 3/4 VDD. Any time the PIC outputs a high, the current into the capacitor will be 1/4 VDD/R. Any time the PIC outputs a low, the current from the cap will be 3/4 VDD/R. Since the average current into and out of the cap must match for the cap to stay at the same voltage, the PIC's output must be on 3 times as much as it is off (i.e. on 3/4 of the time). Choosing the R and C for this circuit is an art/science for which the best values will depend upon the application. If the R and C are too small, then the non-linear change in capacitor voltage during the cycle will throw off the measurement accuracy a little bit. If R and C are too large, the device will take a long time to get to the proper voltage. I have not yet modeled RC's to find the optimum value, but I think an RC time constant of about 256-1000 subsample times is probably pretty good. Note that when I've used a windowed 16C622's internal comparator along with a rather large R, the circuit was a bit sensitive to light. I don't know whether a smaller R (balanced with a larger C) would help this. It is definitely something to bear in mind, however.