Hands-on Lab
1. What You Will Be Able to Do
By the end of Unit 6, you should be able to:
- Describe the basic operating principles of UART, I2C, and SPI.
- Use the Serial Monitor (UART) for two-way communication with a program.
- Interface an I2C-based module (LCD or sensor) using a library.
2. Why This Unit Matters
Virtually every interesting sensor or display module you’ll ever buy — GPS receivers, temperature/humidity sensors, OLED screens, SD card readers, real-time clock modules — communicates using one of these three protocols. You won’t need to build these protocols from scratch (libraries handle the low-level details), but you do need to recognise which protocol a module uses, wire it correctly, and understand enough about how it works to debug a connection that isn’t responding.
3. Key Concept 1 — UART (Universal Asynchronous Receiver/Transmitter)
UART is the protocol behind the Serial Monitor you’ve already been using since Unit 3. It’s called asynchronous because the sender and receiver don’t share a clock signal — instead, both sides simply agree in advance on a speed (the baud rate) and use that shared timing assumption to know when each bit starts and ends.
3.1 How It’s Wired
UART uses two data wires: TX (transmit) on one device connects to RX (receive) on the other, and vice versa — TX always connects to RX, never TX to TX. This is a point-to-point connection: only two devices can talk on one UART pair at a time.
|
Line / Setting |
Purpose |
|
TX (Transmit) |
Sends data out |
|
RX (Receive) |
Receives incoming data |
|
Baud rate |
Agreed transmission speed (bits per second); must match on both ends |
|
You already know this When you called Serial.begin(9600) back in Unit 3, you were configuring UART. The USB cable to your computer carries this same UART signal, converted to USB by a small chip on your Arduino board. |
4. Key Concept 2 — I2C (Inter-Integrated Circuit)
I2C solves a limitation of UART: what if you want to connect several devices to the microcontroller using just a couple of wires, instead of a dedicated pair for each one? I2C is a two-wire bus that allows multiple devices to share the same two lines.
4.1 How It’s Wired
|
Line |
Purpose |
|
SDA (Serial Data) |
Carries the actual data, shared by all devices on the bus |
|
SCL (Serial Clock) |
Carries a shared timing signal generated by the master, keeping all devices synchronised |
4.2 Master/Slave and Addresses
In an I2C bus, one device (usually your Arduino) acts as the master, initiating all communication. Every other device on the bus is a slave, and each slave has its own unique address (typically a 7-bit number, often written in hexadecimal, like 0x27 for a common LCD backpack). When the master wants to talk to a specific device, it first sends that device’s address on the shared bus — every other device ignores the conversation unless its own address is called.
|
Simple definition to memorise I2C = one shared 2-wire bus (SDA + SCL), many devices, each with its own address so the master knows who it’s talking to. |
Code pattern: scanning for I2C devices
|
#include <Wire.h>
void setup() { Wire.begin(); Serial.begin(9600); for (byte addr = 1; addr < 127; addr++) { Wire.beginTransmission(addr); if (Wire.endTransmission() == 0) { Serial.print(“Found device at 0x”); Serial.println(addr, HEX); } } }
void loop() {} |
This small “I2C scanner” sketch is a genuinely useful debugging tool: if you’re not sure a module is wired correctly, or you don’t know its address, run this first — a correctly wired device will show up in the list.
5. Key Concept 3 — SPI (Serial Peripheral Interface)
SPI trades I2C’s simplicity (fewer wires) for speed. It uses four wires and is commonly used for modules that need to move larger amounts of data quickly, such as SD cards and some displays.
|
Line |
Purpose |
|
MOSI (Master Out, Slave In) |
Carries data from the master to the slave |
|
MISO (Master In, Slave Out) |
Carries data from the slave back to the master |
|
SCK (Serial Clock) |
Shared timing signal generated by the master |
|
SS / CS (Slave Select / Chip Select) |
A dedicated line per slave device, used to say “I’m talking to you specifically” |
Unlike I2C, where devices share the data line and are told apart by address, SPI tells devices apart with a dedicated Chip Select wire per device — this is faster but uses more pins as you add more devices. For this unit, SPI is introduced at a conceptual/demo level only; you’ll mainly work hands-on with UART and I2C.
6. Quick Comparison — Choosing the Right Protocol
|
Aspect |
UART |
I2C |
SPI |
|
Wires needed |
2 (TX, RX) |
2 (SDA, SCL) — shared by all devices |
4+ (MOSI, MISO, SCK, + 1 CS per device) |
|
Devices per bus |
1 (point-to-point) |
Many, told apart by address |
Many, told apart by dedicated CS wire |
|
Speed |
Moderate |
Moderate |
Fast |
|
Typical uses |
Computer/Serial Monitor, GPS modules, Bluetooth modules |
LCD/OLED displays, many sensors (BMP280, RTC modules) |
SD cards, some high-speed displays |
7. What You’ll Need for the Practical Lab
- I2C LCD (16×2) module or OLED display
- Jumper wires
- A sensor or value from Unit 5 (e.g., LDR or potentiometer reading) to display
8. Practical Lab — I2C Display Dashboard
Goal: get a real I2C module talking to your Arduino, understand how a manufacturer’s library hides the low-level protocol details from you, and combine it with a live sensor reading and two-way Serial communication.
8.1 Steps to Follow
- Wire the I2C LCD/OLED module to the microcontroller’s SDA/SCL pins, plus power and ground.
- Install the required display library through the IDE’s Library Manager (your trainer will point you to the correct one for your specific module).
- Run the library’s example sketch first, unmodified, to confirm the display initialises and shows text. If it doesn’t, run the I2C scanner sketch from Section 4.2 to confirm the module is detected and note its address.
- Modify the sketch to display a live sensor reading (e.g., an LDR or potentiometer value from Unit 5), updated once per second.
- Add a second line on the display showing a running counter of how many times the reading has updated.
- While the display is running, use the Serial Monitor to send a text command (e.g., typing ‘reset’ and pressing Enter) that resets the counter shown on the display — this requires reading incoming Serial data with Serial.available() and Serial.readStringUntil(), which your trainer will demonstrate.
8.2 If Something Isn’t Working
- Display shows nothing: run the I2C scanner sketch first — if no device is found, recheck the SDA/SCL wiring and power before touching the code.
- Display shows the wrong address error in code: update the address in your sketch to match what the scanner found — not every module uses the same default address.
- Serial command doesn’t reset the counter: confirm the Serial Monitor’s line ending setting matches what your code expects, and that the baud rate matches Serial.begin().
9. Checkpoint — What to Demonstrate
Your display should correctly show a live-updating sensor value and counter, and respond to at least one command sent through the Serial Monitor.
10. Common Misconceptions to Watch For
|
Misconception |
Correction |
|
“UART, I2C, and SPI are interchangeable — pick whichever.” |
Each module is built to use one specific protocol; you must use whichever one the manufacturer designed the module for, not whichever is most convenient. |
|
“I2C devices need a unique pair of wires each.” |
That’s SPI’s chip-select approach. I2C devices share the same SDA/SCL wires and are distinguished purely by their address. |
|
“If a library exists for a module, I don’t need to understand the protocol.” |
Libraries handle the low-level protocol details, but you still need to understand wiring, addressing, and basic troubleshooting (like running an I2C scanner) when something doesn’t work. |
|
“TX connects to TX.” |
In UART, TX on one device must connect to RX on the other device, and vice versa — connecting TX to TX (or RX to RX) will not work. |
11. Glossary
- UART — a two-wire, asynchronous, point-to-point communication protocol using TX and RX lines and an agreed baud rate.
- Baud rate — the agreed transmission speed, in bits per second, used by both sides of a UART connection.
- I2C — a two-wire bus protocol (SDA + SCL) allowing a master to communicate with multiple addressed slave devices.
- Master / Slave — in I2C, the master initiates all communication; slaves respond only when their address is called.
- Address — a unique identifier (often shown in hexadecimal) that lets an I2C master pick out one specific device on a shared bus.
- SPI — a four-wire (or more) protocol using MOSI, MISO, SCK, and a per-device Chip Select line, favoured for speed.
- Library — pre-written code, usually provided by a module’s manufacturer, that handles the low-level protocol details so you can use simple function calls instead.
12. Self-Check Before Moving to Unit 7
- Can you explain, without notes, the difference between UART, I2C, and SPI in terms of wiring?
- Can you explain how an I2C master tells multiple devices apart on the same two wires?
- Could you use an I2C scanner sketch to troubleshoot a module that isn’t responding?
- Do you understand why TX must connect to RX, not TX to TX?
- Could you look at a new sensor module’s datasheet and identify which protocol it uses, based on its pin labels?
If you answered “no” to any of these, review the relevant section before Unit 7 — you’ll be working with timers and interrupts next, which often work alongside the communication protocols from this unit in real projects.


