View previous topic :: View next topic |
Author |
Message |
sema_tufan
Joined: 03 Mar 2020 Posts: 14 Location: turkey
|
instant voltage information with HLVD |
Posted: Tue Mar 03, 2020 6:07 am |
|
|
How can I learning of instant voltage information with HLVD.
Code: | for example: setup_low_volt_detect (LVD_TRIGGER_BELOW | LVD_18); |
This code compares the current voltage to 1.8V and reaches the result.
I want to show the battery icon on the oled screen.
I need instant supply voltage information.
Two AA batteries are used in the circuit. (1.5V+1.5V=3Volts in total) |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Tue Mar 03, 2020 6:19 am |
|
|
you should post which PIC you're using.
There will be some 'setup' required and maybe an interrupt can be generated when the LVD_18 is met. |
|
|
sema_tufan
Joined: 03 Mar 2020 Posts: 14 Location: turkey
|
|
Posted: Tue Mar 03, 2020 6:35 am |
|
|
I'm using the pic18f25k20 processor. For example, I gave LVD_18 this value.
Code: |
setup_low_volt_detect( LVD_TRIGGER_BELOW | LVD_18 );
enable_interrupts(INT_LOWVOLT);
#INT_LOWVOLT
void lowBattery()
{
clear_interrupt(INT_LOWVOLT);
output_high(LEDK);
}
|
the code is working there is no problem. I want to trade for many values, not for a single value. So I need instant voltage information.
In the code, I just said that for example, the instantaneous voltage is compared to the value that I have determined. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19541
|
|
Posted: Tue Mar 03, 2020 7:56 am |
|
|
LVD, cannot do this.
LVD does not 'measure' the voltage. It is just a comparator, that triggers
when the voltage falls below the set point. Key is that this is _fast_. No
ability to 'measure' though.
Use the internal ADC, to read the FVR reference voltage but with the
ADC fed off the supply rail. This then gives you the reciprocal of the actual
supply voltage.
If you read (for example) 512, then the supply voltage is:
(1.2/512)*1024 = 2.4v. |
|
|
sema_tufan
Joined: 03 Mar 2020 Posts: 14 Location: turkey
|
|
Posted: Tue Mar 03, 2020 8:10 am |
|
|
I already researched fvr. According to my reading in the datasheet of the pic18f25k20 processor, it only allowed FVR in the comparison process. So I couldn't find how to code for this processor with fvr. Can you provide sample code? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Tue Mar 03, 2020 9:14 am |
|
|
OK, that's a powerful, fast PIC so simply configure the ADC to read VDD and decide what to do. Vin is low....display Battery Icon, Vin OK, clear the Icon.
Since the PIC is battery powered I assume it's not doing too much so read adc/decide/do is easy. |
|
|
sema_tufan
Joined: 03 Mar 2020 Posts: 14 Location: turkey
|
|
Posted: Tue Mar 03, 2020 9:37 am |
|
|
I read from adc. unfortunately I always saw the value of 1023. I searched fvr for this. but I couldn't use fvr on this processor. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19541
|
|
Posted: Tue Mar 03, 2020 9:47 am |
|
|
The setup for the ADC will depend on your clock settings. You need to tell
us these. The FVR is available as 1111 into the ADC multiplexer.
For a 16MHz master clock:
Code: |
#BIT FVREN=getenv("BIT:FVREN")
void main()
{
float supply=0.0;
unsigned int16 value;
setup_adc_ports(ADC_CLOCK_DIV_16, VSS_VDD);
set_adc_channel(15); //select FVR as input channel
FVREN=TRUE; //enable the FVR
while(TRUE)
{
delay_us(30); //needs 15uSec minimum when reading FVR
value=read_adc();
supply=(1.2/value)*1024; //calculate supply voltage
}
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Tue Mar 03, 2020 10:20 am |
|
|
also..
the FVR isn't 1.20000 volts ! It can be anything between 1.15 to 1.25 volts.
As such , you'll have to run a 'calibration' program to get accurate readings.
Be sure to read about the delay needed for FVR to stabilize. |
|
|
sema_tufan
Joined: 03 Mar 2020 Posts: 14 Location: turkey
|
|
Posted: Wed Mar 04, 2020 5:06 am |
|
|
Dear Ttelmah thank you very much for your answer.
Thank you too for your temtronic answer.
Code: | #BIT FVREN=getenv("BIT:FVREN")
float supply=0.0;
unsigned int16 value;
void main()
{
FVREN=TRUE; //enable the FVR
setup_adc(ADC_CLOCK_DIV_16|VSS_VDD);
setup_adc_ports(15);
while (TRUE)
{
set_adc_channel(15); //select FVR as input channel
delay_us(30); //needs 15uSec minimum when reading FVR
value=read_adc(ADC_START_AND_READ);
supply=(1.2/value)*1024;
}
} |
This code worked.
This is the code I edit with your code.
Can you explain the logic of fvr.
We had to see 1024 resolution with 1.2 volt.
Where is the supply voltage compared to the reference voltage and the process is performed? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Wed Mar 04, 2020 5:22 am |
|
|
The ADC peripheral is a 10 bit adc, though you can use it as an 8 bit adc. It's in chapter 19 ,abut page 249.
FVR is described in section 21.2 of the datatsheet, page 273. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19541
|
|
Posted: Wed Mar 04, 2020 8:41 am |
|
|
The FVR is available as analog input 15. So set_adc_channel(15) selects to
look at the FVR.
Now the ADC can use an external voltage reference _or_ the chip's supply
rails as it's 'reference'. The setting VSS_VDD, tells it to use the chip's
supply as it's reference.
So if your chip was sitting with a 3v supply, each step of the ADC would
be supply/1024, and you would read the FVR as:
1.2 / (3/1024) = 409
If the supply was 2v, you would get:
1.2 / (2/1024) = 614
etc. etc..
So basically you are reading the fixed reference using the PIC's supply
voltage as the reference for the conversion. Since you (nominally), 'know'
the reference voltage, you can calculate the supply.
So you read the 'fixed' voltage as a fraction of the supply. So if the reading
was 512, the supply would be 2.4v (twice the FVR). |
|
|
sema_tufan
Joined: 03 Mar 2020 Posts: 14 Location: turkey
|
|
Posted: Fri Mar 06, 2020 6:50 am |
|
|
Only 1 problem occurred after this code. I couldn't read the value when I pressed the button. Since the buttons are connected to analog pins. I do the analog reading only where I need it, and then turn off the reading. By doing this I solved the problem.
Code: | void batteryStatus()
{
FVREN=TRUE; //enable the FVR
setup_adc(ADC_CLOCK_DIV_16|VSS_VDD);
setup_adc_ports(15);
set_adc_channel(15); //select FVR as input channel
delay_us(30); //needs 15uSec minimum when reading FVR
value=read_adc(ADC_START_AND_READ);
supply=(1.2/value)*1024;
setup_adc_ports(NO_ANALOGS); //
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 06, 2020 7:24 am |
|
|
sema_tufan wrote: |
Only 1 problem occurred after this code. I couldn't read the value when I
pressed the button. Since the buttons are connected to analog pins. I do
the analog reading only where I need it, and then turn off the reading.
By doing this I solved the problem.
void batteryStatus()
{
FVREN=TRUE; //enable the FVR
setup_adc(ADC_CLOCK_DIV_16|VSS_VDD);
setup_adc_ports(15); // *** NOT NEEDED ***
set_adc_channel(15); //select FVR as input channel
delay_us(30); //needs 15uSec minimum when reading FVR
value=read_adc(ADC_START_AND_READ);
supply=(1.2/value)*1024;
setup_adc_ports(NO_ANALOGS); //
}
|
When you read the FVR channel, you don't need to enable any analog pins
so you don't need the setup_adc_ports(15) line.
With that line in your program, you are setting up pins B1,B2,B2,and B4
as analog pins. You don't want that.
See this list from the 18F25K20.h file:
Quote: | #define sAN8 0x1 //| B2
#define sAN9 0x2 //| B3
#define sAN10 0x4 //| B1
#define sAN11 0x8 //| B4 |
If you bitwise OR together all those values, you get 0x0F, which is 15.
That's what you're doing. You're making those four pins into analog pins.
Get rid of the line in bold in the quoted code above. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19541
|
|
Posted: Fri Mar 06, 2020 8:15 am |
|
|
The 'adc pins' function is used to connect pins to the analog multiplexer.
The FVR is permanently connected to this, so as PCM says, you do not
want or need this.... |
|
|
|