Skip to content

Latest commit

 

History

History
653 lines (472 loc) · 38.9 KB

File metadata and controls

653 lines (472 loc) · 38.9 KB

Hands-On Arduino Course for Beginners — Course Notes

Detailed, structured notes compiled from the course video transcript. Use the index below to jump to any section.


📑 Table of Contents

  1. Course Introduction
  2. Choosing an Arduino Kit
  3. Using a Digital Simulator (Tinkercad)
  4. Breadboards — How They Work
  5. Resistors — Theory and Ohm's Law
  6. Reading Resistor Values
  7. LEDs — The Science Behind Them
  8. Semiconductors, Doping, N-Type and P-Type
  9. Building Your First LED Circuit
  10. Arduino vs. a Battery — Why Use Arduino?
  11. Setting Up the Code Editor
  12. Basic Arduino Code Structure (setup/loop)
  13. Homework Project: Traffic Light
  14. Variables in Arduino
  15. Analog Pins vs. Digital Pins
  16. PWM (Pulse Width Modulation) and analogWrite
  17. analogRead and Reading Voltage
  18. The Serial Monitor Basics
  19. Potentiometers
  20. Buzzers — Active vs. Passive
  21. AC vs. DC and How Buzzers Use Them
  22. Playing Melodies with Libraries
  23. Photoresistors (LDRs)
  24. Thermistors (NTC/PTC)
  25. Temperature Sensors — LM35
  26. Temperature Sensors — DHT Series
  27. Digital Read vs. Analog Read (Efficiency)
  28. Switches / Push Buttons
  29. RGB LEDs — Color Theory
  30. Building and Coding an RGB LED
  31. Serial Communication — Reading User Input
  32. Strings vs. Numbers in Arduino
  33. If / Else If / Else Conditionals
  34. Comparison (==) vs. Assignment (=)
  35. Completing the Color-Changing RGB Project
  36. Seven-Segment LED Displays (Single Digit)
  37. Common Cathode vs. Common Anode
  38. Building a Countdown Timer (Single Digit)
  39. Four-Digit Seven-Segment Displays
  40. Multiplexing / Digit Scanning
  41. Reverse-Engineering an Unknown Display's Pinout
  42. Building a 4-Digit Timer with a Buzzer (SevSeg Library)
  43. Understanding the while() Loop
  44. LED Matrices — How They Work
  45. Wiring and Testing an LED Matrix
  46. Drawing Letters and Images (Byte Arrays)
  47. Animating / Scrolling Text on the Matrix
  48. Course Conclusion

1. Course Introduction

  • This is a beginner-friendly, hands-on Arduino course — no prior programming or electronics knowledge required.
  • The course covers electronics, programming, and relevant physics concepts all in one place, to avoid the common problem of having to jump between multiple courses/instructors to learn different aspects.
  • You can follow along with a physical Arduino kit (recommended for engagement) or a digital simulator if you don't own hardware.

2. Choosing an Arduino Kit

  • The instructor uses an Inland Starter Kit and Inland Electronic Parts Pack (mostly available in the US).
  • For those outside the US: an Elegoo UNO Superstarter Kit is suggested, plus a separate LED Matrix component (not included in that kit but needed for this course).
  • If you already own a kit, cross-check your components against the ones listed on-screen in the video; missing parts can be purchased separately (e.g., from Amazon).

3. Using a Digital Simulator (Tinkercad)

For those without a physical Arduino:

  1. Go to tinkercad.com and sign up/log in.
  2. Go to Designs → Create → Circuits.
  3. Use the components tab to search for and add parts to your circuit.
  4. Use the code section to write code for your simulated Arduino and run simulations.

