Void -> how it returns values to the main programm

Hallo

i am new to C and the arduino

i have a question

i am bulding a vu meter

and i want to find the max and the min analog read from my microphone

so i write a "void"

void analog_calibration (int analoginput)
{
  
  timecounter = millis();
  timerunning = 0;
  mini = 1030;
  maxi = 0;
  
  for (i=1; ((timerunning-timecounter) < calibrationtime); i++ )
    {
      
      value = analogRead(analoginput);
      
      if (value < mini) mini = value;
      if (value > maxi) maxi = value;
      
      timerunning = millis();
      
    }

}

so in my programm sometime i will write

analog_calibration(microphone);

how can i make return me the min and the max value?
to the main programm

"void" means "nothing".
A "void" function returns no value.

A function can return only a single value, so if you want to pass back two values from a function, you can use:

  1. a structure
  2. pointers
  3. references.

I'd probably go with 3).

void analog_calibration (int analoginput, int& maxVal, int& minVal))

so i write a "void"

You don't write a "void", you write a function of type void.

void analog_calibration(int analoginput, unsigned long calibrationtime, int *detectedMini, int *detectedMaxi)
{
  //reset these to ensure a new reading
  detectedMini = 1030;
  detectedMaxi = 0;
  
  //local variables used to time the calibration
  unsigned long timecounter = millis();
  unsigned long timerunning = 0;
  int value = 0; //store the current read
  while ((timerunning-timecounter) < calibrationtime)
  {
      value = analogRead(analoginput);

      if (value < *detectedMini) *detectedMini = value;
      if (value > *detectedMaxi) *detectedMaxi = value;

      timerunning = millis();
  }
}

Call it like:

int micMin;
int micMax;
analog_calibration(microphone,1000,&micMin,&micMax); //calibrate min and max for mic over a period of 1000 ms

[edit]Groove beat me to it.
Since we ended up 'recommending' different solutions I'll explain why I used the pointer method: It is simply because the the code that calls the function will have to explicitly say that the adress of a variable is to be sent. This is a way to tell the coder 'remember that these variables may, or may not, be altered when you call this function'. The reference method provides the caller no visual cues as to what might happen to the original variable (not just the value of it).[/edit]
[edit]WHOOPS!
Thank you Groove!

I forgot that 'tiny' detail in the midst of everything :-[(I forgot to dereference the min/max variables in the function body)[/edit]

so i write a "void"

No. You wrote a function. Functions can have many different return types. The function you wrote was defined to not return a value (that's what the void in front means).

Had you defined the function to return an int, you could (and should) have had a return statement, to return the appropriate value.

Functions can return only a single value, though.

You could declare the function like this:

void analog_calibration(int analoginput, int &mini, int &maxi)
{
   // Compute mini and maxi
}

Then, call it like this:

int minVal;
int maxVal;
int inVal = 27;
analog_calibration(inVal, minVal, maxVal);
// minVal contains the value defined in the function as mini
// maxVal contains the value defined in the function as maxi

However, mini and maxi are not typed in the function you wrote, so they must be global variables. In which case, there is not need to return them.

void analog_calibration(int analoginput, unsigned long calibrationtime, int *detectedMini, int *detectedMaxi)

...
if (value < detectedMini) detectedMini = value;

Ahem. :wink:

thanks

so the & means that the value goes back

The & means that you are passing by reference, instead of by value. In other words, the address of the memory location referred to by that name (the location to read from/write to) is passed to the function, instead of the value at that address.

Having the address, instead of the value, means that the function can modify the value and that modified value will be seen by the caller when the function ends.

void analog_calibration (int analoginput, int &mini, int &maxi )
{
  long value;
  
  long timecounter = millis();
  long timerunning = 0;
  mini = 1030;
  maxi = 0;
  
  for (i=1; ((timerunning-timecounter) < calibrationtime); i++ )
    {
      
      value = analogRead(analoginput);
      
      if (value < mini) mini = value;
      if (value > maxi) maxi = value;
      
      timerunning = millis();
      
    }

}

then i call

analog_calibration (int microphone, minval, maxval )

and below this line

in minval i will have the last value of the mini
and on the maxval the last value of the maxi

?

sry but the arduino is still on the way and i cant test it

for (i=1; ((timerunning-timecounter) < calibrationtime); i++ )

The variable i is not typed. This will not compile, unless i is a global variable. If it is, using a global variable as a loop counter is not appropriate.

Typically, a for loop is used when the number of iterations is known. In this case, the termination of the loop is not dependent on i, so a for loop is not really appropriate.

calibrationtime is not typed, so it must be a global variable.

millis() returns an unsigned long, not a long. So, timecounter and timerunning are not typed appropriately.

As a side note, camel case is preferred for variable names, so timeCounter, timeRunning, and calibrationTime would be better names.

Finally, analogRead does not return a long, so value is mis-typed.

i didnt find a way to loop something for a amount of time(sec) not an amount o times ( repeats )

yes i use i j k as global for many void functions

about the unsigned long

its gone work ?

i didnt find a way to loop something for a amount of time

Look at the while statement.

yes i use i j k as global for many void functions

Stop that. And get rid of the word there. The term is function(s). void is a return type.

about the unsigned long

What about it?

A function can return only a single value, so if you want to pass back two values from a function, you can use:

  1. a structure
  2. pointers
  3. references.

I'd probably go with 3).

The Arduino-preprocessor cannot handle reference parameters in sketches (yet?).
There is a bug-report for this (google-code-servers are currently down :frowning: I can't set a link to the issue).

So only structure and pointer solutions will work.
Eberhard

i made the changes

it is a knight rider project

i have write the most of my patterns

but i dont have write the main programm


how can we fase an led and the same check if a button is pressed

can the arduino goes over two loops at the same time


the whole code

run out of Remaining characters on post


int led[ ] = {54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8};

is this correct

the led[0] is equal to 54
and led[45] is equal to 8

"45" is the total numbers minus one for the zero

they have to be 46 - i havent count them

The Arduino-preprocessor cannot handle reference parameters in sketches (yet?).

Arduino 0017:

void myProc (int& a, int& b)
{
  a = 2;
  b = 7; 
}

int myA = 0;  //Belt AND braces.
int myB = 0;

void setup ()
{
  myProc (myA, myB);
  Serial.begin (9600);
  Serial.println (myA);
  Serial.println (myB);
}

void loop ()
{
}

seems to work perfectly.

This has become a long thread!

Stop that! And get rid of the word there. The term is thread(s). long is an adjective

OK, so I put it on the edge, but I think it is perfectly fine to say 'void function', it is easier to say and understand than 'a function that returns void' which is kind of a paradox, really.

Pun slightly intended PaulS :sunglasses:

Yes your code works

void myProc (int& a, int& b) {
  a = 2;
  b = 7;
}

int myA = 0;  //Belt AND braces.
int myB = 0;

void setup () {
  myProc (myA, myB);
  Serial.begin (9600);
  Serial.println (myA);
  Serial.println (myB);
}

void loop () {
}

but this one doesn't

int myA = 0;  //Belt AND braces.
int myB = 0;

void setup () {
  myProc (myA, myB);
  Serial.begin (9600);
  Serial.println (myA);
  Serial.println (myB);
}

void loop () {
} 

void myProc (int& a, int& b) {
  a = 2;
  b = 7;
}

The IDE does not generate a prototype for functions that use arguments with reference parameters.

see:
http://code.google.com/p/arduino/issues/detail?id=205
(please ignore that the OP of the google-code issue got the headline wrong)

Eberhard