int and pinMode vs #Define

  1. Where do I find the "Search", if I click on the magnifying glass at the top of the screen it takes me to Google?

  2. The programming question.
    When I go through elementary training videos they all start off with something like this :-

int ledPin = 2;

pinMode (ledPin, OUTPUT);

then as the videos progress and the programming gets more complicated it turns into,

#define ledPin 2

What is the difference, is it just a shortcut?

1: Did you not notice that the google results where all from this site?

2: This is actually 2 questions.

2a: int ledPin = 2; This creates a variable of type int(an integer)and assigns it the value of 2.
Search keyword "c/c++ variables" to learn more.

#define ledPin 2 This is a "preprocessor macro"(another search keyword) and what it does is before your sketch is compiled it replaces every mention of the word "ledPin" with the number 2 in the code. This is considered more dangerous as it can sometimes do unexpected things to your code.

While they can sometimes seem to do the same thing they are very different things and you should learn the difference.

Neither one has anything to do with the pinMode statement.

2b: pinMode (ledPin, OUTPUT); the pinMode statement tell the arduino if you are using this pin as a input or an output. The arduino default mode is all pins are inputs. So it is not absolutely necessary to use pinMode for input pins but it is always necessary to use pinMode for pins you want to use as outputs.

Hutkikz:

#define ledPin 2

This is a “preprocessor macro”(another search keyword) and what it does is before your sketch is compiled it replaces every mention of the word “ledPin” with the number 2 in the code. This is considered more dangerous as it can sometimes do unexpected things to your code.

There is a difference, but it’s not dangerous if you understand how to use preprocessor directives. For example, suppose you have some software that deals with speed limits. For a while, federal laws set it at 55 mph, so you had statements in the code like:

  • if (speed > 55) { // Get ready to write a ticket*

When the law was relaxed, you had to go through the code and look for every instance where 55 appeared in the code and change it to 70. You couldn’t do a global search-and-replace because you might have something like:

  • startingSerialNumber = 55100;*

which would have changed it to 70100, probably not what you wanted. By using a #define, you can get rid of “magic numbers” in your code, like:

#define SPEEDLIMIT 55
// … more code…

  • if (speed > SPEEDLIMIT) { // Get ready to write a ticket*

Now all you have to do to change the speed limit is change the #define to 70 and recompile. All instances of SPEEDLIMIT are automatically changed, which is much less error-prone than using a magic number. Also, the symbolic constant SPEEDLIMIT makes it easier to read the code because the number now has some context.

It’s also important to know that a symbolic constant is a purely textual substitution, there is no variable created. If you choose to use:

  • int SPEEDLIMIT = 55;*
    that does create a variable in the Arduino address space. In most cases, you would want to define it as:

  • const int SPEEDLIMIT = 55;*

That way, any attempt to change SPEEDLIMIT in your code is flagged as an error. (Most programmers use all upper-case letters for symbolic constants, while fewer upper-case the name if it’s a const. I prefer upper-case letters for both forms.)

Another difference is that symbolic constants are “typeless”, while the const definition is clearly defined to be an int. This means you can’t really expect the compiler to do type checking on a symbolic constant where the const version is type-checked in expressions. This is both good and bad.

For example, it’s common to see:

   int myArray[20];
   // ... some code...

   for (i = 0; i < 20; i++) {
   // .. more code...

You could use a #define for 20 (e.g., #define ARRAYSIZE 20) and that’s a little better because you got rid of the magic number. However, what happens if you have dozens of arrays, all of difference sizes? It gets cluttered and messy. That’s why you often see:

  • #define ARRAYSIZE(x) (sizeof(x) / (sizeof(x[0]))*

Now you can write:

  • for (i = 0; i < ARRAYSIZE(myArray); i++) {*

and the compiler will set the array size for you during the preprocessor pass. This is called a parametized macro because you pass it a parameter that identifies the array you’re using. The beauty of the parametized macro is that it works with any aggregate data type (e.g., any type of array, but also structures). That is, it is a “typeless” expression.

So, symbolic constants are really not dangerous, provided you understand how they work. Using them to replace magic numbers in your code will make it easier to change your code down the road, and will make it easier to read the code, too.

econjack:
It’s also important to know that a symbolic constant is a purely textual substitution, there is no variable created. If you choose to use:

int SPEEDLIMIT = 55;

that does create a variable in the Arduino address space.

This is also an important factor when writing more complex applications for small devices like the arduino

When every byte counts due to program size:

#define MYSENSORPIN 4 <== uses no space

int MYSENSORPIN = 4; <== uses at least 2 bytes, depending on the processor

you can see that using a #define makes more sense.

darrob:
This is also an important factor when writing more complex applications for small devices like the arduino

When every byte counts due to program size:

#define MYSENSORPIN 4 <== uses no space

int MYSENSORPIN = 4; <== uses at least 2 bytes, depending on the processor

you can see that using a #define makes more sense.

This statement is only valid pertaining to SRAM as a variable will be allocated space where a defined constant will be stored in FLASH.

The opposite however, is the case where FLASH is concerned. Where a variable is stored in SRAM, it only makes a brief appearance in a register on the stack before it quietly returns to it’s hiding place. A defined constant on the other hand, will replace it’s namesake during pre-processing at every occurrence. A thousand replacements of a single defined byte will consume 1,000 byte of FLASH where a thousand references to a byte variable will only consume one byte of SRAM.

There is no ‘best’ case. As always it’s a trade-off between size and speed. The use of a variable may result in smaller code, but the use of a defined constant is faster. The other key issue that should not be overlooked is that one is a variable and the other is a constant. This difference may make all other discussions moot.

DKWatson:
This statement is only valid pertaining to SRAM as a variable will be allocated space where a defined constant will be stored in FLASH.

Ooops, my bad.
I was thinking in terms of SRAM only (having had to pare down character arrays and reduce ints to int8_t where possible in my project.)

darrob:
Ooops, my bad.
I was thinking in terms of SRAM only (having had to pare down character arrays and reduce ints to int8_t where possible in my project.)

That’s perfectly fine. It’s done all the time with functions like PROGMEM and the F() macro. As long as people are aware that’s it’s not free.

Thanks.

Was not aware that Pins are INPUTS by default.