const int led = 13;
That is the correct method. Or even:
const byte led = 13;
How many pins do you have?
Some of the tutorials did not quite go through as much quality control as they might have.
Performance will be better using const byte
, compare to int
however the compiler may be smart enough to realize what you are doing.
What you can do is gently encourage people to use more efficient techniques by using them in your own code.
Responses to comments
A commenter has suggested that byte
is not standard C. This is correct, however this is an Arduino StackExchange site, and I believe using standard types supplied by the Arduino IDE is acceptable.
In Arduino.h there is this line:
typedef uint8_t byte;
Note that this is not exactly the same as unsigned char
. See uint8_t vs unsigned char and When is uint8_t ≠ unsigned char?.
Another commenter has suggested that using byte will not necessarily improve performance, because numbers smaller than int
will be promoted to int
(see Integer Promotion Rules if you want more on this).
However in the context of a const identifier, the compiler will generate efficient code in any case. For example, disassembling "blink" gives this in the original form:
00000086 <loop>:
86: 8d e0 ldi r24, 0x0D ; 13
88: 61 e0 ldi r22, 0x01 ; 1
8a: 1b d1 rcall .+566 ; 0x2c2 <digitalWrite>
In fact it generates the same code whether the 13
:
- Is a literal
- Is a
#define
- Is a
const int
- Is a
const byte
The compiler know when it can fit a number into one register and when it can't. However it is good practice to use coding that indicates your intent. Making it const
makes it clear that the number won't change, and making it byte
(or uint8_t
) makes it clear that you are expecting a small number.
Confusing error messages
Another major reason to avoid #define
is the error messages you get if you make a mistake. Consider this "blink" sketch which has an error:
#define LED = 13;
void setup() {
pinMode(LED, OUTPUT); // <---- line with error
}
void loop() {
digitalWrite(LED, HIGH); // <---- line with error
delay(1000);
digitalWrite(LED, LOW); // <---- line with error
delay(1000);
}
On the surface it looks OK, but it generates these error messages:
Blink.ino: In function ‘void setup()’:
Blink:4: error: expected primary-expression before ‘=’ token
Blink:4: error: expected primary-expression before ‘,’ token
Blink:4: error: expected `;' before ‘)’ token
Blink.ino: In function ‘void loop()’:
Blink:8: error: expected primary-expression before ‘=’ token
Blink:8: error: expected primary-expression before ‘,’ token
Blink:8: error: expected `;' before ‘)’ token
Blink:10: error: expected primary-expression before ‘=’ token
Blink:10: error: expected primary-expression before ‘,’ token
Blink:10: error: expected `;' before ‘)’ token
You look at the first highlighted line (line 4) and don't even see a "=" symbol. Plus, the line looks fine. Now it's fairly obvious what the problem is here (= 13
is being substituted for LED
), but when the line is 400 lines further down in the code, it isn't obvious the problem is with the way LED is defined.
I've seen people fall for this many times (including myself).