PDA

View Full Version : configuring AD converter in a 12F615



tekart
- 16th February 2011, 19:00
I'm having trouble getting an analog reading on GP4/AN3 of the 12F615 chip. Been wading through the spec sheet and trying to find all the right bits in the various registers. No matter what I try, I get a value of 1023 from this:
adcin gpio.4,reading

Here are the register setups I'm using:
ADCON0 = %11001101 ' select analog input for AN3
ANSEL = %00001000 ' select analog input for AN3
vrcon = %10000000 ' CVref = ON
CMCON0 = %10000111 ' comparators off

Can anyone tell me what I'm doing wrong? Must be something really dumb.

Darrel Taylor
- 16th February 2011, 19:33
Use the AN number in ADCIN statements instead of the PORT.pin.


adcin 3,reading

And you don't need the ADCON0, VRCON or CMCON0 statements.
But you will need ADCON0.7 = 1 ; Right Justify A/D result

Since you are getting 1023 as the result, I assume you've set the ADC defines to 10-bit.

Also, make sure your primary oscillator is set to _INTRC_OSC_NOCLKOUT in the configs (it's the default).

tekart
- 16th February 2011, 19:42
Thanks Darrel! It WAS something dumb! :) Got it working.

So what I'm trying to do is read the battery level of the 2 coin batteries that power the PIC so I can have a low battery warning. Now I need to figure out if that can be done. I'm guessing I have to change the voltage reference? I don't have a good intuitive grasp of A/D converters...

Darrel Taylor
- 16th February 2011, 20:04
Yes, that can be done with the 615.
And you don't even need to use a PIN to do it.

I've got a code snippet around here somewhere.
I'll see if I can find it ... or re-write it.

tekart
- 16th February 2011, 20:10
That would be awesome Darrell!

I have something working now using a 1N914 diode from the pin to ground and a 10K to plus from the pin. Sorta using the diode as a reference. But it's depending on the diode drop which may not be accurate in production.

A no-pin solution would be a better design. Have you posted this idea to the forum in the past? If not I'm sure that many of us that design battery powered products would benefit from your genius!

Darrel Taylor
- 17th February 2011, 00:38
Yes, I had posted it before. But it was for a different chip, and I can't find it now.
It's not too difficult, so I re-wrote it for the 12F615 and tested it on a LAB-X4.

The idea is to use the internal 0.6V reference (ADC channel 5).
The reference stays the same as VDD changes, so with VDD as the ADC's Vref, the value read changes too. You can use that change to calculate actual VDD without needing an external Analog Pin.


DEFINE ADC_BITS 10

LCD VAR GPIO.1 ; serial pin for LCD
LCDbaud CON 396 ; serial baud rate

ADval VAR WORD
VDD VAR WORD

ANSEL = 0 ; All Pins are Digital
ADCON0.7 = 1 ; Right Justify A/D result
HIGH LCD : PAUSE 2 ; Initialize serial data level

SEROUT2 LCD,LCDbaud,[$FE,1] : PAUSE 3 ; Clear LCD

GOSUB GetVDD

SEROUT2 LCD,LCDbaud,["A/D=",DEC ADval," ", _
"VDD= ",DEC VDD/10,".",DEC1 VDD]
STOP
;------------------------------------------------------------------
Vref_AD CON 117 ; A/D reading for 0.6V Vref @ 5V VDD

GetVDD:
VRCON.4 = 1 ; Enable 0.6V Fixed reference
PAUSE 10 ; allow reference to stabilize
ADCIN 5, ADval ; read the 0.6V reference
VDD = (Vref_AD * 50) / ADval ; convert to volts
VRCON.4 = 0 ; turn off fixed reference
RETURN

The VDD result has 1 decimal place, so 5.0V will be 50.

HTH,

tekart
- 17th February 2011, 00:54
Awesome Darrell! :)

I plugged in your brilliant code and it works flawlessly!

Is it possible to get 2 decimals of resolution using the 10bit ADC? On a 3 Volt system that drops out a 2.0 Volts it could make a difference.

Darrel Taylor
- 17th February 2011, 01:38
Well as far as the math goes, you can get 2 decimals by multiplying *500 instead of 50. Then change the SEROUT2 to divide by 100 and use DEC2.

But those references aren't really accurate enough to get that kind of resolution reliably.
And they drift some with temperature, so you'll probably want to stick with 1 decimal place.

You could also do the same thing with an external "Precision" reference and get better resolution. But of course that uses a PIN, which are precious on an 8-pin chip.

tekart
- 17th February 2011, 01:55
Yeah, I though that would work. I tried X500 and got readings that varied by about .05 Volts even when I hit the PIC with a heat gun to see if there would be significant temperature drift. Not bad actually.

This is a totally awesome way to read the battery voltage Darrell. THANKS AGAIN. You are a friggin genius!

klantz12
- 17th February 2011, 10:29
Can anyone help me with configuring the AD converter in 16F877A on the labX1 board? I am using MicroCode Studio-pbp and i have tried the following code from the help button and from another post i read.


