Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Using AN2 to read voltage and create digital variable

Status
Not open for further replies.

pigman

New Member
Hey, I am using the 12F675 and AN2 with a couple of resistors to divide the voltage to allow me to check the voltage of a battery, this works great however I would like to know if anyone has the formula or a table/chart of what each voltage point turns into as a digital variable?

I am using a 10k and 20k resistor to divide the voltage on AN2

I just need to know how to figure out what the digital converted value will be. IE 4v = 200 or something ?

Can anyone help?

Thanks heaps!
 
The AD reading (assuming 10bit AD) = INT(1023*k*Vbat/Vref),

where:
k is your voltage divider factor, in your case R2/(R1+R2) = 10K/(10K+20K) = 0.3333
Vbat is the battery voltage.
Vref is usually the PIC's Vdd, likely ~5V. You need to measure the actual voltage to at least three significant figures.
INT( ) is the integer function.
1023 comes from the number of bits, 2^10-1

for example, if the battery voltage is 14.00V and the Vref is 4.950V, the AD reading would be 964 decimal (03C4 hex).
 
Last edited:
Mike,

You are some sort of guru man. always there to help!

Here is the code I found that I've been messing with. I ran 11.5v for Vbat through your calculation and I'm way off, I think I might be doing it wrong? Any ideas?

BATT
call ACQUIRE_AD
movf ADRESH,w ; look at value 11.5V = 3.83V and D195
sublw D'195' ; if negative then drive ok
btfss STATUS,C
goto DRIVE
 
I make 11.5V to be about 784 +-correction for the actual Vref
 
It doesn't. 195 decimal out of the AD would correspond to a battery voltage of 2.859V
 
Why is it that every one wants to use 1023 that's wrong there are 1024 steps in 10 bit ADC not 1023

Adc values are held in two 8 bit register so there is not a limited like there would be if it was just 10 bits wide
 
Last edited:
Ok, so the expression for the AD reading (assuming 10bit AD) = FLOOR(1024*k*Vbat/Vref), where FLOOR() is the C function.

I dont understand what you are saying about two eight bit registers? There are still only 1024 unique values, regardless of how the bits are packed into two bytes.
 
Most every one thinks thinks it is only 10 bits wide so it can only be 1023 but it's 1024 steps in two 8 bit register's.

It 1024/volts =
 

Attachments

  • volts.PNG
    volts.PNG
    6 KB · Views: 143
Last edited:
It doesn't. 195 decimal out of the AD would correspond to a battery voltage of 2.859V

Mike,
I am a simpleton here how do I get to correspond the 195 decimal out of the AD to asscertain that it is a battery voltage of 2.859?

Wait I think I just got it. We are substituting the "divided" voltage into the equation IE using a voltage of 3.83 and a reference of 5 I would get 261 decimal out?

Another quick one, how do I determine the reference voltage? this is just the supply voltage to the PIC?
 
Mike,
I am a simpleton here how do I get to correspond the 195 decimal out of the AD to asscertain that it is a battery voltage of 2.859?

Wait I think I just got it. We are substituting the "divided" voltage into the equation IE using a voltage of 3.83 and a reference of 5 I would get 261 decimal out?

No, Think of it like this. If Vref=Vdd=5.000V, and we put 5V into the AD in port, then the AD reads 1023. If you put in 3.83V, then the AD puts out (3.83/5.00)*1024 = 784.384, but since the AD must put out an integer, then it has to be truncated down to 784.

The voltage divider puts out 1/3 of what goes in, so to get 3.83V at the AD in, the battery voltage must have been 3*3.83V = 11.49V.

So where does 261 come from????

Another quick one, how do I determine the reference voltage? this is just the supply voltage to the PIC?

Yes, but to do the math accurately, you have to measure it with an accurate DVM, measure it to the nearest mV, or so.
 
Mike,

Ok I think it is all sinking in now :) the question is tho how does it currently work with such low numbers?
As mentioned early on the current AN2 check code (taken from some other program I found somewhere) says

Code:
BATT
call	ACQUIRE_AD
movf	ADRESH,w	; look at value 11.5V = 3.83V and D195
sublw	D'195'	 ; if negative then drive ok
btfss	STATUS,C
goto	DRIVE

So I'm curious how they get D195 when it should be 785, any ideas? I have posted below the beginnings of the program related to setting up the AD part and below that is the ACQUIRE_AD.

