What Language Does Arduino Use?

Arduino's Secret Code: The Language That Powers the Magic

February 14, 2024 by Alessandro Colucci
Arduino Secret Code

Introduction - History of Arduino and IDE

 

Arduino Integrate Development Environment (IDE) is a powerful tool shaped by Massimo Banzi, David Cuartielles, Tom Igoe, Gianluca Martino, and David Mellis. It originates from Wiring, a project within Hernando Barragán's 2003 Master's thesis at the Interaction Design Institute Ivrea (IDII).

Massimo Banzi supervised and Casey Reas (of Processing) influenced, as Hernando developed the Wiring platform, setting the foundation for microcontroller development. In 2005, Massimo Banzi, collaborating with David Mellis, another IDII student, and David Cuartielles, expanded Wiring, adding support for the cost-effective ATmega8 microcontroller. This development gave rise to a new project, Arduino, which emerged as a branch from Wiring. It marked the commencement of a transformative journey originating in Italy.

Arduino, inspired by the user-friendly principles of the Processing IDE, aimed to democratize digital project creation. The Arduino programming language, essential to the platform, played a crucial role in broadening access to microcontroller technology. This commitment to simplicity and availability has defined Arduino's legacy, a legacy born in the innovative landscape of Italy.

Now a fascinating question arises: "What programming language is the driving force behind Arduino's magic?"

The magic of Arduino arises from a simplified variant of C++, a language made simple for everyone to understand. This language is like a bridge, connecting beginners and experts. It's easy for beginners but still has the strong features that experts need. It helps people who love electronics turn their ideas into real things easily and smoothly.

 

Benefits of Arduino's C++ Variant

 

Before we get into the cool stuff about Arduino's language, let's talk about why it's great. It's like a special version of C++ that makes Arduino awesome and easy to use.
 
  1. C++ Core Foundation 

    • Arduino's language relies on C++, widely recognized for its flexibility in handling complex tasks.

  2. Simplified for Everyone  

    • Arduino's language simplifies C++, making it easier for everyone to understand and use its powerful features.

  3. Bridge for All Skill Levels

    • Arduino's language acts as a bridge, connecting beginners with clear syntax for an easy entry into programming. Simultaneously, it accommodates seasoned coders with robust features, making it a versatile choice for a diverse community of electronics enthusiasts.

  4. Empowering Electronic Dreams

    • More than just a language, Arduino's C++ variant is a tool empowering individuals passionate about electronics. Whether you're a hobbyist with a first project or a seasoned developer working on complex creations, Arduino turns electronic ideas into tangible realities.

  5. Bringing Everyone Together

    • As we explore Arduino's language, think of it like a superhero - its special version of C++ makes things simpler for everyone. It breaks down barriers, creating a friendly space where people can work together and be super creative without limits.

 

Key Features of Arduino Programming Language

 

Intuitive Structure with setup() and loop() functions

 

In standard C++, a main() function is essential to initiate program execution. Arduino removes this part, simplifying the initiation process. Users can focus on their code logic without the need for a dedicated main function, reducing complexity.

Arduino simplifies the structure of programs by introducing two fundamental functions: setup() and loop(). The setup() function runs once at the beginning, while loop() runs continuously. This clear structure enhances readability and guides users in organizing their code.


void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

 

Curious to see the main function in Arduino? Well, here's an example of the main.cpp code for the Arduino Uno board, hidden in the core folder.


/*
  main.cpp - Main loop for Arduino sketches
  Copyright (c) 2005-2013 Arduino Team.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include <Arduino.h>

// Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (* /*func*/ )()) { return 0; }

// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }

void setupUSB() __attribute__((weak));
void setupUSB() { }

int main(void)
{
	init();

	initVariant();

#if defined(USBCON)
	USBDevice.attach();
#endif
	
	setup();
    
	for (;;) {
		loop();
		if (serialEventRun) serialEventRun();
	}
        
	return 0;
}


 

At line 44, the main function calls the setup() function only once. That's why code into setup() function runs only 1 time.

At line 47, the main function calls the loop() function, situated within a for loop at line 46 that is always true. This structure ensures that the code within the loop() runs repeatedly. 

 

To find the core files of your boards in the Arduino IDE, look in the "Arduino15" folder.

    • Windows: C:\Users\{username}\AppData\Local\Arduino15
    • macOS: /Users/{username}/Library/Arduino15
    • Linux: home/{username}/.arduino15

Navigate to the Arduino15 folder, then open packages › arduino › hardware › avr › 1.8.6 › cores › arduino › main.cpp

For additional information, refer to the Arduino website.

 

