Voltage given to ADC was from UNI_T 9V battery
so you have a resitor network divider ..
9V -- R serial --- Potentiometer ---- 0V
curseur ------------------> ADC input
what is the value of R serial ? 820 ohms ?
Does the 9V battery voltage keep constant when you move the potar cursor
How do you convert Points to Volts ?
// LCD module connections
sbit LCD_RS at RC0_bit;
sbit LCD_EN at RC1_bit;
sbit LCD_D4 at RA0_bit;
sbit LCD_D5 at RA1_bit;
sbit LCD_D6 at RC4_bit;
sbit LCD_D7 at RC5_bit;
sbit LCD_RS_Direction at TRISC0_bit;
sbit LCD_EN_Direction at TRISC1_bit;
sbit LCD_D4_Direction at TRISA0_bit;
sbit LCD_D5_Direction at TRISA1_bit;
sbit LCD_D6_Direction at TRISC4_bit;
sbit LCD_D7_Direction at TRISC5_bit;
// End LCD module connections
char look(int a)
{
switch(a)
{
case 0:
return '0';
case 1:
return '1';
case 2:
return '2';
case 3:
return '3';
case 4:
return '4';
case 5:
return '5';
case 6:
return '6';
case 7:
return '7';
case 8:
return '8';
case 9:
return '9';
default:
return '.';
}
}
void main()
{
unsigned int k = 0; // stores ADC result for voltage
unsigned int count; // used in average loop
CMCON0.CM2 = 1;
CMCON0.CM1 = 1;
CMCON0.CM0 = 1;
TRISA0_bit = 0;
TRISA1_bit = 0;
TRISA2_bit = 1;
ANSEL = 0x80; // AN7
ADCON1 = 0x00; // Fosc/2
ADCON0 = 0x81; // Vref is VDD
TRISC = 0x0C;
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
LCD_Cmd(_LCD_CURSOR_OFF);
do
{
k = 0;
count = 0;
while(count<64) {
k = k + ADC_Read(0);
k = ADC_Read(7);
count++;
}
k = k >> 6;
LCD_Chr(1,1,look(k/1000)); // Display First Digit
k = k % 1000;
LCD_Chr_CP(look(k/100)); // Display Second Digit
k = k % 100;
LCD_Chr_CP(look(k/10)); // Display Third Digit
LCD_Chr_CP(look(k%10)); // Display Fourth Digit
Delay_ms(550);
} while(1);
}
I was using three ADC channels and was suffering this problem (non-linear). I dont know why. But then i changed the code for only one ADC channel. and found it was linear. Actually, i have to show voltage, current and current limit on LCD. So, i need three ADC channels. Now the problem is that even i use only one ADC, the ADC result is not constant at voltage greater than 3V (ADC pin voltage) approx. It is fluctuating 3 to 4 digits up and down.
AND code.
Code:// LCD module connections sbit LCD_RS at RC0_bit; sbit LCD_EN at RC1_bit; sbit LCD_D4 at RA0_bit; sbit LCD_D5 at RA1_bit; sbit LCD_D6 at RC4_bit; sbit LCD_D7 at RC5_bit; sbit LCD_RS_Direction at TRISC0_bit; sbit LCD_EN_Direction at TRISC1_bit; sbit LCD_D4_Direction at TRISA0_bit; sbit LCD_D5_Direction at TRISA1_bit; sbit LCD_D6_Direction at TRISC4_bit; sbit LCD_D7_Direction at TRISC5_bit; // End LCD module connections char look(int a) { switch(a) { case 0: return '0'; case 1: return '1'; case 2: return '2'; case 3: return '3'; case 4: return '4'; case 5: return '5'; case 6: return '6'; case 7: return '7'; case 8: return '8'; case 9: return '9'; default: return '.'; } } void main() { unsigned int k = 0; // stores ADC result for voltage unsigned int count; // used in average loop CMCON0.CM2 = 1; CMCON0.CM1 = 1; CMCON0.CM0 = 1; TRISA0_bit = 0; TRISA1_bit = 0; TRISA2_bit = 1; ANSEL = 0x80; // AN7 ADCON1 = 0x00; // Fosc/2 ADCON0 = 0x81; // Vref is VDD TRISC = 0x0C; Lcd_Init(); Lcd_Cmd(_LCD_CLEAR); LCD_Cmd(_LCD_CURSOR_OFF); do { k = 0; count = 0; while(count<64) { k = k + ADC_Read(0); k = ADC_Read(7); count++; } k = k >> 6; LCD_Chr(1,1,look(k/1000)); // Display First Digit k = k % 1000; LCD_Chr_CP(look(k/100)); // Display Second Digit k = k % 100; LCD_Chr_CP(look(k/10)); // Display Third Digit LCD_Chr_CP(look(k%10)); // Display Fourth Digit Delay_ms(550); } while(1); }
I think the noise from Power Supply is causing the fluctuation. I saw the noise at scope. I think at voltage greater than 3V, noise peak is effective ans causing the disturbance. Is there a way to reduce that noise?
PS: Power Supply is Switch Mode.
k = 0;
count = 0;
while(count<64) {
k = k + ADC_Read(0);
k = ADC_Read(7);
count++;
}
k = k >> 6;
k = 0;
count = 0;
while(count<64) {
k = k + ADC_Read(7);
count++;
}
k = k >> 6;
I would recommend replace the resistor network you implemented for the power supply with a proper linear voltage regulator and filter cap. Do so would provide better voltage regulation and eliminate the majority of noise for SMPS
Reading of ADC result was 960 (constant) between 4.63 and 4.71V. How it could be possible?
k = 0;
count = 0;
while(count<64) {
k = k + ADC_Read(0);
k = ADC_Read(7);
count++;
}
k = k >> 6;
ignores the the value from ADC_Read(0) after the first time around the loop and can potentially overflow the storage size by adding 65 * 1023 = 66495 in an unsigned int.
unsigned int ADCread(unsigned char channel)
{
delay_us(40);
ADCON0 = (channel << 2) | 1 | (0x80); .
delay_us(40);
ADCON0.GO_DONE = 1;
while(ADCON0.GO_DONE)
continue; // wait for conversion complete
delay_us(40);
return ((ADRESH<<8)|(ADRESL));
}
Today i added the acquisition delay. But the problem was same. ADC result is not constant. Fluctuating 4 to 5 digits up and down.
Here is the code for reading ADC result.
Why do you not use (or test with) MikroC Library ADC ?
ADCON0 = (channel << 2) | 1 | (0x80);
delay_us(40);
unsigned int ADCread(unsigned char channel)
{
delay_us(40); <-- a minimum delay must occurs between each ADC measure
ADCON0.GO_DONE = 1;
delay_us(5); <--- add somme NOP or little delay here
while(ADCON0.GO_DONE); // wait for conversion complete
return ((ADRESH<<8)|(ADRESL));
}
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?