About Arduino Programming

The Adafruit Metro is programmed in the C language. This is a quick little primer targeted at people who have a little bit of programing experience and just need a briefing on the idiosyncrasies of C and the Arduino IDE. If you find the concepts a bit daunting, don't worry, you can start going through the circuits and pick up most of it along the way.

For a more in-depth explanation of topics discussed both here and in the language, check out the Arduino.cc Reference page.

The Arduino IDE

Now that Arduino is installed and configured, we're going to take a peek at it. Double click the Arduino icon to open it.  It'll open up in a workspace, also called the IDE:

Don't feel overwhelmed - as you progress through the Experimenters Guide, you'll learn to use each part of the IDE.

Structure

You can think of the structure of an Arduino project like the scaffolding for a building. There's a specific structure that must be adhered to, or it all falls apart (and doesn't compile).

void setup() { } 

All the code between the two curly brackets { } will be run only once when your Metro program first runs.

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

void loop() { }

This function is run after void setup() has finished. After it has run once it will be run again, and again, forever, until power is removed.

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

Syntax

One of the slightly frustrating elements of C is its formatting requirements, or syntax. While frustrating, this also makes the language very powerful. If you remember the following you should be alright:

// (single line comment)

When writing a new sketch, or looking over an old one, having a comment to mark what you were thinking is important. To do this type two forward slashes and everything until the end of the line will be ignored by your program.

Download: file
// this is a comment, it won't get run by the compiller 
this is not a comment, it will cause an error when run!!

/* */ (multi-line comment)

If you have a lot to say, you can type on multiple lines using a multi-line comment. Everything between these two symbols will be ignored in your program just like the single line comment.

Download: file
/* 
 * Oh, hey!
 * hi there!
*/

{ } (curly brackets)

These are used to mark when a block of code begins and ends. You'll see it used in functions and loops.

Download: file
void serialPrintHello () 
{ // code begins 
  Serial.println("Hello");
} // code ends 

; (the semicolon) 

Each line of code must be ended with a semicolon. Missing a semicolon will cause your code to refuse to compile. It's often hard to find these, think of them as the hide and seek champion of your code and they're harder to overlook and cause errors.

Download: file
// this will compile 
int servoPin = 5; 
// this won't compile, it's missing a semicolon
int servoPin = 5

Variables

A program is nothing more than instructions to move numbers around in an intelligent way. Variables are used to do the moving.

int (integer)

The main workhorse. The integer stores a number in 2 bytes (or, 16 bits). It has no decimal places and will store a value between -32,768 and 32,767.

Download: file
// this makes the variable i store the value 2
int i = 2;

long

The long is used when an integer is not large enough. Takes 4 bytes (32 bits) of RAM and has a larger range than an integer: between -2,147,483,648 and 2,147,483,647.

Download: file
// this makes the variable j store the value 2000083647
j = 2000083647

bool (boolean)

The boolean is a simple variable that can either be True or False. True corresponds to a bit '1' and False corresponds to '0', it's only one bit.

Download: file
// let's make a boolean called openSource and 
// set it to True
bool openSource = True;
// now let's make a variable called closedSource and
// set it to False
bool closeDSource = False;

float 

Used for floating point math, like decimals. Pi is a super long decimal, 3.1415...but it can be represented as a float such that it has more accurate precision (3.14 is more precise than just 3). It takes up 4 bytes (32 bits) of RAM and has a range between -3.4028235E+38 and 3.4028235E+38.

Download: file
// integers can't store decimal points
int pi = 3;
// so we use a float!
float pi = 3.14;

char (character)

Stores one character using the ASCII code (ie 'A' = 65). Uses one byte (8 bits) of RAM. The Metro handles strings as an array of char’s.

Download: file
// mychar stores the letter A, represented by an ascii value of 65
char myChar = 'A';

Math

Now that we can store numbers in variables, we are going to manipulate them: 

= (equals)

Makes something equal to something else.

Download: file
// b equals one
int b = 1;
// now, the value stored in b equals b times 2, which is one
b = b * 2;

% (modulo)

Gives the remainder of a division operation.

Download: file
// 12 divided by 10 = 1.2, modulo (%) will give us the remainder only
int mod = 12%10
// the value stored in int mod now equals 2

+ (addition) 

Adds two numbers together. 

Download: file
int i = 2+2
// the value stored in int i now equals 4

- (subtraction)

Subtracts one number from another.

Download: file
int f = 4-2
// the value stored in int f now equals 2

* (multiplication)

Multiplies two numbers together.

Download: file
int z = 5*2
// the value stored in int z now equals 10

/ (division)

Divides two numbers.

Download: file
int y = 10/2 
// the value stored in int y now equals 5

Control Flow

Programs are able to control the flow of execution (what runs next). These are a  couple basic elements that you should get familiar with:

If Conditions

This will execute the code between the curly brackets if the condition is true, and if not it will test the else if condition if that is also false the else code will execute.

Download: file
int i = 0;

if(i > 5) {
  // this code does not execute, i is not greater than 5
}
else if (i > 2) {
  // this code also does not execute, i is not greater than 2
}
else {
  // this code DOES execute, i is none of the above, so it falls into
  // this category 
}

for() Loops

Used when you would like to repeat a chunk of code a number of times (can count up i++ or down i-- or use any variable).

Download: file
for (int i = 1; i < 5; i++) {
  // this code will run 4 times
}

Digital Input/Output

The right side of your Metro (or Metro Express) has a header containing 13 digital pins. These pins can be set to digital values ranging from 0 to 1023. The following commands pertain to these pins only:

pinMode(pin, mode)

Used to set a pin's mode.

Pin is the pin number you would like to address, Digital 0-19. You can also set digital pinModes on Analog pins 0-5. The mapping for 0-5 is 14-19.

Mode can either be set as an INPUT or an OUTPUT

Download: file
// a red LED is connected on Pin #11
int redLedPin = 11; 

void setup()
{
  // set the red LED as an OUTPUT 
  pinMode(redLedPin, OUTPUT);      
}

digitalWrite(pin, value)

If you set a pin as an OUTPUT using pinMode, you can then set it to either HIGH or LOW. Setting the pin HIGH will pull it up to +3.3V or +5V. Setting it low will pull it to ground, or zero volts. 

Download: file
// this code will flash the LED on and off forever
void loop()
{
  // set the pin high to turn ON the LED
  digitalWrite(redLedPin, HIGH);
  delay(500);
  // set the pin low to turn OFF the LED
  digitalWrite(redLedPin, LOW);
  delay(500);
}

digitalRead(pin)

Once a pin is set as an INPUT, you can use this to return whether it is HIGH (pulled to +5 volts) or LOW (pulled to ground).

Download: file
// this will store the value of sensorPin in an integer called sensorValue
int sensorValue = digitalRead(sensorPin);

Analog Input/Output

While the Metro is a digital board, it's able to do analog operations. This is useful for getting precise sensor values. Here's how to deal with things that aren't digital:

analogWrite(pin, value)

Through some "under the hood" tricks, the Metro is able to write analog values via Pulse Width Modulation. You can write any value between 0 and 255. 

Download: file
void loop()
{
  // set the LED to full brightness 
  analogWrite(ledPin, 255);  
  // turn the LED off
  analogWrite(ledPin, 0);
}

analogRead(pin)

Reads the value of the analog pin. The value returned can be between 0 and 1024. 

Download: file
sensorVal = analogRead(sensorPin);

This guide was first published on Aug 18, 2017. It was last updated on Aug 18, 2017.

This page (Programming Primer) was last updated on Nov 07, 2020.