The Wiring framework gives Arduino its easy-to-use functions for controlling the hardware pins; however, the main structural part of the language is all provided by C.
In early versions of Arduino, if you looked in your Arduino installation directory, you could still find a file called WProgram.h (Wiring Program). This file has now been replaced by a similar file called Arduino.h that indicates the gradual drift of the Arduino fork away from the original Wiring Project.
If you go to your Arduino installation folder, you’ll find a folder called “hardware,” and within that, a folder called “arduino,” and within that, a folder called “cores.”
It is this concept of “cores” that allows the use of non-Arduino boards with the Arduino IDE. Note that if you are using a Mac, then you can only get to this folder by right-clicking on your Arduino application, selecting View Package Contents from the menu, and then navigating to the Resources/Java/ folder.
Inside the cores folder is another folder called “arduino,” and, in there, you will find a whole load of C header files with the file extension .h and C++ implementation files with the extension .cpp.
If you open Arduino.h in an editor, you’ll discover that it consists of many #include statements. These pull in definitions from other header files within the cores/arduino folder, so they are included during compi- lation (converting the sketch into a form suitable for installing into the microcontroller’s flash memory).
You’ll also find constant definitions like this:
#define HIGH 0x1
#define LOW 0x0

#define INPUT 0x0
#define OUTPUT 0x1
#define INPUT_PULLUP 0x2
You can think of these as being a bit like variables, so the name HIGH is given the value 1. The value is specified as 0x1 rather than just 1 because the values are all specified in hexadecimal (number base 16). These are not actually variable definitions; they are called C precompiler directives, which means that while your sketch is being turned into something that can be installed into the flash memory on the microcontroller, if it uses the words HIGH, LOW, and so on, they are automatically converted into the appro- priate number. This has an advantage over using variables in that no memory has to be reserved for their use.
Because these constants are numbers, you could write something like this in your sketch to set pin 5 to be an OUTPUT, but it is better to use the name in case the Arduino developers ever decide to change the constant’s value. Using a name also makes the code easier to read.
setMode(5, 1);
setMode(5, OUTPUT);
Also, within arduino.h, you’ll find lots of function “signatures” like this:
void pinMode(uint8_t, uint8_t);
void digitalWrite(uint8_t, uint8_t);
int digitalRead(uint8_t);
int analogRead(uint8_t);
void analogReference(uint8_t mode);
void analogWrite(uint8_t, int);
These warn the compiler about functions whose actual implementations are to be found elsewhere. Take the first one as an example. It specifies the function pinMode as taking two arguments (that you know to be pin number and mode) that are specified as having a type of uint8_t. The void command means the function will not return a value when it is called.
You might be wondering why these parameters’ type is specified as uint8_t rather than int. Normally when defining which pin to use, you specify an int. In actual fact, int is a universal type when writing sketches. It means users do not need to worry about a large number of possible types that they might have to use. But in Arduino C, an int is actually a 16-bit signed number that can represent a number between −32,768 and 32,767. However, when specifying a pin to use, having negative pin num- bers doesn’t make sense and you are very unlikely to ever get a 32,767-pin Arduino.
The type uint_8 is a much more precise convention for defining types because an int in C can be anything between 16 and 64 bits, depending on the C implementation. The way to read “uint_8” is that the u is for unsigned, then you have int, and, finally, after the _ you have the number of bits. So uint_8 is an unsigned 8-bit integer that can represent a number between 0 and 255.
You can use these well-defined types within your sketches, and, indeed, some people do. You have to remember, however, that this makes your code a little less accessible to those who aren’t as experienced in Arduino programming.
The reason that using a regular signed 16-bit int works, rather than, say, a unit_8, is that the compiler automatically performs the conversion for you. Using int variables for pin numbers actually wastes memory. However, you have to balance this against the simplicity and readability of the code.
Alternatively, you can use “byte” for pin numbers. Generally, in program- ming it’s better to favor easy-to-read code over minimizing memory usage, unless you know you are doing something complex that is going to push the microcontroller’s limits.
It’s a bit like having a truck in which you want to deliver some goods to someone. If you have a load of stuff to deliver, then you need to think care- fully about how to pack the load so it all fits. If you know that you are only going to use one little corner of the available space, then spending a lot of time minimizing the space it takes is simply unnecessary.
Also within the arduino folder, you’ll find a file called main.cpp. Open this file; you’ll find it pretty interesting.
#include <Arduino.h>
int main(void)
{
init();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
If you have done any C, C++, or Java programming before, you are familiar with the concept of a main function. This function runs automati- cally when the program is run. Main is the starting point for the whole program. This is also true of Arduino programs, but it is hidden from the sketch writer, who is instead told to implement two functions—setup and loop—within their sketch.
If you look carefully at main.cpp, ignoring the first few lines for now, you can see that it actually calls setup() and then has a for loop with no conditions, with the loop function called inside the loop.
The command for(;;) is simply an ugly way of writing while (true), which just means repeat forever. Notice that in addition to running the loop function, there is also an if command inside the for that checks for serial messages and services them if they arise.
Returning to the top of main.cpp, you can see that the first line is an include command that pulls in all the definitions in the header file arduino.h that I mentioned previously.
Next, you see the start of the definition of the main function, which begins by invoking an init() function. If you look, you can find what this does in the file wiring.c; it in turn calls a function sei, which enables interrupts.
#if defined(USBCON)
USBDevice.attach();
#endif
are another example of a C preprocessor directive. This code is a bit like an if command that you might use in your sketch, but the decision in the if is not made when the sketch is actually running on the Arduino. The #if is evaluated as the sketch is being compiled. This directive is a great way to switch chunks in and out of your program, depending on whether they are needed for a particular type of board. In this case, if the Arduino sup- ports USB, then include the code for attaching the USB (initialize it); oth- erwise, there is no point in even compiling the code to do that.