Delicious Bookmark this on Delicious      HOME > > ARDUINO LANGUAGE COURSE  t.o.c.

Functions which return a value

(And some information on Arduino arithmetic)

This is one of a collection of pages which, together, attempt to show you "everything" about the Arduino's programming language.

There is a page for you with more information about the project in general, and the way these pages are organized, if you want that.

Please visit my page about power browsing notes sometime.

This page, and the software it references, ©TK Boyd, 1/2010.

========

This tutorial covers a major topic: Functions which return values. Some information on Arduino arithmetic is presented along the way.

========

We've seen and used functions. The "setup" and "loop" are functions present in every Arduino program.

We've made functions of our own, e.g. "setLEDs"

We have NOT (yet) made a function which returns a value. We're going to do that several times in this tutorial, and if you can't imagine what "returning a value" would be, don't worry yet. Before we get to that, we're going to explore a little very, very basic arithmetic, using the serial monitor to see the answers calculated for us by the Arduino.

=========

Enter the following, run it, and glance at the output produced in the serial monitor, just to be sure you remember all of those skills.

/*FEAa1Arith1
29 Dec 09

Just does a little arithmetic, and sends
answer to serial monitor*/

void setup()
{
  Serial.begin(9600);//Prepare serial port for use
}

void loop()
{
  int intAns;
  intAns=2+2;
  Serial.print("That equals: ");
  Serial.println(intAns);
  delay(500);/*So serial port isn't overwhelmed
    by too-rapidly repeated instances of
    sending the answer again and again. */
}

A few odds and ends....

