[SOLVED] problem in reading multiple adc channels

Status
Not open for further replies.

vinay bs

Member level 3
Joined
May 22, 2012
Messages
65
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Visit site
Activity points
1,751
Hi,

i am new to micro controllers programming, and i stuck up in the middle of code, the problem i am facing is, i can read the data when i tried using single
adc channel, but i am not able to read data while using two adc channels,i am using pic16f676 microcontroller and hi tech c compiler for compilation..
when i debug the program using mplab sim the program works perfectly but failing to get the data from pins in the circuit...

please help me to continue

thanks
 

Attachments

  • Document1.txt
    1.6 KB · Views: 223



hi,
i attached simple hardware schematic here, p.f.a

using ldr for input(solar sense) and variable dc for olsense..

using leds to check the output(load,spulse, solarled)
 

View attachment 74691

hi,
i attached simple hardware schematic here, p.f.a

using ldr for input(solar sense) and variable dc for olsense..

using leds to check the output(load,spulse, solarled)

ok did you checked adc channel 1 separately? i guess you having adc channel 1 problem. did you check voltage on your that particular channel?
your schematic don't helpful.

i suggest if you have simulator try simulation your code.
 

actually i tried with single adc channel(solar sense).... it worked good....
in the same lines i tried to implement another channel using loop technique....
then checked voltage on first channel .... no use not getting any voltage...
i did circus in all the directions but no use....
did u cheked my code???
 

I checked your code but not in detail though you just try swapping adc channels just for debugging i mean in your code use adc channel 1 in place of adc channel 0 so if your channel 1 sensor faulty then you can fix that
 

tried swapping channels, even by giving 1m sec delay....
not working in any ways....
atleast if i got to know algorithm to access 2 or more channels it may be help full....
 

thanks ud23 for the links...
but all examples they have given is for single adc channel.....
 

Do it like this:

1. Set the desired channel.
2. Wait for 20 us.
3. Read the ADC.
4. Do the calculations.