ADCON1=132 ' 128 + 4 = %10000100 'Left just 3 analog inputs rest digital
TrisA = 255 'all inputs for the a to d
Define ADC_BITS 10 ' Set number of bits in result
Define ADC_CLOCK 3 ' Set clock source (rc = 3)
Define ADC_SAMPLEUS 50 ' Set sampling time in microseconds

AdcIn 1, W0
AdcIn 3, W1


The error says that ADCIN needs a variable.

My assignment is just to read the AD input from the three potentiometers at A0 A1 and A3.

Pretty lost. Thanks! also, i didnt know how to start a new thread so sorry for posting in ya'lls.

Kay

mackrackit
- 17th February 2011, 10:37
didnt know how to start a new thread so sorry for posting in ya'lls.

Big button near the top of forum pages, "+ Post New Thread".

tekart
- 17th February 2011, 15:14
AdcIn 1, W0
AdcIn 3, W1

The error says that ADCIN needs a variable.

Kay, I'm assuming that you have migrated to the PIC world from Basic Stamps and you may not have defined your variables - something you do not need to do in Stamps. So you need:

W0 var byte

to define W0 as a byte variable - these definitions usually go near the top of the page.

Bruce
- 17th February 2011, 15:48
For 10-bit A/D you'll want to define W0 & W1 as WORD sized vars...;o)

dhouston
- 18th February 2011, 00:04
So what I'm trying to do is read the battery level of the 2 coin batteries that power the PIC so I can have a low battery warning.I recently lost a NAS HDD so I don't have the code but 4-5 years back I designed a generic, battery powered ADC module. My battery monitor used a couple of pins so it probably is not applicable here but it may be useful for others. In my case, I needed only a single ADC input pin so I had a surplus of pins.

I used two BR2032 coin cells. BR type cells maintain their rated charge until slightly before their end of life while CR type cells fall off gradually throughout their life.

The batteries connected to Vdd and I fed an LP2980 LDO from a PIC pin. Vdd was 6V but the PIC12F675 (and PIC12F615) can handle 6.5V. The output of the LDO was used to power the attached analog sensor and also connected to Vref. A second pin can also supply the LDO if more current is needed.

To monitor the battery, measure the output of the LDO using Vdd as reference. Initially, the reading will be something less than maximum but will approach maximum as the batteries start to drop off just before end of life.

This wasn't my original idea but I cannot recall where I came across it.

Aussie Barry
- 30th May 2011, 13:12
Hi All,

I am having difficulty understanding a line from Darrel's no-pin battery monitor code snippet. Can someone please explain the line

Vref_AD CON 117 ;A/D reading for 0.6V Vref @ 5V VDD

Is this a constant or does it vary? I am confused!

I would like to implement this no-pin battery monitor into a project using a 12F683. The two devices appear to be pin compatible so I am hopint this will work. Am I sadly mistake?

Cheers
Barry

mackrackit
- 30th May 2011, 13:21
Vref_AD CON 117 ;A/D reading for 0.6V Vref @ 5V VDD

Is this a constant or does it vary? I am confused!


From the manual:


4.6. Constants

Named constants may be created in a similar manner to variables. It can be more convenient to use a constant name instead of a constant number. If the number needs to be changed, it may be changed in only one place in the program; where the constant is defined. Variable data cannot be stored in a constant.

Label CON Constant expression

Some examples of constants are:

mice con 3
traps con mice * 1000

Darrel Taylor
- 30th May 2011, 20:40
I would like to implement this no-pin battery monitor into a project using a 12F683. The two devices appear to be pin compatible so I am hopint this will work. Am I sadly mistake?

The 12F683 does not have an internal 0.6V fixed reference.
So you won't be able to do it with that chip.

Aussie Barry
- 31st May 2011, 00:57
Thanks for the input Darrel and Dave.

It is amazing what you can find in the manual when you know where to look ;)

Darrel, can you please explain how you arrived at the value 117 for the Vref_AD constant? I would have expected it to be 0.6/5*1023 = 122

For my project I was able to use another ADC pin to monitor the supply voltage so all is good (for the time being).

Cheers
Barry

Darrel Taylor
- 31st May 2011, 02:25
Darrel, can you please explain how you arrived at the value 117 for the Vref_AD constant? I would have expected it to be 0.6/5*1023 = 122
The internal fixed references are not very accurate, so you have to read the actual value to determine the number to use.


For my project I was able to use another ADC pin to monitor the supply voltage so all is good (for the time being).
Thats a bit like lifting yourself up by your own bootstraps.

Aussie Barry
- 1st June 2011, 03:38
Thanks Darrel.
I am using the other ADC pin to sense the pre-regulator voltage (via an appropriate voltage divider).
If the pre-reg voltage drops below 5.3V then the circuit will flash a "Low Battery" indicator and disable any future water pump operation.
I am trying to save the 6V SLA battery from a harmful depletion condition.

Cheers
Barry