CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

voltage measurement

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
strsh



Joined: 16 Jul 2013
Posts: 37

View user's profile Send private message

voltage measurement
PostPosted: Sun Aug 04, 2024 6:35 am     Reply with quote

Greeting,
I wrote a simple voltage measurement code with PIC 16F886 and PCWHD 5.112 compiler.
Code:

/* Voltmeter
 *
 * Created:   uto mar 19 2024
 * Processor: PIC16F886
 * Compiler:  CCS for PIC
 */

#include <16F886.h>
#device ADC=10
#fuses NOMCLR INTRC_IO
#use delay(clock=8000000)

unsigned long voltage=0;
unsigned int n1=0, n2=0, h=0;
unsigned char number[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};

int display()
{
   n2=(voltage/10)%10;   // first number
   n1=(voltage/1)%10;   // second number

   output_C(number[n1]);
   output_low(PIN_C7);
   output_low(PIN_B0);
   delay_ms(10);
   output_high(PIN_B0);

   output_C(number[n2]);
   output_low(PIN_C7);
   output_low(PIN_B1);
   delay_ms(10);
   output_high(PIN_B1);


int main (void)
{
setup_adc_ports(sAN1 | VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);

   while(1)
   {
      h++;
      if(h>50)
      {
    set_adc_channel( 1 );
         delay_ms(10);
         voltage=read_adc()*0.489;
         h=0;
      } 
   display();   
   }   
}


I simulated in Proteus and didn't see any problems, but...
When I made the hardware, the voltage I measure with the instrument shows that there is no voltage deviation, in contrast to the display, which shows me that the voltage varies by a couple of volts. Also, by changing the controller's supply voltage, the measured voltage also changes, although the input voltage I am measuring is fixed.
I'm wrong somewhere, if you could help me I would be grateful.
Thanks in advance, Alexander.
Ttelmah



Joined: 11 Mar 2010
Posts: 19358

View user's profile Send private message

PostPosted: Sun Aug 04, 2024 8:11 am     Reply with quote

Quite a lot of parts to this.
First thing, look at table 9-1 in the data sheet. What does it say about clock
sources for the ADC, and processor clock rates above 1MHz?.
You need to be using the CPU clock suitably divided, not the internal RC
oscillator. Using this will lead to the ADC being more noisy than it should be.
This then brings the second point. Noise. Both your voltage source, and
the power supply will have lots of noise on them. Unfortunately a DVM
(unless a special very expensiive one), will not read the instantaneous
voltage of anything, it integrates it's reading, typically over about 1/4 second.
So a voltage can appear dead stable on a DVM, but actually be fluctuating
by many mV. This applies both to your voltage source, and to the processor
supply. Remember using VDD_VDD, means this supply is the reference to
the ADC. Unless this is dead stable, there will be fluctuations in the
reading.
Now comes the next part. What do you think your digits display?. You speak
about 'volts', but this is not what the digits are showing.

Your ADC counts 0-1023 for 0 to just fractionally under 5v (assuming the
supply is 5v). You multiply this by o.489, so will get a count for just under
every 10mV (your maths is slightly wrong, so you will actually get 500
for a voltage of 4.99v).
You then take this count, and display the bottom digit of this for your
bottom display digit, and the next for the next. So your display actually
reads .99v. So each count of the bottom digit is hundredths of a volt.
Unless both your source and the supply are very smooth, this will jump.
(Made worse by the clock selection).

There are then some comments. Floating point arithmetic is awfully
heavy on code size, and slow. You would get a better result by doing the
maths in integer.
Also avoid using names like 'long' for type sizes. Problem is these vary
with different chips. Much better to use int8, int16, int32 etc., which
ensures you know the size of the variable you are using.
So
Code:


int16 voltage;

//then read with
voltage=(read_adc()*64)/131;


This is much faster, uses less code size, and would give 499 for the largest
voltage the ADC can read (actually 4.995 volts).
You are still going to be working in hundredths of a volt though.

Realistically though unless your system has a very smooth supply and
source, you are going to have to look at damping the reading. so have a
look at this thread:

[url]
http://www.ccsinfo.com/forum/viewtopic.php?t=60386
[/url]

Which is just the latest one discussing exactly this.
strsh



Joined: 16 Jul 2013
Posts: 37

View user's profile Send private message

PostPosted: Tue Aug 06, 2024 2:37 pm     Reply with quote

Thank you for the answer.
I followed the suggestions and corrected the code. I got a more accurate voltage measurement and reduced the oscillation of the measured voltage display.
Is it possible, and in what way, to cancel the MCU voltage change to the measured voltage, ie. that the power supply of the MCU has no effect on the measurement of the second voltage? I mean a software solution.
temtronic



Joined: 01 Jul 2010
Posts: 9167
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Aug 06, 2024 3:14 pm     Reply with quote

There is no software solution for your hardware configuration.

Now you 'can' minimize the effects possibly using Olympic averaging. You take 10 reading , delete min and max, then average the remaining 8. It's very fast for a PIC to do on the RAW ADC results.

Check to see if that PIC has an internal Vref ! some do, some don't. Might be an option,though it is technically a 'hardware' change.
Ttelmah



Joined: 11 Mar 2010
Posts: 19358

View user's profile Send private message

PostPosted: Wed Aug 07, 2024 1:13 am     Reply with quote

Realistically, you have to understand that you cannot 'create precision'. There
has to be real precision to begin with.
As Jay says, you can improve the effect, by using tricks like Olympic
averaging, but at the end of the day, to get (say) 0.1% genuine precision,
requires a voltage reference that is better than this, and the same from
each of the other components n the design (resistors used in the connections
etc. etc..).
Honestly, you need to start with a precision Vref, to have any hope of a
precise reading. Also, there needs to be extreme care in the actual board
layout etc..
You cannot magically produce accuracy where it doesn't exist.
However (for example), you can get a form of short term higher precision,
by reading a known voltage from something, then switching to your
real reading. Allows you to calculate an 'adjustment factor' that will
only slowly go badly wrong.
strsh



Joined: 16 Jul 2013
Posts: 37

View user's profile Send private message

PostPosted: Thu Aug 08, 2024 8:44 am     Reply with quote

Thanks for the answers.
I will take your suggestions into consideration and implement them into the project.
Once again, thank you.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group