PDA

View Full Version : Battery voltage monitoring for use on 16F1825



longpole001
- 13th April 2013, 17:55
Hi Guys , would like to get some input on implementing a Voltage monitor on a battery powered pic on the 16F1825

The Battery source produces 7.2V - 7.4v Fully charged ,

I use a Low drop Voltage regulator to produce 3.3v , via a schottky diode ( Forward V Drop of 0.4v) to ensure polarisation, so voltage presented into the regulator is about 6.8V - 7V

The pic (16F1825) and associated ccts run on the 3.3v ,

All the I/O pins are in use as digital outputs with Mosfets connected . ICSP header is also connected , so there are 10K resistors on PortA.0 ,portA.1 feeding the P ch mosfets on those ports

As the PIc has Fixed Voltage Ref that i would select to VDD as Vref

The plan is to feed the voltage from the input side of the regulator via 47K resistor ( to limit current when i/o low ) to the 10K resistor connected to PortA.0 and the Pch mosfet

but the concern is the expected voltage difference between VDD to I/O pin on the PIC both for ADC input , the digital output high and low ( active Low to use Pch mosfet)

I will have to turn on / off ACD and work out all that side during the times i dont have to digital output on this port.

but any thoughts on this proposel and a better way to go on how to get the voltage monitor to work / connect


Cheers

Sheldon

HenrikOlsson
- 13th April 2013, 20:24
Hi Sheldon,
Sounds tricky.... How would you prevent the MOSFET from turning ON when you're no longer driving the output high?
Could you possibly whip up a schematic showing what you're trying to describe?
One thing you should take into consideration the max recommended impendence on the ADC input, if the resistor divider has high impedence you may need to buffer the voltage before feeding it into the PIC or take other precautions (extra long sample time perhaps).

/Henrik.

languer
- 14th April 2013, 01:17
I think I understand what you're proposing. The 47K would pull-up the FET gate to the supply voltage; I don't think that's a big issue. The 10K isolates the PIC output (input) from the FET gate; that looks ok except when the pin pulls low you have a voltage divider leaving about 1.2V on the FET gate.

Perhaps the following is what you are describing and I misunderstood you. If you have a pull-up from the supply to the FET's gate, and a pull-down from the FET's gate to ground; you can perhaps size them such that while there is supply voltage the FET stays off, and when you're also scaling the supply voltage to the PICs pin (for analog measurement). You also would want a small resistor (say 100-200 ohms) between the PIC's pin and the FET's gate; to provide a little isolation without taking away the ability to pull down the FET's gate when you want to turn the FET on. Does this makes any sense?

Wow this is probably my first ASCII art.

What I described before is something like the following:
.........SUPPLY
.............|
.............|
.............R
.............|
.............|
PIC---R--|--FET
.............|
.............R
.............|
.............|
...........GND

But this next one probably works as well - and perhaps a little better

......SUPPLY
........|
........|
........R
........|
........|
PIC---R--|--FET
.............|
.............R
.............|
.............|
............GND

To make sure it works you have to work the math such that the gate is always off unless the PIC pulls it to gnd. Also the voltage division from the supply to the PIC has to be such that you can sense when the voltage decreases (and the PIC running at +3.3V means that that voltage has to be scaled down as such). I haven't worked out the math, but you'll have two equations and two unknowns; you should be able to work it and see if it converges to a solution.

You don't have any other pin you can use for the supply monitoring?

longpole001
- 14th April 2013, 01:21
Hi Hendric , yes its gong to be a bit tricky , as the pin is digital output normally ACTIVE LOW , then need to go setup ACD on the pin , sample positive voltage , then switch bak, but the goal is to have some battery monitor on the main input voltage to the regulator , this will make the power LED flash at a rapid rate when battery is low , ( normally power led would flash 1 time in 2 sec or so)

The mosfet chosen has to allow gate to source voltage larger than say 5v???

see attached proposed diagram

Cheers

Sheldon


6962

spcw1234
- 14th April 2013, 01:26
Not sure what you want to do with the mosfet, but a simple voltage divider into an analog input is the easiest way to monitor the battery voltage.

edit: Sorry, was goofing around, my post is late :)

longpole001
- 14th April 2013, 01:51
yes choosing the Pch mosfet - looking at the gate to source voltage spec (Vgs) has to be at least rated above +/- 5v, the gate threshold voltage would be be a bit higher than say - 2v to -4 , but the pic i/o pin (low) would need to sink less than 20ma ( no problem with the values proposed) ???

