Measuring Pots With a 16F84A






Components shown will give 8-bit resolution. Highest reading for a 10k pot was e9h (233d). There's a small overhead to remove from this (about a 4-5 count). Bigger pots will need a correspondingly smaller cap, eg 100k pot = 15n pot. Not decreasing the cap would allow finer resolution, but it would take longer to go through the pots. The discharge loop is far too long - discharging the cap takes only a few microseconds, although I've yet to update this program. The code below is just a test program. A good quality plastic cap is recommended for stability, as well as using a stable regulated power supply.



The code for a 4051 MUX would be quite similar, even a little simpler. The 4017 way can be expanded indefinitely using the same 2-wire system, whereas a 4051 system needs an extra chip for the Inhibit (or Chip Select=0) lines

This could be useable in a robotics system as cheap or convenient (possibly more so than encoders) position sensing for something like a grasp or turntable




rs      equ porta.0   ;o/p       4017 reset
pot     equ porta.1   ;i/p  o/p  measure/discharge cap
clk     equ porta.2   ;o/p       4017 clock
led     equ porta.3   ;o/p       finished
go      equ porta.4   ;i/p       start

 orgdata ram

idx      rb    ;current position
ptn      rb    ;pot number to be done
count1   rb
count2   rb
count3   rb

entry    movlw  12h        ;...i ooio
         tris   porta
         bcf    clk
         bcf    rs
         bcf    led
         bsf    go
         movlw  00h        ;oooo oooo
         tris   portb
         clrf   portb
         movlw  80h
         option

         movlw  10h        ;store pot readings in RAM at address 10h up
         movwf  fsr
         clrf   idx
         movlw  01h        ;start with pot#1
         movwf  ptn
         bcf    led

wait     btfsc  go         ;wait for PB release on a.4
         goto   wait
         call   msdelay
waitl    btfss  go
         goto   waitl

setpot   call   reset      ;discharge cap, select pot

measure  btfsc  pot        ;bump measure while pot pin is low
         goto   store      ;else jump out and store count
         incf   count1,f
         goto   measure

; Suggestion by Scott Dattalo
;
; This cuts one instruction out of the loop. The consequence of this
; alteration is that the loop will reach 256 25% sooner. So the 150n 
; capacitor needs to be lowered to around 120n, in order for the count 
; to approach 256 at maximum resistance. The advantages are that the 
; pot can be read faster, and the capacitor discharged faster, which 
; may be helpful in multi-pot applications

;         decf   count1,f
;measure  incf   count1,f
;         btfss  pot        ;bump measure while pot pin is low
;         goto   measure    ;else jump out and store count

store    call   cstore     ;store reading
         incf   ptn,f      ;next pot#
         movlw  04h        ;limit = (number of pots)+1
         xorwf  ptn,w
         btfss  zero
         goto   setpot     ;next pot
         goto   stop       ;all done

cstore   movf   count1,w   ;put count value in RAM
         movwf  indf
         call   stee       ;and/or EEPROM (also from 10h up)
         incf   fsr,f
         return

reset    bsf    rs         ;reset 4017, q0=1, no pot selected
         nop
         nop
         bcf    rs

         movlw  10h        ;a.2 = o/p, discharge cap
         tris   porta
         bcf    pot
         call   msdelay
         clrf   idx

nextpot  bsf    clk
         nop
         nop
         bcf    clk
         incf   idx,f      ;current 4017 position
         movf   ptn,w      ;pot to be measured
         xorwf  idx,w
         btfss  zero
         goto   nextpot    ;loop until 4017=pot#
         movlw  12h
         tris   porta
         clrf   count1
         return            ;to measure new pot 
         
msdelay  movlw  0f6h       ;delay about 1 millisecond @ 10MHz
         movwf  count1
         clrf   count2
inc      incfsz count2,f
         goto   inc
         incfsz count1,f
         goto   inc
         return

stee     movf   fsr,w      ;store pot reading in EEPROM
         movwf  eeadr
         movf   count1,w
         movwf  eedata
         call   write
         return

write    bsf    rp0
         bsf    wren
         movlw  55h
         movwf  eecon2
         movlw  0aah
         movwf  eecon2
         bsf    wr

wrend    btfss  eeif
         goto   wrend
         bcf    eeif
         bcf    wren
         bcf    rp0
         return

stop     bsf    led        ;LED on, finished
wrst     goto   wrst       ;wait for RESET to go again

More pot reading circuitry