Code:
;---------------------------------------- 
; Analog-to-Digital Converter (A/D) Module (Section 7.0) (PIC12F675 Only) 
; 
; The analog-to-digital converter (A/D) allows conversion of an analog 
; input signal to a 10-bit binary representation of that signal. The 
; PIC12F675 has four analog inputs multiplexed into one sample and hold 
; circuit. There are two registers to control the functions of the A/D 
; module: 
;   A/D Control Register (ADCON0) 
;   Analog Select Register (ANSEL) 
; 
; Note: When using GPIO pins as analog inputs, ensure the TRISIO register 
;       bits are set (= 1) for input. 
;		Ports=    xxx4x210
        movlw   b'00000100'			; Enable AN2 with A/D Clk = Fosc/8 
        movwf   ANSEL 
 
        ; VRCON (Register 6-2) 
        clrf    VRCON				; CVref circuit: powered down, no Idd drain 
 
        bcf     STATUS, RP0         ; ---- Select Bank 0 ----- 
 
        movlw	b'00001000'			; left justified, Vdd ref, A/D off
		movwf	ADCON0
		bsf		ADCON0,ADON			; A/D On
		clrf	T1CON
		bsf		T1CON,0				; timer 1 on
		bcf		PIR1,TMR1IF			; clear timer 1 overflow 

TIME_0
		bcf		INTCON,T0IF

Code:
; subroutine to wait for A/D conversion
ACQUIRE_AD
	bsf		ADCON0,GO_DONE	; GO/DONE bit start conversion
WAIT_CONV
	btfsc	ADCON0,GO_DONE	; conversion complete when cleared ~11 cycles
	goto	WAIT_CONV
	return

This is the thing that is confusing me, I totally understand your math and it all makes sense but this number D'195' that has been used doesn't make sense, and the funny thing is.... it works at D'195' for 11.5v input. My issue however is that I need to raise that to about 13.5 and really don't want to do it by trial and error

I guess the other question would be what happens if the input voltage goes over 5v (above the reference). I guess chip damage? or potentially the count starts at 0 again if it didn't destroy the chip?
 
Only thing I can figure is that they used different external voltage divider resistor values.
 
Mike,

Strange thing is I have the schematic for that project as well and they are using the same divider resistors, that's why I went with those resistors so I could adapt their code. I tested it with those lower values and it works, very strange. I may change them to the ones we have been discussing here and see if those work.

One other thing would I refer to it like this?

Code:
BATT
call	ACQUIRE_AD
movf	ADRESH,w	; look at value 11.5V = 3.83V and D195
sublw	D'785'	 ; if negative then drive ok
btfss	STATUS,C
goto	DRIVE

Or something like this?

Code:
BATT
call	ACQUIRE_AD
movf	ADRESH,w	; look at value 11.5V = 3.83V and D195
sublw	.785	 ; if negative then drive ok
btfss	STATUS,C
goto	DRIVE

Just added the schematic.
 

Attachments

  • Power Module v2.pdf
    19.7 KB · Views: 229
Last edited:
Ok,

so I've just done some testing and I put vBatt 13.5 = 4.5 = 921
sublw D'921' and it just doesn't seem to work.

I still can't get my head around how the working file is calling D'195' and that is referencing 11.5v. Any idea's?

Thanks guys
 
A 10bit AD reading can be either right or left justified in a 16bit unsigned INT in two 8bit bytes, depending on how the AD is configured. Also, when you read the AD, you can choose to treat the answer as 8bits (by discarding the two LSBs). At least in the C functions I use.

921 right shifted by two bits is ~230, so that is likely what is going on.
 
Last edited:
Ahhh ok, that sounds like whats happening. So how do I calculate / figure out the shifted by two bits final reading?

Cheers
 
I'm not an expert on PIC assember, so I will let someone else look at your code.

AD reading (assuming 8bit AD reading) = FLOOR(256*k*Vbat/Vref), where FLOOR() is the C function, where k = 1/3

so, FLOOR((256*11.5)/(3*5.00)) = 196 (assuming Vref=5.00V).


If programmer was lazy, and is only using the 8msb of the AD reading, then the constant equivalent to 11.5V at the battery would be 196.

Note that the smallest step of battery voltage change that can be resolved while using only the 8bits is 5/256*3 = 59mV. If all ten bits were used, you could resolve 15mV.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top