Passing two variables back from a Hi-Tech C function

Thread Starter

Guinness1759

Joined Dec 10, 2010
64
Here's my code:

Rich (BB code):
unsigned char, unsigned char
get_temp() {

        ADCON0 = 0b00000111; //  Start ADC and Set Channel to AN1 (RA1)
		while(ADGO)
			continue;	// wait for conversion complete
		temph = ADRESH;
		templ = ADRESL;
        return ADRESH, ADRESL;
}
This code gives me numerous errors. Works fine if I want to return only one variable. Looked through a lot of example code and can't find anywhere, where they return 2 variables.
 

debjit625

Joined Apr 17, 2010
790
You have to provide an identifier for your variable.
Here is how we declare and define a variable.
Rich (BB code):
unsigned char var1 ; 
unsigned char var2 ;
.
And always end your statement with a semicolon in C.

This is how your code should be
Rich (BB code):
unsigned char temph;
unsigned char templ;

void get_temp() 
{
ADCON0 = 0b00000111; //  Start ADC and Set Channel to AN1 (RA1)
while(ADGO)
continue; // wait for conversion complete
temph = ADRESH;
templ = ADRESL;

}
 

debjit625

Joined Apr 17, 2010
790
Or your could be like this

Rich (BB code):
#define Value() ((((unsigned int)ADRESH)<<8)|(ADRESL))
 
unsigned char temph;
unsigned char templ;
 
unsigned int get_temp() 
{
ADCON0 = 0b00000111; //  Start ADC and Set Channel to AN1 (RA1)
while(ADGO)
continue; // wait for conversion complete
temph = ADRESH;
templ = ADRESL;
return Value();
}
I have not removed the variables temph and templ because they may be used for some purpose.Here I have used a macro "Value()" to get the full 16 bits value of ADC in an unsigned int var.

Good Luck
 

Thread Starter

Guinness1759

Joined Dec 10, 2010
64
Is there a way to get it to return two 8 bit values? I would like to stick with 8 bits because my serial function accepts 8 bit values. Thanks.
 

debjit625

Joined Apr 17, 2010
790
You have not specified your mcu, but as it’s hi tech C and you mentioned 8 bits so I assume you are using any Microchip's 8 bits mcu like PIC16Fxxx, PIC18Fxxx or etc.

Normally in 8bit PIC you will get a 10bit ADC module i.e.. when you get the ADC value the 10bit value is stored in 2 registers ADRESL and ADRESH, the low 8 bits will be in register ADRESL and the remaining higher 2 bits will be in ADRESH.

Is there a way to get it to return two 8 bit values? I would like to stick with 8 bits because my serial function accepts 8 bit values.
You can follow the first code...

Rich (BB code):
unsigned char temph;
unsigned char templ;
 
void get_temp() 
{
ADCON0 = 0b00000111; //  Start ADC and Set Channel to AN1 (RA1)
while(ADGO)
continue; // wait for conversion complete
temph = ADRESH;
templ = ADRESL;
}
After you call the get_temp() function, the low 8 bits value of ADRESL is stored in the 8 bits(i.e.. unsigned char) variable named templ and ADC's higher 2 bits value from ADRESH is stored in the 8 bits variable temph.Now you can use these to 8 bits variable templ and temph where you want, may be your serial function.

Good Luck
 

Thread Starter

Guinness1759

Joined Dec 10, 2010
64
Ok, so lets say I need to run the function 4 times before I send the serial data, because I'm collecting 4 temperature values.

get_temp()
temp1h = temph;
temp1l = templ;
get_temp()
temp2h = temph;
temp2l = templ;
get_temp()
temp3h = temph;
temp3l = templ;
get_temp()
temp4h = temph;
temp4l = templ;

It would be nice to be able to condense it to 4 lines of code such as

temp1h, temp1l = get_temp();
temp2h, temp2l = get_temp();
temp3h, temp3l = get_temp();
temp4h, temp4l = get_temp();

Or something like that. Not a big deal, just semantics. If I need to use a 16 bit variable, then I'll just stick with the longer code I guess.
 

John P

Joined Oct 14, 2008
2,068
This seems easiest if you declare a 2-element array and pass it to the function, then let the function load it.

Rich (BB code):
unsigned char temp[2];

get_temp(temp);
If you want to call it 4 times, then it could be:
Rich (BB code):
unsigned char temp[4][2];

get_temp(temp[0]);
get_temp(temp[1]);
get_temp(temp[2]);
get_temp(temp[3]);
And the function would be:
Rich (BB code):
void get_temp(unsigned char *tmp) 
{
ADCON0 = 0b00000111; //  Start ADC and Set Channel to AN1 (RA1)
while(ADGO)
continue; // wait for conversion complete
*tmp = ADRESH;
*(tmp+1) = ADRESL;
}
I think that's right.
 

someonesdad

Joined Jul 7, 2009
1,583
C is a relatively primitive language and you can't pass more than one object back from a function. Thus, you have to use some kind of container; arrays, structs, and unions (and objects in C++) are the usual tools. Or, declare a structure with static scope and pass back a pointer to it.
 

debjit625

Joined Apr 17, 2010
790
John P have showed a solution which could be used i.e.. array stuff.
someonesdad also showed some ways to achieve the goal,but I will point out the last way he showed.

someonesdad said:
Or, declare a structure with static scope and pass back a pointer to it.
Or why not pass pointers of the variable to the function like this.

First create your four variables,I dont think you will need four variables as two is enough but as your logic I am creating the four variables.
Rich (BB code):
unsigned char temp1l,temp1h,temp2l,temp2h,temp3l,temp3h,temp4l,temp4h;
Then create your function like this.
Rich (BB code):
void get_temp(unsigned char * templ,unsigned char * temph) 
{
ADCON0 = 0b00000111; //  Start ADC and Set Channel to AN1 (RA1)
while(ADGO)
continue; // wait for conversion complete
*temph = ADRESH;
*templ = ADRESL;
}
Now you can use this function by providing the address of the two variables as the parameters and after the call ends the two variables will contain the value of the ADC.

For example you want the ADC value to be stored in temp1l and temp1h....
Rich (BB code):
get_temp(&temp1l,&temp1h);
Or in your words
Guinness1759 said:
It would be nice to be able to condense it to 4 lines of code such as
Rich (BB code):
get_temp(&temp1l,&temp1h);
get_temp(&temp2l,&temp2h);
get_temp(&temp3l,&temp3h);
get_temp(&temp4l,&temp4h);
Good Luck
 

John P

Joined Oct 14, 2008
2,068
Where I suggested passing the address of a 2-element array, you're saying use 2 individual bytes. Either should work.

But the quick-and-dirty way to do it is to use global variables and pass nothing at all. Just load the variables and the job is done.
 

Thread Starter

Guinness1759

Joined Dec 10, 2010
64
edit: Thanks everyone for the help, I had to move the functions part of my code to the beginning of my file, to avoid declaration errors. Now everything should be working fine.
 
Last edited:
Top