longpole001
- 14th April 2013, 02:07
in answer to the question of free available pins , no it s full house , i would love to the only input pin , but its not able to do adc ( vpp/m-clr) , as far as the math i see it as this

input Voltage range at regulator to produce output of 3.3v = 3.8V - 7V
low voltage monitor trigger point - 4.5v ???
Pch mosfet gate threshold highest value = below 2v will most likly be between 0- 1v to turn on mosfet ?
Pch mosfet Vgs greater than +-5v - better at -+10v for safe use

any thing i missed ??

longpole001
- 14th April 2013, 02:17
thanks Languer , placing a resistor to ground at the fet gate with the other proposed values , would make the threshold lower trigger voltage on the fet trigger and provide a smaller input voltage to the I/O pin for measure ??

longpole001
- 14th April 2013, 03:35
yes going to some online voltage divider calculators using 22k to Voltage supply and 15K to ground joined at the Pch gate will give a range of 1.5v - 2.8V when Vsupply gives 3.8V - 7v input , this is with no Resistance load calculation of both the pic i/0 pin and fet worked out but in practice will play and measure.

I think this should work after i sort out timing of the sample and when to input / output

any other things i should consider ???

Charlie
- 14th April 2013, 11:22
You can reduce the complexity with an N-channel FET by changing the order from +3.3V / FET / LED / R / GND to 3.3V / LED / R / FET / GND. Now R12 can be replaced with a piece of wire. Set the voltage divider to be about 3V when the battery is at maximum, and choose a FET that is full on with VGS ~1V.

By the way, if you are using a high powered LED, they typically have a forward volt drop closer to 3V, so your 100 ohm resistor might be too large.

longpole001
- 14th April 2013, 23:59
by removing r12 , with a direct link to gate and resistors is more likely to effect ,PGD input when doing ISCP programming i would have thought .

finding the right N channel is preferred to P channel , but always easier to be lower to gnd voltage to turn on then finding the right trigger voltage on the gate as well as matching the voltage range for ADC measurement , but some play is going to happen

Charlie
- 15th April 2013, 10:41
Removing R12 will have no impact on PGD. The resistor divider might be another matter, but the values are reasonably large, so I doubt it. Worst case you can add a programming jumper, but it won't be necessary. Double check the spec if you are in doubt.

languer
- 15th April 2013, 20:24
Values look good, and calculations match your expectations. I like R12 (bot not 10K, something like 330 or 1,000) only because it provides a bit of isolation from the gate. But Charlie is right, it probably makes little difference. Best way is to go ahead and try it, and then optimize as needed.

As far as the N-ch FET, not sure this would work for this application as the turn-voltage for a "bad" condition would be the same as the ADC voltage for the "good" condition.

longpole001
- 16th April 2013, 23:09
yes tried the P ch - it is is easier to ensure low trigger than using N channel ,with voltage divider , now to actually get some reading to work correctly , it would have been easier if there were more pins LOL .

longpole001
- 20th April 2013, 07:37
Hi guys well had some time to continue with this , changes to proposed cct are the voltage small in that the voltage divider has 27k to supply and 15k to ground to give voltage in to porta.0 of 2.8 - 1.4v , and languer was right in that a 150R for R12 was need to to be able to drive to ground to fully turn on the Pch mosfet

Problem is setup the ACD section for the 16F1825/29 chips and are not sure if i am doing it correctly , and have gone on what i read in the chip data

Also i not sure what results i should get when looking at the value it reads and how it relates so some help with how it is calculated

As can be seen from the code comments for each part this is what i am expecting
at the moment my debug write result to eeprom is giving a value of 3 ?? so something is not right

cheers

Sheldon




' ---------- Gets a Voltage reading on Port1.0 ---------

' Note: - Application circuit has a 3.3v voltage reg fitted so could use VDD as Vref in ASCON1 register
' - have used the ADC Fixed Voltage Ref Modual in 16F1825.
' - PortA.0 ia also used as Digital Output of Power LED active low via Pch - Mosfet
' - Supply Voltage input range is 8.1V - 3.5V to Voltage divider ( Vsupply --> 27k -|- 15K -- GND) giving ADC input on PORTA.0 = 2.8 - 1.4V
' ( PortA.0 )

Get_volts :

ADCON0 = %00000001 ' bit 7 -N/A , Bit 6-2 = ADC chan Sel /Tempature output /FVR output = AN0 sel = 00000 ,
' Bit 1 - Go/_done status flag - 1 = Go do ADC / 0 = Done ADC , Bit 0 = Enable ADC = 1 / 0 = Disable ADC

