Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Trying to pass and return a variable to a function returns uneffected value

Status
Not open for further replies.

ghead

Member level 2
Joined
Nov 19, 2010
Messages
43
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,288
Activity points
2,384
HI, I'm using Mikroc pro for pic and PIC16F877A

I'm trying to pass a variable to a function like this

Code C - [expand]
1
filter(average);

to this function

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Filter(unsigned int sample){
   if (sum == 0) {
      bufferA[0] = sample;
      sum = sample * 4;
   }
 
   sum -= bufferA[oldest];
   sum += sample;
   bufferA[oldest] = sample;
   oldest++;
   if (oldest >= 4) oldest = 0;
 
   return sum/4;
}

The function calls and returns and with the variable unchanged. Tested by setting a flag in the function and also just adding a number to "sum" in the function and returning with "sum".

Code C - [expand]
1
2
3
4
Filter(unsigned int sample){
   sample = sample + 100;
   return sample;
}

Still the same result unchanged. Everything in function is declared except "sample".
Any ideas what am I missing here?
 

hello


unsigned int Filter(unsigned int sample);

to get a returned value ...
 
  • Like
Reactions: ghead

    ghead

    Points: 2
    Helpful Answer Positive Rating
I tried

Code C - [expand]
1
2
3
4
unsigned int Filter(unsigned int sample){
   sample = sample + 100;
   return sample;
}


but still same result of variable unchanged.
And calling from main loop

Code C - [expand]
1
2
average = 100;
Filter(average);



I was sure this was right but still not working, I will try write new code to test this on its own outside of my current code as I'm at a loss why this isn't working.

- - - Updated - - -

So this is my test that still doesn't work

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
sbit LCD_RS at RD1_bit;
sbit LCD_EN at RD3_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;
////////////////////////////////////////////////////////////////////////////////
sbit LCD_RS_Direction at TRISD1_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
// Variables ///////////////////////////////////////////////////////////////////
unsigned char arrayDisp[7];
unsigned int average;
// Lcd Text ////////////////////////////////////////////////////////////////////
char msg[17]; //declare array set 16 bytes of RAM aside for copying txt into
const char txt1[] = "RESULT:";
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//////////copy const char txt to ram string/////////////////////////////////////
char * CopyConst2Ram(char * dest, const char * src){
   char * d ;
   d = dest;
   for(;*dest++ = *src++;);
   return d;
}
////////////////////////////////////////////////////////////////////////////////
void Int_Main() {                  //Prepare ports turn A/D off comparators off//
   TRISA = 255;
   TRISB = 255;
   TRISC = 255;
   TRISD =   0;                 //PORTD LCD outputs
   CVRCON =  0;                 //vref off
   CMCON =   7;                 //compartors off
   ADCON0 =  0;                 //a/d converter off
   ADCON1 =  6;                 //All Digital
}
/////////////DISPLAY current temp///////////////////////////////////////////////
void Display_cur(){
   Lcd_cmd(_LCD_CLEAR);  //Clear display/////////////////////////////////
   Lcd_out (1,1,CopyConst2Ram(msg,txt1));
   IntToStr(average, arrayDisp);
   Lcd_Chr_Cp(arrayDisp[1]);
   Lcd_Chr_Cp(arrayDisp[2]);
   Lcd_Chr_Cp(arrayDisp[3]);
   Lcd_Chr_Cp(arrayDisp[4]);
   Lcd_Chr_Cp(arrayDisp[5]);
   Delay_200ms();
}
////////////////////////////////////////////////////////////////////////////////
unsigned int Filter(unsigned int sample){
   sample = sample + 10;
   return sample;
}
/////////////////////////////>>>>MAIN PROGRAM<<<////////////////////////////////
void Main(){
   Int_Main();                    //Initialise PORTS and Periphirals
   Lcd_init();                   //Initialise LCD
   Lcd_Cmd(_LCD_CLEAR);          //Clear display
   Lcd_Cmd(_LCD_CURSOR_OFF);     //No cursor on the lcd display
   delay_1sec();                 //Wait for lcd settle
   average = 100;
////////////Main loop - Never leave here////////////////////////////////////////
   while(1){
      Display_cur();
      Filter(average);      //Running Average of last 4 Values
      Delay_1sec();                  //Display Average Temp
   }
}
//////////////////////////////////////END///////////////////////////////////////

 

Two ways to do

1. First is you are returning a value from the function but you are not assigning to any variable. So, the return value is wasted.

2. Second thing you have to check the argument you are passing is global or local variable. If it is global variable then you can return void or if it is local variable assign the return value.
 
  • Like
Reactions: ghead

    ghead

    Points: 2
    Helpful Answer Positive Rating
Aha so for first point call should be like this

Code C - [expand]
1
average = Filter(average);



and for second, the argument/variable I'm passing is a global variable, So i would just assign the altered value within the call thus not needing to bother returning, Or really even passing it as an argument in this situation as I could just manipulate the global var within the call.

Thanks I think I got my head round it now.
 

The usual solution is to pass the variable by reference rather than by value. Review your C programming text book.


Code C - [expand]
1
2
3
4
5
6
void Filter(unsigned int *sample){
   *sample = *sample + 100;
}
 
unsigned int average;
Filter(&average);

 
  • Like
Reactions: ghead

    ghead

    Points: 2
    Helpful Answer Positive Rating
If what you want is a running average of the last 4 samples, you are not even close.

To do that, you have to keep the last 4 values in an array, and their sum in another variable.

Lets call sum the sum of the last 4, and values[4] the array of the last 4 values.

When a new sample comes in, you subtract the oldest value from the sum:

sum = sum - values[0];

Then you slide down the other 3 values:

for (i=0; i<3; i++) values = values[i+1];

Add the new value into the array:

values[3] = new_value;

And add it to the sum:

sum += new_value;

Once you have processed 4 values, the running average is sum / 4.


You also have a misunderstanding of how function arguments and return values work. You need to work through a tutorial on that until you understand it.


Bob
 
  • Like
Reactions: ghead

    ghead

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top