4. Breadboards — How They Work

  • A breadboard solves the practical problem of connecting multiple wires to an Arduino without them being physically awkward to hold, and prevents accidental shocks.
  • Layout:
    • The main rows (e.g., labeled A–E and F–J) run horizontally — pins within the same row are electrically connected.
    • Rows A–E are not connected to rows F–J (there's a physical gap in the middle).
    • The outer edge columns (power rails) run vertically — connected all the way top to bottom.
  • Verification tool: A multimeter set to "continuity" mode beeps and lights up when a closed electrical path exists — useful for confirming which holes are connected.

5. Resistors — Theory and Ohm's Law

  • Resistors limit current flow to protect components (like LEDs) from being damaged by current overflow.
  • Ohm's Law: V = I × R
    • V = Voltage (volts)
    • I = Current (amperes/amps)
    • R = Resistance (ohms, symbol Ω)
  • Example calculation: An Arduino outputs 5V. LEDs have a max current limit of ~20mA (recommended 10–15mA). Using 15mA as a safe target:
    • R = V / I = 5V / 0.015A ≈ 333Ω
    • In practice, a resistor in the 300–400Ω range is used (exact value isn't critical, just needs to be in a safe range).

6. Reading Resistor Values

Two methods to determine a resistor's resistance:

a) Resistor Color Code

  • Read colored bands left to right: first two bands = significant digits, third band (or fourth on 4-band resistors) = multiplier, final band = tolerance.
  • Example: Red-Red-Black-Black → 2, 2, 0, ×1 → 220Ω (final tolerance band, e.g. brown, is not critical for this level).

b) Multimeter

  • Set the multimeter to resistance/ohm mode and select an appropriate range (e.g., 200Ω, 2kΩ) to measure the resistor directly. Note: readings are approximate, not exact.

7. LEDs — The Science Behind Them

  • Traditional light bulbs (Edison-style) work by heating a coil until it glows — this is inefficient: ~95% of energy becomes heat, only ~5% becomes light.
  • LEDs (Light Emitting Diodes) convert electrical energy directly into light energy — far more efficient.
  • LEDs are a type of diode, which is a device made from semiconductors.
    • Conductors (e.g., wire) conduct electricity.
    • Insulators (e.g., paper/pencil wood) do not.
    • Semiconductors exhibit properties of both, depending on conditions.

8. Semiconductors, Doping, N-Type and P-Type

  • Silicon has 4 valence electrons. Pure silicon atoms bond together sharing electrons, reaching a stable 8-electron configuration — meaning no free electrons, so it acts as an insulator.
  • Doping changes this behavior:
    • N-type: doping with a 5-valence-electron atom creates a surplus electron (9 total) — negatively charged, has a free electron that wants to move → conducts electricity.
    • P-type: doping with a 3-valence-electron atom creates an electron deficiency (7 total) — positively charged, creates "holes" (empty spaces where an electron should be) that want to receive electrons.
  • Diode behavior:
    • Connecting positive terminal to N-type and negative to P-type → electrons and holes repel each other → no current flows.
    • Reversing this (negative to N-type, positive to P-type) → electrons flow from N-type to P-type, moving from a higher to lower energy level, releasing energy as light.
  • Identifying LED polarity: The longer leg = positive (P-type); the shorter leg = negative (N-type).

9. Building Your First LED Circuit

Steps to build a basic LED circuit:

  1. Connect Arduino 5V pin to the breadboard.
  2. Connect a resistor (~300–400Ω) across the gap in the breadboard (in the current path).
  3. Connect the LED, ensuring the longer (positive) leg faces the positive/resistor side.
  4. Connect the circuit back to GND (ground) on the Arduino.
  5. Power the Arduino via USB — the LED should light up.

If the resistor isn't seated properly (not making a complete circuit), the LED simply won't light up (safe failure) rather than being damaged.


10. Arduino vs. a Battery — Why Use Arduino?

  • A basic LED circuit can technically be powered by a simple battery instead of an Arduino (lower voltage = dimmer light, since voltage relates directly to current).
  • Batteries are cheaper, more portable, and more reliable as a pure power source — so why use Arduino?
  • Answer: Arduino is more than a power source — it's an "intelligent" programmable power source.
    • It lets you code physical/electrical components (e.g., make an LED blink automatically, control robots), which a battery alone cannot do without manual intervention.

11. Setting Up the Code Editor

  • Digital simulator users: Use the built-in code editor (choose "Text" mode over "Blocks" for this course).
  • Physical Arduino users: Download the Arduino IDE for your OS (Windows/Linux/Mac), or use the Arduino Web Editor (works without downloads — useful for Chromebooks, etc.).
  • In the IDE, select your Board (e.g., Arduino Uno/Nano) and the correct communication Port (COM port). If multiple ports are listed and you're unsure which one is your Arduino, unplug it and see which port disappears.