The same steps are required for each channel.
Do it in a for(; loop.
 

Try this.

Code:
[syntax = c]

//Overload, Dusk and Dawn Control
#include<htc.h>
#include<stdlib.h>
#include<stdio.h>
__CONFIG(FOSC_INTRCCLK&PWRTE_ON&BOREN_OFF&WDTE_OFF);
#define load PORTBbits.RB3
#define spulse PORTBbits.RB2
#define solarled PORTBbits.RB6
#define solarsense PORTAbits.RA0
#define olsense PORTAbits.RA1

unsigned long int analogchannel(unsigned int i)
{
	unsigned short int hbyte,lbyte,adcout;
        ADON = 1;
        GODONE = 1;
	switch(i)
	{
		case'0':
		ADCON0=0x81;
		while(GODONE);
                ADON = 0
                return ADRES;
                break;
		case'1':	
 		ADCON0=0x85;
                while(GODONE);
                ADON = 0
                return ADRES;
		break;
	}

	
}

void main(void)
{
unsigned long int ssvalue,olvalue;
unsigned long int lon_value=409;//(for 2V)
unsigned long int htvalue=665;//(for 3.25V)
unsigned long int ltvalue=563;//(for 2.75)
unsigned long int olvoltage=819;//(for 4V)
TRISBbits. TRISB2=0;//spulse
TRISBbits. TRISB6=0;//solarled
TRISBbits. TRISB3=0;//load
TRISAbits. TRISA1=1;//ol sense
TRISAbits. TRISA0=1;//solar sense
ANSEL = 0x03;
ADCON1=0x00;

	while(1)
	{
		solarled=1;//led ON to show uc working
		ssvalue=analogchannel(0);
		if(ssvalue >= ltvalue && ssvalue <= htvalue)
		{
			msdelay(5);
			if(ssvalue >= ltvalue && ssvalue <= htvalue)
			{
				spulse=1;
			}     	 
		}
		else
		spulse=0;

		if(ssvalue <= lon_value)
		{
			msdelay(5);
			if(ssvalue <= lon_value)
			{
				load=1;//light on
			}
		}	
		else
		load=0;//light off
		
		olvalue=analogchannel(1);
		if(olvalue >= olvoltage)
		{
			msdelay(5);
			if(olvalue >= olvoltage)
			{
				load=0;//light off
			}	
		}
		
	}
}

void msdelay(unsigned int time)
{
unsigned char i,j;
	for(i=0;i<time;i++)			
		for(j=0;j<165;j++);
}



[syntax]

Are you sure that passing arg to function uses single quotes?

Code:
[syntax = c]

ssvalue=analogchannel('0');
olvalue=analogchannel('1');

[/syntax]

Or is it

Code:
[syntax = c]

ssvalue=analogchannel(0);
olvalue=analogchannel(1);

[/syntax]


---------- Post added at 07:22 ---------- Previous post was at 06:52 ----------

Are you sure it is giving values for channel 1? Because you have not used hbyte,lbyte,adcout anywhere in your code. How can analogchannel(); return adcout when there is no code written for finding the value of adcout. Isn't there library for adc in htc?

---------- Post added at 07:52 ---------- Previous post was at 07:22 ----------

There is no algorithm to access 2 or more channels. You have to select a channel, then read the channel and assign the return value of some raed_adc(); function to some float variable. like.

float channel1_val, channel2_val;

channel1_val = read_adc(0);
channel2_val = read_adc(1);
.............
channeln_val = read_adc(n-1);

Do you know the what is the function used to read adc channels in htc?
 
Last edited:

//Overload, Dusk and Dawn Control
#include<htc.h>
#include<stdlib.h>
#include<stdio.h>
__CONFIG(FOSC_INTRCCLK&PWRTE_ON&BOREN_OFF&WDTE_OFF);
#define load PORTCbits.RC3
#define olsense PORTAbits.RA0
#define spulse PORTAbits.RA5
#define solarled PORTCbits.RC4
#define solarsense PORTCbits.RC2
void msdelay(unsigned int);

unsigned int oadc(unsigned char osource)
{
unsigned short int hbyteo,lbyteo,adcouto;
switch(osource)
{
case'o':
ADCON0=0x80;
ADCON1=0x10;
ANSEL=0x01;
TRISAbits. TRISA0=1;
}
msdelay(1);
ADCON0bits.ADON=1;
ADCON0bits.GO=1;
while(ADCON0bits.nDONE==1);
hbyteo=ADRESH;
lbyteo=ADRESL;
adcouto=lbyteo|(hbyteo<<8);
return adcouto;
}

unsigned int sadc(unsigned char ssource)
{
unsigned short int hbytes,lbytes,adcouts;
switch(ssource)
{
case's':
ADCON0=0x98;
ADCON1=0x10;
ANSEL=0x40;
TRISCbits. TRISC2=1;
}
msdelay(1);
ADCON0bits.ADON=1;
ADCON0bits.GO=1;
while(ADCON0bits.nDONE==1);
hbytes=ADRESH;
lbytes=ADRESL;
adcouts=lbytes|(hbytes<<8);
return adcouts;
}

//#pragma psect code main=0x100
void main(void)
{
unsigned short int ssvalue,olvalue;
unsigned short int lon_value=409;//(for 2V)
unsigned short int htvalue=665;//(for 3.25V)
unsigned short int ltvalue=563;//(for 2.75)
unsigned short int olvoltage=819;//(for 4V)
TRISAbits. TRISA5=0;//spulse
TRISCbits. TRISC4=0;//solarled
TRISCbits. TRISC2=1;//solar sense
TRISCbits. TRISC3=0;//load
TRISAbits. TRISA0=1;//ol sense

while(1)
{
solarled=1;//led ON to show uc working
ssvalue=sadc('s');
if(ssvalue >= ltvalue && ssvalue <= htvalue)
{
msdelay(5);
if(ssvalue >= ltvalue && ssvalue <= htvalue)
{
spulse=1;
}
}
else
spulse=0;

if(ssvalue <= lon_value)
{
msdelay(5);
if(ssvalue <= lon_value)
{
load=1;//light on
}
}
else
load=0;//light off

olvalue=oadc('o');
if(olvalue >= olvoltage)
{
msdelay(5);
if(olvalue >= olvoltage)
{
load=0;//light off
}
}

}
}

void msdelay(unsigned int time)
{
unsigned char i,j;
for(i=0;i<time;i++)
for(j=0;j<165;j++)
}

---------- Post added at 09:35 ---------- Previous post was at 09:32 ----------

this is my actual code.....


---------- Post added at 09:36 ---------- Previous post was at 09:35 ----------

please check the above code and let me know if any mistakes.....

---------- Post added at 09:45 ---------- Previous post was at 09:36 ----------

sorry no library function to read adc in htc :-(
 

Did you try this code?

Code:
[syntax = c]

//Overload, Dusk and Dawn Control
#include<htc.h>
#include<stdlib.h>
#include<stdio.h>
__CONFIG(FOSC_INTRCCLK&PWRTE_ON&BOREN_OFF&WDTE_OFF);
#define load PORTBbits.RB3
#define spulse PORTBbits.RB2
#define solarled PORTBbits.RB6
#define solarsense PORTAbits.RA0
#define olsense PORTAbits.RA1

unsigned long int analogchannel(unsigned int i)
{
	unsigned short int hbyte,lbyte,adcout;
        ADON = 1;
        GODONE = 1;
	switch(i)
	{
		case'0':
		ADCON0=0x81;
		break;

		case'1':	
 		ADCON0=0x85;
                break;
	}

        while(GODONE);
        ADON = 0
        return ADRES;

	
}

void main(void)
{
unsigned long int ssvalue,olvalue;
unsigned long int lon_value=409;//(for 2V)
unsigned long int htvalue=665;//(for 3.25V)
unsigned long int ltvalue=563;//(for 2.75)
unsigned long int olvoltage=819;//(for 4V)
TRISBbits. TRISB2=0;//spulse
TRISBbits. TRISB6=0;//solarled
TRISBbits. TRISB3=0;//load
TRISAbits. TRISA1=1;//ol sense
TRISAbits. TRISA0=1;//solar sense
ANSEL = 0x03;
ADCON1=0x00;

	while(1)
	{
		solarled=1;//led ON to show uc working
		ssvalue=analogchannel(0);
		if(ssvalue >= ltvalue && ssvalue <= htvalue)
		{
			msdelay(5);
			if(ssvalue >= ltvalue && ssvalue <= htvalue)
			{
				spulse=1;
			}     	 
		}
		else
		spulse=0;

		if(ssvalue <= lon_value)
		{
			msdelay(5);
			if(ssvalue <= lon_value)
			{
				load=1;//light on
			}
		}	
		else
		load=0;//light off
		
		olvalue=analogchannel(1);
		if(olvalue >= olvoltage)
		{
			msdelay(5);
			if(olvalue >= olvoltage)
			{
				load=0;//light off
			}	
		}
		
	}
}

void msdelay(unsigned int time)
{
unsigned char i,j;
	for(i=0;i<time;i++)			
		for(j=0;j<165;j++);
}



[syntax]


---------- Post added at 10:19 ---------- Previous post was at 10:02 ----------

In you code

Code:
olvalue=oadc('o');
ssvalue=sadc('s');

You've not initialized olvalue and ssvalue.
 

Try this

In the code I've given, use ADCON0 = 80; and ADCON0 = 84; For ADCON1 you have to mention your Fosc. What is your Fosc?
 

https://extremeelectronics.co.in/mi...tal-converter-–-pic-microcontroller-tutorial/

try this adc routines its give you idea how use two channels adcs they using adc channel selection and you using switch case in your code i guess
Code:
unsigned int analogchannel(unsigned int i)
{
	unsigned short int hbyte,lbyte,adcout;
	switch(i)
	{
		case'0':
		ADCON0=0x41;
		ADCON1=0x00;
        break;
		case'1':	
 		ADCON0=0x49;
		ADCON1=0x00;
		break;
	}

	
}
 
Try this

Code:
[syntax = c]

//Overload, Dusk and Dawn Control
#include<htc.h>
#include<stdlib.h>
#include<stdio.h>
__CONFIG(FOSC_INTRCCLK&PWRTE_ON&BOREN_OFF&WDTE_OFF);
#define load PORTBbits.RB3
#define spulse PORTBbits.RB2
#define solarled PORTBbits.RB6
#define solarsense PORTAbits.RA0
#define olsense PORTAbits.RA1

unsigned long int analogchannel(unsigned int i)
{
	unsigned short int hbyte,lbyte,adcout;
        ADON = 1;
        GODONE = 1;
	switch(i)
	{
		case'0':
		ADCON0=0x80;
		break;

		case'1':	
 		ADCON0=0x84;
                break;
	}

        while(GODONE);
        ADON = 0
        return ADRES;

	
}

void main(void)
{
unsigned long int ssvalue,olvalue;
unsigned long int lon_value=409;//(for 2V)
unsigned long int htvalue=665;//(for 3.25V)
unsigned long int ltvalue=563;//(for 2.75)
unsigned long int olvoltage=819;//(for 4V)
unsigned long int ssvalue, olvalue;

TRISBbits. TRISB2=0;//spulse
TRISBbits. TRISB6=0;//solarled
TRISBbits. TRISB3=0;//load
TRISAbits. TRISA1=1;//ol sense
TRISAbits. TRISA0=1;//solar sense
ANSEL = 0x03;
ADCON1=0x00;

	while(1)
	{
		solarled=1;//led ON to show uc working
		ssvalue=analogchannel(0);
		if(ssvalue >= ltvalue && ssvalue <= htvalue)
		{
			msdelay(5);
			if(ssvalue >= ltvalue && ssvalue <= htvalue)
			{
				spulse=1;
			}     	 
		}
		else
		spulse=0;

		if(ssvalue <= lon_value)
		{
			msdelay(5);
			if(ssvalue <= lon_value)
			{
				load=1;//light on
			}
		}	
		else
		load=0;//light off
		
		olvalue=analogchannel(1);
		if(olvalue >= olvoltage)
		{
			msdelay(5);
			if(olvalue >= olvoltage)
			{
				load=0;//light off
			}	
		}
		
	}
}

void msdelay(unsigned int time)
{
unsigned char i,j;
	for(i=0;i<time;i++)			
		for(j=0;j<165;j++);
}



[syntax]

In your second version of code, you've to set the ADCON0 for channel 1 to 0x80 and ADCON0 for channel 2 to 0x84. For ADCON1, you've to calculate using your Fosc.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…