Unit A - Foundations

04. Sketch Structure, Variables & Types

Build readable sketches: setup/loop, named pins, suitable types, scope, and clean syntax.

Estimated time 3 hours

Learning outcomes

  • Explain the roles of global declarations, setup() and loop()
  • Declare const pin names and changing variables with clear names
  • Choose suitable Uno data types for pins, counts, flags and decimals
  • Distinguish global and local scope
  • Apply case sensitivity, semicolons, braces and useful comments

Parts and preparation

Arduino Uno, USB data cable and Arduino IDE 2. Use the onboard LED - no breadboard required.

Before power: inspect wiring, confirm supply voltage and ensure all connected circuits share GND.

Sketch Structure, Variables & Types instructional connection diagram

What a sketch is

An Arduino program is called a sketch. After reset or power-up, the board runs your code from flash memory. Almost every sketch has the same backbone: optional global declarations, then setup(), then loop().

This lesson is about reading and writing that backbone clearly - before sensors and libraries pile on.

Three stacked blocks: globals, setup once, loop repeating
Globals, setup once, loop forever. Learn this shape by heart.

setup once, loop forever

setup() runs exactly once after reset. Use it for configuration: pinMode, Serial.begin, and one-time starts.

loop() then runs repeatedly for as long as the board is powered. Each pass typically reads inputs, makes decisions, writes outputs, then returns to the top of loop.

Both functions must exist. An empty body { } is legal if you truly have nothing to do there yet.

Flow from reset through setup then repeating loop
Reset starts setup once, then loop repeats.
void setup() {
  // runs once
}

void loop() {
  // runs again and again
}

Variables store changing values

A variable is a named place in memory that holds a value your program can read and update. Declare it with a type, a name, and usually an initial value.

Example: unsigned long flashCount = 0; creates a counter starting at zero. Later, flashCount++; increases it.

PartMeaning
TypeHow the bits are interpreted (byte, int, ...)
NameHow you refer to the value in code
Initial valueStarting contents (recommended)
unsigned long flashCount = 0;
bool ledOn = false;
flashCount++;
ledOn = !ledOn;

const for pins and fixed values

Use const when a name must not change after it is set - especially pin numbers. const byte ledPin = LED_BUILTIN; documents intent and lets the compiler reject accidental reassignment.

Course style: name pins clearly (ledPin, buttonPin). Some teams prefer LED_PIN in UPPERCASE for constants - pick one style and stay consistent in a sketch.

Side by side const pin versus changing flashCount variable
const for fixed pins and limits. Variables for values that update while running.

Choosing a type on the Uno

On a classic Uno (ATmega328P), common types have different ranges. Too small a type overflows - values wrap and look like random bugs.

Rules of thumb for this course: byte for pin numbers and small counts, int for everyday integers, unsigned long for millis() and long-running counters, float when you need decimals, bool for true/false flags.

Cards for byte int unsigned long float bool and char with typical uses
Match the type to the range. millis timestamps belong in unsigned long.
TypeTypical range / noteCourse use
byte0 to 255Pin numbers, small indexes
intAbout -32768 to 32767 on UnoGeneral integers
unsigned long0 to about 4.29 billionmillis, flash counts
floatApproximate decimalsVolts, averages
booltrue or falseFlags, LED state
charOne characterSerial characters later

Global vs local scope

Scope is where a name is visible. A global declared above setup can be used by setup, loop and other functions. A local declared inside a function exists only in that block.

If you declare bool ledOn = false; inside loop, it is recreated every pass - fine for a temporary, bad if you expected it to remember the previous toggle. Prefer the narrowest useful scope so names do not collide.

Global region containing setup and loop local boxes
Globals are shared. Locals live only inside their braces.

Names people can read

Good names beat long comments. Prefer ledPin and flashCount over x and temp2. Use camelCase for most variables and functions (buttonPressed, readSensor).

C++ is case-sensitive: setup and Setup are different. Arduino APIs use exact forms such as pinMode, digitalWrite, HIGH and LOW.

Prefer clear camelCase names versus vague short names
Clear names reduce bugs. Avoid single-letter names for important values.

Syntax that trips beginners

Most early red errors are punctuation or spelling, not electronics:

- Missing semicolon - the compiler often points at the next line - Mismatched { } braces - count them or use the IDE brace highlight - Wrong case - PinMode will not compile; pinMode will - Comments: // for one line, /* ... */ for a block - explain why, units and pin roles

Course style: put the opening brace on the same line as the function or if header, and indent nested blocks by 2 spaces.

Four cards for case sensitivity, semicolons, braces and comments
Case, semicolons, braces, comments. Fix the first compiler error, then Verify again.
void loop() {
  digitalWrite(ledPin, HIGH);  // statement ends with ;
  // this whole line is a comment
}

What the worked sketch practises

The onboard LED toggles every 500 ms. A bool remembers on/off. An unsigned long counts flashes and prints to Serial so you can watch the value grow.

delay(500) is fine for this first demo. Later lessons replace long delays with millis() when several tasks must stay responsive.

Wiring and safe build sequence

  1. No breadboard required - use the Uno onboard LED (LED_BUILTIN, usually pin 13)
  2. Connect USB data cable, select board and port, open Serial Monitor at 9600 baud
Power rule: switch off before moving wires. Arduino I/O pins are control signals; high-current loads require a driver and suitable external supply.
const byte ledPin = LED_BUILTIN;  // onboard LED pin
unsigned long flashCount = 0;     // grows each toggle - needs a wide type
bool ledOn = false;               // remembers current LED state

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  Serial.println("Lesson 04: structure, variables, types");
}

void loop() {
  ledOn = !ledOn;                 // flip true/false
  digitalWrite(ledPin, ledOn);    // bool works as HIGH/LOW here
  flashCount++;
  Serial.print("flashCount = ");
  Serial.println(flashCount);
  delay(500);
}

How the code works

  1. const byte is enough for a pin number (0-255).
  2. ledOn = !ledOn; toggles a Boolean with the NOT operator.
  3. flashCount is unsigned long so a long run will not overflow as quickly as int.
  4. Serial.print labels make the Monitor easier to read than bare numbers.

Test and record evidence

Expected result: The onboard LED toggles about twice per second. Serial Monitor at 9600 baud shows flashCount increasing: 1, 2, 3, ...

Practical evidence checklist

Common faults and checks
  • Check exact capitalization of setup, loop, pinMode, HIGH and LOW.
  • A missing semicolon often causes an error reported on the next line.
  • Blank Serial: match Monitor baud to Serial.begin(9600) and use a USB data cable.
  • LED never blinks: confirm board/port, and that you uploaded this sketch (not an empty one).
  • If you move ledOn inside loop without care, it may reset every pass - that is a scope lesson.
Extension challenge: Move ledOn inside loop as a local with an initial value, upload, and explain why the blink behaviour changes (or why it does not). Then restore a version that remembers state correctly.

Check your understanding

Q1. What runs once after reset, and what repeats?

Show answer

setup() runs once; loop() repeats.

Q2. Why use const for a pin number?

Show answer

It documents that the value must not change and lets the compiler prevent reassignment.

Q3. Why is flashCount an unsigned long instead of byte?

Show answer

A long-running counter can exceed 255 (and even int range); unsigned long fits millis-scale counts better.

Q4. What is local scope?

Show answer

The region inside a block or function where a declared name is visible.

Q5. Why might the compiler complain about Setup()?

Show answer

C++ is case-sensitive; the required function name is setup with a lowercase s.