Automatic Function Prototypes

 

Arduino's language eliminates the requirement for users to explicitly declare function prototypes. This allows beginners to start coding more easily, without the need for intricate declarations. 

In traditional C++, it's necessary to declare its prototype at the beginning of the program. For example:


// Explicit function prototype
void myFunction(int x);

void setup() {
  // Function call
  myFunction(10);
}

void loop() {
  // Code here
}

// Function definition
void myFunction(int x) {
  // Function implementation
}

 

In Arduino's simplified C++, you can directly define and use functions without the need for explicit prototypes:


void setup() {
  // Function call
  myFunction(10);
}

void loop() {
  // Code here
}

// Function definition
void myFunction(int x) {
  // Function implementation
}

 

Intuitive Sketch Files (.ino) Organization

 

The use of .ino files is a distinctive feature that contributes to the simplicity of Arduino programming. Each .ino file includes a portion of the sketch, making it an intuitive and user-friendly unit of code. This approach allows developers to focus on specific functionalities within separate files, promoting a modular and organized project structure.

In Arduino projects, when you have multiple .ino files in the same project folder, the Arduino IDE handles them collectively during compilation. The IDE follows a specific process to concatenate these files before compiling and uploading to the Arduino board.

This approach offers a simplified alternative compared to standard C++ IDEs, which often rely on .h and .cpp files.

In standard C++, header files handle function prototypes, and function implementations reside in .cpp files, requiring careful management of include statements.

 

Take a look at the example below.

Imagine a simple project written in a single .ino file: an Arduino reads a value from a potentiometer and adjusts the LED blinking interval.

 

BlinkingLED.ino


int ledPin = 13;
int potentiometerPin = A0;

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

void loop() {
  int potValue = analogRead(potentiometerPin);
  int blinkInterval = map(potValue, 0, 1023, 100, 2000);  // Map potentiometer value to blink interval
  digitalWrite(ledPin, HIGH);
  delay(blinkInterval);
  digitalWrite(ledPin, LOW);
  delay(blinkInterval);
}

 

Now, let's reorganize the project. A reading function (readPotentiometer) in one file and the LED setting function (blinkLED) in another. This splits the project into three files: 

 

1. BlinkingLED.ino


// BlinkingLED.ino

int ledPin = 13;
int potentiometerPin = A0;

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

void loop() {
  readPotentiometer();
  blinkLED();
}

 

2. ReadData.ino


// ReadData.ino


int blinkInterval = 0; void readPotentiometer() { int potValue = analogRead(potentiometerPin); blinkInterval = map(potValue, 0, 1023, 100, 2000); // Map potentiometer value to blink interval }

 

3. WriteData.ino


// WriteData.ino

void blinkLED() {
  digitalWrite(ledPin, HIGH);
  delay(blinkInterval);
  digitalWrite(ledPin, LOW);
  delay(blinkInterval);
}

 

The Arduino IDE concatenates all .ino files starting from the principal project file (BlinkingLED).

So, ReadData.ino and WriteData.ino will be concatenated alphabetically in order like below.

 

Concatenation performed by Arduino IDE preprocessor during compilation phase:


int ledPin = 13;
int potentiometerPin = A0;

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

void loop() {
  readPotentiometer();
  blinkLED();
}


int blinkInterval = 0; void readPotentiometer() { int potValue = analogRead(potentiometerPin); blinkInterval = map(potValue, 0, 1023, 100, 2000); // Map potentiometer value to blink interval void blinkLED() { digitalWrite(ledPin, HIGH); delay(blinkInterval); digitalWrite(ledPin, LOW); delay(blinkInterval); }

 

Takeaways:

    1. No need for additional header files to manage connections between functions.

    2. No need to manage function prototypes in multiple files.

 

Points to note:

    1. While functions are in different files, they aren't as fully segregated as with .h and .cpp files.

    2. Be cautious when dealing with global variables instantiated in a specific file (e.g. blinkInterval):

      • they will be visible in other files, potentially causing conflicts.

      • declare global variables before using them in other consecutive files to avoid conflicts during concatenation.

 

For better control over concatenation, consider naming files with a number prefix, such as '01_ReadData.ino' and '02_WriteData.ino.' This practice simplifies the order and organization of file concatenation.

 

Conclusion

 

Arduino's language simplifies the programming experience, allowing individuals to engage with electronics, whether they are beginners or seasoned developers. It's a language that brings everyone together, breaking down barriers and creating a collaborative space for innovation. With its roots in Italy, Arduino's legacy continues to inspire and shape the world of electronics.

Chat with us on WhatsApp