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 CCS Technical Support

read adc in millivolt

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



Joined: 13 Jul 2017
Posts: 135
Location: IZMIR

View user's profile Send private message Send e-mail

read adc in millivolt
PostPosted: Thu Sep 19, 2019 1:01 am     Reply with quote

Hello to everyone
I want to read the voltage in millivolt. At first, however, my power supply is 0 volts, and my display shows 9.7 mv. What do you think might be the reason for this?
Code:


#include <18F46K80.h>
#device ADC=12

#FUSES NOWDT                    //No Watch Dog Timer

#use delay(crystal=10MHz)
#define LCD_ENABLE_PIN  PIN_B3
#define LCD_RS_PIN      PIN_B5                                   
#define LCD_RW_PIN      PIN_B4                                   
#define LCD_DATA4       PIN_B2                                   
#define LCD_DATA5       PIN_B1                                   
#define LCD_DATA6       PIN_B0                                   
#define LCD_DATA7       PIN_E0
#include <lcd.c>
#include <math.h>

void main()
{
   int8 counter = 0;
   int32 wValue = 0;
   float Total_Voltage = 0.0;
   float Average_Voltage = 0.0;
   
   setup_adc_ports(sAN1, VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_2 | ADC_TAD_MUL_0);
   
   delay_ms(500);
   lcd_init();
   
   while(TRUE)
   {
      set_adc_channel(1);
      delay_us(20);
      wValue = (read_adc() * (int32)5000)/4096;
      if(counter >= 100)
      {
         Average_Voltage = Total_Voltage / 100;
         
         lcd_gotoxy(1,1);
         printf(lcd_putc,"Volt %2.1f mV ",Average_Voltage);
         
         Total_Voltage=0;
         counter=0;
      }
      else
      {
         counter++;
         Total_Voltage = Total_Voltage + wValue;
      }
   
   }

}

_________________
Es
Ttelmah



Joined: 11 Mar 2010
Posts: 19548

View user's profile Send private message

PostPosted: Thu Sep 19, 2019 1:10 am     Reply with quote

Seriously, using Vss to Vdd, you are unlikely to get even 8bit accuracy...
An accurate ADC, needs an accurate reference.

However the reason for your actual problem, is in the errata.

Quote:

The 12-bit A/D performance is outside the data
sheet’s A/D Converter specifications. When used
as a 12-bit A/D, the possible issues are: high offset
error, up to a maximum of ±25 LSBs at 25°C,
±30 LSBs at 85°C, 125°C and -40°C; high DNL
error, up to a maximum of +6.0/-4.0 LSBs; and
multiple missing codes, up to a maximum of
twenty. Users should evaluate the 12-bit A/D
performance in their application using the
suggested work around below. See Table 3 for
guidance specifications.


So an offset error of up to 30mV as you are using it.....

This is not the chip to use if you want an accurate 12bit ADC.
ertansuluagac



Joined: 13 Jul 2017
Posts: 135
Location: IZMIR

View user's profile Send private message Send e-mail

PostPosted: Thu Sep 19, 2019 1:27 am     Reply with quote

OK thanks. I will feed the Vref voltage to LM336 5v. Is there a chip we can offer me?
_________________
Es
Ttelmah



Joined: 11 Mar 2010
Posts: 19548

View user's profile Send private message

PostPosted: Thu Sep 19, 2019 3:33 am     Reply with quote

Use the Microchip product selection tool.
<https://www.microchip.com/paramchartsearch/chart.aspx?branchID=1005>
Select the family, and then using the parametric search, add all the features
your design needs. Once you have the list whittled down, then look at the
data sheets and (as you have already found), the errata for the suitable
chips.
Understand though that you can work 'with' the offset, by just recording it
and subtracting it. However the missing codes are much more nasty....
temtronic



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

View user's profile Send private message

PostPosted: Thu Sep 19, 2019 4:25 am     Reply with quote

also....
There's also another huge issue with 'noise' or 'lousy' readings. To get accurate, consistent readings you need proper PCB layout, shielded wiring, super stable PSU, Vref tied to precision Vref 'chip' and LOTS of VDD bypass caps. And that's just the start.
Getting reliable ADC results with 10, 12 or 16 bits is 1/2 proper design, 1/2 rework based on observations with scope and 1/2 good luck.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19548

View user's profile Send private message

PostPosted: Thu Sep 19, 2019 11:37 am     Reply with quote

and particularly well designed/routed grounds.
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Fri Sep 20, 2019 7:56 am     Reply with quote

Note that the LM336 has a +/-1% tolerance, which is like 50 mV.

The good thing is that you can put a multi-turn pot on there and you can carefully trim the output. (and it's really cheap)

For more money, there are precision voltage reference ICs like ADR5045 that have a +/- 0.1%. No adjustment, but also a tighter tolerance.
ertansuluagac



Joined: 13 Jul 2017
Posts: 135
Location: IZMIR

View user's profile Send private message Send e-mail

PostPosted: Mon Sep 23, 2019 5:02 am     Reply with quote

thank you very much.
_________________
Es
Ttelmah



Joined: 11 Mar 2010
Posts: 19548

View user's profile Send private message

PostPosted: Mon Sep 23, 2019 6:38 am     Reply with quote

As a couple of extra 'comments' to this consider a couple of other things:

1) The averaging maths can be done much faster using integer arithmetic.
get into the habit of doing as much as possible using integer, and only use
float as a 'last resort'. Remember just how bulky and slow float maths
is on a processor like this.
In fact the entire maths can be done in integer. The chip has an output
function %LW, which allows an integer to be output as if it is a scaled
fixed point number. This is a much nicer way to do this type of operation.

2) In the same vein, why use 100?. In binary it is always much faster
(and potentially more accurate), to divide by binary values. So /64 or
/128 can be done much more easily.
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