12. Basic Arduino Code Structure (setup/loop)

Every Arduino sketch has two core functions:

  • void setup() — runs once when the board starts; used for initial configuration (e.g., pinMode()).
  • void loop() — runs repeatedly forever; contains the main program logic.

Key functions introduced:

  • pinMode(pin, OUTPUT) — configures a pin as an output (to send voltage) or INPUT (to receive data).
  • digitalWrite(pin, HIGH) — sets a pin to 5V ("on").
  • digitalWrite(pin, LOW) — sets a pin to 0V ("off").
  • delay(milliseconds) — pauses execution for the given time (1000ms = 1 second). Needed because digital switching happens too fast (milliseconds) for the human eye to perceive without a delay.

Capitalization matters in Arduino code (e.g., pinMode, not pinmode; OUTPUT, not output) — incorrect capitalization causes compile errors.


13. Homework Project: Traffic Light

  • Goal: Build a working traffic light using 3 LEDs (green, yellow, red), each on its own digital pin and resistor, sharing a common GND.
  • Timing logic: Green on for 5s → off; Yellow on for 1s → off; Red on for 5s → off; repeat.
  • This reinforces using multiple pinMode, digitalWrite, and delay calls across several pins.

14. Variables in Arduino

  • A variable is like a labeled box — it doesn't change the underlying value, but makes code easier to read, and lets you reuse and update values from a single location.
  • Declaring a variable in Arduino requires a type, e.g.:
    int delay_time = 3000;
  • Benefits demonstrated:
    • If the same value (e.g., a delay time or pin number) is used in multiple places, defining it once as a variable means you only need to update it in one place instead of hunting through the whole code.
    • Naming variables descriptively (e.g., redPin instead of just 7) makes code self-documenting for yourself and others.
  • Editor tip: Use Cmd/Ctrl+D to select and simultaneously edit multiple instances of the same value in the IDE.

15. Analog Pins vs. Digital Pins

  • Digital pins are labelled with plain numbers (e.g., pin 7). Analog pins are labelled with a capital "A" before the number (e.g., A4) to distinguish them from digital pins of the same number.
  • Digital pins only support two states: HIGH (5V) or LOW (0V) — no in-between values.
  • Analog output (via specific pins) allows intermediate voltage values — e.g., outputting ~2.5V (half of 5V) or any other fraction.

16. PWM (Pulse Width Modulation) and analogWrite

  • analogWrite(pin, value) accepts an integer from 0–255 (0 = 0V/off, 255 = 5V/full on), allowing intermediate brightness/voltage levels.
  • Important: analogWrite() only works on specific pins marked with a squiggly line (~) or dot next to the pin number on the board — these are the PWM-capable pins (also usable as regular digital pins).
  • How PWM actually works: The pin doesn't truly output a steady intermediate voltage. Instead, it rapidly switches between HIGH and LOW at high speed. The proportion of "on" time vs. "off" time determines the perceived average voltage/brightness (e.g., 50% on/50% off ≈ 2.5V equivalent). This happens too fast for the human eye to notice flickering — it just looks dimmer or brighter.
  • A pin marked for PWM can be used either as an analog output (with analogWrite) or as a regular digital pin (with digitalWrite).

17. analogRead and Reading Voltage

  • analogRead(pin) reads a voltage value on an analog pin and returns an integer from 0 to 1023 (10-bit resolution — 2¹⁰ = 1024 possible values, counting from 0).

  • Comparison: analogWrite uses 8-bit resolution (0–255 for 5V), while analogRead uses 10-bit resolution (0–1023 for 5V) — this is simply an Arduino design convention, not something the user needs to justify.

  • Safety note: Directly connecting 5V straight into an analog pin (with no resistor/component in between) is generally fine for reading purposes, but connecting 5V directly to GND (shorting the circuit) can fry the board — always be cautious with direct connections.

  • To convert a raw analog reading into a real voltage:

    float calcValue = (5.0 / 1023) * analogRead(readPin);
    • Note: values must be declared as floats (decimals), not integers, or the result rounds down to 0 due to integer division.

