View previous topic :: View next topic |
Author |
Message |
Jackma
Joined: 26 Aug 2019 Posts: 6
|
Pic16f676 voltmeter |
Posted: Mon Aug 26, 2019 11:21 am |
|
|
Hi to all. I am new here.
I am also working on this project.
My main problem is voltmeter reading. Its not stable.
HERE is my code:
Code: |
#include <16f676.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC //Internal RC Osc, no CLKOUT
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOBROWNOUT //No brownout reset
#FUSES PUT
#device ADC=10
#use delay(INT=4Mhz)
#define aon output_LOW(PIN_C0);
#define aof output_HIGH (PIN_C0);
#define bon output_LOW(PIN_C1);
#define bof output_HIGH (PIN_C1);
#define con output_LOW(PIN_C2);
#define cof output_HIGH (PIN_C2);
#define don output_LOW(PIN_C3);
#define dof output_HIGH (PIN_C3);
#define eon output_LOW(PIN_C4);
#define eof output_HIGH (PIN_C4);
#define fon output_LOW(PIN_C5);
#define fof output_HIGH (PIN_C5);
#define gon output_LOW(PIN_A2);
#define gof output_HIGH (PIN_A2);
#define d1_of output_LOW(PIN_A1);
#define d1_on output_HIGH (PIN_A1);
#define d2_of output_LOW(PIN_A0);
#define d2_on output_HIGH (PIN_A0);
#define d3_of output_LOW(PIN_A5);
#define d3_on output_HIGH (PIN_A5);
int32 value=0,val2,ind=0,ind2=0,cnt5=0,d1;
void off();
int thu,ten,unit,digit;
void zero(){
aon;
bon;
con;
don;
eon;
fon;
gof;
}
void one(){
aof;
bon;
con;
dof;
eof;
fof;
gof;
}
void two(){
aon;
bon;
cof;
don;
eon;
fof;
gon;
}
void three(){
aon;
bon;
con;
don;
eof;
fof;
gon;
}
void four(){
aof;
bon;
con;
dof;
eof;
fon;
gon;
}
void five(){
aon;
bof;
con;
don;
eof;
fon;
gon;
}
void six(){
aon;
bof;
con;
don;
eon;
fon;
gon;
}
void seven(){
aon;
bon;
con;
dof;
eof;
fof;
gof;
}
void eight(){
aon;
bon;
con;
don;
eon;
fon;
gon;
}
void nine(){
aon;
bon;
con;
don;
eof;
fon;
gon;
}
void comp1(){
if(digit==0)zero();
if(digit==1)one();
if(digit==2)two();
if(digit==3)three();
if(digit==4)four();
if(digit==5)five();
if(digit==6)six();
if(digit==7)seven();
if(digit==8)eight();
if(digit==9)nine();
DELAY_MS(1);
}
void mux(){
d1_on;digit=thu;comp1();d1_of;
d2_on;digit=ten;comp1();d2_of;
d3_on;digit=unit;comp1();d3_of;
//d3_on;digit=unit;comp1();d3_of;
}
void mdelay()
{
mux();mux();//mux();mux();
mux();mux();mux();mux();
mux();mux();mux();mux();
mux();mux();mux();mux();
mux();mux();mux();mux();
mux();mux();mux();mux();
//mux();mux();mux();mux();
//mux();mux();mux();mux();
}
void getad(){
int32 result=0;int8 i;
SET_ADC_CHANNEL(3);
// for(i=0;i<2;i++)
// {
// delay_ms(1);
mux(); mux();mux();mux(); mux();mux();
result=read_adc();
//}
val2=result;
// value = (int8) (read_adc() * 500)/1023;
//val2 = read_adc ();
value = (val2* 5000)/1023;
thu = (value/1000); mux(); mux();mux();mux(); mux();mux();
ten = (value/100)%10; mux(); mux();mux();mux(); mux();mux();
unit = (value/10)%10; mux(); mux();mux();mux(); mux();mux();
/*
putc(thu+48);
putc(ten+48);
putc(unit+48);
unit = value%10;
putc(unit+48);
putc(10);putc(13);
*/
}
void main ()
{
DELAY_MS(1);
/*
//SETUP_ADC_PORTS(NO_ANALOGS);
// set_tris_a(0);
set_tris_c(0x00);
setup_comparator(NC_NC_NC_NC);
setup_adc_ports(sAN0 | VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc(ADC_CLOCK_INTERNAL );
set_tris_c(0x00);
set_tris_a(0xff);
set_tris_a(0b00011001);
setup_comparator(NC_NC_NC_NC); // not use comparator module
setup_adc_ports( sAN3 | VSS_VDD);
setup_adc(ADC_CLOCK_DIV_64);
set_tris_a(0b00011001);
zero();
//DELAY_MS(1000);
while(1)
{
// DELAY_MS(10);
//pwmd();
getad();
mdelay();
}
} |
|
|
|
drolleman
Joined: 03 Feb 2011 Posts: 116
|
|
Posted: Mon Aug 26, 2019 12:26 pm |
|
|
I think he and his project will win a Darwin award. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9283 Location: Greensville,Ontario
|
|
Posted: Mon Aug 26, 2019 1:39 pm |
|
|
OK, he's trying to get the PIC to read ADC and then display on 3-7 segment displays. Quite do-able, BTDT 2 decades ago....
Stability problem could very well be the ADC_clock selection.
I quote, from the datasheet...
Quote: | 4: When the device frequency is greater than 1 MHz, the A/D RC clock source is only recommended if the
conversion will be performed during SLEEP. |
You need to change the ADC clock, based upon the PIC clock frequency
(4MHz in your case). Have a look at the ADC section.
Also you'll need to have a small cap on the ADC input, maybe a Voltage Follower OPAMP, shielded wiring, stable Vref, etc..... Using VDD as the Vref AND muxing LEDs is a bad design choice.
Jay |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Mon Aug 26, 2019 2:01 pm |
|
|
drolleman wrote: | I think he and his project will win a Darwin award. |
It's an old thread, but now I am curious to see what the circuit was... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9283 Location: Greensville,Ontario
|
|
Posted: Mon Aug 26, 2019 2:33 pm |
|
|
If you've got 2 decade old Microchip application books, it's in there, with ASM for 'real' prorammers.....
Probably available as a download 'ap note'...
Might be one for the 16C1671 as well...
Jay |
|
|
Jackma
Joined: 26 Aug 2019 Posts: 6
|
i am using 4mhz |
Posted: Sat Oct 12, 2019 6:20 am |
|
|
I am using 4 mhz internal clock and adc=10
but adc not stable reading.
What can i change
Thanks |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19607
|
|
Posted: Sat Oct 12, 2019 7:56 am |
|
|
The reference voltage.
The ADC depends on the quality of it's reference. Using the supply as a
reference you are unlikely to actually be able to get better than perhaps
1% actual accuracy/noise. For an accurate ADC, you need a stable/accurate
reference voltage. Vref, and feed it from a bandgap diode reference. |
|
|
Jackma
Joined: 26 Aug 2019 Posts: 6
|
pic16f676 adc voltage |
Posted: Sun Oct 13, 2019 2:14 am |
|
|
How to set pic adc voltage ?
I am using default settings.
and what you mean about bandgap ?
I am not set or study about bandgap. |
|
|
Jackma
Joined: 26 Aug 2019 Posts: 6
|
|
|
Jackma
Joined: 26 Aug 2019 Posts: 6
|
Diagram hardware |
Posted: Sun Oct 13, 2019 2:27 am |
|
|
If you say, then I also send the diagram as well. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9283 Location: Greensville,Ontario
|
|
Posted: Sun Oct 13, 2019 5:04 am |
|
|
OK, I looked at the source code and the major problem.
Trying to use the ADC in 10 bit mode.
#1 is that you're using VDD as the ADC's Vref AND assuming it is 5.000 volts. Odds are real good VDD is NOT 5.000 volts AND it will vary everytime the LEDs are used.
If you must use VDD as Vref, I suggest having at least a 4700mfd cap in the power supply to help minimize 'fluctuations' in VDD. A DVM will not show them( 3Hz sample rate) but the PIC WILL see them ! Also wire as PSU-->4700mfd---->LEDS--->1000mfdcap--->PIC. This configuration should reduce VDD from wide variations in voltage.
Honestly even with great PSU filtering, you'll never get stable,repeatable readings. I do suggest adding say a .68 or 1mfd cap to the analog input, that should help.
Also, 'over sample'. Take 8 readings, then average them. Olympic average is a good method. The more readings, teh smoother the result, just be sure to use 8,16,32 readings as the math is fast and simple for the PIC.
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19607
|
|
Posted: Sun Oct 13, 2019 5:19 am |
|
|
Understand, the PIC ADC, does not magically measure voltages. It makes
it's measurements as a 'ratiometric' figure, relative to what is being fed
as it's reference. Now the default _low accuracy_ option, is to use
the chip's supply as this reference. However this is _low accuracy_. The
'best' you will get this way is perhaps 1%, and this only with a really
good supply and a lot of care in the layout. On most systems you are
more likely to get perhaps 5% accuracy. In your case, this is made
worse, since your supply is likely to change as different digits are lit
on the LED. Result you are very likely to see a situation where as
digits change, the value read from the ADC also changes....
To get better accuracy, you have to tell the code to use Vref instead of
Vdd, and feed and accuirate voltage into the Vref pin.
A bandgap reference, is the standard way of getting a more accurate
reference voltage. So:
<https://www.mouser.co.uk/Semiconductors/Power-Management-ICs/Voltage-References/_/N-10vu2?P=1z0wa1tZ1yzt45d>
Understand also, that a voltage that reads as (say) 2v on a DVM, may
well give fluctuation when read using the PIC ADC. The reason is that
the standard DVM, won't resolve high frequency noise. Stick a scope
on this 2v signal, and you may well see many mV of noise. |
|
|
Jackma
Joined: 26 Aug 2019 Posts: 6
|
Ok i try it |
Posted: Sun Oct 13, 2019 5:22 am |
|
|
temtronic wrote: | OK, I looked at the source code and the major problem.
Trying to use the ADC in 10 bit mode.
#1 is that you're using VDD as the ADC's Vref AND assuming it is 5.000 volts. Odds are real good VDD is NOT 5.000 volts AND it will vary everytime the LEDs are used.
If you must use VDD as Vref, I suggest having at least a 4700mfd cap in the power supply to help minimize 'fluctuations' in VDD. A DVM will not show them( 3Hz sample rate) but the PIC WILL see them ! Also wire as PSU-->4700mfd---->LEDS--->1000mfdcap--->PIC. This configuration should reduce VDD from wide variations in voltage.
Honestly even with great PSU filtering, you'll never get stable,repeatable readings. I do suggest adding say a .68 or 1mfd cap to the analog input, that should help.
Also, 'over sample'. Take 8 readings, then average them. Olympic average is a good method. The more readings, teh smoother the result, just be sure to use 8,16,32 readings as the math is fast and simple for the PIC.
Jay |
|
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sun Oct 13, 2019 7:43 am |
|
|
What is the order of magnitude of the variation in your ADC readings?
Using a 'scope how does it compare with the ADC reference noise and the noise at your ADC input?
Mike |
|
|
|