Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ Electronics ➜ Microprocessors ➜ Blink sketch explained

Blink sketch explained

Postings by administrators only.

Refresh page


Posted by Nick Gammon   Australia  (23,101 posts)  Bio   Forum Administrator
Date Wed 04 Jan 2017 03:36 AM (UTC)

Amended on Thu 05 Jan 2017 12:38 AM (UTC) by Nick Gammon

Message
This post explains a simple Arduino sketch, line by line. It is a variant of the standard "blink" sketch which comes with the IDE. I modified it slightly to show constants rather than "magic numbers" inside the code.

The code (which you can copy and paste):


const byte LEDPIN = 13;
const unsigned long DELAYTIME = 1000;  // milliseconds

void setup()
{
  pinMode(LEDPIN, OUTPUT);
}

void loop()
{
  digitalWrite(LEDPIN, HIGH);
  delay(DELAYTIME);
  digitalWrite(LEDPIN, LOW);
  delay(DELAYTIME);
}


It looks like this in the IDE (Interactive Development Environment):






Constant definitions


Line 1



The keyword const tells the compiler that the definition for LEDPIN is constant (unchanging). This lets the compiler make certain optimizations. It also tells the compiler to not let you change it in your code.

It is a convention that constants are named in all capitals. Thus if you see something in all capitals it is probably a constant.

If you omit const then you would have a variable which you could change later on in the code.

The "blink" sketch that ships with the IDE looks like this, by comparison:

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second
}


Notice that the number 13 (the LED pin number) is mentioned three times? If you wanted to make it pin 11 instead you would have to change "13" to "11" in three places, which would be tedious. Much more so in a larger sketch. Also you might change two but overlook the third.

Also the sketch above uses the number 1000 twice (the number of milliseconds to wait). If you wanted the LED to blink faster you would have to change both of those places.

It is better to move such "magic numbers" (numbers that appear inside the sketch for no obvious reason) to the front of the sketch as constants.




Line 2



This is similar to line 1, except it also has a comment. Comments should be used to make things clearer, not state the bleeding obvious. In this case I commented what the "units" are. Knowing that 1000 means milliseconds make it clearer when looking at this sketch later.

Function definitions


Lines 4 to 7



Now we move onto something interesting: a function definition. Functions are pieces of code you call, often more than once and often from more than one place. Functions can:


  • Accept arguments (parameters) - for example if you wanted to square a number the argument would be the number that is to be squared.
  • Return a value. If you need to calculate something then the return value is the thing that was calculated.


For example:


long square (const int num)
{
  return num * num;
}


This function (called "square") takes a single argument (called "num"), squares it, and returns the result.

Since "num" isn't changed we can make it const. Since the squared number might be larger than can fit into an int we make the return value long.

If a function does not return a value you can put void as the return type (such as in setup and loop). If a function does not take arguments you can put void in the parameter list, or just leave the parameter list empty.

Calling a function


Inside setup we see a function call. This calls (invokes) the function pinMode. We know a function is being called because of the round brackets (parentheses).

Whenever you see something like this it is a function call:


foo ();                    // call function foo
bar (1, 2, 3);             // call function bar with 3 arguments
long fubar = square (16);  // call function square with one argument, and getting a result


Even if a function takes no arguments, you must use the parentheses (like in the case of foo above) or it will not be treated as a function call.

If you see some operator (like addition, subtraction, multiplication, division) before the parentheses then it is not a function call. For example:


int x = y + (6);


That is simply adding 6 to whatever value is in y. Without the "+" sign it would be calling function y and passing 6 to it.





Lines 9 to 15



The function loop is similar in structure to setup.

Putting it together


So where does execution start? It is a standard in C that the compiler generates code to jump to a function called main which is supposed to be your "main code".

However the Arduino sketch doesn't have main! This is because the Arduino designers tried to simplify things for you. Under the hood is a main function that looks similar to this:


int main (void)  // main takes no arguments, and returns an int
{
  init ();    // set up hardware timers, etc.
  setup ();   // call your setup function once
  while (true)
    loop ();  // call your loop function indefinitely
  return 0;   // this line will never be executed
}


You can see from this that init will be called first to configure the hardware timers (for stuff like delay and millis), then your setup is called, and finally loop is called repeatedly. If you exit loop then the above code will just call it again.

The code for init is supplied by the IDE (in a file called wiring.c).

Global constructors


It is worth noting that any constructors called by objects at global scope will be called before init and thus the hardware may not have been set up correctly. For example, attempting to do a delay may not work in such a constructor.

The normal paradigm in the Arduino world is to have a constructor do little or nothing, and have the main initialization work done by a class function called begin which your code calls from setup.

Further research


There is a lot more to C and C++ than this example shows. I suggest doing a search for "C tutorial" or "C++ tutorial" for which there are thousands of hits.

Remember that your main sketch in the Arduino IDE is compiled as C++. The IDE does some preprocessing (for example, generating function prototypes) but generally speaking anything you learn about C++ can be used in the Arduino environment. (Once exception is exceptions which are disabled by a compile-time option. Exceptions use the keywords try, catch and throw).

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,101 posts)  Bio   Forum Administrator
Date Reply #1 on Wed 04 Jan 2017 11:07 PM (UTC)

Amended on Thu 05 Jan 2017 12:29 AM (UTC) by Nick Gammon

Message
So what does it actually do?


The function setup is called once by main. Inside it:


  pinMode(LEDPIN, OUTPUT);


That configures the LED pin (13 in this case) to be an output pin. If this wasn't done it would default to input and thus the LED would not flash.




The function loop is called repeatedly by main. Inside it:


  digitalWrite(LEDPIN, HIGH);
  delay(DELAYTIME);
  digitalWrite(LEDPIN, LOW);
  delay(DELAYTIME);


The function digitalWrite first sets the LED pin to HIGH (that is, 5V if you are running a 5V Arduino). Then it delays for DELAYTIME which is 1000 ms (in other words, one second). The delay is "blocking" which means that the function delay doesn't return until the second is up.

After that it sets the output pin to LOW (0V) and then waits another second. After that loop exits. main calls loop again, so that the same code is executed another time. Thus the LED keeps flashing.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


14,504 views.

Postings by administrators only.

Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.