ADCON1 = %10100011 ' bit 7 = 1 ADFM ( ADRESH, ADRESL - right justify ).Bit 6-4 ADCS = 010 - Fosc/32 conversion clock
' Bit3 - N/A , Bit2 = 0 (Vref- is connected to Vss) , Bit1-0 = 11 - Vref+ connected to FVR Modual

FVRCON = %10000010 ' Bit 7 =1 enable Fixed Voltage Ref Modual, Bit 6 = VRef ready bit =1 always ok on 16F1825, Bit 5 - Temp indicator 1= enable/0 = disable
' Bit 4 = Temp Indicator Range Sel 0=Vout -Low range / 1= Vout -High range , Bit 3-2 = 00( DAC Fixed volt sel )
' Bit 1-0 = 10 - ADC Fixed Vref of 2.048v

pauseus 10 ' allow Vref to stablise - ??? - not required for the 16F1825/29 ??

ANSELA = %00000001 ' Set Port A.0 - Analoge I/O , 0 = Digital 1 = Analog
TRISA = %00001001 ' setup Port A.0 input=1,output=0 for I/O pins ( Note RA3 - is input only (digital)- refer spec)

adcin 0, ADval ' Read PortA.0 value into variable , this applies the fixed voltage ref (via ADCON0,ADCON1,FVRCON)
' to comparitor and ADC pin selected and gives result ???

write $01 ,ADval.byte0 ' debug of voltage measurement - lower byte
write $02 ,ADval.byte1 ' debug of voltage measurement - upper byte

If ADval <= 1024 then ' Have no idea of the value its going to get ?? , but if below value of 1.6V ( 4.5v Vsupply) then set Power low values
Pulse_off = 500 ' Set Pulse_off duration to 500us to signal power low to IR_RX
Flash_rate = 10 ' Set Power Led toggle to fast rate to show low power
Else
Pulse_off = 276 ' Set Pulse_off duration to 300us( adj) to signal NOT power low to IR_RX
Flash_rate = 100 ' Set Power Led toggle to Normal rate to show NOT low power
endif

' Restore PortA.0 to digital . ACD OFF etc
ADCON0 = %00000000 ' Set ADC to Disable - Bit 0 = Enable ADC = 1 / 0 = Disable ADC
ANSELA = %00000000 ' Set Port A.0 = 0 Digital, 0 = Digital 1 = Analog
TRISA = %00001000 ' setup Port A.0 input=1,output=0 for I/O pins ( Note RA3 - is input only (digital)- refer spec)

return

longpole001
- 21st April 2013, 23:20
Any feed back on why the ACD is not working , how to workout the calculation for the what result i should see ?

prstein
- 22nd April 2013, 04:28
I notice a couple of oddities in your code that may (or may not!) be part of the problem. You are using the PBP ADCIN command but not any of the PBP defines. I don't know if PBP needs the defines beyond setting some register bits which you do directly. Below is a gentle re-arrangement of your code, trying to follow the exact order recommended in the manual. Also, it explicitly waits until the FVR is ready and, instead of using ADCIN, manually starts the conversion, waits for it to finish, and then reads the result.


' ---------- Gets a Voltage reading on Port1.0 ---------

' Note: - Application circuit has a 3.3v voltage reg fitted so could use VDD as Vref in ASCON1 register
' - have used the ADC Fixed Voltage Ref Modual in 16F1825.
' - PortA.0 ia also used as Digital Output of Power LED active low via Pch - Mosfet
' - Supply Voltage input range is 8.1V - 3.5V to Voltage divider ( Vsupply --> 27k -|- 15K -- GND) giving ADC input on PORTA.0 = 2.8 - 1.4V
' ( PortA.0 )

Get_volts :
TRISA.0 = 1 ' setup Port A.0 input=1,output=0 for I/O pins ( Note RA3 - is input only (digital)- refer spec)
ANSELA = %00000001 ' Set Port A.0 - Analoge I/O , 0 = Digital 1 = Analog

FVRCON = %10000010 ' Bit 7 =1 enable Fixed Voltage Ref Modual, Bit 6 = VRef ready bit =1 always ok on 16F1825, Bit 5 - Temp indicator 1= enable/0 = disable
' Bit 4 = Temp Indicator Range Sel 0=Vout -Low range / 1= Vout -High range , Bit 3-2 = 00( DAC Fixed volt sel )
' Bit 1-0 = 10 - ADC Fixed Vref of 2.048v

while FVRCON.6 = 0 : wend 'wait for FVR to be ready

