• No results found

Using Pointers with Functions

One last pointer topic to cover is how to use pointers with functions. One of the downsides to

functions is that the return statement can only return one value back to the calling sketch code. In your sketch writing, you may run into a situation where you need to return more than one value.

One way to solve that problem is to use global variables. However, you saw in Hour 10, “Creating Functions,” that makes the function code reliant on resources external to the function.

Pointers help us solve that problem. When you define a function, instead of passing arguments as values to the function, you can define the function to accept pointers instead. The pointers point to the location in memory where the data is stored.

Because the pointer points to the memory locations, the function can directly access the data in

memory, and directly change the data in memory. Although this sounds like it could prove dangerous, with the proper use, this can be a lifesaver in your sketches.

Try It Yourself: Passing Pointers to Functions

In this example, you define a function that accepts two pointers as parameters. The function will calculate the addition and subtraction results of two values and make the results of both calculations available to the calling sketch code. Here are the steps to test this:

1. Open the Arduino IDE, and enter this code into the editor window: Click here to view code image

void setup() {

Serial.begin(9600); int a = 5;

int b = 3;

Serial.print("The intitial values are "); Serial.print(a);

Serial.print(" and "); Serial.println(b); addsub(&a, &b);

Serial.print("The addition result is "); Serial.println(a);

Serial.print("The subtraction result is "); Serial.println(b);

}

void addsub(int *x, int *y) { int add = *x + *y;

int sub = *x - *y; *x = add;

*y = sub; }

void loop() { }

2. Save the sketch code as sketch1105.

3. Click the Upload icon to verify, compile, and upload the sketch to your Arduino unit. 4. Start the serial monitor to run the sketch and view the output.

FIGURE 11.5 Using pointers to pass and retrieve values from functions.

The first thing you should notice is that we passed the values to the addsub function as memory locations using the reference operator:

addsub(&a, &b);

Because we’re passing the values as memory locations, we need to define the addsub function parameters as pointers:

void addsub(int *x, int *y) {

Now that the function has the memory locations of both variables, it has to handle them as memory locations instead of data values. When we perform calculations, we need to use the dereference operator to retrieve the data values stored in the memory locations:

int add = *x + *y; int sub = *x - *y;

And when we return the results, we need to place those values back in the memory locations: *x = add;

*y = sub;

Notice that the code places the addition result into the memory location passed as the first parameter, and the subtraction result into the memory location passed as the second parameter. When using pointers, it’s important to keep straight which memory locations will contain which return values.

Warning: Returning Values in Pointers

It’s also important to remember that when using pointers to return values from functions, the original values stored in the variables will be overwritten by the return values. If you need to retain the original values passed to the function, you must store them in another variable.

Summary

This hour covered the complicated topic of C data pointers. Pointers allow you to directly access the memory location where you store data on the Arduino, which can be a very powerful tool, but can also cause problems if you’re not careful. The reference operator (&) allows you to retrieve the memory location where a variable is stored in memory, and the dereference operator (*) allows you to retrieve the value stored in a specific memory location. You must define the data type of a pointer so that the Arduino knows what type of data the pointer points to. That allows you to use pointer

arithmetic to increase or decrease a pointer to point to additional data elements. Finally, you saw how to use pointers to retrieve more than one data value from a function, by passing memory locations to the function and allowing it to alter the data stored in those memory locations.

The next hour stays on the topic of storing data in memory on the Arduino and covers the different types of memory available and how to store your data in a specific type of memory.

Workshop

Quiz

1. What operator would you use to find the memory location where the variable named test is

stored?

A. The dereference operator *test B. The reference operator &test C. The incrementor operator test++ D. The decrementor operator test--

2. The dereference operator returns the value stored at the memory location specified by the

variable. True or false?

3. How can you tell whether a pointer assignment returns a valid memory address?

Answers

1. B. The reference operator returns the memory location where the Arduino stores the variable.

2. True. The dereference operator reads the value stored in the variable and then goes to that

memory location and retrieves the value stored at that location.

3. You can assign a NULL value to the pointer before the assignment statement and then check

whether the pointer is still NULL:

Click here to view code image

ptr = &test2; if (ptr) {

Serial.println("Sorry, the pointer assignment failed"); }

Q&A

Q. Is there a benefit to using pointers rather than arrays?

A. With pointers, you can use pointer arithmetic to iterate through the stored numbers, whereas you

can’t do that with an array. That may save some coding from having to iterate through the array indexes.

Q. Is there a benefit to using arrays instead of pointers?

A. The one thing that pointers cannot do is return the number of data elements stored in the memory

block. You can use the sizeof function on an array variable to return the number of data elements contained in the array, but that doesn’t work with a pointer variable.

Q. So which is better, pointers or arrays?

A. Both have their use in different applications. You might find that you can use pointers to help

cut down on your code if you have to do a lot of manipulation within the array of numbers. However, if you find yourself having to determine the number of values stored, you’ll have to use arrays rather than pointers.

Hour 12. Storing Data

What You’ll Learn in This Hour:

How the Arduino handles data in your sketches How to get the most use out of Arduino memory How to store data long term on an Arduino

One of the challenges of programming for the Arduino is that your sketches are limited by the

resources available on the microcontroller. Nowhere is that more evident than when you try to handle large amounts of data. Because of the limited memory resources on the Arduino, you sometimes have to get a little creative in how you handle the data in your sketch. This hour shows some ways to help conserve memory in your sketches and shows how to utilize the extra EEPROM memory to store data for long-term use.