2

I have a question with the topic variables.

So, a variable is a place where you can store data.

And when you make a variable with datatype int (int ledpin=13;) then you store a value 10 in a variable named ledpin.

BUT how can the Arduino know it's a pin number 13 from Arduino or a random number 13 that we are storing there?

1
  • 1
    Was the answer helpful? If so, please accept it by clicking on the "tick" icon next to the answer, and also possibly upvote it. This indicates to other users that you found the answer useful, and it also stops Stack Exchange from periodically "bumping" your question in the hope of getting an accepted answer. Thanks for your understanding and cooperation!
    – Majenko
    Commented Jan 28, 2016 at 0:20

3 Answers 3

3

You need to put the correct number into the pinMode() function.

You could put the number into a variable like:

int ledPin = 13;
pinMode(ledPin, OUTPUT);

or you can put a number straight into pinMode() like this:

pinMode(13, OUTPUT);

Whatever number you put in will be the pin that you start using.

Here's an example to blink the onboard LED:

int ledPin = 13;                 // LED connected to digital pin 13

void setup()
{
  pinMode(ledPin, OUTPUT);      // Whatever number is in ledPin is made an output.
}

void loop()
{
  digitalWrite(ledPin, HIGH);   // sets the LED on
  delay(1000);                  // waits for a second
  digitalWrite(ledPin, LOW);    // sets the LED off
  delay(1000);                  // waits for a second
}
0
3

Yes, a variable is just somewhere to store some data.

It's what you do with the variable that is important.

For instance:

int ledpin = 13;
pinMode(ledpin, OUTPUT);
digitalWrite(ledpin, HIGH);

That will set the variable ledpin to 13, then the next line will query the ledpin variable to find out what number it is, then pass that number to the pinMode function to set the mode of the pin to OUTPUT. The line after then does the same thing but passes the number 13 that it read from ledpin to the digitalWrite function to turn the LED on.

However, if you do this:

int ledpin = 13;
pinMode(ledpin, OUTPUT);
ledpin = 10
digitalWrite(ledpin, HIGH);

then it will act just the same at first, but the digitalWrite function will get the number 10 not the number 13 since the value in ledpin has been changed to 10 in the third line.

Remember: an integer is just a number - it's only when you do something with that number that it has any meaning.

1
  • thank you so much. Finally i got it. It was an great explanation. :) Commented Jan 27, 2016 at 20:27
0

BUT how can the Arduino know it's a pin number 13 from Arduino or a random number 13 that we are storing there?

The Arduino does not "know" the intention of a variable. The variable "becomes" a pin number when passed as an argument to pinMode() or digitalRead().

The use of a variable to "name" a pin is part of a programming style. There are a lot of examples sketches that try to convey programming style. One of these is to reduce the amount of ripple effects of change; reduce the number of line to change for a logical change.

Continuing the LED pin number example above. The "baseline" code is:

void setup()
{
  pinMode(13, OUTPUT);
  ...
}
void loop()
{
   digitalWrite(13, HIGH);
   ...
   digitalWrite(13, LOW);
   ...
 }

This works just fine BUT what is the ripple effect if we change the pin "13". The example uses symbols OUTPUT, HIGH and LOW which are also just numbers.

Typically in C the tradition is to use the preprocessor and define a macro.

 #define LED 13

The preprocessor will replace LED in the source code with 13 and the compiler sees the same code as above.

An alternative is using a variable.

 int LED = 13;

The drawback is that memory is allocated and it is possible to change the value at run-time which is often a very bad idea especially for a pin. The definition should actually be:

 const int LED = 13;

The drawback with the macro is that it is just a value. In C++ it is best to use a constant variable. This tells the compiler both what data type and value it is. A constant variable cannot be assigned (again).

The next level to strength code quality and reduce ripple effects is to use lexical scope. A lexical scope such as a function body, class or namespace defines "when" a symbol is available.

An example; first global scope where definitions are available across the source code (just as for a macro):

const size_t BUF_MAX = 32;
static char buf[BUF_MAX];

const char* read()
{
   ...
   for (int i = 0; i < BUF_MAX; i++) buf[i] = ...
   ...
}

Local lexical scope; definitions within a function:

const char* read()
{
   const size_t BUF_MAX = 32;
   static char buf[BUF_MAX];
   ...
   for (int i = 0; i < BUF_MAX; i++) m_buf[i] = ...
}

The symbols buffer buf and the buffer size BUF_MAX are only available in the function.

class Reader {
public:
  void read()
  {
    ...
    for (int i = 0; i < BUF_MAX; i++) m_buf[i] = ...
  }
protected:
  const size_t BUF_MAX = 32;
  char m_buf[BUF_MAX];
  ...
};

Again the symbols are only available within the class and member function. Here is also another example of programming style. The prefix m_ is used to show that it is member data.

Last, the same example using a namespace:

namespace Reader {
  const size_t BUF_MAX = 32;
  char buf[BUF_MAX];
  ...
  void read() 
  {
    ...
    for (int i = 0; i < BUF_MAX; i++) buf[i] = ...
  }
};
...
for (int i = 0; i < Reader::BUF_MAX; i++) Reader::buf[i] = ...;

All symbols must have the prefix Reader when used outside the namespace.

These techniques have been developed to allow writing larger programs with reuse. It is important to use them when writing a library for Arduino and especially when sharing. Ripple effects and symbol redefinition/collisions are reduced.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.