No edit summary |
No edit summary |
||
(29 intermediate revisions by the same user not shown) | |||
Line 4: | Line 4: | ||
* clarity: the bigger the program gets the harder it is to keep the general overview | * clarity: the bigger the program gets the harder it is to keep the general overview | ||
* decoupling: you only want to change a certain part of the program without influencing all the rest | * decoupling: you only want to change a certain part of the program without influencing all the rest of it | ||
* recyclability: there are several similar parts in your robot for which you would like to reuse particular sections of your code | * recyclability: there are several similar parts in your robot for which you would like to reuse particular sections of your code | ||
These problems reach back to the beginning of programming and their solution is an art and a science at the same time. | These problems reach back to the beginning of programming and their solution is an art and a science at the same time.<br> | ||
It generally helps a lot to separate your program into single subunits that are relatively independent from each other. | It generally helps a lot to separate your program into single subunits that are relatively independent from each other. | ||
Line 16: | Line 16: | ||
The [http://arduino.cc/de/Reference/FunctionDeclaration function] is an enormous useful tool that can help you structuring your code. Functions allow you to sum up several operations under the same command. This command can be called again and again without knowing about or duplicating the included code. | The [http://arduino.cc/de/Reference/FunctionDeclaration function] is an enormous useful tool that can help you structuring your code. Functions allow you to sum up several operations under the same command. This command can be called again and again without knowing about or duplicating the included code. | ||
Here is an example for a function | Here is an example for a function that sets the speed of a motor which is connected to an H-bridge: | ||
[[File:OOPARD1.jpg]] | |||
Line 38: | Line 25: | ||
[[File:OOPARD2.jpg]] | |||
This already saves us a lot of typing – | This already saves us a lot of typing –<br> | ||
But one thing still seems quite laborious: we have to know the exact pin numbers every time we want to change the speed. | But one thing still seems quite laborious: we have to know the exact pin numbers every time when we want to change the speed. | ||
Imagine a program in which similar function calls are distributed all over. | Imagine a program in which similar function calls are distributed all over. <br> | ||
In case of a hardware update you would have to find every single function call and change the parameters manually. | In case of a hardware update you would have to find every single function call and change the parameters manually. <br> | ||
This effort could surely be spent for more useful things.. | This effort could surely be spent for more useful things.. | ||
It would be ideal to find a way of calling a certain function that only offers the most useful parameters (like setting the speed) and which handles technical details (switching pins on and off) internally. | It would be ideal to find a way of calling a certain function that only offers the most useful parameters (like setting the speed) and which handles technical details (switching pins on and off) internally. | ||
<br> | |||
==Possible | ==Possible Solution: Data and Code in One Package – "Classes" and "Objects"== | ||
C++ (and also Arduino) provides a specific feature that can solve our problem: Classes and Objects | C++ (and also Arduino) provides a specific feature that can solve our problem: Classes and Objects. | ||
A Class predefines common qualities of a group of Objects. | A Class predefines common qualities of a group of Objects. <br> | ||
It for instance determines that every motor has the possibility to exert a certain amount of throttle. | It for instance determines that every motor has the possibility to exert a certain amount of throttle. <br> | ||
The corresponding program could look like this: | The corresponding program could look like this: | ||
[[File:OOPARD3.jpg]] | |||
Now the computer knows that there is a class called | Now the computer knows that there is a class called "Motor".<br> | ||
This class (class) provides a function called | This class (class) provides a function called "setThrottle" that is called as an argument by using a number (int) and that does not return anything (void). | ||
===Classes are Data | ===Classes are Data Types=== | ||
We can use our | We can use our "Motor" - class the same way we are using other data - types (int, long, float).<br> | ||
The following lines use that quality in order to implement two motors: | The following lines use that quality in order to implement two motors: | ||
<br> | |||
<br> | |||
[[File:OOPARD4.jpg]] | |||
<br> | |||
<br> | |||
===Calling inner functions of a class (Methods)=== | ===Calling inner functions of a class (Methods)=== | ||
Imagine we want to drive the left motor with full throttle whereas the right motor should stop completely. | Imagine we want to drive the left motor with full throttle whereas the right motor should stop completely. <br> | ||
This can be expressed as follows: | This can be expressed as follows: | ||
[[File:OOPARD5.jpg]] | |||
A positive side effect: your program gains readability by picking distinct names for your Objects and Methods. | A positive side effect: your program gains readability by picking distinct names for your Objects and Methods. | ||
<br> | |||
===Classes can contain other variables that can only be accessed "internally"=== | |||
===Classes can contain other variables that can only be accessed | |||
How do the Objects | How do the Objects "leftMotor" and "rightMotor" know which pins they want to switch on and off? | ||
Until now our | Until now our "Motor" class is quite abstract since it does not contain this information. <br> | ||
A class that should conduct practical actions needs further variables (concrete pin numbers) and lines of code that describe what to do exactly. | A class that should conduct practical actions needs further variables (concrete pin numbers) and lines of code that describe what to do exactly.<br> | ||
We can simply include both things in the class definition: | We can simply include both things in the class definition: | ||
[[File:OOPARD6.jpg]] | |||
class | How do we include the pin numbers into the Object if they are not visible from the outside?<br> | ||
We simply write a "setup" Function for the class: | |||
[[File:OOPARD7.jpg]] | |||
<br> | |||
<br> | |||
==A Complete Example == | |||
In order to construct a complete example we only have to include the "speed"-Function (see description above): | |||
[[File:OOPARD8.jpg]] | |||
<br> | |||
<br> | |||
==Organizing Classes in Separate Files== | |||
We can improve our program structure by putting classes in separate files: | |||
1. <br> | |||
Click on the arrow in the right corner in order to add a new file.<br> | |||
Select "new Tab". | |||
[[File:NewTabARDU.jpg]] | |||
<br> | |||
2.<br> | |||
Enter a filename at the bottom of the window. <br> | |||
It must end with ".h" – In our case it could be "motorControl.h". | |||
3.<br> | |||
The first line of your code should be: | |||
'#include „Arduino.h“' | |||
This line | This line 'links' the file to the Arduino–specific features.<br> | ||
Now we can include the code of our class. | Now we can include the code of our class. | ||
4 | 4.<br> | ||
Go back to your main file. | Go back to your main file.<br> | ||
Now you have to | Now you have to "link" the new file to your main file in order to use the features of our class.<br> | ||
Include the following line in the top of your main file | Include the following line in the top of your main file | ||
'#include "MotorControl.h“' | |||
' | |||
#include | |||
and write the rest of your program as usual. | and write the rest of your program as usual. | ||
<br> | |||
<br> | |||
==More Information== | |||
Classes can build up on each other ("inheritance"). | |||
In the beginning we promised that it is possible to replace different motor drivers without changing the rest of the program.<br> | |||
Classes can indeed include other Objects in the form of "[https://en.wikipedia.org/wiki/Member_variable member variables]". | |||
Classes can | |||
C++ allows class declarations and the code for included Functions to be be placed in different files. <br> | |||
If you want to know more about that you can read this article about creating libraries in Arduino: <br>[http://arduino.cc/en/Hacking/LibraryTutorial http://arduino.cc/en/Hacking/LibraryTutorial ] | |||
<br> | |||
<br> | |||
<br> |
Latest revision as of 14:02, 28 March 2017
Motivation
Soon after starting to write the program for your robot you will encounter some typical problems:
- clarity: the bigger the program gets the harder it is to keep the general overview
- decoupling: you only want to change a certain part of the program without influencing all the rest of it
- recyclability: there are several similar parts in your robot for which you would like to reuse particular sections of your code
These problems reach back to the beginning of programming and their solution is an art and a science at the same time.
It generally helps a lot to separate your program into single subunits that are relatively independent from each other.
Example: Controlling Motors
The function is an enormous useful tool that can help you structuring your code. Functions allow you to sum up several operations under the same command. This command can be called again and again without knowing about or duplicating the included code.
Here is an example for a function that sets the speed of a motor which is connected to an H-bridge:
Now (and for every prospective motor movement) we only need to write one single line in order to for instance setting the left wheels speed:
This already saves us a lot of typing –
But one thing still seems quite laborious: we have to know the exact pin numbers every time when we want to change the speed.
Imagine a program in which similar function calls are distributed all over.
In case of a hardware update you would have to find every single function call and change the parameters manually.
This effort could surely be spent for more useful things..
It would be ideal to find a way of calling a certain function that only offers the most useful parameters (like setting the speed) and which handles technical details (switching pins on and off) internally.
Possible Solution: Data and Code in One Package – "Classes" and "Objects"
C++ (and also Arduino) provides a specific feature that can solve our problem: Classes and Objects.
A Class predefines common qualities of a group of Objects.
It for instance determines that every motor has the possibility to exert a certain amount of throttle.
The corresponding program could look like this:
Now the computer knows that there is a class called "Motor".
This class (class) provides a function called "setThrottle" that is called as an argument by using a number (int) and that does not return anything (void).
Classes are Data Types
We can use our "Motor" - class the same way we are using other data - types (int, long, float).
The following lines use that quality in order to implement two motors:
Calling inner functions of a class (Methods)
Imagine we want to drive the left motor with full throttle whereas the right motor should stop completely.
This can be expressed as follows:
A positive side effect: your program gains readability by picking distinct names for your Objects and Methods.
Classes can contain other variables that can only be accessed "internally"
How do the Objects "leftMotor" and "rightMotor" know which pins they want to switch on and off?
Until now our "Motor" class is quite abstract since it does not contain this information.
A class that should conduct practical actions needs further variables (concrete pin numbers) and lines of code that describe what to do exactly.
We can simply include both things in the class definition:
How do we include the pin numbers into the Object if they are not visible from the outside?
We simply write a "setup" Function for the class:
A Complete Example
In order to construct a complete example we only have to include the "speed"-Function (see description above):
Organizing Classes in Separate Files
We can improve our program structure by putting classes in separate files:
1.
Click on the arrow in the right corner in order to add a new file.
Select "new Tab".
2.
Enter a filename at the bottom of the window.
It must end with ".h" – In our case it could be "motorControl.h".
3.
The first line of your code should be:
'#include „Arduino.h“'
This line 'links' the file to the Arduino–specific features.
Now we can include the code of our class.
4.
Go back to your main file.
Now you have to "link" the new file to your main file in order to use the features of our class.
Include the following line in the top of your main file
'#include "MotorControl.h“'
and write the rest of your program as usual.
More Information
Classes can build up on each other ("inheritance").
In the beginning we promised that it is possible to replace different motor drivers without changing the rest of the program.
Classes can indeed include other Objects in the form of "member variables".
C++ allows class declarations and the code for included Functions to be be placed in different files.
If you want to know more about that you can read this article about creating libraries in Arduino:
http://arduino.cc/en/Hacking/LibraryTutorial