18. The Serial Monitor Basics

  • Serial.begin(9600) — starts serial communication at a baud rate (9600 is a common default; baud rate is the speed at which data is transferred).
  • Serial.print(value) — prints without a line break (values run together on one line).
  • Serial.println(value) — prints with a line break (each new value appears on a fresh line) — much easier to read.
  • The Serial Monitor must be closed before uploading new code to the board (you cannot upload while it's open).
  • The Serial Monitor can also be used to send messages/input to the Arduino, not just to read output from it (explored further in later sections).

19. Potentiometers

  • A potentiometer is essentially a variable resistor with a turnable knob and 3 legs.
  • Internally, think of it as two resistors (R1 and R2) in series, where R_total = R1 + R2 is fixed, but turning the knob shifts the split between R1 and R2.
  • The middle pin outputs a variable voltage (V_out) between the two end pins (connected to 5V and GND respectively).
  • Uses demonstrated:
    • Dimming/brightening an LED by adjusting the knob (adjusting voltage supplied).
    • Adjusting the volume of a buzzer.
    • Reading the potentiometer's position via analogRead to display a live voltage value (0–5V) on the Serial Monitor.

20. Buzzers — Active vs. Passive

Two types of buzzers, distinguished visually (active buzzers have a small circuit board/cover on the bottom; passive buzzers show the visible internal components):

Type Power Requirement Behavior
Active buzzer DC voltage (e.g., connect directly to 5V) Makes a fixed sound automatically when powered — cannot be turned on/off via code logic alone (since 5V is always "on") unless connected through a digital pin
Passive buzzer AC-like signal (via a PWM/digital pin) Can be turned on/off, and volume/pitch can be controlled via analogWrite() since the digital pin can toggle
  • Both have a longer leg (positive) and shorter leg (negative), just like LEDs.
  • A passive buzzer connected to a PWM pin and analogWrite() with different values produces different volumes.

21. AC vs. DC and How Buzzers Use Them

  • DC (Direct Current): constant voltage in one direction (a flat line on a voltage-vs-time graph).
  • AC (Alternating Current): voltage oscillates back and forth (an up-and-down wave on the graph).
  • Passive buzzers contain a vibration cone that needs to physically move back and forth to create sound — this requires an AC-like signal.
  • Active buzzers use an internal electromagnet mechanism: the magnet attracts/repels rapidly when powered with DC, causing the cone to vibrate indirectly.
  • A diode/rectifier can be used to convert an AC-like signal into a DC-like signal by only allowing current to flow in one direction, blocking the other half of the cycle.

22. Playing Melodies with Libraries

  • Complex buzzer melodies often require third-party code that depends on external libraries (e.g., a "pitches.h" header file for musical notes).
  • Installing libraries:
    • Library Manager: Sketch → Include Library → Manage Libraries → search and install.
    • Manual/zip install: Download a .zip from GitHub, then Sketch → Include Library → Add .ZIP Library.
  • Real-world troubleshooting is part of the process: reading documentation carefully (e.g., checking which pin a sample sketch expects), library dependency errors, and iterating are normal parts of using someone else's code.

23. Photoresistors (LDRs)

  • A photoresistor (light-dependent resistor) changes its resistance based on light level.
  • Relationship: As light increases, resistance decreases (and vice versa).
  • Important safety note: Because resistance is variable and could theoretically approach a very low value, a backup fixed resistor should always be used in series to prevent excessive current (and a fried LED/Arduino) in bright conditions.
  • Real-world application: Automatic street lamps — smart lighting that turns on/off based on ambient light, using photoresistors to detect when it's dark.

24. Thermistors (NTC/PTC)

  • A thermistor changes resistance based on temperature.
  • Two types:
    • NTC (Negative Temperature Coefficient): resistance decreases as temperature increases (inversely proportional).
    • PTC (Positive Temperature Coefficient): resistance increases as temperature increases (directly proportional).
  • Like photoresistors, thermistors should be paired with a fixed backup resistor to prevent current overflow.
  • High-value thermistors (e.g., 10,000Ω) require large temperature changes to produce a noticeable resistance/brightness difference — small changes (e.g., from a nearby lamp) may not be visibly detectable.
  • Safety note: Avoid using open flames or very hot objects near a thermistor/breadboard for testing — use a digital simulator instead if you want to safely test extreme temperature scenarios.

25. Temperature Sensors — LM35

  • The LM35 is a 3-legged analog temperature sensor: left leg → 5V, middle leg → analog read pin, right leg → GND (flat side facing you).
  • Datasheet key spec: Linear scale factor of 10mV per degree Celsius.
  • Formula:
    Temperature (°C) = Voltage / Scale Factor
    Scale Factor = 0.01 V/°C
    
  • Code implementation:
    float readValue = analogRead(readPin);
    float calcValue = (readValue / 1023) * 5.0;  // convert to voltage
    float scaleF = 0.01;
    float temperature = calcValue / scaleF;      // convert to °C
  • Conversions practiced (as homework exercises):
    • Fahrenheit: F = (C × 9.0/5.0) + 32 — note: parentheses matter for correct order of operations, and constants should be written as floats (e.g., 9.0) to avoid integer division errors.
    • Kelvin: K = C + 273

26. Temperature Sensors — DHT Series

  • The DHT11/DHT22 sensors also measure temperature (and humidity) but communicate differently: left pin → digital pin, middle pin → 5V, right pin → GND.

  • Requires a library (e.g., the Adafruit DHT sensor library, plus its dependency, the Adafruit Unified Sensor library) — install via Library Manager or as a .zip.

  • Basic setup:

    #define DHTTYPE DHT11
    #define DHTPIN 2
    DHT dht(DHTPIN, DHTTYPE);
    
    dht.begin();
    float humidity = dht.readHumidity();
    float tempC = dht.readTemperature();
  • Like the LM35 example, Fahrenheit/Kelvin values can be derived from the Celsius reading, and all three can be printed to the Serial Monitor together with labels (e.g., "C:", "F:", "K:") to distinguish them.


27. Digital Read vs. Analog Read (Efficiency)

  • digitalRead(pin) returns only 0 or 1 (1 bit of information) — very fast to transmit/interpret.
  • analogRead(pin) returns a value in a 10-bit range (0–1023) — more information but slower to transmit/interpret.
  • The DHT sensors only ever send binary (on/off) signals, so using digitalRead (via a digital pin) is the appropriate, faster, more efficient choice — even though it would technically be possible to read them with an analog pin, it would be less accurate and slower.
  • Analogy: saying "hi" (1 bit) is much faster than saying "hey, how are you?" (10 bits) — smaller amounts of transmitted information are always quicker.

28. Switches / Push Buttons

  • Switches have 4 legs, arranged so that:
    • Legs on the same side (adjacent, same edge) are the ones where switching occurs — connected only when the button is pressed.
    • Legs on parallel/opposite sides are always connected internally, regardless of whether the button is pressed.
  • Key identification tip: Always look for two pins that share the same side — those are the "switching" pair. Don't rely on "near vs. far" positioning, especially on square (symmetrical) switches, since that can be misleading.
  • Push buttons vs. toggle switches:
    • Push buttons: only connected while actively pressed (like a spring-loaded push-door — releases back to default when let go).
    • Toggle switches (e.g., household light switches): stay in the position you leave them in until switched again.
  • Basic circuit: 5V → switch → resistor → LED → GND. Pressing the button completes the circuit and lights the LED; releasing breaks it.

29. RGB LEDs — Color Theory

  • An RGB LED has 4 legs: think of it as three separate LEDs (Red, Green, Blue) combined into one component, sharing a common cathode or anode (the longer leg).
  • Subtractive colors (Red, Yellow, Blue): created by splitting/separating light (e.g., a prism splitting sunlight) — relevant to physical pigments and light from natural sources.
  • Additive colors (Red, Green, Blue): created by combining/blending light — relevant to electronic displays, since devices generate light from electricity rather than filtering sunlight.
  • Combining full-intensity Red + Green + Blue produces white light.
  • RGB values range from 0–255 for each channel (matching the 0–255 range used in analogWrite), and any color can be found using an online "Color Picker" tool by looking up its RGB values (e.g., pink = 255, 192, 203).

30. Building and Coding an RGB LED

  • Wiring requirement: Unlike single-color LEDs, an RGB LED needs three separate resistors — one for each of the Red, Green, and Blue legs (a common beginner mistake is using only one resistor for the whole component).
  • Important: RGB LEDs must be connected to PWM-capable pins (marked with a squiggly line/dot) since analogWrite() is required to blend intermediate color values — a plain digital pin (without PWM) will not allow this.
  • Code pattern:
    analogWrite(redPin, 132);
    analogWrite(greenPin, 255);
    analogWrite(bluePin, 0);
  • Different RGB combinations (found via a color-picker tool) can be plugged in to produce custom colors (e.g., cyan, pink, yellow-green).

31. Serial Communication — Reading User Input

  • Serial.readString() reads a string of characters sent from the Serial Monitor's input box into the Arduino.
  • Combined with a while (Serial.available() == 0) {} loop, the Arduino will pause and wait for user input before proceeding, rather than repeatedly asking the same question or executing with an empty/default value.
  • Serial.available() returns how much incoming data is waiting to be read — if nothing has been sent, it equals 0.

32. Strings vs. Numbers in Arduino

  • Arduino needs to distinguish between code/commands and plain text (strings) — this is done using quotation marks ("...") to denote a string.
  • Key behavior of Serial.readString():
    • It always stores the received input as a string (text), even if the user types a number — so "10" (a string) is not the same as the number 10, and cannot be used in arithmetic directly.
    • It also appends a newline character at the end of what it reads by default in newer Arduino IDE versions (2.x) — this can cause string comparisons to unexpectedly fail (e.g., comparing an input string to "red" fails because the actual stored value is "red\n").
    • Fix: Append \n (backslash + n, representing a newline) to the string literal you're comparing against, e.g., if (setColor == "red\n").
    • Note: older Arduino IDE versions (e.g., 1.8.x) do not have this newline quirk.

33. If / Else If / Else Conditionals

  • Basic structure:
    if (condition) {
      // code A — runs if condition is true
    } else if (anotherCondition) {
      // code B — runs if the first condition is false but this one is true
    } else {
      // code C — runs if none of the above conditions are true (the "final straw")
    }
  • Key behavior: Conditions are evaluated top to bottom. As soon as one condition evaluates true, its code block runs and all remaining else if/else blocks are skipped — even if a later condition would also technically be true.
  • You can chain multiple else if blocks to handle many possible cases (analogous to real-life decision chains, e.g., "if it rains, do X; else if it's too hot, do Y; else do Z").

34. Comparison (==) vs. Assignment (=)

  • Assignment (=): stores/sets a value into a variable — e.g., setColor = Serial.readString();
  • Comparison (==): checks whether two values are equal (used in conditionals) — e.g., if (setColor == "red").
  • This mirrors the math distinction between an expression and an equation: a single = "solves for" or assigns a value, while == asks a true/false question ("are these equal?").
  • Using a single = where == is intended is a common bug source, since Arduino "takes things literally" and won't infer your intent.

35. Completing the Color-Changing RGB Project

Putting it all together — a project where typing a color name into the Serial Monitor changes the RGB LED's color:

String setColor;

void loop() {
  while (Serial.available() == 0) {}
  setColor = Serial.readString();

  if (setColor == "red\n") {
    analogWrite(redPin, 255);
    analogWrite(greenPin, 0);
    analogWrite(bluePin, 0);
  } else if (setColor == "cyan\n") {
    analogWrite(redPin, 0);
    analogWrite(greenPin, 100);
    analogWrite(bluePin, 100);
  } else {
    Serial.println("Color not recognized");
  }
}
  • Debugging lessons demonstrated: printing the raw received value helps reveal hidden characters (like the newline) causing comparisons to silently fail — a valuable general debugging technique.
  • Homework: Add 3–4 more favorite colors using the same pattern (look up RGB values online for each).

36. Seven-Segment LED Displays (Single Digit)

  • A 7-segment display is made of 7 individual LED segments (labeled A–G) plus often a decimal point (DP), used to display digits (0–9) and some letters cheaply — commonly seen in digital clocks, calculators, and gas pump displays.
  • Always check the manufacturer's datasheet for your specific model, since pin layouts vary.
  • Each individual segment requires its own resistor (recommended: 500–1000Ω), except for the shared common pin.

37. Common Cathode vs. Common Anode

Two variants of 7-segment displays, which look identical but wire up oppositely:

Type Shared/Common Pin Individual Segment Pins
Common Cathode Connects to GND Set to HIGH to light up a segment
Common Anode Connects to 5V Set to LOW to light up a segment
  • Identifying which type you have: Check the datasheet, or use trial-and-error — connect the presumed "common" pin to 4V/GND (with a resistor protecting any segment pin you test) and see which config makes an individual segment light up.

38. Building a Countdown Timer (Single Digit)

  • By turning on/off different combinations of the 7 segments (A–G), you can display any digit 0–9. Example segment combinations were manually mapped out (e.g., "9" needs A, B, C, D, F, G on; "1" needs only B, C on).
  • A common bug: forgetting to explicitly set unused segments to LOW after a previous digit already set them HIGH — since segments don't automatically reset between digits, leftover "on" segments bleed into the next number's display, producing garbled output.
  • A simple timer counts down from 9 to 0 with a delay() between each digit, cycling through each digit's specific segment pattern.

39. Four-Digit Seven-Segment Displays

  • A 4-digit display cleverly uses only 12 pins total (not 34, which would be needed if every segment on every digit had its own pin).
  • How this works: All four digits share the same 8 segment pins (A–G + DP), but each digit has its own separate common pin (D1, D2, D3, D4) that acts like an individual GND (common cathode) or 5V (common anode) selector for that digit.
  • The catch: You can only light up one digit at a time without segments "bleeding" into other digits (since they share the same segment wiring) — if you try to activate multiple digit-common pins simultaneously with different segment patterns, all active digits will incorrectly display the same pattern.

40. Multiplexing / Digit Scanning

  • Solution to the "one digit at a time" limitation: multiplexing. Rapidly cycle through each digit, one at a time, turning it on with its specific segment pattern, then switching to the next digit — done fast enough (milliseconds) that the human eye perceives all digits as lit simultaneously (this is the same principle as how a TV/monitor refresh works, or how a movie is made of individual still frames shown quickly).
  • Practical demonstration: Setting the delay between digit switches to something visible (e.g., 100ms) shows visible "scanning" flicker; reducing it to ~5ms makes it appear as a smooth, constant, unflickering display.
  • A refresh function should be called repeatedly (with a small delay, e.g., 5ms) many times to accumulate roughly 1 second of total "on" display time before advancing program logic (e.g., decrementing a timer).

41. Reverse-Engineering an Unknown Display's Pinout

If a datasheet can't be found for your specific 4-digit display model:

  1. Assume a pin is a "digit" (common) pin and connect it to GND (common cathode) or 5V (common anode).
  2. Try connecting other pins (through a resistor) as potential "segment" pins, one at a time, until a segment lights up.
  3. Once one segment lights up, you can deduce: which digit it belongs to (by position), which segment letter it is (by shape/position on the display), and whether the display is common cathode or common anode (based on which wiring scheme worked).
  4. Repeat this trial-and-error process to map out and document all remaining pins.

42. Building a 4-Digit Timer with a Buzzer (SevSeg Library)

  • The SevSeg library greatly simplifies driving 4-digit 7-segment displays (avoiding manually multiplexing/refreshing).

  • Setup:

    #include "SevSeg.h"
    SevSeg sevseg;
    
    byte numDigits = 4;
    byte digitPins[] = {D1, D2, D3, D4};      // order matters!
    byte segmentPins[] = {A, B, C, D, E, F, G, DP}; // order matters!
    bool resistorsOnSegments = true;
    
    sevseg.begin(COMMON_CATHODE, numDigits, digitPins, segmentPins, resistorsOnSegments);
    sevseg.setBrightness(90); // 0–100 recommended; 100–200 can cause flickering
  • sevseg.setNumber(value) sets the number to display; sevseg.refreshDisplay() must be called frequently (in a loop with a small delay, e.g., 5ms) to keep the display lit and updated.

  • Buzzer integration: An active buzzer, powered through a diode (to approximate DC from an analog/PWM pin) and an analogWrite() call, rings when the countdown reaches zero.

  • sevseg.blank() clears/turns off the display.


43. Understanding the while() Loop

  • A while (condition) { } loop repeatedly executes its code block as long as the condition remains true, checking the condition again after each pass.
  • Common use #1 — waiting for input: while (Serial.available() == 0) {} pauses execution until the user sends a message, preventing the program from proceeding with an empty/default value.
  • Common use #2 — a countdown timer:
    while (userInput > 0) {
      sevseg.setNumber(userInput);
      // refresh display repeatedly for ~1 second total
      userInput = userInput - 1;
    }
    This continues looping (displaying and decrementing) until the condition (userInput > 0) becomes false.
  • Logical operators:
    • && (AND) — both conditions must be true for the overall statement to be true.
    • || (OR) — at least one condition must be true for the overall statement to be true.

44. LED Matrices — How They Work

  • An LED matrix (e.g., 8×8) is wired as a grid of rows and columns — individual LEDs light up only at the intersection of an active row (HIGH) and active column (LOW), completing a circuit only at that specific point.
  • Key limitation: Turning on multiple rows and columns simultaneously causes unintended segments to also light up wherever any active row crosses any active column — similar to the "bleeding" issue seen with 4-digit displays.
  • Solution: Just like with 4-digit displays, you must light up one row at a time (with the correct columns active for that row), cycling through very quickly (multiplexing) so the human eye perceives a complete, stable image.
  • Wiring convention/tip: Orient the display consistently (pin markers at top/bottom, not left/right) to avoid accidentally swapping your understanding of "rows" and "columns."

45. Wiring and Testing an LED Matrix

  • LED matrices typically have 16 pins total (8 for rows + 8 for columns) — this often exceeds the number of digital pins available on smaller boards (like the Arduino Nano, which has ~13 digital pins), requiring some analog pins to be used as extra digital-style pins.
  • Best practice for brightness/consistency: connect the resistor on the GND/column side rather than the 5V/row side — this produces more consistent and brighter illumination.
  • As with other unknown components, if no datasheet is available, use trial-and-error (light up one LED at a time) to map out which physical pin corresponds to which row/column number, then document it for reference.

46. Drawing Letters and Images (Byte Arrays)

  • Manually calculating which rows/columns to activate for every letter or image would be extremely tedious. Instead:
    • Use an online "LED Matrix Editor" tool to visually draw a letter, number, or simple image (like a smiley face) on a grid.
    • The tool automatically generates the corresponding byte array code (each row represented as a byte, e.g., B01111100, where each bit represents one column's on/off state).
  • Byte/binary notation in code: prefixing a number with B (e.g., B00000000) tells Arduino to interpret the following digits as raw binary rather than a decimal number.
  • Pre-written library-style helper code (provided by the instructor, not manually explained in depth) accepts these byte arrays and a drawScreen(letter) function to display any defined character/image on the matrix.
  • You can define custom byte arrays for your own images (e.g., a smiley face) the same way you would for letters.

47. Animating / Scrolling Text on the Matrix

  • Simply calling drawScreen() for one letter after another inside the main loop() cycles through them far too fast to read, since loop() repeats continuously.

  • Solution: Use a manually incremented counter variable inside nested conditional/while blocks to control how many display cycles each letter is shown for before moving to the next — effectively creating a controllable "custom timer" based on processing speed rather than delay() (since delay() would pause/blank the display entirely, causing visible flicker).

  • Example pattern:

    int counter = 0;
    int delayTime = 200; // controls how long each letter displays, in loop iterations
    
    if (counter <= delayTime) {
      drawScreen(A);
      counter = counter + 1;
    } else if (counter <= delayTime * 2) {
      drawScreen(R);
      counter = counter + 1;
    }
    // ...continue for each letter...
    else {
      counter = 0; // reset to loop the animation
    }
  • Caveat discussed: This approach is tied to the specific board's processing speed — faster boards in the future would cycle through letters faster than intended, so it isn't perfectly "future-proof," but works fine for a hobby/home project.


48. Course Conclusion

  • Completing the course is just the beginning of your Arduino journey — countless components, projects, and problems remain to explore.
  • Encouragement to continue experimenting, check out further courses, and engage with the wider maker community.

End of course notes.