The line "int intAns;" in the "loop" function creates a variable called intAns in which we can keep data of data type "int" (that IS short for "integer", but there are many "integer" data types. This is just one of them. An "int" datum must be a whole number, in the range -32,768 to +32,767, inclusive. Because we put the declaration of this variable within the "loop" function declaration, the variable can only be used within "loop". It is a local, not global, variable. Local variables are good. Don't worry, the computer won't do the "create the variable" step every time it passes through the loop, slowing things down. (At least I trust that the compiler is written so that the creation of the variable happens just once, during the compile process... I admit that I don't "know". It is the right thing to do, anyway, even if there is a time penalty!)

Local variables are a Good Thing. You might not see why you'd want to do it at this stage, but you COULD have an "intAns" in the "setup" function and ANOTHER "intAns" in the "loop" function. As your programs get bigger, you will have more and more functions, more and more variables, and keeping them all clear in your head can become a challenge... but if the variables are local, an "intAns" which is part of function "A" can't cause problems for you with a different "intAns" which is part of function "B". Of course you can be caught the other way... when you think that two different intAns's are the same intAns... but that won't happen to careful programmers who use functions well and keep their code clear.

---

Next odd/end...

Yes, in many languages, you simply could have done just....

Serial.print("That equals: ", intAns);

... to cause "That equals: 4" to appear.

Not in the Arduino language. Sorry. Live with it. (There is a silver lining to this cloud, but this isn't the time to discuss it.)

By saying Serial.print I set things up so that whatever was printed next would appear on the same line as what I had just printed. In the following line, I use println, so that a new line will be started after the material specified.

Originally, I had the number I wanted to print out in a byte type variable. And things didn't work right. If you want to print a number, put it in an "int" type variable, and use a separate line to print it, putting any text to go with the number in a separate Serial.print (or Serial.println) statement.

(If you have something in a byte type variable, say bMyNumber, you can print it by using the conversion function "int"... Your code would look like....

Serial.println(int(bMyNumber));

---

Right. That's the odds and ends out of the way.

The Arduino does subtraction and multiplication mostly as you would expect it to, so the line...

intAns=2+2;

...could be replaced by any of the following...

intAns=10-6;
intAns=2*2; // "*" is used for multiplying.

I said it does the arithmetic MOSTLY as you would expect.

Humans can, more or less, cope with any number. Pretend that the biggest number you had ever heard of was 999,999,998. You would be quite capable of counting beyond that....

   999,999,999
 1,000,000,000
 1,000,000,001... etc.

Computers are not as clever. Every data type has limitations. I mentioned the limits of the "int" data type a moment ago. Earlier I told you that "byte" type data consists of whole numbers in the range 0-255 inclusive. It is, generally speaking, a bad idea to go outside a data types range. So, if you had a byte type variable called bMyNumber, it would not be wise to say....

bMyNumber= 250+100;

That's all I'm going to say about that for the moment. For many, many things you'll want to do on an Arduino, a good choice of data type will keep you out of trouble. (The famous "Millennium Bug", if you remember it, arose from something like trying to put a number bigger than 255 into a byte type variable, by the way. And I believe that it was a genuine problem, and we owe all of the programmers who did the re-programming to prevent it from causing chaos, a vote of thanks.)

We've seen adding, subtracting and multiplying. What about division?

So far, apart from the type "boolean", we have dealt only with data types which can only hold whole numbers.

What happens if we do...

intAns=101/2;

Try it! If only our lives had been so simple in school. The Arduino does the calculation, and just throws away any fractional part. So 101/2 "is", according to the Arduino, 50. And all of the following equal 2:

8/4 is 2,
9/4 is 2, (to an Arduino)
10/4 is 2, and
11/4 is 2.

Note the Arduino doesn't even ROUND the answers. Even 199/100 comes back as 1. Not 1.99, not 2. 1. (This "throw away the fraction" trick is called "truncating" the answer.)

---

Just before we move on from Arduino arithmetic, let me tell you about one other "trick" it can do. You may not have had a need for this trick in your life so far, but there are times in computer programming when it is useful.

Remember long ago when you first started doing division, the answer to 9/4 was "2 remainder 1", not 2.25?

The "modulo" operator will tell you the "remainder" part of any division, and to say "modulo", we type %....

  9%4=1
 10%4=2
 11%4=3
 12%4=0
 13%4=1
 14%4=2, etc...

It IS useful... believe me!

---

And now we're going to move on.

First, as a reminder, I'm going to rewrite the program we had earlier, using a function that is SENT something by the program that calls it. The point of the re-write is to make what is in "loop" easy to read. I've moved some of the "details" of printing the answer OUT of "loop", into a function of their own. As long as I know that printAns(5) takes care of printing a 5, I don't want or need to be distracted by the details. (I can, of course, replace the 5 with anything that BOILS DOWN to a number, e.g. a variable.)

/*FEAa1Arith2
29 Dec 09

Just does a little arithmetic, and sends
answer to serial monitor*/

void setup()
{
  Serial.begin(9600);//Prepare serial port for use
}

void loop()


{
  int intAns;
  intAns=2+2;
  printAns(intAns);
  delay(500);//So serial port isn't overwhelmed by too-rapidly
           //repeated instances of sending the answer again
           //and again.
}

void printAns(int intTmp)
{
  Serial.print("That equals: ");
  Serial.println(intTmp);
}

I've "made up" a "new word" for the language, "printAns" which... marvel of marvels... prints the answer. (I chose what the new word would be. If you do a good job of naming your functions, using them becomes easy. Don't be too sure that this is "easy" or "obvious". You may be surprised how often you get in a muddle about EXACTLY what a given function does.

Note how the name of where "it" is changes as you proceed? Where the function is CALLED, the number to be printed is in intAns.

Down in the function itself, in the header we have intTmp, and, within the function, we print what is in intTmp. This passing of "it" from variable to variable is all taken care of for us by the functions mechanisms.

---

Okay... so far, so easy.

Now I'm going to create a function which will be sent a number, just as printAns was, but this function will SEND SOMETHING BACK!

The new function will send back twice the number it was sent, hence the name "doubleIt". ("double" was unacceptable as a name as that word is already in use by the Arduino language, it is a "keyword", like "loop", "if", etc.)

Study the following. Start with the last five lines...

/*FEAa1Arith2
29 Dec 09

Just does a little arithmetic, and sends
answer to serial monitor*/

void setup()
{
  Serial.begin(9600);//Prepare serial port for use
}

void loop()
{
  int intAns;
  intAns=doubleIt(42);
  printAns(intAns);
  delay(500);//So serial port isn't overwhelmed by too-rapidly
           //repeated instances of sending the answer again
           //and again.
}

void printAns(int intTmp)
{
  Serial.print("That equals: ");
  Serial.println(intTmp);
}

int doubleIt(int intToDouble)
{
  intToDouble=intToDouble*2;
  return intToDouble;
}

The last five lines create the function that was the reason for this program, the one that demonstrates passing something back.

In the past, the first line of a function's declaration was "void", which said that the function wasn't returning, wasn't passing back, anything.

This time, the function declaration starts "int", to say that we are going to pass back a datum of type "int".

Next comes the function's name, followed by parentheses. Inside the parentheses we have "int intToDouble" which creates a local variable called intToDouble, of type "int". Furthermore, because of where this variable declaration is made, the functions mechanisms ensure that when we use, say doubleIt(42), intToDouble gets filled with the 42, or with whatever else is in that place when the call is made.

Within the curly braces of the doubleIt function, the first line should not be very puzzling. We're just replacing what's in intToDouble with whatever was there before times two... i.e. doubled.

The word "return" in the next line is new, and pivotal: Whatever follows the word "return" is what is sent back to where the call of doubleIt was made.

And that's it! Seems simple, and is... but it is very powerful. The more you write programs, the more you look at programs made by others, the more you will realize how much can be done with and because of functions which return a value.

One little point: You "know" this, but just to stress the point: intToDouble is a local variable. Do not think that you can put things in it, or read what is in it, from other parts of the program.

In general, the more you can avoid using global variables, the happier you will be. There are times to break this rule... but try to do a lot with local variables.




   Search this site or the web      powered by FreeFind

Site search Web search
Site Map    What's New    Search

The search engine is not intelligent. It merely seeks the words you specify. It will not do anything sensible with "What does the 'could not compile' error mean?" It will just return references to pages with "what", "does", "could", "not".... etc.

SPELL your search term properly. When I review search logs, it is amazing how many people ask the engine to search for something meaningless.


Why does this site cause a script to run? I have my web-traffic monitored for me by eXTReMe tracker. They offer a free tracker. If you want to try it, check out their site. And if there are Google ads on the page, they are run with scripts, too.


Click here to return to Arduino COURSE table of contents.
Click here to go to the author's home page.

Ad from page's editor: Yes.. I do enjoy compiling these things for you... hope they are helpful. However.. this doesn't pay my bills!!! If you find this stuff useful, (and you run an MS-DOS or Windows PC) please visit my freeware and shareware page, download something, and circulate it for me? Links on your page to this page would also be appreciated!
Click here to visit editor's freeware, shareware page.


Here is how you can contact this page's editor. This page, and the software it references, ©TK Boyd, 1/2010.

Valid HTML 4.01 Transitional Page tested for compliance with INDUSTRY (not MS-only) standards, using the free, publicly accessible validator at validator.w3.org