ADCON0 = %00000001 ' bit 7 -N/A , Bit 6-2 = ADC chan Sel /Tempature output /FVR output = AN0 sel = 00000 ,
' Bit 1 - Go/_done status flag - 1 = Go do ADC / 0 = Done ADC , Bit 0 = Enable ADC = 1 / 0 = Disable ADC

ADCON1 = %10100011 ' bit 7 = 1 ADFM ( ADRESH, ADRESL - right justify ).Bit 6-4 ADCS = 010 - Fosc/32 conversion clock
' Bit3 - N/A , Bit2 = 0 (Vref- is connected to Vss) , Bit1-0 = 11 - Vref+ connected to FVR Modual


pauseus 10 ' allow Vref to stablise - ??? - not required for the 16F1825/29 ??


' adcin 0, ADval ' Read PortA.0 value into variable , this applies the fixed voltage ref (via ADCON0,ADCON1,FVRCON)
' ' to comparitor and ADC pin selected and gives result ???
ADCON0.0 = 1 'start the conversion
while ADCON0.0 = 1 : wend 'wait for it to finish
ADVal.byte0 = ADRESL
ADVal.byte1 = ADRESH

write $01 ,ADval.byte0 ' debug of voltage measurement - lower byte
write $02 ,ADval.byte1 ' debug of voltage measurement - upper byte

If ADval <= 1024 then ' Have no idea of the value its going to get ?? , but if below value of 1.6V ( 4.5v Vsupply) then set Power low values
Pulse_off = 500 ' Set Pulse_off duration to 500us to signal power low to IR_RX
Flash_rate = 10 ' Set Power Led toggle to fast rate to show low power
Else
Pulse_off = 276 ' Set Pulse_off duration to 300us( adj) to signal NOT power low to IR_RX
Flash_rate = 100 ' Set Power Led toggle to Normal rate to show NOT low power
endif

' Restore PortA.0 to digital . ACD OFF etc
ADCON0 = %00000000 ' Set ADC to Disable - Bit 0 = Enable ADC = 1 / 0 = Disable ADC
ANSELA = %00000000 ' Set Port A.0 = 0 Digital, 0 = Digital 1 = Analog
TRISA.0 = 0 ' setup Port A.0 input=1,output=0 for I/O pins ( Note RA3 - is input only (digital)- refer spec)

return

Hope this helps...

Best Regards,
Paul

peterdeco1
- 22nd April 2013, 14:43
A while back I added a battery voltage tester to an existing circuit board. I didn't have a choice - the PIC was operating from the battery directly without a regulator at 5.4V (6V battery through series protection diode). Using a jumper wire I connected the ADC to an on-board regulator in another part of the circuit. Now it measured voltage in reverse; the lower the battery voltage, the higher the ADC reading. With trial and error I found 167 to be my alert number for low battery.

ADCIN 1, BATTERYCONDITION
IF BATTERYCONDITION >= 167 THEN HIGH PORTB.0.

Portb.0 connected to Nch FET. For low voltages I always use a logic-level FET with a very low gate threshold voltage. I prefer IRLZ44N. It's a power transistor that I use to supply 2A without needing a heatsink. Just barely gets warm at that current.

longpole001
- 23rd April 2013, 02:22
thanks guys , i found that the defines of DEFINE ADC_BITS 10 , DEFINE ADC_SAMPLEUS 10 were not inplace as such the acdin would not work , i did try the direct register approch and this also worked with bit ' ADCON0.1 = 1 'start the conversion set

In the end due to the voltage range of 3.8v -9v Vsupply input ,the voltage divider resistor values i had chosen and using the Vref internal of the chip of 2v off the Vref module i found that at the highest voltage the ACD reading was higher that 1024 , so decided to use VDD as Vref in the ADCON1 register ( as regularor is inplace on this cct)

Also found that using the FRC internal allowed the ACD reading to allow for the voltage range using the existing Voltage divider resistor values ,i am still usure of how to work out the calculations for what the expected reading should be , but in practice i measured the voltage and did debug of the values by writing them to eeprom at the high and low points when voltage was applied

so here is the working code for those like me that find its best to post code results as those that read this forum a lot gain lots .

I also note i included DT's Average subroutine to do an accumulative average of samples

next PWM how to set that up correctly for what i want as adding the ACD routines has screwed the regular timing of the simple pulse output code i have

Cheers

Sheldon




DEFINE ADC_BITS 10 ' Number of bits in ADCIN result - Required for adcin command
DEFINE ADC_SAMPLEUS 10 ' ADC sampling time in microseconds - Required for adcin command

' ------------ADC routines and Varaiables ----------------
ADval VAR WORD ' Value of raw ACD voltage read

