Let’s look at an example where we actually pass a parameter.
For this we create a new function, called “blinkLed”, to which we want to pass the LED number of the LED that needs to be switched on.
We already know that this number is a whole number of datatype “int”.
We also know that it will not return any values, which then gets us this function:
voidblinkLed(intledNumber){Serial.print("Blinking LED ");Serial.println(ledNumber);digitalWrite(ledNumber,HIGH);delay(100);// assume a delay of 100 for nowdigitalWrite(ledNumber,LOW);delay(100);// assume a delay of 100 for now}
The parameter “ledNumber” is defined as an “int”. You can see that there is a the definition of the variable “ledNumber” inside the function called “blinkLed”. When we pass a value for that parameter, the value will be copied into that “new” variable.
Keeping “scope” in mind, “ledNumber” obviously only exists in the function “blinkLed”.
Calling our function (line 6) is just the same as the previous example, this time however we pass the value of the variable “pin”. The value of “pin” is being copied into the variable “ledNumber” – remember that it’s COPIED.
Thus we get:
voidsetup(){// set the speed for the serial monitor:Serial.begin(9600);for(intpin=2;pin<=15;pin++){pinMode(pin,OUTPUT);blinkLed(pin);}}voidloop(){// leave empty for now}voidblinkLed(intledNumber){Serial.print("Blinking LED ");Serial.println(ledNumber);digitalWrite(ledNumber,HIGH);delay(100);// assume a delay of 100 for nowdigitalWrite(ledNumber,LOW);delay(100);// assume a delay of 100 for now}
You see how the parameter “ledNumber” is being used in the function?
But this was just an example on how to pass just one value as a parameter. How does this work if we need to pass multiple values?
As an illustration, we will add two more parameters.
To do this we need to separate the parameters and for this we use a comma ( , ).
Parameters in a function are separated by a comma, both when defining the function and when calling the function.
As with any parameter we’d like to pass, we again need to define its datatype (integer) and name (ledOnTime or ledOffTime).
All this combined:
voidsetup(){// set the speed for the serial monitor:Serial.begin(9600);// blink the LEDs on for 600ms, off for 300 msfor(intpin=2;pin<=15;pin++){pinMode(pinOUTPUT);blinkLed(pin,600,300);}// blink the LEDs on for 100ms, off for 0 msfor(intpin=2;pin<=15;pin++){blinkLed(pin,400,0);}}voidloop(){// leave empty for now}voidblinkLed(intledNumber,intledOnTime,intledOffTime){Serial.print("Blinking LED ");Serial.println(ledNumber);digitalWrite(ledNumber,HIGH);delay(ledOnTime);digitalWrite(ledNumber,LOW);delay(ledOffTime);}
As you can see, we run the function twice, and change the timing from being slow in the first for loop to fast in the second.
The values we pass are separated by a comma as well!
Notice that our code is now starting to look simpler for common activities.
Returning a Value from a Function
So we know that a function can “receive” values by using parameters. Now what if we want the function to return an answer or result – for example from a complex calculation?
Remember we used “void” with our previous function definitions? That’s where we define what the type (e.g. int or void) of the function return will be. This is called the return type.
In the function itself however, we do need to actually “return” that type of value, and we use the function “return” for that.
If you define a function which will return a defined datatype, then you will need to use the “return” statement to return a value, which has to be of the same datatype as the defined return value datatype of your function (then return again…)
An example would be to read the potentiometer knob position on pin A5 of the LED Light Shield, scale that position to be between 0 and 1, multiply the result by an input number, and return the result.
To do this, we're going to introduce a new type of variable: float, a floating point number, is the basic decimal data type in C.
Go ahead and try this code on your Arduino. Move the knob on the board and observe the results.
intknobPin=A5;
intledToBlink=2; voidsetup(){// set the speed for the serial monitor:Serial.begin(9600);pinMode(ledToBlink,OUTPUT);pinMode(knobPin,INPUT);}voidloop(){intmaxOnTime=1000;intscaledOnTime=scaleValueWithPotentiometer(maxOnTime);blinkLed(ledToBlink,scaledOnTime,maxOnTime - scaledOnTime);}voidblinkLed(intledNumber,intledOnTime,intledOffTime){Serial.print("Blinking LED ");Serial.println(ledNumber);digitalWrite(ledNumber,HIGH);delay(ledOnTime);digitalWrite(ledNumber,LOW);delay(ledOffTime);}intscaleValueWithPotentiometer(intinputValue){floatmaxPotentiometerValue=1023.0;// float is a decimal numberfloat thisKnobValue=analogRead(knobPin);// read the potentiometer knobSerial.print("Potentiometer knob value: ");Serial.println(thisKnobValue);floatscaledKnobValue= thisKnobValue/maxPotentiometerValue;// scale to between 0 and 1intscaledInputValue=inputValue*scaledKnobValue;// take the input value and scale it by the knob positionreturnscaledInputValue;// return the result}
At this point I strongly recommendplaying with functions. Make up a function yourself, with or without return values, and do some experimenting.
Check Your Understanding
1. Functions can take one or more that act as local variables in the function definition and have values given by the function call. If you have multiple of these, separate them with the symbol (spell out the name of the symbol here).
2. To declare a function named scaleValue that returns a float and takes in an integer named inputValue, begin the function definition with the statement (line of code) (remember the symbols, use spacing as above examples).
3. The statement (line of code) to declare an integer variable named knobValue and assign it to be the value of the potentiometer knob on pin knobPin is (use spacing as above examples)
4. The minimum value that knobValue will be is , the maximum value that knobValue can be is (Google "analogRead" or check the Serial Monitor of the example code if unsure).