AvgCount CON 10 ' Number of samples to average in Average routine
FAspread CON 200 ' Fast Average threshold +/- in Average routine
ADavg VAR WORD ' Accumulated Varable of Readings in Average routine
Value VAR WORD ' Temp varable assigned in Average routine




' ---------- Gets a Voltage reading on Port1.0 ---------

' Note: - Application circuit has a 3.3v voltage reg fitted so use VDD as Vref in ASCON1 register
' - have used the ADC Fixed Voltage Ref Modual in 16F1825.
' - PortA.0 ia also used as Digital Output of Power LED active low via Pch - Mosfet
' - Supply Voltage input range is 9V - 3.5V to Voltage divider ( Vsupply --> 27k -|- 15K -- GND) giving ADC input on PORTA.0 = 3.1 - 1.4V
' ( PortA.0 )

Get_volts :

ADCON0 = %00000001 ' bit 7 -N/A , Bit 6-2 = ADC chan Sel /Tempature output /FVR output = AN0 sel = 00000 ,
' Bit 1 - Go/_done status flag - 1 = Go do ADC / 0 = Done ADC , Bit 0 = Enable ADC = 1 / 0 = Disable ADC

ADCON1 = %11110000 ' bit 7 = 1 ADFM ( ADRESH, ADRESL - right justify ).Bit 6-4 ADCS = 111 - using FRC internal ( 1.6us per sample)
' Bit3 - N/A , Bit2 = 0 (Vref- is connected to Vss) , Bit1-0 = 00 - Vref+ connected to VDD

FVRCON = %00000010 ' Bit 7 =0 disable Fixed Voltage Ref Modual, Bit 6 = VRef ready bit =1 always ok on 16F1825, Bit 5 - Temp indicator 1= enable/0 = disable
' Bit 4 = Temp Indicator Range Sel 0=Vout -Low range / 1= Vout -High range , Bit 3-2 = 00( DAC Fixed volt sel )
' Bit 1-0 = 10 - ADC Fixed Vref of 2.048v

pauseus 10 ' allow ADC change and Vref to stablise

ANSELA = %00000001 ' Set Port A.0 - Analoge I/O , 0 = Digital 1 = Analog
TRISA = %00001001 ' setup Port A.0 input=1,output=0 for I/O pins ( Note RA3 - is input only (digital)- refer spec)


y = 0 ' ensure 0
While Y < 10 ' do 10 voltage reads
ADCIN 0,ADval ' Read PortA.0 value into variable , this applies the fixed voltage ref (via ADCON0,ADCON1,FVRCON)
' to comparitor and ADC pin selected and gives result.
Value = ADval ' Assign ADval from ACD to Value for Average Routine Calculations
gosub Average ' Go do running average of ADC reading

y = y+1 ' Increment loop counter
wend


If ADval <= 510 then ' below value of 1.6V ( 4.8v Vsupply) then set Power low values
Pulse_off = 500 ' Set Pulse_off duration to 500us to signal power low to IR_RX
Flash_rate = 10 ' Set Power Led toggle to fast rate to show low power
Else
Pulse_off = 276 ' Set Pulse_off duration to 300us( adj) to signal NOT power low to IR_RX
Flash_rate = 200 ' Set Power Led toggle to Normal rate to show NOT low power
endif

' Restore PortA.0 to digital . ACD OFF etc
ADCON0 = %00000000 ' Set ADC to Disable - Bit 0 = Enable ADC = 1 / 0 = Disable ADC
ANSELA = %00000000 ' Set Port A.0 = 0 Digital, 0 = Digital 1 = Analog
TRISA = %00001000 ' setup Port A.0 input=1,output=0 for I/O pins ( Note RA3 - is input only (digital)- refer spec)

return


' -=-=-=-=-=-= Average Analog values - a DT routine -=-=-=-=-=-=-=-=-=-=
Average:
IF Value = ADavg Then NoChange
IF ABS (Value - ADavg) > FAspread OR Value < AvgCount Then FastAvg
IF ABS (Value - ADavg) < AvgCount Then RealClose
ADavg = ADavg - (ADavg/AvgCount)
ADavg = ADavg + (Value/AvgCount)
GoTo AVGok
FastAvg:
ADavg = Value
GoTo AVGok
RealClose:
ADavg = ADavg - (ADavg/(AvgCount/4))
ADavg = ADavg + (Value/(AvgCount/4))
AVGok:
Value = ADavg ' Put Average back into Value
NoChange:
Return

prstein
- 23rd April 2013, 14:57
Congrats on getting it working. Will you be using the software-based PWM or the hardware based HPWM?

Best Regards,
Paul