Programming IoT with Arduino

Complete IoT Textbook โ€” 10 Chapters

From blinking LEDs to cloud-connected smart systems โ€” master Arduino, sensors, actuators, wireless communication, and IoT cloud platforms in one book.

โฑ๏ธ 50+ hrs total  |  ๐ŸŽฏ Arduino + ESP8266 + Cloud  |  ๐Ÿ’ฐ โ‚น6โ€“20 LPA Embedded/IoT  |  ๐Ÿ–ฅ๏ธ Smart India Hackathon Ready

๐Ÿ’ผ Jobs this unlocks: Embedded Developer (โ‚น6โ€“10 LPA)  |  IoT Engineer (โ‚น8โ€“15 LPA)  |  Firmware Developer (โ‚น10โ€“20 LPA)

Chapter 1

LCD Interfacing with Arduino Uno

๐Ÿ–ฅ๏ธ Every Display Around You Started with an LCD

ATM machines, railway ticket counters, petrol pump meters, weighing scales at kirana shops โ€” they all use LCD displays. The 16ร—2 LCD is like the "sabse pehla output device" for Arduino. Think of it as a TV remote's display โ€” small, simple, but powerful enough to show you what matters.

LCD = Jugaad Display! With just โ‚น80 and 6 wires, you can make Arduino talk to you. By the end of this chapter, you'll display custom messages, scrolling text, and even create your own characters like โค๏ธ on a tiny screen.

๐Ÿ‡ฎ๐Ÿ‡ณ Indian Railways๐Ÿ‡ฎ๐Ÿ‡ณ Petrol Pumps๐Ÿ‡ฎ๐Ÿ‡ณ ATM Machines๐Ÿ‡ฎ๐Ÿ‡ณ Weighing Scales

1.1 LCD Pin Details โ€” All 16 Pins Explained

A standard 16ร—2 LCD module (based on the HD44780 controller) has 16 pins. Understanding each pin is crucial before wiring.

Pin #NameFunction
1VSSGround (0V)
2VDDPower Supply (+5V)
3V0Contrast Adjustment (connect to potentiometer)
4RSRegister Select: 0=Command, 1=Data
5RWRead/Write: 0=Write, 1=Read (usually GND)
6ENEnable: Latches data on falling edge
7D0Data Bit 0 (not used in 4-bit mode)
8D1Data Bit 1 (not used in 4-bit mode)
9D2Data Bit 2 (not used in 4-bit mode)
10D3Data Bit 3 (not used in 4-bit mode)
11D4Data Bit 4
12D5Data Bit 5
13D6Data Bit 6
14D7Data Bit 7
15A (LED+)Backlight Anode (+5V through 220ฮฉ resistor)
16K (LED-)Backlight Cathode (GND)
16x2 LCD Pin Diagram (Front View) โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ H e l l o W o r l d ! โ”‚ โ”‚ โ† Row 0 (16 chars) โ”‚ โ”‚ A r d u i n o I o T โ”‚ โ”‚ โ† Row 1 (16 chars) โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 V V V R R E D D D D D D D D A K S D 0 S W N 0 1 2 3 4 5 6 7 + - S D โ†“ โ†“ โ†“ โ†“ โ†“ โ†“ โ†“ GND 5V POT Used in 4-bit mode

1.2 Interfacing 16ร—2 LCD with Arduino (4-bit Mode)

In 4-bit mode, we only use pins D4โ€“D7, saving 4 Arduino pins. This is the most common wiring method.

Arduino Uno โ†โ†’ 16x2 LCD Wiring (4-bit Mode) ARDUINO UNO 16x2 LCD โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ D12 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ RS (4) โ”‚ โ”‚ D11 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ EN (6) โ”‚ โ”‚ D5 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ D4 (11)โ”‚ โ”‚ D4 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ D5 (12)โ”‚ โ”‚ D3 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ D6 (13)โ”‚ โ”‚ D2 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ D7 (14)โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 5V โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ VDD (2)โ”‚ โ”‚ GND โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ VSS (1)โ”‚ โ”‚ GND โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ RW (5)โ”‚ โ”‚ 5V โ”€โ”€โ”€โ”€โ”ผโ”€โ”€220ฮฉโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ A (15)โ”‚ โ”‚ GND โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ K (16)โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 10kฮฉ POT โ”Œโ”€โ”€โ”€โ”คโ”œโ”€โ”€โ”€โ” 5V โ”€โ”€โ”˜ โ”‚ โ””โ”€โ”€ GND โ”‚ V0 (3)

Connection Table

LCD PinArduino PinPurpose
VSS (1)GNDGround
VDD (2)5VPower
V0 (3)Potentiometer WiperContrast control
RS (4)D12Register Select
RW (5)GNDWrite mode (always)
EN (6)D11Enable pulse
D4 (11)D5Data bit 4
D5 (12)D4Data bit 5
D6 (13)D3Data bit 6
D7 (14)D2Data bit 7
A (15)5V via 220ฮฉBacklight ON
K (16)GNDBacklight GND

1.3 LiquidCrystal Library Functions

FunctionDescriptionExample
LiquidCrystal(rs,en,d4,d5,d6,d7)Constructor โ€” define pinsLiquidCrystal lcd(12,11,5,4,3,2)
lcd.begin(cols, rows)Initialize LCD sizelcd.begin(16, 2)
lcd.print(data)Print text/number at cursorlcd.print("Hello")
lcd.setCursor(col, row)Move cursor (0-indexed)lcd.setCursor(0, 1)
lcd.clear()Clear screen, cursor to 0,0lcd.clear()
lcd.scrollDisplayLeft()Scroll entire display leftUse in loop for marquee
lcd.scrollDisplayRight()Scroll entire display rightReverse marquee
lcd.blink()Blinking block cursorShows cursor position
lcd.noBlink()Stop blinking cursorHide cursor
lcd.createChar(num, data)Create custom 5ร—8 charMax 8 custom chars (0โ€“7)

1.4 Arduino Code โ€” Hello World on LCD

Arduino
// Program: Display "Hello World!" on 16x2 LCD
// Board: Arduino Uno
// Connection: 4-bit mode (RS=12, EN=11, D4=5, D5=4, D6=3, D7=2)

#include <LiquidCrystal.h>

// Initialize LCD: LiquidCrystal(RS, EN, D4, D5, D6, D7)
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  lcd.begin(16, 2);       // Set LCD to 16 columns, 2 rows
  lcd.setCursor(0, 0);    // Move cursor to column 0, row 0
  lcd.print("Hello World!"); // Print on first line
  lcd.setCursor(0, 1);    // Move cursor to second line
  lcd.print("Arduino IoT");  // Print on second line
}

void loop() {
  // Nothing to repeat โ€” static display
}
LCD Display Output: โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚Hello World! โ”‚ โ”‚Arduino IoT โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

1.5 Custom Character Display โ€” createChar()

The LCD can store up to 8 custom characters (numbered 0โ€“7). Each character is a 5ร—8 pixel grid defined by a byte array.

5x8 Pixel Grid for Heart Character (โ™ฅ) Column: 0 1 2 3 4 Row 0: . # . # . โ†’ 0b01010 โ†’ 0x0A Row 1: # # # # # โ†’ 0b11111 โ†’ 0x1F Row 2: # # # # # โ†’ 0b11111 โ†’ 0x1F Row 3: # # # # # โ†’ 0b11111 โ†’ 0x1F Row 4: . # # # . โ†’ 0b01110 โ†’ 0x0E Row 5: . . # . . โ†’ 0b00100 โ†’ 0x04 Row 6: . . . . . โ†’ 0b00000 โ†’ 0x00 Row 7: . . . . . โ†’ 0b00000 โ†’ 0x00
Arduino
// Program: Display custom heart character on LCD
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// Define heart character as byte array
byte heart[8] = {
  0b01010,  // Row 0: .#.#.
  0b11111,  // Row 1: #####
  0b11111,  // Row 2: #####
  0b11111,  // Row 3: #####
  0b01110,  // Row 4: .###.
  0b00100,  // Row 5: ..#..
  0b00000,  // Row 6: .....(blank)
  0b00000   // Row 7: .....(blank)
};

void setup() {
  lcd.begin(16, 2);
  lcd.createChar(0, heart);   // Store heart at position 0
  lcd.setCursor(0, 0);
  lcd.print("I ");
  lcd.write(byte(0));        // Display custom character 0 (heart)
  lcd.print(" Arduino!");
}

void loop() {}

1.6 Worked Examples

Example 1: Display Your Name

Arduino
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
  lcd.begin(16, 2);
  lcd.print("Name: Rahul");
  lcd.setCursor(0, 1);
  lcd.print("Roll: 101");
}
void loop() {}

Example 2: Counter 0โ€“99

Arduino
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() { lcd.begin(16, 2); }
void loop() {
  for (int i = 0; i < 100; i++) {
    lcd.clear();
    lcd.print("Count: ");
    lcd.print(i);
    delay(500);
  }
}

Example 3: Scrolling Marquee

Arduino
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
  lcd.begin(16, 2);
  lcd.print("  Welcome to EduArtha IoT Lab!  ");
}
void loop() {
  lcd.scrollDisplayLeft();  // Shift text left by 1 position
  delay(300);              // Speed of scrolling
}

Example 4: Temperature Display Format

Arduino
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
byte degreeSymbol[8] = {0x06,0x09,0x09,0x06,0x00,0x00,0x00,0x00};
void setup() {
  lcd.begin(16, 2);
  lcd.createChar(0, degreeSymbol);
  lcd.print("Temp: 32");
  lcd.write(byte(0));
  lcd.print("C");
  lcd.setCursor(0, 1);
  lcd.print("Humidity: 65%");
}
void loop() {}

Example 5: Custom Heart + Smiley

Arduino
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
byte heart[8] = {0x00,0x0A,0x1F,0x1F,0x0E,0x04,0x00,0x00};
byte smiley[8] = {0x00,0x0A,0x0A,0x00,0x11,0x0E,0x00,0x00};
void setup() {
  lcd.begin(16, 2);
  lcd.createChar(0, heart);
  lcd.createChar(1, smiley);
  lcd.write(byte(0));
  lcd.print(" I love IoT ");
  lcd.write(byte(1));
}
void loop() {}

Example 6: Blinking Cursor

Arduino
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
  lcd.begin(16, 2);
  lcd.print("Enter PIN:");
  lcd.setCursor(0, 1);
  lcd.blink();  // Show blinking block cursor
}
void loop() {}

Example 7: Two-Line Message

Arduino
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
  lcd.begin(16, 2);
  lcd.setCursor(2, 0);
  lcd.print("Jai Hind!");
  lcd.setCursor(0, 1);
  lcd.print("Bharat Mata Ki");
}
void loop() {}

Example 8: Right-to-Left Scroll

Arduino
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Scrolling Right");
}
void loop() {
  lcd.scrollDisplayRight();
  delay(400);
}

Example 9: Display Analog Reading

Arduino
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
  lcd.begin(16, 2);
}
void loop() {
  int val = analogRead(A0);  // Read pot/sensor on A0
  lcd.clear();
  lcd.print("Analog: ");
  lcd.print(val);              // 0-1023
  lcd.setCursor(0, 1);
  lcd.print("Volts: ");
  lcd.print(val * 5.0 / 1023, 2); // Convert to voltage
  delay(500);
}

Example 10: Simple LCD Menu

Arduino
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int btnPin = 7;
int menu = 0;
void setup() {
  lcd.begin(16, 2);
  pinMode(btnPin, INPUT_PULLUP);
  showMenu();
}
void loop() {
  if (digitalRead(btnPin) == LOW) {
    menu = (menu + 1) % 3;
    showMenu();
    delay(300); // Debounce
  }
}
void showMenu() {
  lcd.clear();
  lcd.print("> Menu Option:");
  lcd.setCursor(0, 1);
  if (menu == 0) lcd.print("1. Read Temp");
  else if (menu == 1) lcd.print("2. Read Light");
  else lcd.print("3. Motor ON");
}
LCD shows blank or garbled text? Most common causes: (1) V0 contrast not adjusted โ€” turn potentiometer slowly. (2) Wrong pin connections โ€” double-check RS, EN, D4-D7. (3) Missing lcd.begin(16,2) in setup. (4) Backlight not connected โ€” check A and K pins.

1.7 MCQs โ€” Chapter 1 (20 Questions)

Q1

How many pins does a standard 16ร—2 LCD module have?

  1. 8
  2. 14
  3. 16
  4. 20
Remember
โœ… Answer: (C) 16 โ€” The standard HD44780-based 16ร—2 LCD has 16 pins including VSS, VDD, V0, RS, RW, EN, D0-D7, A, and K.
Q2

What is the function of pin V0 on the LCD?

  1. Power supply
  2. Contrast adjustment
  3. Data transmission
  4. Backlight control
Remember
โœ… Answer: (B) Contrast adjustment โ€” V0 is connected to a potentiometer to control the display contrast.
Q3

In 4-bit mode, which data pins of the LCD are used?

  1. D0โ€“D3
  2. D4โ€“D7
  3. D0โ€“D7
  4. D2โ€“D5
Remember
โœ… Answer: (B) D4โ€“D7 โ€” In 4-bit mode, only the upper nibble pins (D4-D7) are used, saving 4 Arduino pins.
Q4

What does the RS pin on the LCD control?

  1. Reset the display
  2. Select between command and data mode
  3. Control the refresh speed
  4. Enable the backlight
Understand
โœ… Answer: (B) โ€” RS (Register Select): When LOW, it sends commands (like clear, cursor move). When HIGH, it sends data (characters to display).
Q5

Which function initializes the LCD dimensions?

  1. lcd.init(16,2)
  2. lcd.start(16,2)
  3. lcd.begin(16,2)
  4. lcd.setup(16,2)
Remember
โœ… Answer: (C) lcd.begin(16,2) โ€” This function sets the LCD to 16 columns and 2 rows.
Q6

What is the maximum number of custom characters you can create on a 16ร—2 LCD?

  1. 4
  2. 8
  3. 16
  4. 32
Remember
โœ… Answer: (B) 8 โ€” The HD44780 controller supports 8 custom characters stored at positions 0โ€“7 in CGRAM.
Q7

What is the pixel grid size for each custom character on a 16ร—2 LCD?

  1. 8ร—8
  2. 5ร—7
  3. 5ร—8
  4. 7ร—5
Remember
โœ… Answer: (C) 5ร—8 โ€” Each character cell is 5 pixels wide and 8 pixels tall.
Q8

Why is the RW pin usually connected to GND?

  1. To save power
  2. Because we only write to the LCD, never read from it
  3. It doesn't work otherwise
  4. To increase speed
Understand
โœ… Answer: (B) โ€” In most Arduino projects, we only send data/commands TO the LCD. Tying RW to GND keeps it in write-only mode permanently.
Q9

Which function moves the cursor to column 5, row 1?

  1. lcd.setCursor(1, 5)
  2. lcd.setCursor(5, 1)
  3. lcd.moveTo(5, 1)
  4. lcd.goto(5, 1)
Apply
โœ… Answer: (B) lcd.setCursor(5, 1) โ€” The format is setCursor(column, row), both 0-indexed.
Q10

What happens when you call lcd.clear()?

  1. Only the first line is cleared
  2. The backlight turns off
  3. All text is erased and cursor moves to position (0,0)
  4. The LCD resets completely
Understand
โœ… Answer: (C) โ€” lcd.clear() erases all displayed text and returns the cursor to the top-left corner (0,0).
Q11

How many Arduino digital pins are needed for LCD in 4-bit mode (excluding power)?

  1. 4
  2. 6
  3. 8
  4. 10
Apply
โœ… Answer: (B) 6 โ€” RS, EN, D4, D5, D6, D7 = 6 digital pins.
Q12

What is the purpose of the EN (Enable) pin?

  1. Enables the backlight
  2. Latches data on the falling edge of a pulse
  3. Enables write mode
  4. Enables the power supply
Understand
โœ… Answer: (B) โ€” The Enable pin latches data into the LCD's registers on the falling edge (HIGHโ†’LOW transition) of the enable pulse.
Q13

Which resistor value is typically used with the LCD backlight (pin A)?

  1. 10ฮฉ
  2. 100ฮฉ
  3. 220ฮฉ
  4. 10kฮฉ
Remember
โœ… Answer: (C) 220ฮฉ โ€” A 220ฮฉ current-limiting resistor protects the backlight LED from excessive current.
Q14

Which library is used for basic LCD control in Arduino?

  1. LCD.h
  2. LiquidCrystal.h
  3. Display.h
  4. HD44780.h
Remember
โœ… Answer: (B) LiquidCrystal.h โ€” This is Arduino's built-in library for HD44780-based LCD displays.
Q15

What controller chip does the standard 16ร—2 LCD use?

  1. ATmega328P
  2. HD44780
  3. ESP8266
  4. MAX7219
Remember
โœ… Answer: (B) HD44780 โ€” The Hitachi HD44780 is the standard controller IC for character LCD modules.
Q16

To display the byte stored at custom character position 0, which function is used?

  1. lcd.print(0)
  2. lcd.display(0)
  3. lcd.write(byte(0))
  4. lcd.show(0)
Apply
โœ… Answer: (C) lcd.write(byte(0)) โ€” lcd.write() sends raw bytes, while lcd.print() would print the number "0" as text.
Q17

What does lcd.scrollDisplayLeft() do?

  1. Moves the cursor left
  2. Shifts the entire display content one position to the left
  3. Erases the leftmost character
  4. Rotates the display 90 degrees
Understand
โœ… Answer: (B) โ€” It shifts ALL displayed text one position to the left, creating a scrolling/marquee effect when called repeatedly.
Q18

How many total characters can a 16ร—2 LCD display at once?

  1. 16
  2. 24
  3. 32
  4. 64
Remember
โœ… Answer: (C) 32 โ€” 16 columns ร— 2 rows = 32 characters visible at any time.
Q19

If you want to display text starting from the 3rd column of the 2nd row, which call do you use?

  1. lcd.setCursor(3, 2)
  2. lcd.setCursor(2, 1)
  3. lcd.setCursor(3, 1)
  4. lcd.setCursor(2, 2)
Apply
โœ… Answer: (B) lcd.setCursor(2, 1) โ€” Columns and rows are 0-indexed. 3rd column = index 2, 2nd row = index 1.
Q20

What advantage does 4-bit mode have over 8-bit mode?

  1. Faster data transfer
  2. Uses fewer Arduino pins (6 instead of 10)
  3. Better contrast
  4. Supports more characters
Understand
โœ… Answer: (B) โ€” 4-bit mode uses only 6 digital pins (RS, EN, D4-D7) instead of 10 (RS, EN, D0-D7), freeing 4 pins for other components. Speed difference is negligible.
Chapter 2

LDR, Ultrasonic & IR Sensor Interfacing

๐Ÿ‘๏ธ Sensors = Arduino Ki Aankhein Aur Kaan

Without sensors, Arduino is blind and deaf โ€” it can't sense the world. An LDR detects light (street lights that auto-ON at night), an ultrasonic sensor measures distance (parking sensors in cars), and an IR sensor detects objects (automatic doors at malls). These three sensors are the foundation of every IoT project.

Analogy: Think of sensors as your body's senses โ€” LDR is your eyes (light), ultrasonic is your ears (echo/sonar), IR is your touch (proximity detection).

๐Ÿš— Parking Sensors๐Ÿ  Smart Street Lights๐Ÿšช Auto Doors๐Ÿค– Line Follower Robots

2.1 LDR (Light Dependent Resistor)

An LDR's resistance changes with light: bright light โ†’ low resistance (~1kฮฉ), dark โ†’ high resistance (~10Mฮฉ). We use a voltage divider circuit to convert this resistance change into a voltage that Arduino can read via analogRead().

LDR Voltage Divider Circuit +5V โ”‚ โ”Œโ”ดโ” โ”‚ โ”‚ LDR (resistance varies with light) โ”‚ โ”‚ โ””โ”ฌโ”˜ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Arduino A0 โ”Œโ”ดโ” โ”‚ โ”‚ 10kฮฉ (fixed resistor) โ”‚ โ”‚ โ””โ”ฌโ”˜ โ”‚ GND In DARK: LDR resistance HIGH โ†’ A0 voltage LOW โ†’ analogRead LOW In LIGHT: LDR resistance LOW โ†’ A0 voltage HIGH โ†’ analogRead HIGH

Street Light Automation โ€” Full Code

Arduino
// Program: Automatic Street Light using LDR
// When dark (LDR value < threshold) โ†’ LED ON
// When bright (LDR value >= threshold) โ†’ LED OFF

int ldrPin = A0;     // LDR connected to analog pin A0
int ledPin = 13;     // LED connected to digital pin 13
int threshold = 500; // Adjust based on your environment

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int ldrValue = analogRead(ldrPin);  // Read LDR (0-1023)
  Serial.print("LDR Value: ");
  Serial.println(ldrValue);

  if (ldrValue < threshold) {   // Dark condition
    digitalWrite(ledPin, HIGH); // Turn ON street light
    Serial.println("STATUS: Dark โ†’ LED ON");
  } else {                       // Bright condition
    digitalWrite(ledPin, LOW);  // Turn OFF street light
    Serial.println("STATUS: Bright โ†’ LED OFF");
  }
  delay(500);
}
LDR Value: 234 STATUS: Dark โ†’ LED ON LDR Value: 756 STATUS: Bright โ†’ LED OFF

2.2 Ultrasonic Sensor (HC-SR04)

The HC-SR04 sends an ultrasonic pulse (40kHz) and measures the time it takes for the echo to return. Distance is calculated using: distance = (time ร— 0.034) / 2 (speed of sound โ‰ˆ 340 m/s).

PinFunctionArduino Connection
VCCPower (+5V)5V
TrigTrigger pulse inputD9
EchoEcho pulse outputD10
GNDGroundGND
HC-SR04 Ultrasonic Sensor Circuit ARDUINO UNO HC-SR04 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ 5V โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ VCC โ”‚ โ”‚ D9 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ Trig โ”‚ โ† Send pulse โ”‚ D10 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ Echo โ”‚ โ† Receive echo โ”‚ GND โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ GND โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” Ultrasonic wave: โ”‚ )))) โ†’ OBJECT โ†’ (((( โ”‚ โ”‚ Trig sends Echo receives โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ Distance = (Time ร— 0.034) / 2 cm

Distance Measurement โ€” Full Code

Arduino
// Program: Measure distance using HC-SR04 Ultrasonic Sensor
// Formula: distance = (duration * 0.034) / 2

const int trigPin = 9;   // Trigger pin
const int echoPin = 10;  // Echo pin
long duration;
float distance;

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  Serial.begin(9600);
  Serial.println("HC-SR04 Distance Sensor Ready");
}

void loop() {
  // Step 1: Send 10ยตs trigger pulse
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Step 2: Measure echo pulse duration
  duration = pulseIn(echoPin, HIGH);

  // Step 3: Calculate distance
  distance = (duration * 0.034) / 2;

  // Step 4: Display result
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");
  delay(500);
}
HC-SR04 Distance Sensor Ready Distance: 25.34 cm Distance: 12.67 cm Distance: 5.11 cm

Parking Sensor with Buzzer

Arduino
// Parking sensor: buzzer beeps faster as object gets closer
const int trigPin = 9;
const int echoPin = 10;
const int buzzerPin = 8;
long duration;
float distance;

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(buzzerPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration * 0.034) / 2;

  if (distance < 10) {
    tone(buzzerPin, 1000); // Continuous beep โ€” very close!
  } else if (distance < 30) {
    tone(buzzerPin, 1000, 100); // Short beep
    delay(distance * 10);       // Beep faster when closer
  } else {
    noTone(buzzerPin); // No beep โ€” safe distance
  }
  delay(100);
}

2.3 IR Sensor โ€” Object Detection

An IR sensor module has an IR LED (emitter) and a photodiode (receiver). When an object is close, IR light reflects back and the output goes LOW. It gives a digital output โ€” HIGH (no object) or LOW (object detected).

IR Sensor Module Circuit ARDUINO UNO IR SENSOR MODULE โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ 5V โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ VCC โ”‚ โ”‚ D7 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ OUT (Signal)โ”‚ โ”‚ GND โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ GND โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ Object Present: IR reflects โ†’ OUT = LOW (0) No Object: IR passes โ†’ OUT = HIGH (1)
Arduino
// Program: Object detection using IR Sensor
int irPin = 7;
int ledPin = 13;

void setup() {
  pinMode(irPin, INPUT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int irValue = digitalRead(irPin);
  if (irValue == LOW) {  // Object detected
    digitalWrite(ledPin, HIGH);
    Serial.println("Object Detected!");
  } else {
    digitalWrite(ledPin, LOW);
    Serial.println("No Object");
  }
  delay(200);
}
Indian traffic lights use IR sensors for vehicle detection at signals. Many Smart City projects under the Indian government's Smart Cities Mission use ultrasonic + IR sensor combinations for traffic management and smart parking systems.

2.4 Worked Examples

Example 1: LDR with LED brightness (PWM)

Arduino
int ldrPin = A0;
int ledPin = 9; // PWM pin
void setup() { pinMode(ledPin, OUTPUT); }
void loop() {
  int val = analogRead(ldrPin);
  int brightness = map(val, 0, 1023, 255, 0); // Dark=bright LED
  analogWrite(ledPin, brightness);
  delay(100);
}

Example 2: Ultrasonic + LCD display

Arduino
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int trig = 9, echo = 10;
void setup() { lcd.begin(16,2); pinMode(trig,OUTPUT); pinMode(echo,INPUT); }
void loop() {
  digitalWrite(trig,LOW); delayMicroseconds(2);
  digitalWrite(trig,HIGH); delayMicroseconds(10);
  digitalWrite(trig,LOW);
  float d = (pulseIn(echo,HIGH) * 0.034) / 2;
  lcd.clear(); lcd.print("Distance:");
  lcd.setCursor(0,1); lcd.print(d); lcd.print(" cm");
  delay(300);
}

Example 3: IR counter (count objects passing)

Arduino
int irPin = 7;
int count = 0;
bool lastState = HIGH;
void setup() { pinMode(irPin,INPUT); Serial.begin(9600); }
void loop() {
  bool curr = digitalRead(irPin);
  if (lastState == HIGH && curr == LOW) {
    count++;
    Serial.print("Count: "); Serial.println(count);
  }
  lastState = curr;
  delay(50);
}

Example 4: Multi-zone parking (3 ultrasonic sensors)

Arduino
int trig[] = {2, 4, 6};
int echo[] = {3, 5, 7};
void setup() {
  Serial.begin(9600);
  for(int i=0;i<3;i++) { pinMode(trig[i],OUTPUT); pinMode(echo[i],INPUT); }
}
float getDistance(int t, int e) {
  digitalWrite(t,LOW); delayMicroseconds(2);
  digitalWrite(t,HIGH); delayMicroseconds(10);
  digitalWrite(t,LOW);
  return (pulseIn(e,HIGH) * 0.034) / 2;
}
void loop() {
  for(int i=0;i<3;i++) {
    float d = getDistance(trig[i],echo[i]);
    Serial.print("Zone "); Serial.print(i+1);
    Serial.print(": "); Serial.print(d);
    Serial.println(d<20 ? " OCCUPIED" : " EMPTY");
  }
  Serial.println("---"); delay(1000);
}

Example 5: LDR night lamp with Serial plotter

Arduino
void setup() { Serial.begin(9600); }
void loop() {
  Serial.println(analogRead(A0)); // Open Serial Plotter to see graph
  delay(100);
}

Example 6: Ultrasonic + RGB LED (distance โ†’ color)

Arduino
const int trig=9, echo=10, redPin=3, greenPin=5, bluePin=6;
void setup() {
  pinMode(trig,OUTPUT); pinMode(echo,INPUT);
  pinMode(redPin,OUTPUT); pinMode(greenPin,OUTPUT); pinMode(bluePin,OUTPUT);
}
void loop() {
  digitalWrite(trig,LOW); delayMicroseconds(2);
  digitalWrite(trig,HIGH); delayMicroseconds(10);
  digitalWrite(trig,LOW);
  float d = (pulseIn(echo,HIGH)*0.034)/2;
  if(d<10){analogWrite(redPin,255);analogWrite(greenPin,0);analogWrite(bluePin,0);}
  else if(d<30){analogWrite(redPin,255);analogWrite(greenPin,255);analogWrite(bluePin,0);}
  else{analogWrite(redPin,0);analogWrite(greenPin,255);analogWrite(bluePin,0);}
  delay(200);
}

Example 7: IR-based line follower (2 sensors)

Arduino
int leftIR = 6, rightIR = 7;
int motorL = 9, motorR = 10;
void setup() {
  pinMode(leftIR,INPUT); pinMode(rightIR,INPUT);
  pinMode(motorL,OUTPUT); pinMode(motorR,OUTPUT);
}
void loop() {
  int L = digitalRead(leftIR), R = digitalRead(rightIR);
  if(L==LOW && R==LOW) { analogWrite(motorL,200); analogWrite(motorR,200); } // Forward
  else if(L==LOW) { analogWrite(motorL,0); analogWrite(motorR,200); } // Turn left
  else if(R==LOW) { analogWrite(motorL,200); analogWrite(motorR,0); } // Turn right
  else { analogWrite(motorL,0); analogWrite(motorR,0); } // Stop
}

Example 8: LDR alarm (buzzer when too dark)

Arduino
void setup() { pinMode(8,OUTPUT); }
void loop() {
  if(analogRead(A0) < 200) tone(8,1000); else noTone(8);
  delay(100);
}

Example 9: Ultrasonic water level monitor

Arduino
const int trig=9,echo=10;
const float tankHeight = 30.0; // cm
void setup() { pinMode(trig,OUTPUT); pinMode(echo,INPUT); Serial.begin(9600); }
void loop() {
  digitalWrite(trig,LOW); delayMicroseconds(2);
  digitalWrite(trig,HIGH); delayMicroseconds(10);
  digitalWrite(trig,LOW);
  float d = (pulseIn(echo,HIGH)*0.034)/2;
  float level = tankHeight - d;
  float pct = (level/tankHeight)*100;
  Serial.print("Water Level: "); Serial.print(pct); Serial.println("%");
  delay(1000);
}

Example 10: Combined sensor dashboard (LDR+Ultrasonic+IR on Serial)

Arduino
const int trig=9,echo=10,irPin=7;
void setup() {
  pinMode(trig,OUTPUT);pinMode(echo,INPUT);pinMode(irPin,INPUT);
  Serial.begin(9600);
  Serial.println("=== IoT Sensor Dashboard ===");
}
void loop() {
  int ldr = analogRead(A0);
  digitalWrite(trig,LOW);delayMicroseconds(2);
  digitalWrite(trig,HIGH);delayMicroseconds(10);
  digitalWrite(trig,LOW);
  float dist = (pulseIn(echo,HIGH)*0.034)/2;
  int ir = digitalRead(irPin);
  Serial.print("Light:"); Serial.print(ldr);
  Serial.print(" | Dist:"); Serial.print(dist);
  Serial.print("cm | Object:"); Serial.println(ir==LOW?"YES":"NO");
  delay(500);
}
Ultrasonic reads 0 cm? Check: (1) Trig and Echo pins not swapped. (2) Object too close (<2cm) or too far (>400cm). (3) Missing 10ยตs trigger pulse. (4) Object surface is too soft/angled (absorbs sound).

2.5 MCQs โ€” Chapter 2 (20 Questions)

Q1

What happens to LDR resistance in darkness?

  1. Decreases
  2. Increases
  3. Stays same
  4. Becomes zero
Remember
โœ… Answer: (B) โ€” In darkness, LDR resistance increases to ~10Mฮฉ.
Q2

Which Arduino function reads analog voltage?

  1. digitalRead()
  2. analogRead()
  3. voltageRead()
  4. sensorRead()
Remember
โœ… Answer: (B) analogRead() โ€” Returns a value 0โ€“1023 representing 0โ€“5V.
Q3

The HC-SR04 ultrasonic sensor operates at what frequency?

  1. 20 kHz
  2. 40 kHz
  3. 100 kHz
  4. 1 MHz
Remember
โœ… Answer: (B) 40 kHz โ€” This is in the ultrasonic range, above human hearing.
Q4

What is the formula for distance using HC-SR04?

  1. distance = time ร— 340
  2. distance = (time ร— 0.034) / 2
  3. distance = time / 340
  4. distance = time ร— 0.034
Understand
โœ… Answer: (B) โ€” We divide by 2 because the sound travels TO the object AND back. Speed of sound โ‰ˆ 0.034 cm/ยตs.
Q5

What does pulseIn(echoPin, HIGH) return?

  1. Voltage in volts
  2. Time in microseconds the pin was HIGH
  3. Distance in cm
  4. Frequency in Hz
Understand
โœ… Answer: (B) โ€” pulseIn() measures the duration (in ยตs) that the specified pin is at the given state (HIGH).
Q6

What is the range of HC-SR04 sensor?

  1. 0โ€“10 cm
  2. 2โ€“400 cm
  3. 1โ€“1000 cm
  4. 10โ€“200 cm
Remember
โœ… Answer: (B) 2โ€“400 cm โ€” Objects closer than 2cm or farther than 400cm give unreliable readings.
Q7

An IR sensor output is LOW when:

  1. No object is present
  2. An object is detected
  3. Power is off
  4. Sensor is broken
Remember
โœ… Answer: (B) โ€” Most IR modules output LOW (active low) when an object reflects IR light back.
Q8

In an LDR voltage divider, the fixed resistor is typically:

  1. 100ฮฉ
  2. 1kฮฉ
  3. 10kฮฉ
  4. 1Mฮฉ
Remember
โœ… Answer: (C) 10kฮฉ โ€” This value gives a good range of voltage variation for the LDR's typical resistance range.
Q9

analogRead() returns a value in the range:

  1. 0โ€“255
  2. 0โ€“1023
  3. 0โ€“4095
  4. 0โ€“65535
Remember
โœ… Answer: (B) 0โ€“1023 โ€” Arduino Uno has a 10-bit ADC (2^10 = 1024 levels).
Q10

Which trigger pulse duration is needed for HC-SR04?

  1. 2 ยตs
  2. 10 ยตs
  3. 100 ยตs
  4. 1 ms
Remember
โœ… Answer: (B) 10 ยตs โ€” The trigger pin must be held HIGH for at least 10 microseconds to initiate measurement.
Q11

What type of output does an IR obstacle sensor give?

  1. Analog
  2. Digital
  3. PWM
  4. Serial
Remember
โœ… Answer: (B) Digital โ€” IR obstacle sensors output HIGH or LOW only.
Q12

map(val, 0, 1023, 0, 255) converts analog reading to:

  1. Voltage
  2. PWM duty cycle range
  3. Temperature
  4. Distance
Understand
โœ… Answer: (B) โ€” The map() function scales the 10-bit ADC range (0โ€“1023) to 8-bit PWM range (0โ€“255).
Q13

Speed of sound used in ultrasonic calculation is approximately:

  1. 340 m/s
  2. 3400 m/s
  3. 34 m/s
  4. 34000 m/s
Remember
โœ… Answer: (A) 340 m/s โ€” At room temperature, sound travels at approximately 340 meters per second in air.
Q14

Which application uses LDR sensors in India?

  1. Automatic street lights
  2. Motor speed control
  3. Temperature measurement
  4. RFID reading
Understand
โœ… Answer: (A) โ€” Automatic street lights that turn ON at dusk and OFF at dawn use LDRs for light detection.
Q15

How many pins does the HC-SR04 module have?

  1. 2
  2. 3
  3. 4
  4. 6
Remember
โœ… Answer: (C) 4 โ€” VCC, Trig, Echo, GND.
Q16

For a line follower robot, which sensor is used?

  1. LDR
  2. Ultrasonic
  3. IR sensor
  4. Temperature sensor
Understand
โœ… Answer: (C) โ€” IR sensors detect the contrast between black line and white surface for line following.
Q17

What is the ADC resolution of Arduino Uno?

  1. 8-bit
  2. 10-bit
  3. 12-bit
  4. 16-bit
Remember
โœ… Answer: (B) 10-bit โ€” Provides 1024 discrete levels (0โ€“1023).
Q18

Which function generates a square wave on a pin for a buzzer?

  1. analogWrite()
  2. tone()
  3. buzz()
  4. sound()
Remember
โœ… Answer: (B) tone() โ€” tone(pin, frequency) generates a square wave at the specified frequency.
Q19

Why do we divide the ultrasonic time by 2?

  1. To convert units
  2. Sound travels to object and back (round trip)
  3. Sensor has 2 pins
  4. Arduino clock is 2x faster
Understand
โœ… Answer: (B) โ€” The measured duration is the round-trip time (to object + back), so we halve it for one-way distance.
Q20

What component is paired with LDR in a voltage divider?

  1. Capacitor
  2. LED
  3. Fixed resistor
  4. Transistor
Understand
โœ… Answer: (C) โ€” A fixed resistor creates a voltage divider with the LDR, producing a variable voltage at the junction that Arduino reads.
Chapter 3

Temperature & Humidity Sensor (DHT22)

๐ŸŒก๏ธ Weather Station Banaao โ€” Apne Room Ka Mausam Jaano!

India's weather is extreme โ€” from Rajasthan's 50ยฐC summers to Kashmir's -10ยฐC winters. A single โ‚น250 sensor can tell you the exact temperature and humidity of any room. Build your own weather station, greenhouse monitor, or server room alert system!

Analogy: DHT22 = Your room ka personal mausam vibhaag (weather department)!

3.1 DHT22 Module Specifications

ParameterDHT22 (AM2302)DHT11 (for comparison)
Temperature Range-40ยฐC to +80ยฐC0ยฐC to +50ยฐC
Temperature Accuracyยฑ0.5ยฐCยฑ2ยฐC
Humidity Range0โ€“100% RH20โ€“80% RH
Humidity Accuracyยฑ2% RHยฑ5% RH
Sampling RateEvery 2 secondsEvery 1 second
Operating Voltage3.3V โ€“ 5V3.3V โ€“ 5V
Pins3 (VCC, DATA, GND)3 (VCC, DATA, GND)
Price (India)โ‚น200โ€“300โ‚น80โ€“120
DHT22 Pin Diagram (Front View) โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ DHT22 โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ Sensor โ”‚ โ”‚ โ”‚ โ”‚ Grid โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ””โ”€โ”€โ”ฌโ”€โ”€โ”ฌโ”€โ”€โ”ฌโ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ 1 2 3 VCC DATA GND (+) (S) (-) Pin 1 (VCC) โ†’ Arduino 5V Pin 2 (DATA) โ†’ Arduino D2 (with 10kฮฉ pull-up to VCC) Pin 3 (GND) โ†’ Arduino GND
DHT22 โ†’ Arduino Circuit ARDUINO UNO DHT22 MODULE โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 5V โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ VCC (1)โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”ดโ”€โ” โ”‚ โ”‚ โ”‚ โ”‚ โ”‚10kโ”‚ Pull-up โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”ฌโ”€โ”˜ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ D2 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ DATA(2)โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ GND โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ GND (3)โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

3.2 DHT Library Installation

  1. Open Arduino IDE โ†’ Sketch โ†’ Include Library โ†’ Manage Libraries
  2. Search for "DHT sensor library" by Adafruit
  3. Click Install (also install "Adafruit Unified Sensor" if prompted)

3.3 Basic DHT22 Code โ€” Read Temperature & Humidity

Arduino
// Program: Read Temperature and Humidity from DHT22
// Board: Arduino Uno | Sensor: DHT22 on pin D2

#include <DHT.h>

#define DHTPIN 2       // DHT22 data pin connected to D2
#define DHTTYPE DHT22  // Sensor type: DHT22

DHT dht(DHTPIN, DHTTYPE); // Create DHT object

void setup() {
  Serial.begin(9600);
  dht.begin();  // Initialize DHT sensor
  Serial.println("DHT22 Weather Station Ready!");
  Serial.println("==========================");
}

void loop() {
  delay(2000);  // DHT22 needs 2 sec between readings

  float humidity = dht.readHumidity();
  float tempC = dht.readTemperature();       // Celsius
  float tempF = dht.readTemperature(true);  // Fahrenheit

  // Check if reading failed
  if (isnan(humidity) || isnan(tempC)) {
    Serial.println("ERROR: Failed to read DHT22!");
    return;
  }

  // Calculate heat index
  float heatIndex = dht.computeHeatIndex(tempC, humidity, false);

  Serial.print("Temperature: ");
  Serial.print(tempC);
  Serial.print("ยฐC (");
  Serial.print(tempF);
  Serial.println("ยฐF)");
  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.println("%");
  Serial.print("Heat Index: ");
  Serial.print(heatIndex);
  Serial.println("ยฐC");
  Serial.println("---");
}
DHT22 Weather Station Ready! ========================== Temperature: 28.50ยฐC (83.30ยฐF) Humidity: 65.20% Heat Index: 30.14ยฐC --- Temperature: 28.60ยฐC (83.48ยฐF) Humidity: 64.80% Heat Index: 30.22ยฐC ---

3.4 Weather Station Project โ€” DHT22 + LCD

Arduino
// Weather Station: DHT22 + 16x2 LCD Display
#include <DHT.h>
#include <LiquidCrystal.h>

#define DHTPIN 2
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal lcd(12, 11, 5, 4, 3, 8); // Changed D2โ†’D8 (D2 used by DHT)

byte degreeChar[8] = {0x06,0x09,0x09,0x06,0x00,0x00,0x00,0x00};

void setup() {
  lcd.begin(16, 2);
  lcd.createChar(0, degreeChar);
  dht.begin();
  lcd.print("Weather Station");
  lcd.setCursor(0, 1);
  lcd.print("Initializing...");
  delay(2000);
}

void loop() {
  float t = dht.readTemperature();
  float h = dht.readHumidity();

  if (isnan(t) || isnan(h)) {
    lcd.clear(); lcd.print("Sensor Error!");
    delay(2000); return;
  }

  lcd.clear();
  lcd.print("Temp: ");
  lcd.print(t, 1);
  lcd.write(byte(0));
  lcd.print("C");
  lcd.setCursor(0, 1);
  lcd.print("Humid: ");
  lcd.print(h, 1);
  lcd.print("%");
  delay(2000);
}

3.5 Worked Examples

Example 1: Temperature alert (buzzer when >35ยฐC)

Arduino
#include <DHT.h>
DHT dht(2, DHT22);
void setup() { dht.begin(); pinMode(8,OUTPUT); Serial.begin(9600); }
void loop() {
  delay(2000);
  float t = dht.readTemperature();
  if(t > 35.0) { tone(8,1000); Serial.println("HOT ALERT!"); }
  else { noTone(8); Serial.print("Temp: "); Serial.println(t); }
}

Example 2: Humidity-based fan control

Arduino
#include <DHT.h>
DHT dht(2, DHT22);
int fanPin = 9;
void setup() { dht.begin(); pinMode(fanPin,OUTPUT); }
void loop() {
  delay(2000);
  float h = dht.readHumidity();
  if(h > 70) digitalWrite(fanPin,HIGH); else digitalWrite(fanPin,LOW);
}

Example 3: Min/Max temperature logger

Arduino
#include <DHT.h>
DHT dht(2, DHT22);
float minT=100, maxT=-100;
void setup() { dht.begin(); Serial.begin(9600); }
void loop() {
  delay(2000);
  float t = dht.readTemperature();
  if(t<minT) minT=t; if(t>maxT) maxT=t;
  Serial.print("Now:"); Serial.print(t);
  Serial.print(" Min:"); Serial.print(minT);
  Serial.print(" Max:"); Serial.println(maxT);
}

Example 4: Comfort index indicator (LED colors)

Arduino
#include <DHT.h>
DHT dht(2, DHT22);
int red=3,green=5,blue=6;
void setup() { dht.begin(); pinMode(red,OUTPUT); pinMode(green,OUTPUT); pinMode(blue,OUTPUT); }
void loop() {
  delay(2000);
  float t = dht.readTemperature();
  if(t<20) { digitalWrite(blue,HIGH); digitalWrite(green,LOW); digitalWrite(red,LOW); } // Cold
  else if(t<30) { digitalWrite(blue,LOW); digitalWrite(green,HIGH); digitalWrite(red,LOW); } // Comfortable
  else { digitalWrite(blue,LOW); digitalWrite(green,LOW); digitalWrite(red,HIGH); } // Hot
}

Example 5: Data logger to Serial (CSV format)

Arduino
#include <DHT.h>
DHT dht(2, DHT22);
unsigned long reading = 0;
void setup() { dht.begin(); Serial.begin(9600); Serial.println("Reading,Temp_C,Humidity_%"); }
void loop() {
  delay(5000); reading++;
  Serial.print(reading); Serial.print(",");
  Serial.print(dht.readTemperature()); Serial.print(",");
  Serial.println(dht.readHumidity());
}

Example 6: Dew point calculation

Arduino
#include <DHT.h>
DHT dht(2, DHT22);
void setup() { dht.begin(); Serial.begin(9600); }
void loop() {
  delay(2000);
  float t=dht.readTemperature(), h=dht.readHumidity();
  float dp = t - ((100-h)/5.0); // Simplified dew point
  Serial.print("Dew Point: "); Serial.print(dp); Serial.println("ยฐC");
}

Example 7: Greenhouse monitor (temp + humidity thresholds)

Arduino
#include <DHT.h>
DHT dht(2, DHT22);
int pumpPin=7, ventPin=8;
void setup() { dht.begin(); pinMode(pumpPin,OUTPUT); pinMode(ventPin,OUTPUT); Serial.begin(9600); }
void loop() {
  delay(2000);
  float t=dht.readTemperature(), h=dht.readHumidity();
  Serial.print("T:"); Serial.print(t); Serial.print(" H:"); Serial.println(h);
  if(h<40) digitalWrite(pumpPin,HIGH); else digitalWrite(pumpPin,LOW); // Irrigate
  if(t>35) digitalWrite(ventPin,HIGH); else digitalWrite(ventPin,LOW); // Ventilate
}

Example 8: Moving average temperature (smoothing)

Arduino
#include <DHT.h>
DHT dht(2, DHT22);
float readings[5]; int idx=0;
void setup() { dht.begin(); Serial.begin(9600); }
void loop() {
  delay(2000);
  readings[idx] = dht.readTemperature();
  idx = (idx+1) % 5;
  float avg = 0;
  for(int i=0;i<5;i++) avg += readings[i];
  avg /= 5;
  Serial.print("Avg Temp: "); Serial.println(avg);
}

Example 9: Heat index warning system

Arduino
#include <DHT.h>
DHT dht(2, DHT22);
void setup() { dht.begin(); Serial.begin(9600); }
void loop() {
  delay(2000);
  float t=dht.readTemperature(), h=dht.readHumidity();
  float hi = dht.computeHeatIndex(t, h, false);
  Serial.print("Heat Index: "); Serial.print(hi);
  if(hi>40) Serial.println(" DANGER!");
  else if(hi>32) Serial.println(" Caution");
  else Serial.println(" Normal");
}

Example 10: Temp + humidity on Serial Plotter

Arduino
#include <DHT.h>
DHT dht(2, DHT22);
void setup() { dht.begin(); Serial.begin(9600); }
void loop() {
  delay(2000);
  Serial.print(dht.readTemperature());
  Serial.print("\t"); // Tab separator for Serial Plotter
  Serial.println(dht.readHumidity());
}
DHT22 reads NaN or fails? Common fixes: (1) Add 10kฮฉ pull-up resistor between DATA and VCC. (2) Wait at least 2 seconds between readings. (3) Use correct DHTTYPE โ€” DHT22 not DHT11. (4) Check wiring โ€” DATA pin must go to the correct Arduino pin.

3.6 MCQs โ€” Chapter 3 (20 Questions)

Q1

What is the temperature accuracy of DHT22?

  1. ยฑ1ยฐC
  2. ยฑ0.5ยฐC
  3. ยฑ2ยฐC
  4. ยฑ0.1ยฐC
Remember
โœ… Answer: (B) ยฑ0.5ยฐC โ€” DHT22 is more accurate than DHT11 (ยฑ2ยฐC).
Q2

What is the minimum delay between DHT22 readings?

  1. 100 ms
  2. 500 ms
  3. 1 second
  4. 2 seconds
Remember
โœ… Answer: (D) 2 seconds โ€” DHT22 has a sampling rate of 0.5 Hz (one reading every 2 seconds).
Q3

Which pull-up resistor is used with DHT22 data line?

  1. 220ฮฉ
  2. 1kฮฉ
  3. 10kฮฉ
  4. 100kฮฉ
Remember
โœ… Answer: (C) 10kฮฉ โ€” A 10kฮฉ pull-up resistor between VCC and DATA pin ensures reliable communication.
Q4

What does isnan() check in the DHT code?

  1. If the value is zero
  2. If the value is negative
  3. If the reading failed (Not a Number)
  4. If the sensor is disconnected
Understand
โœ… Answer: (C) โ€” isnan() checks if the value is "Not a Number", which happens when the sensor fails to communicate properly.
Q5

DHT22 uses which communication protocol?

  1. I2C
  2. SPI
  3. UART
  4. Single-wire (proprietary)
Remember
โœ… Answer: (D) โ€” DHT22 uses a proprietary single-wire digital protocol on the DATA pin.
Q6

What is the humidity range of DHT22?

  1. 20โ€“80%
  2. 0โ€“100%
  3. 10โ€“90%
  4. 30โ€“70%
Remember
โœ… Answer: (B) 0โ€“100% RH โ€” DHT22 covers the full humidity range.
Q7

Which library is used for DHT sensors in Arduino?

  1. Wire.h
  2. DHT.h
  3. Sensor.h
  4. Temperature.h
Remember
โœ… Answer: (B) DHT.h โ€” The Adafruit DHT sensor library provides easy-to-use functions.
Q8

dht.readTemperature(true) returns temperature in:

  1. Celsius
  2. Fahrenheit
  3. Kelvin
  4. Raw ADC value
Understand
โœ… Answer: (B) Fahrenheit โ€” Passing true as parameter switches from Celsius (default) to Fahrenheit.
Q9

How many pins does the DHT22 module have?

  1. 2
  2. 3
  3. 4
  4. 6
Remember
โœ… Answer: (B) 3 โ€” VCC, DATA, and GND (some breakout boards may show 4 pins with one unused).
Q10

What does heat index represent?

  1. Actual temperature
  2. Wind chill factor
  3. How hot it feels considering humidity
  4. Maximum temperature
Understand
โœ… Answer: (C) โ€” Heat index combines temperature and humidity to represent the "feels like" temperature for the human body.
Q11

What voltage does DHT22 operate on?

  1. 1.8V only
  2. 3.3V only
  3. 5V only
  4. 3.3V to 5V
Remember
โœ… Answer: (D) 3.3V to 5V โ€” Compatible with both 3.3V and 5V logic levels.
Q12

Which is more accurate: DHT11 or DHT22?

  1. DHT11
  2. DHT22
  3. Both same
  4. Depends on temperature
Understand
โœ… Answer: (B) DHT22 โ€” ยฑ0.5ยฐC vs ยฑ2ยฐC for temperature, ยฑ2% vs ยฑ5% for humidity.
Q13

What does dht.begin() do?

  1. Reads temperature
  2. Initializes the sensor
  3. Calibrates the sensor
  4. Resets the sensor
Understand
โœ… Answer: (B) โ€” dht.begin() initializes the sensor, setting up the data pin and communication timing.
Q14

Temperature range of DHT22 is:

  1. 0ยฐC to 50ยฐC
  2. -40ยฐC to 80ยฐC
  3. -20ยฐC to 60ยฐC
  4. -10ยฐC to 100ยฐC
Remember
โœ… Answer: (B) -40ยฐC to +80ยฐC โ€” Wide range suitable for most applications.
Q15

Which function computes heat index in the DHT library?

  1. dht.heatIndex()
  2. dht.computeHeatIndex()
  3. dht.getHI()
  4. dht.feelTemp()
Remember
โœ… Answer: (B) dht.computeHeatIndex(temp, humidity, isFahrenheit).
Q16

What type of sensor element does DHT22 use?

  1. Thermistor + capacitive humidity sensor
  2. Thermocouple + resistive humidity sensor
  3. RTD + piezoelectric sensor
  4. Infrared sensor
Understand
โœ… Answer: (A) โ€” DHT22 uses an NTC thermistor for temperature and a capacitive humidity sensor.
Q17

If DHT22 reads NaN, the most likely cause is:

  1. Wrong voltage
  2. Missing pull-up resistor or wiring error
  3. Too much humidity
  4. Arduino is too fast
Apply
โœ… Answer: (B) โ€” NaN readings typically indicate communication failure due to missing pull-up resistor, incorrect wiring, or wrong pin assignment.
Q18

In the weather station project, why do we use D8 instead of D2 for LCD?

  1. D2 is faster
  2. D2 is used by DHT22 sensor
  3. D8 has better resolution
  4. No reason
Apply
โœ… Answer: (B) โ€” D2 is already used for the DHT22 data pin, so we assign a different pin (D8) for the LCD.
Q19

What does RH stand for in humidity measurement?

  1. Relative Humidity
  2. Real Humidity
  3. Ratio Humidity
  4. Recorded Humidity
Remember
โœ… Answer: (A) Relative Humidity โ€” The percentage of water vapor in air relative to the maximum at that temperature.
Q20

For a greenhouse, ideal humidity is maintained by:

  1. Increasing temperature
  2. Using fans and irrigation based on DHT readings
  3. Closing all windows
  4. Adding more sensors
Apply
โœ… Answer: (B) โ€” Automated greenhouse systems use DHT sensor readings to trigger irrigation (low humidity) and ventilation (high temperature).
Chapter 4

DC Motors with L298N Motor Driver

๐ŸŽ๏ธ Robot Car Banana Hai? L298N Se Shuru Karo!

Every robot, drone, and automated factory machine uses motors. The L298N is the most popular motor driver for Arduino โ€” it can control 2 DC motors simultaneously with speed and direction control. From line-following robots to automated curtain openers, this is your gateway to motion!

Analogy: Arduino is the brain, L298N is the muscle. Brain decides direction, muscle provides power!

4.1 L298N Specifications

ParameterValue
Driver TypeDual H-Bridge
Motor Supply Voltage5V โ€“ 35V
Logic Voltage5V
Max Current per Channel2A
Control PinsENA, IN1, IN2, IN3, IN4, ENB
Output PinsOUT1, OUT2, OUT3, OUT4
L298N Motor Driver Pin Layout โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ L298N MODULE โ”‚ โ”‚ โ”‚ OUT1 โ”€โ”ค [Motor A+] [Motor B+] โ”œโ”€ OUT3 OUT2 โ”€โ”ค [Motor A-] [Motor B-] โ”œโ”€ OUT4 โ”‚ โ”‚ +12Vโ”€โ”ค Motor Power Logic 5V โ”œโ”€ +5V (output) GND โ”€โ”ค Ground โ”‚ โ”‚ โ”‚ ENA โ”€โ”ค Enable A (PWM for speed) โ”‚ IN1 โ”€โ”ค Input 1 (Direction A) โ”‚ IN2 โ”€โ”ค Input 2 (Direction A) โ”‚ IN3 โ”€โ”ค Input 3 (Direction B) โ”‚ IN4 โ”€โ”ค Input 4 (Direction B) โ”‚ ENB โ”€โ”ค Enable B (PWM for speed) โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

4.2 H-Bridge Working Principle

H-Bridge: How Motor Direction is Controlled FORWARD: REVERSE: +V โ”€โ”€โ” โ”Œโ”€โ”€ +V +V โ”€โ”€โ” โ”Œโ”€โ”€ +V โ”‚ โ”‚ โ”‚ โ”‚ [S1] [S2] (S1=ON,S4=ON) [S1] [S2] (S2=ON,S3=ON) โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€Mโ”€โ”€โ”ค Current โ†’ โ”œโ”€โ”€Mโ”€โ”€โ”ค โ† Current โ”‚ โ”‚ โ”‚ โ”‚ [S3] [S4] [S3] [S4] โ”‚ โ”‚ โ”‚ โ”‚ GND GND GND GND

Direction Control Truth Table

IN1IN2Motor Action
HIGHLOWForward (clockwise)
LOWHIGHReverse (counter-clockwise)
LOWLOWCoast (free spin)
HIGHHIGHBrake (hard stop)

Connection Table

L298N PinArduino PinPurpose
ENAD9 (PWM)Motor A speed control
IN1D8Motor A direction
IN2D7Motor A direction
IN3D6Motor B direction
IN4D5Motor B direction
ENBD3 (PWM)Motor B speed control
+12VExternal 9-12V batteryMotor power
GNDCommon GND (Arduino + Battery)Ground

4.3 Single Motor Control Code

Arduino
// Program: Control single DC motor with L298N
int ENA = 9;   // PWM pin for speed
int IN1 = 8;   // Direction pin 1
int IN2 = 7;   // Direction pin 2

void setup() {
  pinMode(ENA, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
}

void loop() {
  // Forward at full speed
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  analogWrite(ENA, 255);  // Full speed
  delay(2000);

  // Stop
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  delay(1000);

  // Reverse at half speed
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  analogWrite(ENA, 128);  // Half speed
  delay(2000);

  // Stop
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  delay(1000);
}

4.4 Robot Car Code (2 Motors)

Arduino
// Robot Car: Forward, Backward, Left, Right
int ENA=9,IN1=8,IN2=7,IN3=6,IN4=5,ENB=3;
int speed = 200;

void setup() {
  int pins[] = {ENA,IN1,IN2,IN3,IN4,ENB};
  for(int i=0;i<6;i++) pinMode(pins[i],OUTPUT);
}

void forward() {
  digitalWrite(IN1,HIGH); digitalWrite(IN2,LOW);
  digitalWrite(IN3,HIGH); digitalWrite(IN4,LOW);
  analogWrite(ENA,speed); analogWrite(ENB,speed);
}
void backward() {
  digitalWrite(IN1,LOW); digitalWrite(IN2,HIGH);
  digitalWrite(IN3,LOW); digitalWrite(IN4,HIGH);
  analogWrite(ENA,speed); analogWrite(ENB,speed);
}
void turnLeft() {
  digitalWrite(IN1,LOW); digitalWrite(IN2,LOW);
  digitalWrite(IN3,HIGH); digitalWrite(IN4,LOW);
  analogWrite(ENB,speed);
}
void turnRight() {
  digitalWrite(IN1,HIGH); digitalWrite(IN2,LOW);
  analogWrite(ENA,speed);
  digitalWrite(IN3,LOW); digitalWrite(IN4,LOW);
}
void stopMotors() {
  digitalWrite(IN1,LOW); digitalWrite(IN2,LOW);
  digitalWrite(IN3,LOW); digitalWrite(IN4,LOW);
}

void loop() {
  forward(); delay(2000);
  stopMotors(); delay(500);
  turnRight(); delay(1000);
  stopMotors(); delay(500);
  backward(); delay(2000);
  stopMotors(); delay(500);
  turnLeft(); delay(1000);
  stopMotors(); delay(500);
}

4.5 Worked Examples

Ex 1: Speed ramp up

Arduino
int ENA=9,IN1=8,IN2=7;
void setup(){pinMode(ENA,OUTPUT);pinMode(IN1,OUTPUT);pinMode(IN2,OUTPUT);}
void loop(){
  digitalWrite(IN1,HIGH);digitalWrite(IN2,LOW);
  for(int s=0;s<=255;s+=5){analogWrite(ENA,s);delay(50);}
  for(int s=255;s>=0;s-=5){analogWrite(ENA,s);delay(50);}
}

Ex 2: Pot-controlled speed

Arduino
int ENA=9,IN1=8,IN2=7;
void setup(){pinMode(ENA,OUTPUT);pinMode(IN1,OUTPUT);pinMode(IN2,OUTPUT);digitalWrite(IN1,HIGH);digitalWrite(IN2,LOW);}
void loop(){analogWrite(ENA,map(analogRead(A0),0,1023,0,255));delay(50);}

Ex 3: Button direction toggle

Arduino
int ENA=9,IN1=8,IN2=7,btn=2;
bool dir=true;
void setup(){pinMode(ENA,OUTPUT);pinMode(IN1,OUTPUT);pinMode(IN2,OUTPUT);pinMode(btn,INPUT_PULLUP);}
void loop(){
  if(digitalRead(btn)==LOW){dir=!dir;delay(300);}
  digitalWrite(IN1,dir?HIGH:LOW);digitalWrite(IN2,dir?LOW:HIGH);
  analogWrite(ENA,200);
}

Ex 4: Serial-controlled motor

Arduino
int ENA=9,IN1=8,IN2=7;
void setup(){Serial.begin(9600);pinMode(ENA,OUTPUT);pinMode(IN1,OUTPUT);pinMode(IN2,OUTPUT);}
void loop(){
  if(Serial.available()){
    char c=Serial.read();
    if(c=='F'){digitalWrite(IN1,HIGH);digitalWrite(IN2,LOW);analogWrite(ENA,200);}
    else if(c=='R'){digitalWrite(IN1,LOW);digitalWrite(IN2,HIGH);analogWrite(ENA,200);}
    else if(c=='S'){digitalWrite(IN1,LOW);digitalWrite(IN2,LOW);}
  }
}

Ex 5โ€“10: Additional motor examples

Arduino
// Ex 5: Obstacle-avoiding robot (ultrasonic + motors)
int trig=10,echo=11,ENA=9,IN1=8,IN2=7,IN3=6,IN4=5,ENB=3;
void setup(){
  pinMode(trig,OUTPUT);pinMode(echo,INPUT);
  int p[]={ENA,IN1,IN2,IN3,IN4,ENB};
  for(int i=0;i<6;i++)pinMode(p[i],OUTPUT);
}
float getDist(){
  digitalWrite(trig,LOW);delayMicroseconds(2);
  digitalWrite(trig,HIGH);delayMicroseconds(10);
  digitalWrite(trig,LOW);
  return(pulseIn(echo,HIGH)*0.034)/2;
}
void loop(){
  float d=getDist();
  if(d>20){
    digitalWrite(IN1,HIGH);digitalWrite(IN2,LOW);
    digitalWrite(IN3,HIGH);digitalWrite(IN4,LOW);
    analogWrite(ENA,180);analogWrite(ENB,180);
  }else{
    digitalWrite(IN1,LOW);digitalWrite(IN2,HIGH);
    digitalWrite(IN3,LOW);digitalWrite(IN4,LOW);
    analogWrite(ENA,150);
    delay(600);
  }
  delay(100);
}
Arduino
// Ex 6: PWM motor speed display on LCD
#include <LiquidCrystal.h>
LiquidCrystal lcd(12,11,5,4,3,2);
int ENA=9,IN1=8,IN2=7;
void setup(){lcd.begin(16,2);pinMode(ENA,OUTPUT);pinMode(IN1,OUTPUT);pinMode(IN2,OUTPUT);digitalWrite(IN1,HIGH);digitalWrite(IN2,LOW);}
void loop(){
  int pot=analogRead(A0);
  int spd=map(pot,0,1023,0,255);
  analogWrite(ENA,spd);
  lcd.clear();lcd.print("Speed: ");lcd.print(spd);
  lcd.setCursor(0,1);lcd.print(map(spd,0,255,0,100));lcd.print("%");
  delay(200);
}
Arduino
// Ex 7: Timed motor sequence
int ENA=9,IN1=8,IN2=7;
void setup(){pinMode(ENA,OUTPUT);pinMode(IN1,OUTPUT);pinMode(IN2,OUTPUT);}
void loop(){
  int speeds[]={50,100,150,200,255};
  digitalWrite(IN1,HIGH);digitalWrite(IN2,LOW);
  for(int i=0;i<5;i++){analogWrite(ENA,speeds[i]);delay(1000);}
  digitalWrite(IN1,LOW);digitalWrite(IN2,LOW);delay(2000);
}
Arduino
// Ex 8: Motor with emergency stop button
int ENA=9,IN1=8,IN2=7,stopBtn=2;
bool running=true;
void setup(){pinMode(ENA,OUTPUT);pinMode(IN1,OUTPUT);pinMode(IN2,OUTPUT);pinMode(stopBtn,INPUT_PULLUP);}
void loop(){
  if(digitalRead(stopBtn)==LOW) running=!running;
  if(running){digitalWrite(IN1,HIGH);digitalWrite(IN2,LOW);analogWrite(ENA,200);}
  else{digitalWrite(IN1,LOW);digitalWrite(IN2,LOW);}
  delay(200);
}
Arduino
// Ex 9: Temperature-controlled fan motor
#include <DHT.h>
DHT dht(2,DHT22);
int ENA=9,IN1=8,IN2=7;
void setup(){dht.begin();pinMode(ENA,OUTPUT);pinMode(IN1,OUTPUT);pinMode(IN2,OUTPUT);digitalWrite(IN1,HIGH);digitalWrite(IN2,LOW);}
void loop(){
  delay(2000);
  float t=dht.readTemperature();
  int spd=constrain(map(t,25,45,0,255),0,255);
  analogWrite(ENA,spd);
}
Arduino
// Ex 10: Dual motor independent control via Serial
int ENA=9,IN1=8,IN2=7,IN3=6,IN4=5,ENB=3;
void setup(){Serial.begin(9600);int p[]={ENA,IN1,IN2,IN3,IN4,ENB};for(int i=0;i<6;i++)pinMode(p[i],OUTPUT);}
void loop(){
  if(Serial.available()){
    char c=Serial.read();
    switch(c){
      case 'W':digitalWrite(IN1,HIGH);digitalWrite(IN2,LOW);digitalWrite(IN3,HIGH);digitalWrite(IN4,LOW);analogWrite(ENA,200);analogWrite(ENB,200);break;
      case 'X':digitalWrite(IN1,LOW);digitalWrite(IN2,LOW);digitalWrite(IN3,LOW);digitalWrite(IN4,LOW);break;
    }
  }
}
Motor doesn't spin? Check: (1) Remove ENA/ENB jumpers and connect to PWM pins. (2) Common GND between Arduino and motor battery. (3) Motor supply voltage adequate (6-12V). (4) L298N can get HOT โ€” add heatsink for high loads.

4.6 MCQs โ€” Chapter 4 (20 Questions)

Q1

L298N is a:

  1. Single H-bridge driver
  2. Dual H-bridge driver
  3. Motor encoder
  4. Servo controller
Remember
โœ… Answer: (B) โ€” L298N contains two H-bridge circuits, allowing control of 2 DC motors independently.
Q2

To control motor speed with L298N, which function is used?

  1. digitalWrite()
  2. analogWrite()
  3. motorSpeed()
  4. pwmSet()
Remember
โœ… Answer: (B) โ€” analogWrite() sends PWM signal to ENA/ENB pins to control speed (0-255).
Q3

When IN1=HIGH and IN2=LOW, the motor:

  1. Stops
  2. Rotates forward
  3. Rotates reverse
  4. Brakes
Understand
โœ… Answer: (B) โ€” IN1=HIGH, IN2=LOW drives current in the forward direction through the H-bridge.
Q4

What happens when both IN1 and IN2 are HIGH?

  1. Forward
  2. Reverse
  3. Brake (hard stop)
  4. Coast (free spin)
Understand
โœ… Answer: (C) โ€” Both inputs HIGH causes a short-circuit braking effect, stopping the motor immediately.
Q5

Maximum current per channel of L298N is:

  1. 500 mA
  2. 1A
  3. 2A
  4. 5A
Remember
โœ… Answer: (C) 2A per channel.
Q6

Why must Arduino GND and motor battery GND be connected?

  1. To charge battery
  2. For common voltage reference
  3. To power Arduino
  4. Not needed
Understand
โœ… Answer: (B) โ€” Common ground ensures the same voltage reference for logic and motor circuits.
Q7

PWM value 128 represents what percentage of full speed?

  1. 25%
  2. 50%
  3. 75%
  4. 100%
Apply
โœ… Answer: (B) 50% โ€” 128/255 โ‰ˆ 50% duty cycle.
Q8

The ENA pin on L298N controls:

  1. Direction of Motor A
  2. Speed of Motor A
  3. Direction of Motor B
  4. Motor encoder
Remember
โœ… Answer: (B) โ€” ENA (Enable A) controls the speed of Motor A via PWM.
Q9

Motor supply voltage range for L298N is:

  1. 1Vโ€“3V
  2. 5Vโ€“35V
  3. 12Vโ€“48V
  4. 3.3Vโ€“5V
Remember
โœ… Answer: (B) 5Vโ€“35V.
Q10

To make a robot car turn left, you should:

  1. Stop left motor, run right motor
  2. Stop right motor, run left motor
  3. Run both motors forward
  4. Stop both motors
Apply
โœ… Answer: (A) โ€” Stopping the left motor while running the right motor makes the car pivot left.
Q11

What is an H-bridge?

  1. A type of resistor
  2. A circuit that allows voltage to be applied across a load in either direction
  3. A bridge rectifier
  4. A type of capacitor circuit
Understand
โœ… Answer: (B) โ€” An H-bridge uses 4 switches in an H-pattern to reverse current direction through a motor.
Q12

Which Arduino pins can be used for ENA/ENB?

  1. Any digital pin
  2. Only analog pins
  3. Only PWM-capable pins (marked ~)
  4. Only pins 0 and 1
Understand
โœ… Answer: (C) โ€” ENA/ENB need PWM signals, so they must connect to PWM pins (~3, ~5, ~6, ~9, ~10, ~11 on Uno).
Q13

The L298N has a built-in 5V regulator. It outputs 5V when motor supply is:

  1. Less than 5V
  2. 5Vโ€“12V with jumper on
  3. Only 12V exactly
  4. Never
Understand
โœ… Answer: (B) โ€” When motor supply is 7-12V and the 5V regulator jumper is in place, the module outputs 5V that can power Arduino.
Q14

analogWrite(ENA, 0) will:

  1. Run motor at full speed
  2. Run motor at half speed
  3. Stop the motor (0% duty)
  4. Brake the motor
Understand
โœ… Answer: (C) โ€” PWM value 0 means 0% duty cycle, so no power reaches the motor.
Q15

Coast vs Brake in L298N โ€” what's the difference?

  1. No difference
  2. Coast = motor freely decelerates; Brake = motor stops instantly
  3. Brake is slower
  4. Coast needs more power
Understand
โœ… Answer: (B) โ€” Coast (both LOW) lets motor spin down naturally; Brake (both HIGH) short-circuits motor windings for fast stop.
Q16

How many motors can L298N control simultaneously?

  1. 1
  2. 2
  3. 4
  4. 8
Remember
โœ… Answer: (B) 2 DC motors (or 1 stepper motor).
Q17

Why does L298N get hot during operation?

  1. Defective unit
  2. Voltage drop across transistors (~2V) dissipates as heat
  3. Motor is broken
  4. Wrong wiring
Understand
โœ… Answer: (B) โ€” L298N uses bipolar transistors with ~2V drop, causing significant heat at high currents. Use heatsink.
Q18

map(analogRead(A0), 0, 1023, 0, 255) converts pot reading to:

  1. Voltage
  2. Motor speed (PWM range)
  3. Temperature
  4. Distance
Apply
โœ… Answer: (B) โ€” Maps 10-bit ADC (0-1023) to 8-bit PWM (0-255) for motor speed control.
Q19

For an obstacle-avoiding robot, which sensor is combined with motors?

  1. LDR
  2. DHT22
  3. Ultrasonic (HC-SR04)
  4. RFID
Apply
โœ… Answer: (C) โ€” Ultrasonic sensor detects obstacles ahead, triggering motor direction changes.
Q20

constrain(value, min, max) function does what?

  1. Generates random value
  2. Limits value within min-max range
  3. Converts units
  4. Rounds the value
Understand
โœ… Answer: (B) โ€” constrain() ensures the value stays within [min, max] bounds, clamping if necessary.
Chapter 5

LED Displays with MAX7219

๐Ÿ’ก From Railway Stations to Stock Tickers โ€” LED Displays Run India!

Walk into any Indian railway station and you'll see scrolling LED displays showing train timings. Visit Dalal Street and BSE/NSE stock tickers flash prices in real-time. Shop signboards across India glow with LED matrix displays showing offers and greetings.

MAX7219 = LED Display Ka Boss! This single chip can drive 64 LEDs (8ร—8 matrix) or 8 seven-segment digits using just 3 wires (SPI). Chain multiple modules together and you've got a full scrolling display โ€” just like the ones at railway stations. Cost? Under โ‚น150!

๐Ÿ‡ฎ๐Ÿ‡ณ Indian Railways๐Ÿ‡ฎ๐Ÿ‡ณ BSE / NSE๐Ÿ‡ฎ๐Ÿ‡ณ LED Signage๐Ÿ‡ฎ๐Ÿ‡ณ Metro Stations

5.1 MAX7219 LED Dot Matrix 4-in-1 Display

The MAX7219 4-in-1 dot matrix module combines four 8ร—8 LED matrices into a single PCB, giving you a 32ร—8 pixel display. The MAX7219 IC handles all the multiplexing โ€” you just send data over SPI and the chip takes care of driving 64 LEDs per module.

ParameterValue
Display Type8ร—8 LED Dot Matrix (ร—4 = 32ร—8)
Driver ICMAX7219
Operating Voltage5V
CommunicationSPI (CLK, DIN, CS)
Max Cascade8 modules (theoretically unlimited)
LED ColorRed (common), Green/Blue available
Brightness Levels16 (0โ€“15)
Current per Segment~40 mA (set via resistor)
Module Cost (India)โ‚น120โ€“180

SPI Communication

MAX7219 uses a 3-wire SPI interface:

SPI PinFunction
CLK (Clock)Synchronizes data transfer
DIN (Data In)Serial data input (MOSI)
CS (Chip Select)Active LOW โ€” latches data when pulled LOWโ†’HIGH

Cascading Multiple Modules

To chain multiple MAX7219 modules: connect DOUT of the first module to DIN of the next. All modules share the same CLK and CS lines. Data shifts through like a chain โ€” the first data sent ends up on the last module.

MAX7219 4-in-1 Dot Matrix Module โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Module 1โ”‚ Module 2โ”‚ Module 3โ”‚ Module 4โ”‚ โ”‚ 8ร—8 โ”‚ 8ร—8 โ”‚ 8ร—8 โ”‚ 8ร—8 โ”‚ โ”‚ LED โ”‚ LED โ”‚ LED โ”‚ LED โ”‚ โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ โ”‚ DINโ†’[MAX7219]โ†’DOUTโ†’[MAX7219]โ†’DOUTโ†’[MAX7219]โ†’DOUTโ†’[MAX7219] โ”‚ โ”‚ CLK โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ (shared) CS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ (shared) Input Pins (left side): Power: โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ” VCC โ”€โ”€ 5V โ”‚ VCC โ”‚ GND โ”€โ”€ GND โ”‚ GND โ”‚ โ”‚ DIN โ”‚ โ† Data from Arduino โ”‚ CS โ”‚ โ† Chip Select โ”‚ CLK โ”‚ โ† Clock โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Connection Table (Arduino โ†’ MAX7219 4-in-1)

MAX7219 PinArduino PinPurpose
VCC5VPower supply
GNDGNDGround
DIND11 (MOSI)Serial data input
CSD10Chip select (latch)
CLKD13 (SCK)Clock signal
Arduino Uno โ†โ†’ MAX7219 4-in-1 Dot Matrix Wiring ARDUINO UNO MAX7219 4-in-1 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ D11 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ DIN โ”‚ โ”‚ D13 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ CLK โ”‚ โ”‚ D10 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ CS โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 5V โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ VCC โ”‚ โ”‚ GND โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ GND โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

5.2 MD_Parola & MD_MAX72XX Libraries

The MD_MAX72XX library provides low-level control of MAX7219 modules. MD_Parola adds high-level text scrolling, animations, and effects on top of it.

FunctionDescriptionExample
MD_Parola(type, cs, max)Constructor โ€” hardware type, CS pin, number of devicesMD_Parola P = MD_Parola(MD_MAX72XX::FC16_HW, 10, 4)
P.begin()Initialize the displayP.begin()
P.displayText(text, align, speed, pause, effect_in, effect_out)Set text with scrolling parametersSee code below
P.displayAnimate()Animate one frame โ€” call in loop()if (P.displayAnimate()) P.displayReset()
P.displayReset()Reset animation to startCalled after animation completes
P.setIntensity(val)Set brightness (0โ€“15)P.setIntensity(5)
P.setTextAlignment(align)PA_LEFT, PA_CENTER, PA_RIGHTP.setTextAlignment(PA_CENTER)
P.print(text)Print static textP.print("HELLO")

5.3 Full Code โ€” Scrolling Text on Dot Matrix

Arduino
// Program: Scrolling text on MAX7219 4-in-1 Dot Matrix
// Board: Arduino Uno
// Libraries: MD_Parola, MD_MAX72XX

#include <MD_Parola.h>
#include <MD_MAX72XX.h>
#include <SPI.h>

// Hardware configuration
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4    // 4 modules in the 4-in-1
#define CS_PIN      10

// Create Parola object
MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

void setup() {
  myDisplay.begin();
  myDisplay.setIntensity(5);        // Brightness 0-15
  myDisplay.displayClear();
  myDisplay.displayScroll(
    "WELCOME TO EDUARTHA IOT LAB",
    PA_CENTER, PA_SCROLL_LEFT,
    100                              // Speed in ms
  );
}

void loop() {
  if (myDisplay.displayAnimate()) {
    myDisplay.displayReset();         // Restart scroll
  }
}
Dot Matrix Display Output: โ† W E L C O M E T O E D U A R T H A I O T L A B โ†’ (scrolling continuously from right to left)

5.4 MAX7219 Digital Tube Display (8-Digit 7-Segment)

The MAX7219 also drives 8-digit 7-segment displays. Each digit has 7 segments (aโ€“g) + decimal point. The MAX7219 multiplexes all 8 digits, and the LedControl library provides easy functions.

ParameterValue
Display Type8-digit 7-segment (common cathode)
Driver ICMAX7219
InterfaceSPI (DIN, CS, CLK)
WiringSame as dot matrix

LedControl Library Functions

FunctionDescription
LedControl(DIN, CLK, CS, numDevices)Constructor
lc.shutdown(addr, false)Wake up the display
lc.setIntensity(addr, brightness)Set brightness (0โ€“15)
lc.clearDisplay(addr)Clear all digits
lc.setDigit(addr, digit, value, dp)Set a digit (0โ€“7) to value (0โ€“9)
lc.setChar(addr, digit, char, dp)Set a digit to character

Countdown Timer Code (99 โ†’ 00)

Arduino
// Program: Countdown timer on MAX7219 8-digit 7-segment display
#include <LedControl.h>

// LedControl(DIN, CLK, CS, numDevices)
LedControl lc = LedControl(11, 13, 10, 1);

void setup() {
  lc.shutdown(0, false);    // Wake up display
  lc.setIntensity(0, 8);     // Medium brightness
  lc.clearDisplay(0);        // Clear all digits
}

void loop() {
  for (int i = 99; i >= 0; i--) {
    int tens = i / 10;
    int ones = i % 10;
    lc.setDigit(0, 1, tens, false);  // Tens digit
    lc.setDigit(0, 0, ones, false);  // Ones digit
    delay(1000);                      // 1 second interval
  }
}

5.5 Worked Examples

Example 1: Display Static Text "HELLO"

Arduino
#include <MD_Parola.h>
#include <MD_MAX72XX.h>
#include <SPI.h>
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 10
MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
void setup() {
  myDisplay.begin();
  myDisplay.setIntensity(5);
  myDisplay.setTextAlignment(PA_CENTER);
  myDisplay.print("HELLO");
}
void loop() {}

Example 2: Scrolling Text with Custom Speed

Arduino
#include <MD_Parola.h>
#include <MD_MAX72XX.h>
#include <SPI.h>
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, 10, 4);
void setup() {
  myDisplay.begin();
  myDisplay.setIntensity(8);
  myDisplay.displayScroll("FAST SCROLL!", PA_CENTER, PA_SCROLL_LEFT, 50); // 50ms = fast
}
void loop() {
  if (myDisplay.displayAnimate()) myDisplay.displayReset();
}

Example 3: Temperature Reading on 7-Segment

Arduino
#include <LedControl.h>
#include <DHT.h>
LedControl lc = LedControl(11, 13, 10, 1);
DHT dht(2, DHT22);
void setup() {
  lc.shutdown(0, false); lc.setIntensity(0, 8); lc.clearDisplay(0);
  dht.begin();
}
void loop() {
  delay(2000);
  int temp = (int)dht.readTemperature();
  lc.setDigit(0, 3, temp / 10, false);  // Tens
  lc.setDigit(0, 2, temp % 10, true);   // Ones + decimal point
  lc.setChar(0, 1, 'C', false);         // ยฐC symbol
}

Example 4: Dot Matrix Smiley Animation

Arduino
#include <LedControl.h>
LedControl lc = LedControl(11, 13, 10, 1);
byte smiley[8] = {
  0b00111100, 0b01000010, 0b10100101, 0b10000001,
  0b10100101, 0b10011001, 0b01000010, 0b00111100
};
byte sad[8] = {
  0b00111100, 0b01000010, 0b10100101, 0b10000001,
  0b10011001, 0b10100101, 0b01000010, 0b00111100
};
void setup() { lc.shutdown(0,false); lc.setIntensity(0,5); }
void loop() {
  for(int i=0;i<8;i++) lc.setRow(0,i,smiley[i]);
  delay(1000);
  for(int i=0;i<8;i++) lc.setRow(0,i,sad[i]);
  delay(1000);
}

Example 5: Clock Display on 7-Segment (using millis)

Arduino
#include <LedControl.h>
LedControl lc = LedControl(11, 13, 10, 1);
unsigned long prev = 0;
int sec=0, mins=0;
void setup() { lc.shutdown(0,false); lc.setIntensity(0,8); lc.clearDisplay(0); }
void loop() {
  if (millis() - prev >= 1000) {
    prev = millis();
    sec++; if(sec>=60){sec=0;mins++;} if(mins>=60) mins=0;
    lc.setDigit(0,3,mins/10,false);
    lc.setDigit(0,2,mins%10,true);  // Decimal = colon
    lc.setDigit(0,1,sec/10,false);
    lc.setDigit(0,0,sec%10,false);
  }
}

Example 6: Brightness Control via Potentiometer

Arduino
#include <MD_Parola.h>
#include <MD_MAX72XX.h>
#include <SPI.h>
MD_Parola myDisplay = MD_Parola(MD_MAX72XX::FC16_HW, 10, 4);
void setup() {
  myDisplay.begin();
  myDisplay.setTextAlignment(PA_CENTER);
  myDisplay.print("BRIGHT");
}
void loop() {
  int pot = analogRead(A0);
  int brightness = map(pot, 0, 1023, 0, 15);
  myDisplay.setIntensity(brightness);
  delay(100);
}

Example 7: Cycling Multiple Messages

Arduino
#include <MD_Parola.h>
#include <MD_MAX72XX.h>
#include <SPI.h>
MD_Parola P = MD_Parola(MD_MAX72XX::FC16_HW, 10, 4);
const char* msgs[] = {"HELLO", "IoT LAB", "ARDUINO", "MAX7219"};
int idx = 0;
void setup() { P.begin(); P.setIntensity(5); }
void loop() {
  P.setTextAlignment(PA_CENTER);
  P.print(msgs[idx]);
  idx = (idx + 1) % 4;
  delay(2000);
}

Example 8: Visitor Counter on 7-Segment

Arduino
#include <LedControl.h>
LedControl lc = LedControl(11, 13, 10, 1);
int btnPin = 2, count = 0;
void setup() {
  lc.shutdown(0,false); lc.setIntensity(0,8); lc.clearDisplay(0);
  pinMode(btnPin, INPUT_PULLUP);
  showCount();
}
void loop() {
  if (digitalRead(btnPin) == LOW) {
    count++; if(count>9999) count=0;
    showCount();
    delay(300); // Debounce
  }
}
void showCount() {
  lc.setDigit(0,3,count/1000,false);
  lc.setDigit(0,2,(count/100)%10,false);
  lc.setDigit(0,1,(count/10)%10,false);
  lc.setDigit(0,0,count%10,false);
}

Example 9: Scrolling Sensor Data on Dot Matrix

Arduino
#include <MD_Parola.h>
#include <MD_MAX72XX.h>
#include <SPI.h>
MD_Parola P = MD_Parola(MD_MAX72XX::FC16_HW, 10, 4);
char msg[30];
void setup() { P.begin(); P.setIntensity(5); }
void loop() {
  int sensorVal = analogRead(A0);
  sprintf(msg, "Sensor: %d", sensorVal);
  P.displayScroll(msg, PA_LEFT, PA_SCROLL_LEFT, 80);
  while (!P.displayAnimate()) {}
  delay(500);
}

Example 10: Binary Counter on Dot Matrix (Single 8ร—8)

Arduino
#include <LedControl.h>
LedControl lc = LedControl(11, 13, 10, 1);
void setup() { lc.shutdown(0,false); lc.setIntensity(0,5); lc.clearDisplay(0); }
void loop() {
  for(int i=0; i<256; i++) {
    for(int row=0; row<8; row++)
      lc.setRow(0, row, (i>>row) & 1 ? 0xFF : 0x00);
    delay(200);
  }
}
MAX7219 display not working? Check: (1) Power โ€” MAX7219 needs 5V, not 3.3V. (2) CS pin must match code. (3) For FC16 modules use MD_MAX72XX::FC16_HW hardware type. (4) If text appears reversed/mirrored, change hardware type to PAROLA_HW or GENERIC_HW. (5) Ensure SPI pins (D11=MOSI, D13=SCK) are correct โ€” they're hardware SPI.

5.6 MCQs โ€” Chapter 5 (20 Questions)

Q1

MAX7219 communicates with Arduino using which protocol?

  1. I2C
  2. UART
  3. SPI
  4. One-Wire
Remember
โœ… Answer: (C) SPI โ€” MAX7219 uses 3-wire SPI (CLK, DIN, CS).
Q2

How many LEDs can a single MAX7219 IC drive?

  1. 16
  2. 32
  3. 64
  4. 128
Remember
โœ… Answer: (C) 64 โ€” One MAX7219 drives an 8ร—8 matrix (64 LEDs) or 8 seven-segment digits.
Q3

What is the resolution of a MAX7219 4-in-1 dot matrix display?

  1. 8ร—8 pixels
  2. 16ร—8 pixels
  3. 32ร—8 pixels
  4. 64ร—8 pixels
Remember
โœ… Answer: (C) 32ร—8 pixels โ€” Four 8ร—8 matrices side by side = 32 columns ร— 8 rows.
Q4

To cascade multiple MAX7219 modules, which pin connects to the next module's DIN?

  1. CLK
  2. CS
  3. DOUT
  4. VCC
Understand
โœ… Answer: (C) DOUT โ€” Data shifts out from DOUT of one module into DIN of the next in the chain.
Q5

How many brightness levels does MAX7219 support?

  1. 8
  2. 10
  3. 16
  4. 256
Remember
โœ… Answer: (C) 16 โ€” Brightness levels 0 (dimmest) to 15 (brightest).
Q6

Which Arduino pin is typically used for DIN (MOSI) with MAX7219?

  1. D10
  2. D11
  3. D12
  4. D13
Remember
โœ… Answer: (B) D11 โ€” On Arduino Uno, D11 is the hardware SPI MOSI pin.
Q7

Which library provides high-level text scrolling on MAX7219 dot matrix?

  1. LedControl
  2. MD_Parola
  3. Adafruit_GFX
  4. FastLED
Remember
โœ… Answer: (B) MD_Parola โ€” It provides scrolling, animation effects, and text alignment on top of MD_MAX72XX.
Q8

What does the CS (Chip Select) pin do in SPI?

  1. Sends clock signal
  2. Carries data
  3. Latches data when toggled LOWโ†’HIGH
  4. Powers the chip
Understand
โœ… Answer: (C) โ€” CS goes LOW to select the device, data is clocked in, then CS goes HIGH to latch the data.
Q9

The LedControl library function setDigit(0, 3, 5, true) displays:

  1. Digit 5 on position 3 with decimal point
  2. Digit 3 on position 5
  3. Digit 0 on position 3
  4. Nothing โ€” invalid call
Apply
โœ… Answer: (A) โ€” setDigit(address, digit_position, value, decimal_point). Shows "5." on the 4th digit (position 3).
Q10

What is the operating voltage of MAX7219?

  1. 3.3V
  2. 5V
  3. 9V
  4. 12V
Remember
โœ… Answer: (B) 5V โ€” MAX7219 operates at 4.0V to 5.5V.
Q11

In MD_Parola, which function must be called repeatedly in loop() for animations?

  1. displayText()
  2. displayAnimate()
  3. displayScroll()
  4. displayReset()
Understand
โœ… Answer: (B) displayAnimate() โ€” This function advances the animation by one frame each call. Returns true when animation is complete.
Q12

How many 7-segment digits can one MAX7219 drive?

  1. 4
  2. 6
  3. 8
  4. 16
Remember
โœ… Answer: (C) 8 โ€” MAX7219 drives 8 digits ร— 8 segments (including decimal point).
Q13

What happens when you call lc.shutdown(0, false)?

  1. Turns off the display
  2. Wakes up the display (exits shutdown mode)
  3. Resets brightness
  4. Clears all digits
Understand
โœ… Answer: (B) โ€” shutdown(addr, true) puts the device in power-saving mode. shutdown(addr, false) wakes it up.
Q14

SPI stands for:

  1. Serial Peripheral Interface
  2. Simple Protocol Interface
  3. Synchronous Parallel Interface
  4. Serial Pin Integration
Remember
โœ… Answer: (A) Serial Peripheral Interface โ€” A synchronous serial communication protocol using CLK, MOSI, MISO, and SS lines.
Q15

For the hardware type FC16_HW in MD_Parola, what does FC16 refer to?

  1. A type of Arduino board
  2. A specific PCB layout for MAX7219 modules
  3. A font style
  4. A communication speed
Understand
โœ… Answer: (B) โ€” FC16 is a common Chinese PCB layout for 4-in-1 MAX7219 dot matrix modules. Different layouts need different hardware types.
Q16

The maximum number of MAX7219 modules that can be cascaded is:

  1. 4
  2. 8
  3. 16
  4. Theoretically unlimited (practically ~8)
Understand
โœ… Answer: (D) โ€” There's no hardware limit on cascading, but signal degradation and timing issues limit practical chains to about 8 modules.
Q17

To display the number "42" on positions 1 and 0 of a 7-segment display:

  1. lc.setDigit(0,1,4,false); lc.setDigit(0,0,2,false);
  2. lc.setDigit(0,0,4,false); lc.setDigit(0,1,2,false);
  3. lc.setChar(0,1,'4',false); lc.setChar(0,0,'2',false);
  4. Both A and C are correct
Apply
โœ… Answer: (D) โ€” Both setDigit with numeric values and setChar with character values work correctly for displaying numbers.
Q18

Which pin on Arduino Uno is the hardware SPI clock (SCK)?

  1. D10
  2. D11
  3. D12
  4. D13
Remember
โœ… Answer: (D) D13 โ€” On Arduino Uno, D13 is SCK, D11 is MOSI, D12 is MISO.
Q19

If the dot matrix display shows text in reverse, you should:

  1. Reverse the DIN and CLK wires
  2. Change the hardware type in code (e.g., FC16_HW to PAROLA_HW)
  3. Use a different library
  4. Replace the module
Apply
โœ… Answer: (B) โ€” Different MAX7219 modules have different internal wiring. Changing hardware type (FC16_HW, PAROLA_HW, GENERIC_HW) fixes display orientation.
Q20

setIntensity(0, 15) sets the display to:

  1. Minimum brightness
  2. Half brightness
  3. Maximum brightness
  4. Display off
Understand
โœ… Answer: (C) Maximum brightness โ€” Intensity ranges from 0 (dimmest) to 15 (brightest).
Chapter 6

RFID Module with Arduino (RC522)

๐Ÿท๏ธ Tap & Go โ€” RFID Powers Your Daily Life!

Every time you tap your Delhi Metro card, swipe your office ID, or cruise through a FASTag toll booth โ€” you're using RFID technology. Amazon and Flipkart warehouses use RFID to track millions of packages. Libraries use it for book checkout. It's the invisible technology that keeps India moving!

RFID = Contactless Magic! The RC522 module costs just โ‚น120 and can read RFID cards/tags from up to 5cm away. By the end of this chapter, you'll build your own access control system โ€” just like the ones at office doors!

๐Ÿ‡ฎ๐Ÿ‡ณ Delhi Metro๐Ÿ‡ฎ๐Ÿ‡ณ FASTag๐Ÿ‡ฎ๐Ÿ‡ณ Flipkart Warehouse๐Ÿ‡ฎ๐Ÿ‡ณ Amazon Fulfillment

6.1 RFID Concept

RFID stands for Radio Frequency Identification. It's a wireless system with two components:

ComponentDescription
RFID Reader (RC522)Emits radio waves and reads data from tags
RFID Tag/CardContains a microchip + antenna; stores a unique ID (UID)

Active vs Passive Tags

FeaturePassive TagActive Tag
BatteryNo battery โ€” powered by reader's RF fieldHas its own battery
RangeShort (1โ€“10 cm)Long (up to 100m)
Costโ‚น5โ€“20 per tagโ‚น500+ per tag
ExampleMetro card, ID cardVehicle tracking, logistics

RC522 Specifications

ParameterValue
Operating Voltage3.3V (NOT 5V!)
Operating Frequency13.56 MHz
Communication InterfaceSPI
Read Range~5 cm (depending on tag)
Supported CardsMIFARE 1K, MIFARE 4K, MIFARE Ultralight
Data Transfer Rate10 Mbit/s
Current (idle)13โ€“26 mA
Module Cost (India)โ‚น100โ€“150 (includes 1 card + 1 keychain tag)

6.2 Pin Connections

RC522 Pin Description

RC522 PinFunction
SDA (SS)SPI Slave Select / Chip Select
SCKSPI Clock
MOSISPI Master Out Slave In (Data to RC522)
MISOSPI Master In Slave Out (Data from RC522)
IRQInterrupt (usually not connected)
GNDGround
RSTReset
3.3VPower supply (3.3V only!)

Connection Table (Arduino โ†’ RC522)

RC522 PinArduino PinPurpose
3.3V3.3VPower (NOT 5V!)
GNDGNDGround
RSTD9Reset
SDA (SS)D10SPI Chip Select
MOSID11SPI Data to RC522
MISOD12SPI Data from RC522
SCKD13SPI Clock
IRQNot connectedInterrupt (optional)
Arduino Uno โ†โ†’ RC522 RFID Module Wiring ARDUINO UNO RC522 RFID โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 3.3V โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ 3.3V โ”‚ โš ๏ธ NOT 5V! โ”‚ GND โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ GND โ”‚ โ”‚ D9 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ RST โ”‚ โ”‚ D10 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ SDA โ”‚ โ”‚ D11 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ MOSI โ”‚ โ”‚ D12 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ MISO โ”‚ โ”‚ D13 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ SCK โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ IRQ โ”€โ”€ร— โ”‚ (not used) โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โš ๏ธ CRITICAL: RC522 is 3.3V ONLY! Connecting to 5V will permanently damage the module!
RC522 is 3.3V only! The MFRC522 chip operates at 3.3V. Connecting VCC to the Arduino's 5V pin will permanently damage the module. Always use the 3.3V pin! However, the SPI data lines (MOSI, MISO, SCK) are 5V tolerant on most RC522 modules.

6.3 MFRC522 Library

Install the MFRC522 library by GithubCommunity from Arduino Library Manager.

FunctionDescription
MFRC522 mfrc522(SS_PIN, RST_PIN)Constructor โ€” chip select and reset pins
mfrc522.PCD_Init()Initialize the reader
mfrc522.PICC_IsNewCardPresent()Returns true if a new card is in range
mfrc522.PICC_ReadCardSerial()Reads the card's serial/UID data
mfrc522.uid.uidByte[i]Access individual UID bytes (0โ€“3)
mfrc522.uid.sizeNumber of bytes in the UID
mfrc522.PICC_HaltA()Halt communication with the card
mfrc522.PCD_StopCrypto1()Stop encryption on PCD side

6.4 Read Card UID โ€” Basic Code

Arduino
// Program: Read RFID card UID using RC522
// Board: Arduino Uno
// Connections: SDA=D10, SCK=D13, MOSI=D11, MISO=D12, RST=D9

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN  10
#define RST_PIN 9

MFRC522 mfrc522(SS_PIN, RST_PIN);

void setup() {
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
  Serial.println("Scan your RFID card...");
}

void loop() {
  // Check for new card
  if (!mfrc522.PICC_IsNewCardPresent()) return;
  if (!mfrc522.PICC_ReadCardSerial()) return;

  // Print UID
  Serial.print("Card UID: ");
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
  }
  Serial.println();

  mfrc522.PICC_HaltA();
}
Scan your RFID card... Card UID: A3 B7 2E 1F Card UID: D4 12 8A 5C Card UID: A3 B7 2E 1F

6.5 Access Control Project

Arduino
// Project: RFID Access Control System
// Authorized card โ†’ Green LED + Servo opens door
// Unauthorized โ†’ Red LED + Buzzer alarm

#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>

#define SS_PIN  10
#define RST_PIN 9
#define GREEN_LED 6
#define RED_LED   7
#define BUZZER    8
#define SERVO_PIN 3

MFRC522 mfrc522(SS_PIN, RST_PIN);
Servo doorServo;

// Authorized card UID (replace with your card's UID)
byte authorizedUID[4] = {0xA3, 0xB7, 0x2E, 0x1F};

void setup() {
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
  doorServo.attach(SERVO_PIN);
  doorServo.write(0);  // Door locked
  pinMode(GREEN_LED, OUTPUT);
  pinMode(RED_LED, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  Serial.println("Access Control Ready. Scan card...");
}

void loop() {
  if (!mfrc522.PICC_IsNewCardPresent()) return;
  if (!mfrc522.PICC_ReadCardSerial()) return;

  bool authorized = true;
  for (byte i = 0; i < 4; i++) {
    if (mfrc522.uid.uidByte[i] != authorizedUID[i]) {
      authorized = false;
      break;
    }
  }

  if (authorized) {
    Serial.println("ACCESS GRANTED!");
    digitalWrite(GREEN_LED, HIGH);
    doorServo.write(90);   // Unlock door
    delay(3000);
    doorServo.write(0);    // Lock door
    digitalWrite(GREEN_LED, LOW);
  } else {
    Serial.println("ACCESS DENIED!");
    digitalWrite(RED_LED, HIGH);
    tone(BUZZER, 1000, 1000); // 1kHz beep for 1 second
    delay(2000);
    digitalWrite(RED_LED, LOW);
  }

  mfrc522.PICC_HaltA();
}

6.6 Worked Examples

Example 1: Simple Card Detection

Arduino
#include <SPI.h>
#include <MFRC522.h>
MFRC522 mfrc522(10, 9);
void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); }
void loop() {
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    Serial.println("Card Detected!");
    mfrc522.PICC_HaltA();
    delay(1000);
  }
}

Example 2: Display UID on LCD

Arduino
#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal.h>
MFRC522 mfrc522(10, 9);
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
void setup() {
  lcd.begin(16,2); SPI.begin(); mfrc522.PCD_Init();
  lcd.print("Scan Card...");
}
void loop() {
  if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) return;
  lcd.clear(); lcd.print("UID:");
  lcd.setCursor(0,1);
  for(byte i=0;i<mfrc522.uid.size;i++) {
    if(mfrc522.uid.uidByte[i]<0x10) lcd.print("0");
    lcd.print(mfrc522.uid.uidByte[i], HEX);
    lcd.print(" ");
  }
  mfrc522.PICC_HaltA(); delay(2000);
}

Example 3: Multiple Authorized Cards

Arduino
#include <SPI.h>
#include <MFRC522.h>
MFRC522 mfrc522(10, 9);
byte cards[3][4] = {
  {0xA3,0xB7,0x2E,0x1F},  // Card 1 (Rahul)
  {0xD4,0x12,0x8A,0x5C},  // Card 2 (Priya)
  {0x7B,0xE5,0x44,0x91}   // Card 3 (Admin)
};
const char* names[] = {"Rahul", "Priya", "Admin"};
void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); }
void loop() {
  if(!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) return;
  for(int c=0;c<3;c++) {
    bool match=true;
    for(byte i=0;i<4;i++) if(mfrc522.uid.uidByte[i]!=cards[c][i]) match=false;
    if(match) { Serial.print("Welcome, "); Serial.println(names[c]); break; }
    if(c==2) Serial.println("Unknown card!");
  }
  mfrc522.PICC_HaltA(); delay(1000);
}

Example 4: Attendance System (Serial Log)

Arduino
#include <SPI.h>
#include <MFRC522.h>
MFRC522 mfrc522(10, 9);
int attendCount = 0;
void setup() {
  Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init();
  Serial.println("Sr.No, UID, Time(ms)");
}
void loop() {
  if(!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) return;
  attendCount++;
  Serial.print(attendCount); Serial.print(", ");
  for(byte i=0;i<mfrc522.uid.size;i++) {
    Serial.print(mfrc522.uid.uidByte[i], HEX); Serial.print(" ");
  }
  Serial.print(", "); Serial.println(millis());
  mfrc522.PICC_HaltA(); delay(2000);
}

Example 5: RFID LED Toggle

Arduino
#include <SPI.h>
#include <MFRC522.h>
MFRC522 mfrc522(10, 9);
int ledPin = 6;
bool ledState = false;
void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); pinMode(ledPin,OUTPUT); }
void loop() {
  if(mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    ledState = !ledState;
    digitalWrite(ledPin, ledState ? HIGH : LOW);
    Serial.println(ledState ? "LED ON" : "LED OFF");
    mfrc522.PICC_HaltA(); delay(1000);
  }
}

Example 6: RFID Door Lock with Servo

Arduino
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
MFRC522 mfrc522(10, 9);
Servo lockServo;
byte key[4] = {0xA3,0xB7,0x2E,0x1F};
void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); lockServo.attach(3); lockServo.write(0); }
void loop() {
  if(!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) return;
  bool ok=true;
  for(byte i=0;i<4;i++) if(mfrc522.uid.uidByte[i]!=key[i]) ok=false;
  if(ok) { Serial.println("Door Unlocked!"); lockServo.write(90); delay(5000); lockServo.write(0); }
  else Serial.println("Wrong Card!");
  mfrc522.PICC_HaltA(); delay(1000);
}

Example 7: Student Record Lookup

Arduino
#include <SPI.h>
#include <MFRC522.h>
MFRC522 mfrc522(10, 9);
byte students[2][4] = {{0xA3,0xB7,0x2E,0x1F},{0xD4,0x12,0x8A,0x5C}};
const char* info[] = {"Rahul|CS|Roll:101", "Priya|ECE|Roll:205"};
void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); }
void loop() {
  if(!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) return;
  for(int s=0;s<2;s++) {
    bool m=true;
    for(byte i=0;i<4;i++) if(mfrc522.uid.uidByte[i]!=students[s][i]) m=false;
    if(m) { Serial.print("Student: "); Serial.println(info[s]); break; }
    if(s==1) Serial.println("Student not found!");
  }
  mfrc522.PICC_HaltA(); delay(1000);
}

Example 8: Card Tap Counter

Arduino
#include <SPI.h>
#include <MFRC522.h>
MFRC522 mfrc522(10, 9);
int tapCount = 0;
void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); }
void loop() {
  if(mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    tapCount++;
    Serial.print("Total Taps: "); Serial.println(tapCount);
    mfrc522.PICC_HaltA(); delay(1000);
  }
}

Example 9: Buzzer Alarm for Unauthorized Cards

Arduino
#include <SPI.h>
#include <MFRC522.h>
MFRC522 mfrc522(10, 9);
int buzzer = 8;
byte allowed[4] = {0xA3,0xB7,0x2E,0x1F};
void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); pinMode(buzzer,OUTPUT); }
void loop() {
  if(!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) return;
  bool ok=true;
  for(byte i=0;i<4;i++) if(mfrc522.uid.uidByte[i]!=allowed[i]) ok=false;
  if(!ok) {
    Serial.println("INTRUDER ALERT!");
    for(int i=0;i<5;i++) { tone(buzzer,2000,200); delay(300); }
  } else Serial.println("Welcome!");
  mfrc522.PICC_HaltA(); delay(1000);
}

Example 10: RFID with Relay Control

Arduino
#include <SPI.h>
#include <MFRC522.h>
MFRC522 mfrc522(10, 9);
int relayPin = 6;
bool relayState = false;
byte masterCard[4] = {0xA3,0xB7,0x2E,0x1F};
void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); pinMode(relayPin,OUTPUT); digitalWrite(relayPin,LOW); }
void loop() {
  if(!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) return;
  bool ok=true;
  for(byte i=0;i<4;i++) if(mfrc522.uid.uidByte[i]!=masterCard[i]) ok=false;
  if(ok) {
    relayState = !relayState;
    digitalWrite(relayPin, relayState ? HIGH : LOW);
    Serial.println(relayState ? "Relay ON" : "Relay OFF");
  }
  mfrc522.PICC_HaltA(); delay(1000);
}
FASTag uses UHF RFID (860โ€“960 MHz) for highway toll collection โ€” no stopping needed! Delhi Metro cards use MIFARE (13.56 MHz), the same technology as RC522. Over 30 lakh FASTags are active across India. RFID is also used in Aadhaar-linked smart ration cards, library management systems in IITs, and warehouse automation at Flipkart and Amazon India fulfillment centers.

6.7 MCQs โ€” Chapter 6 (20 Questions)

Q1

RFID stands for:

  1. Radio Frequency Identification
  2. Rapid File Input Device
  3. Radio Frequency Integrated Design
  4. Remote Frequency Identity
Remember
โœ… Answer: (A) Radio Frequency Identification.
Q2

What operating voltage does the RC522 module require?

  1. 5V
  2. 3.3V
  3. 9V
  4. 12V
Remember
โœ… Answer: (B) 3.3V โ€” The MFRC522 IC operates at 3.3V. Connecting to 5V will damage it permanently.
Q3

RC522 communicates with Arduino using which protocol?

  1. I2C
  2. UART
  3. SPI
  4. One-Wire
Remember
โœ… Answer: (C) SPI โ€” RC522 uses SPI with pins SDA(SS), SCK, MOSI, and MISO.
Q4

What is the operating frequency of RC522?

  1. 125 kHz
  2. 13.56 MHz
  3. 2.4 GHz
  4. 900 MHz
Remember
โœ… Answer: (B) 13.56 MHz โ€” This is the standard HF RFID frequency used for MIFARE cards.
Q5

A passive RFID tag:

  1. Has its own battery
  2. Gets power from the reader's RF field
  3. Needs USB power
  4. Only works with WiFi
Understand
โœ… Answer: (B) โ€” Passive tags have no battery. They harvest energy from the reader's electromagnetic field to power their microchip and transmit data back.
Q6

What does UID stand for in RFID?

  1. Universal Input Data
  2. Unique Identification
  3. Unique Identifier
  4. User Interface Design
Remember
โœ… Answer: (C) Unique Identifier โ€” Each RFID card has a unique ID number that identifies it.
Q7

Which function checks if a new RFID card is present?

  1. mfrc522.readCard()
  2. mfrc522.PICC_IsNewCardPresent()
  3. mfrc522.cardAvailable()
  4. mfrc522.scanCard()
Remember
โœ… Answer: (B) PICC_IsNewCardPresent() โ€” PICC stands for Proximity Integrated Circuit Card.
Q8

The approximate read range of RC522 is:

  1. ~5 cm
  2. ~50 cm
  3. ~5 meters
  4. ~50 meters
Remember
โœ… Answer: (A) ~5 cm โ€” RC522 has a short read range, typical of passive 13.56 MHz RFID systems.
Q9

What happens if you connect RC522 VCC to 5V instead of 3.3V?

  1. It works faster
  2. It reads from longer range
  3. The module may be permanently damaged
  4. No difference
Understand
โœ… Answer: (C) โ€” The MFRC522 chip is rated for 3.3V maximum. Applying 5V exceeds its absolute maximum rating and can destroy it.
Q10

mfrc522.uid.uidByte[0] returns:

  1. The card type
  2. The first byte of the card's UID
  3. The reader's firmware version
  4. The signal strength
Understand
โœ… Answer: (B) โ€” uid.uidByte[] is an array containing the card's unique identifier bytes.
Q11

MIFARE 1K card has how much storage?

  1. 64 bytes
  2. 512 bytes
  3. 1 KB (1024 bytes)
  4. 4 KB
Remember
โœ… Answer: (C) 1 KB โ€” MIFARE Classic 1K has 1024 bytes organized into 16 sectors of 4 blocks each.
Q12

Which pin on RC522 is NOT typically connected for basic UID reading?

  1. SDA
  2. SCK
  3. IRQ
  4. RST
Understand
โœ… Answer: (C) IRQ โ€” The interrupt pin is not needed for basic polling-based card reading.
Q13

In the access control project, to compare UID bytes, we use:

  1. String comparison
  2. Byte-by-byte array comparison
  3. Hash function
  4. Analog comparison
Apply
โœ… Answer: (B) โ€” We loop through each byte of the scanned UID and compare it with the stored authorized UID byte array.
Q14

SPI requires how many wires (excluding power)?

  1. 1
  2. 2
  3. 3
  4. 4
Remember
โœ… Answer: (D) 4 โ€” MOSI, MISO, SCK, and SS (Slave Select/CS).
Q15

FASTag in India uses which RFID frequency band?

  1. 125 kHz (LF)
  2. 13.56 MHz (HF)
  3. 860โ€“960 MHz (UHF)
  4. 2.4 GHz (Microwave)
Understand
โœ… Answer: (C) UHF โ€” FASTag uses UHF RFID for longer range reading at highway speeds. RC522 uses HF (13.56 MHz).
Q16

What does mfrc522.PCD_Init() do?

  1. Reads the card
  2. Initializes the RFID reader module
  3. Sends data to the card
  4. Resets the UID
Understand
โœ… Answer: (B) โ€” PCD_Init() initializes the MFRC522 reader (PCD = Proximity Coupling Device).
Q17

Which Arduino pin connects to RC522's RST pin?

  1. D10
  2. D9
  3. D11
  4. D13
Remember
โœ… Answer: (B) D9 โ€” Standard wiring uses D9 for RST and D10 for SDA(SS).
Q18

PICC_HaltA() is used to:

  1. Initialize the reader
  2. Stop communication with the current card
  3. Read the next card
  4. Change the card's UID
Understand
โœ… Answer: (B) โ€” HaltA commands the card to enter HALT state, preventing repeated reads of the same card.
Q19

For an RFID attendance system, each card tap should be:

  1. Ignored
  2. Logged with UID, timestamp, and serial number
  3. Counted only once ever
  4. Displayed on LED
Apply
โœ… Answer: (B) โ€” A proper attendance system logs the UID (to identify the person), a timestamp, and a serial number for each entry.
Q20

Delhi Metro card uses which RFID technology?

  1. Active UHF RFID
  2. Passive HF RFID (MIFARE)
  3. Bluetooth Low Energy
  4. NFC only
Understand
โœ… Answer: (B) โ€” Delhi Metro uses MIFARE-based passive HF RFID cards at 13.56 MHz, the same technology used by RC522.
Chapter 7

Pulse Oximeter with MAX30100

โค๏ธ From ICU Monitors to Your Fingertip โ€” Pulse Oximetry Saves Lives!

During COVID-19, pulse oximeters became as common as thermometers in Indian households. Doctors at AIIMS Delhi and Apollo Hospitals used them to detect "happy hypoxia" โ€” when patients felt fine but their oxygen was dangerously low. The Aarogya Setu app even recommended home monitoring.

MAX30100 = Hospital-Grade Sensor at โ‚น200! This tiny sensor uses Red + Infrared LEDs and a photodetector to measure both SpO2 (blood oxygen) and Heart Rate (BPM) โ€” the same principle used in โ‚น50,000 hospital monitors. Build your own health monitor today!

๐Ÿ‡ฎ๐Ÿ‡ณ AIIMS Delhi๐Ÿ‡ฎ๐Ÿ‡ณ Apollo Hospitals๐Ÿ‡ฎ๐Ÿ‡ณ Aarogya Setu๐ŸŒ WHO

7.1 MAX30100 Sensor

The MAX30100 is an integrated pulse oximetry and heart-rate sensor. It combines two LEDs (Red + IR), a photodetector, and signal processing โ€” all in a tiny package.

How It Works

Oxygenated hemoglobin (HbOโ‚‚) absorbs more infrared light (880nm) and lets red light pass. Deoxygenated hemoglobin (Hb) absorbs more red light (660nm) and lets infrared pass. By comparing the absorption ratio of Red vs IR light through your fingertip, the sensor calculates SpOโ‚‚ percentage.

How Pulse Oximetry Works Finger (placed on sensor) โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Blood vessels with RBCs โ”‚ โ”‚ โ”Œโ”€โ” โ”Œโ”€โ” โ”Œโ”€โ” โ”Œโ”€โ” โ”Œโ”€โ” โ”‚ โ”‚ โ”‚โ—โ”‚ โ”‚โ—โ”‚ โ”‚โ—โ”‚ โ”‚โ—โ”‚ โ”‚โ—โ”‚ โ”‚ โ† Red Blood Cells โ”‚ โ””โ”€โ”˜ โ””โ”€โ”˜ โ””โ”€โ”˜ โ””โ”€โ”˜ โ””โ”€โ”˜ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ†‘ โ†‘ Red LED (660nm) IR LED (880nm) โ†“ โ†“ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Photodetector โ”‚ โ”‚ Measures light passing through โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ SpO2 = f(Red_absorption / IR_absorption) Normal SpO2: 95-100% Low: 90-94% Critical: Below 90% โš ๏ธ

MAX30100 Specifications

ParameterValue
Sensor TypeIntegrated Pulse Oximeter + Heart Rate
IC Operating Voltage1.8V โ€“ 3.3V
Module Operating Voltage5V (onboard regulator)
Communication InterfaceI2C
I2C Address0x57
SpO2 Accuracyยฑ2%
Heart Rate Range30 โ€“ 240 BPM
Red LED Wavelength660 nm
IR LED Wavelength880 nm
Current (LEDs active)~20 mA
Module Cost (India)โ‚น150โ€“250

7.2 Pin Connections

Connection Table (Arduino โ†’ MAX30100)

MAX30100 PinArduino PinPurpose
VIN5VPower (module has onboard regulator)
GNDGNDGround
SCLA5 (SCL)I2C Clock
SDAA4 (SDA)I2C Data
INTD2 (optional)Interrupt (beat detection)
Arduino Uno โ†โ†’ MAX30100 Pulse Oximeter Wiring ARDUINO UNO MAX30100 MODULE โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 5V โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ VIN โ”‚ โ”‚ GND โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ GND โ”‚ โ”‚ A5 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ SCL โ”‚ โ”‚ A4 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ SDA โ”‚ โ”‚ D2 โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€ INT โ”‚ (optional) โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ” โ”‚ Place โ”‚ โ”‚ finger โ”‚ โ”‚ here โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ Note: I2C needs pull-up resistors (4.7kฮฉ) Some modules have them built-in.

7.3 MAX30100_PulseOximeter Library

Install MAX30100lib by OXullo Intersecans from Arduino Library Manager.

FunctionDescription
PulseOximeter poxCreate PulseOximeter object
pox.begin()Initialize the sensor (returns true on success)
pox.update()Must be called frequently in loop() โ€” processes sensor data
pox.getHeartRate()Returns heart rate in BPM (float)
pox.getSpO2()Returns blood oxygen saturation in % (uint8_t)
pox.setOnBeatDetectedCallback(fn)Set callback function for each heartbeat detected
pox.setIRLedCurrent(val)Set IR LED current (MAX30100_LED_CURR_*)

7.4 Full Code โ€” Heart Rate & SpO2 Monitor

Arduino
// Program: Heart Rate & SpO2 Monitor using MAX30100
// Board: Arduino Uno
// Connections: SDA=A4, SCL=A5, VIN=5V, GND=GND

#include <Wire.h>
#include <MAX30100_PulseOximeter.h>

#define REPORTING_PERIOD_MS 1000

PulseOximeter pox;
uint32_t lastReport = 0;

// Callback for beat detection
void onBeatDetected() {
  Serial.println("โ™ฅ Beat!");
}

void setup() {
  Serial.begin(9600);
  Serial.println("Initializing Pulse Oximeter...");

  if (!pox.begin()) {
    Serial.println("MAX30100 FAILED! Check wiring.");
    while(1);
  }

  pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
  pox.setOnBeatDetectedCallback(onBeatDetected);
  Serial.println("Place your finger on the sensor...");
}

void loop() {
  pox.update();  // MUST call frequently!

  if (millis() - lastReport > REPORTING_PERIOD_MS) {
    Serial.print("Heart Rate: ");
    Serial.print(pox.getHeartRate());
    Serial.print(" BPM | SpO2: ");
    Serial.print(pox.getSpO2());
    Serial.println("%");
    lastReport = millis();
  }
}
Initializing Pulse Oximeter... Place your finger on the sensor... โ™ฅ Beat! Heart Rate: 72.45 BPM | SpO2: 97% โ™ฅ Beat! Heart Rate: 74.12 BPM | SpO2: 98% โ™ฅ Beat! Heart Rate: 71.88 BPM | SpO2: 97%

7.5 Health Monitoring Project

Arduino
// Project: Health Monitor with LCD + Buzzer + LED indicators
// Normal SpO2: 95-100%, Low: 90-94%, Critical: <90%

#include <Wire.h>
#include <MAX30100_PulseOximeter.h>
#include <LiquidCrystal.h>

#define REPORTING_PERIOD_MS 1000
#define GREEN_LED 6
#define RED_LED   7
#define BUZZER    8

PulseOximeter pox;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
uint32_t lastReport = 0;

void onBeatDetected() {
  digitalWrite(GREEN_LED, HIGH);
  delay(50);
  digitalWrite(GREEN_LED, LOW);
}

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  pinMode(GREEN_LED, OUTPUT);
  pinMode(RED_LED, OUTPUT);
  pinMode(BUZZER, OUTPUT);

  lcd.print("Initializing...");
  if (!pox.begin()) {
    lcd.clear(); lcd.print("SENSOR ERROR!");
    while(1);
  }
  pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
  pox.setOnBeatDetectedCallback(onBeatDetected);
  lcd.clear(); lcd.print("Place finger...");
}

void loop() {
  pox.update();

  if (millis() - lastReport > REPORTING_PERIOD_MS) {
    float bpm = pox.getHeartRate();
    uint8_t spo2 = pox.getSpO2();

    lcd.clear();
    lcd.print("BPM: "); lcd.print(bpm, 0);
    lcd.setCursor(0, 1);
    lcd.print("SpO2: "); lcd.print(spo2); lcd.print("%");

    // Health classification
    if (spo2 >= 95) {
      lcd.setCursor(10, 1); lcd.print("OK");
      digitalWrite(RED_LED, LOW);
      noTone(BUZZER);
    } else if (spo2 >= 90) {
      lcd.setCursor(10, 1); lcd.print("LOW!");
      digitalWrite(RED_LED, HIGH);
    } else if (spo2 > 0) {
      lcd.setCursor(10, 1); lcd.print("CRIT");
      digitalWrite(RED_LED, HIGH);
      tone(BUZZER, 1500);  // Continuous alarm!
    }

    // Check abnormal heart rate
    if (bpm > 120 || (bpm < 50 && bpm > 0)) {
      tone(BUZZER, 1000, 500); // Warning beep
    }

    lastReport = millis();
  }
}
During the COVID-19 second wave in India (Aprilโ€“May 2021), pulse oximeters became a lifeline. AIIMS Delhi issued guidelines to monitor SpO2 at home โ€” any reading below 94% required immediate hospitalization. The PM-CARES Fund distributed pulse oximeters across rural India. DIY Arduino-based oximeters using MAX30100 were built by engineering students for community health centers where commercial devices were unavailable.

7.6 Worked Examples

Example 1: Simple Heart Rate Reading

Arduino
#include <Wire.h>
#include <MAX30100_PulseOximeter.h>
PulseOximeter pox;
uint32_t lastReport = 0;
void setup() { Serial.begin(9600); pox.begin(); pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA); }
void loop() {
  pox.update();
  if(millis()-lastReport > 1000) {
    Serial.print("BPM: "); Serial.println(pox.getHeartRate());
    lastReport = millis();
  }
}

Example 2: SpO2 Only Reading

Arduino
#include <Wire.h>
#include <MAX30100_PulseOximeter.h>
PulseOximeter pox;
uint32_t lastReport = 0;
void setup() { Serial.begin(9600); pox.begin(); pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA); }
void loop() {
  pox.update();
  if(millis()-lastReport > 1000) {
    uint8_t spo2 = pox.getSpO2();
    Serial.print("SpO2: "); Serial.print(spo2); Serial.println("%");
    lastReport = millis();
  }
}

Example 3: Beat Detection with LED Blink

Arduino
#include <Wire.h>
#include <MAX30100_PulseOximeter.h>
PulseOximeter pox;
int ledPin = 13;
void onBeat() { digitalWrite(ledPin, !digitalRead(ledPin)); }
void setup() {
  Serial.begin(9600); pinMode(ledPin, OUTPUT);
  pox.begin(); pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
  pox.setOnBeatDetectedCallback(onBeat);
}
void loop() { pox.update(); }

Example 4: Heart Rate on LCD

Arduino
#include <Wire.h>
#include <MAX30100_PulseOximeter.h>
#include <LiquidCrystal.h>
PulseOximeter pox;
LiquidCrystal lcd(12,11,5,4,3,2);
uint32_t lastReport = 0;
void setup() {
  lcd.begin(16,2); pox.begin();
  pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
  lcd.print("Place finger...");
}
void loop() {
  pox.update();
  if(millis()-lastReport > 1000) {
    lcd.clear();
    lcd.print("Heart Rate:");
    lcd.setCursor(0,1);
    lcd.print(pox.getHeartRate(), 0); lcd.print(" BPM");
    lastReport = millis();
  }
}

Example 5: SpO2 + BPM on LCD with Status

Arduino
#include <Wire.h>
#include <MAX30100_PulseOximeter.h>
#include <LiquidCrystal.h>
PulseOximeter pox;
LiquidCrystal lcd(12,11,5,4,3,2);
uint32_t lastReport = 0;
void setup() { lcd.begin(16,2); pox.begin(); pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA); }
void loop() {
  pox.update();
  if(millis()-lastReport > 1000) {
    float bpm = pox.getHeartRate();
    uint8_t spo2 = pox.getSpO2();
    lcd.clear();
    lcd.print("BPM:"); lcd.print(bpm,0);
    lcd.setCursor(9,0); lcd.print("O2:"); lcd.print(spo2); lcd.print("%");
    lcd.setCursor(0,1);
    if(spo2>=95) lcd.print("Status: NORMAL");
    else if(spo2>=90) lcd.print("Status: LOW!");
    else if(spo2>0) lcd.print("CRITICAL!!!");
    else lcd.print("No finger...");
    lastReport = millis();
  }
}

Example 6: Data Logger to Serial (CSV)

Arduino
#include <Wire.h>
#include <MAX30100_PulseOximeter.h>
PulseOximeter pox;
uint32_t lastReport = 0;
int reading = 0;
void setup() {
  Serial.begin(9600); pox.begin();
  pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
  Serial.println("Reading,BPM,SpO2,Time_ms");
}
void loop() {
  pox.update();
  if(millis()-lastReport > 2000) {
    reading++;
    Serial.print(reading); Serial.print(",");
    Serial.print(pox.getHeartRate()); Serial.print(",");
    Serial.print(pox.getSpO2()); Serial.print(",");
    Serial.println(millis());
    lastReport = millis();
  }
}

Example 7: Heart Rate Zone Indicator

Arduino
#include <Wire.h>
#include <MAX30100_PulseOximeter.h>
PulseOximeter pox;
uint32_t lastReport = 0;
void setup() { Serial.begin(9600); pox.begin(); pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA); }
void loop() {
  pox.update();
  if(millis()-lastReport > 1000) {
    float bpm = pox.getHeartRate();
    Serial.print("BPM: "); Serial.print(bpm);
    if(bpm < 60) Serial.println(" โ†’ Resting");
    else if(bpm < 100) Serial.println(" โ†’ Normal");
    else if(bpm < 140) Serial.println(" โ†’ Exercise");
    else Serial.println(" โ†’ DANGER! Too high!");
    lastReport = millis();
  }
}

Example 8: Moving Average BPM (Smoothing)

Arduino
#include <Wire.h>
#include <MAX30100_PulseOximeter.h>
PulseOximeter pox;
float readings[5]; int idx=0;
uint32_t lastReport = 0;
void setup() {
  Serial.begin(9600); pox.begin(); pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
  for(int i=0;i<5;i++) readings[i]=0;
}
void loop() {
  pox.update();
  if(millis()-lastReport > 1000) {
    readings[idx] = pox.getHeartRate();
    idx = (idx+1) % 5;
    float avg = 0;
    for(int i=0;i<5;i++) avg += readings[i];
    avg /= 5;
    Serial.print("Avg BPM: "); Serial.println(avg);
    lastReport = millis();
  }
}

Example 9: Low SpO2 Alarm System

Arduino
#include <Wire.h>
#include <MAX30100_PulseOximeter.h>
PulseOximeter pox;
int buzzer = 8, redLed = 7;
uint32_t lastReport = 0;
void setup() {
  Serial.begin(9600); pinMode(buzzer,OUTPUT); pinMode(redLed,OUTPUT);
  pox.begin(); pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
}
void loop() {
  pox.update();
  if(millis()-lastReport > 1000) {
    uint8_t spo2 = pox.getSpO2();
    Serial.print("SpO2: "); Serial.println(spo2);
    if(spo2 > 0 && spo2 < 90) {
      digitalWrite(redLed, HIGH);
      tone(buzzer, 2000);
      Serial.println("!!! CRITICAL SpO2 !!!");
    } else {
      digitalWrite(redLed, LOW);
      noTone(buzzer);
    }
    lastReport = millis();
  }
}

Example 10: Full Patient Monitor (LCD + Buzzer + LEDs)

Arduino
#include <Wire.h>
#include <MAX30100_PulseOximeter.h>
#include <LiquidCrystal.h>
PulseOximeter pox;
LiquidCrystal lcd(12,11,5,4,3,2);
int greenLed=6, redLed=7, buzzer=8;
uint32_t lastReport=0;
void onBeat() { digitalWrite(greenLed,HIGH); delay(30); digitalWrite(greenLed,LOW); }
void setup() {
  Serial.begin(9600); lcd.begin(16,2);
  pinMode(greenLed,OUTPUT); pinMode(redLed,OUTPUT); pinMode(buzzer,OUTPUT);
  pox.begin(); pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
  pox.setOnBeatDetectedCallback(onBeat);
  lcd.print("Patient Monitor"); lcd.setCursor(0,1); lcd.print("Place finger...");
}
void loop() {
  pox.update();
  if(millis()-lastReport > 1000) {
    float bpm=pox.getHeartRate(); uint8_t spo2=pox.getSpO2();
    lcd.clear();
    lcd.print("BPM:"); lcd.print(bpm,0);
    lcd.setCursor(8,0); lcd.print("O2:"); lcd.print(spo2); lcd.print("%");
    lcd.setCursor(0,1);
    bool alarm = false;
    if(spo2>0 && spo2<90) { lcd.print("SpO2 CRITICAL!"); alarm=true; }
    else if(bpm>120) { lcd.print("BPM HIGH!"); alarm=true; }
    else if(bpm>0 && bpm<50) { lcd.print("BPM LOW!"); alarm=true; }
    else lcd.print("Status: NORMAL");
    digitalWrite(redLed, alarm?HIGH:LOW);
    if(alarm) tone(buzzer,1500,500); else noTone(buzzer);
    // CSV log to Serial
    Serial.print(bpm); Serial.print(","); Serial.print(spo2);
    Serial.print(","); Serial.println(alarm?"ALARM":"OK");
    lastReport = millis();
  }
}
MAX30100 shows 0 BPM or 0% SpO2? Check: (1) Finger must be placed firmly on the sensor โ€” not too tight, not too loose. (2) Don't move your finger during reading. (3) pox.update() must be called very frequently โ€” avoid using delay() in your loop! (4) Some MAX30100 modules need I2C pull-up resistors removed (if module already has them). (5) Try different setIRLedCurrent() values.
Best practices for accurate readings: (1) Use the index finger โ€” it gives the best signal. (2) Keep the finger still for 10โ€“15 seconds before trusting readings. (3) Avoid cold fingers โ€” warm them first. (4) Dark nail polish can affect readings. (5) The first few readings are always inaccurate โ€” use a moving average filter for stable values.

7.7 MCQs โ€” Chapter 7 (20 Questions)

Q1

MAX30100 measures which two parameters?

  1. Temperature and humidity
  2. Heart rate (BPM) and blood oxygen (SpO2)
  3. Blood pressure and pulse
  4. ECG and respiration rate
Remember
โœ… Answer: (B) โ€” MAX30100 is an integrated pulse oximeter that measures heart rate and SpO2.
Q2

MAX30100 communicates with Arduino using:

  1. SPI
  2. I2C
  3. UART
  4. One-Wire
Remember
โœ… Answer: (B) I2C โ€” MAX30100 uses I2C with SDA and SCL lines, at address 0x57.
Q3

What is the I2C address of MAX30100?

  1. 0x27
  2. 0x3C
  3. 0x57
  4. 0x68
Remember
โœ… Answer: (C) 0x57 โ€” This is the fixed I2C address of the MAX30100 sensor.
Q4

Which two wavelengths of light does MAX30100 use?

  1. Red (660nm) and Infrared (880nm)
  2. Green (530nm) and Blue (470nm)
  3. UV (365nm) and Red (660nm)
  4. White and Infrared
Remember
โœ… Answer: (A) โ€” Red LED at 660nm and IR LED at 880nm are used because oxygenated and deoxygenated hemoglobin absorb these wavelengths differently.
Q5

Normal SpO2 range for a healthy person is:

  1. 80โ€“90%
  2. 85โ€“95%
  3. 95โ€“100%
  4. 100% only
Remember
โœ… Answer: (C) 95โ€“100% โ€” Below 90% is considered critical and requires immediate medical attention.
Q6

Why must pox.update() be called frequently in loop()?

  1. To save battery
  2. To process raw sensor data and calculate BPM/SpO2
  3. To reset the sensor
  4. To calibrate the LEDs
Understand
โœ… Answer: (B) โ€” The library needs to continuously sample and process the photodetector data. Using delay() prevents timely sampling and causes inaccurate readings.
Q7

Oxygenated hemoglobin absorbs more:

  1. Red light
  2. Infrared light
  3. Green light
  4. UV light
Understand
โœ… Answer: (B) Infrared light โ€” Oxygenated hemoglobin (HbOโ‚‚) absorbs more IR light (880nm), while deoxygenated hemoglobin absorbs more red light (660nm).
Q8

Which Arduino pins are used for I2C?

  1. D0, D1
  2. D10, D11
  3. A4 (SDA), A5 (SCL)
  4. D2, D3
Remember
โœ… Answer: (C) โ€” On Arduino Uno, A4 is SDA and A5 is SCL for I2C communication.
Q9

What does SpO2 stand for?

  1. Special Oxygen Level 2
  2. Peripheral capillary oxygen saturation
  3. Systemic Pulse Oxygen
  4. Standard Pulse Output 2
Remember
โœ… Answer: (B) โ€” SpO2 measures the percentage of hemoglobin in arterial blood that is saturated with oxygen.
Q10

The setOnBeatDetectedCallback() function is used to:

  1. Set the heart rate manually
  2. Register a function called each time a heartbeat is detected
  3. Stop the sensor
  4. Calibrate the sensor
Understand
โœ… Answer: (B) โ€” It registers a callback function that gets automatically called whenever the sensor detects a heartbeat.
Q11

SpO2 below 90% is classified as:

  1. Normal
  2. Low
  3. Critical โ€” needs immediate medical attention
  4. Moderate
Understand
โœ… Answer: (C) Critical โ€” SpO2 below 90% indicates severe hypoxemia requiring oxygen therapy or emergency care.
Q12

Why do cold fingers give inaccurate SpO2 readings?

  1. Cold damages the sensor
  2. Reduced blood flow to extremities weakens the signal
  3. Cold changes oxygen levels
  4. The sensor can't work below 20ยฐC
Understand
โœ… Answer: (B) โ€” Cold causes vasoconstriction, reducing blood flow to fingertips and weakening the optical signal for accurate reading.
Q13

MAX30100 module operating voltage is:

  1. 1.8V only
  2. 3.3V only
  3. 5V (module has onboard voltage regulator)
  4. 12V
Remember
โœ… Answer: (C) โ€” While the MAX30100 IC itself works at 1.8โ€“3.3V, most modules include a voltage regulator allowing 5V input.
Q14

Normal resting heart rate for adults is:

  1. 30โ€“50 BPM
  2. 60โ€“100 BPM
  3. 100โ€“150 BPM
  4. 150โ€“200 BPM
Remember
โœ… Answer: (B) 60โ€“100 BPM โ€” Athletes may have lower resting rates (40โ€“60 BPM).
Q15

During COVID-19, AIIMS recommended hospitalization if SpO2 falls below:

  1. 98%
  2. 96%
  3. 94%
  4. 90%
Understand
โœ… Answer: (C) 94% โ€” AIIMS Delhi guidelines recommended seeking medical help if SpO2 dropped below 94% for COVID-19 patients.
Q16

What does the photodetector in MAX30100 measure?

  1. Temperature of the finger
  2. Light transmitted through or reflected from the finger
  3. Electrical signals from the heart
  4. Blood pressure
Understand
โœ… Answer: (B) โ€” The photodetector measures the amount of Red and IR light that passes through the finger (or is reflected), which varies with blood oxygenation and pulse.
Q17

Using delay() in the loop with MAX30100 causes:

  1. More accurate readings
  2. Sensor to read faster
  3. Inaccurate or zero readings due to missed sampling
  4. No effect
Apply
โœ… Answer: (C) โ€” delay() blocks execution, preventing pox.update() from being called frequently enough. Use millis() for timing instead.
Q18

I2C uses how many data wires?

  1. 1
  2. 2
  3. 3
  4. 4
Remember
โœ… Answer: (B) 2 โ€” SDA (data) and SCL (clock). This is a key advantage of I2C over SPI.
Q19

To smooth noisy BPM readings, which technique is used?

  1. Increase LED current
  2. Moving average filter
  3. Reset the sensor
  4. Use SPI instead of I2C
Apply
โœ… Answer: (B) โ€” A moving average filter takes the average of the last N readings, smoothing out noise and providing more stable values.
Q20

pox.getSpO2() returns which data type?

  1. float
  2. int
  3. uint8_t (unsigned 8-bit integer)
  4. String
Understand
โœ… Answer: (C) uint8_t โ€” SpO2 is an integer percentage (0โ€“100), so it's returned as an unsigned 8-bit integer.
Chapter 8

Bluetooth with Arduino (HC-05)

๐ŸŽฏ Why This Matters

Your smartphone connects to speakers, fitness bands, and car systems via Bluetooth. With HC-05 and Arduino, you can build wireless control systems for โ‚น150!

boAtJBLMi BandSmart Home

8.1 HC-05 Bluetooth Module

Specifications:

ParameterValue
ProtocolBluetooth 2.0 + EDR
Frequency2.4 GHz ISM band
Range~10 meters
Operating Voltage3.3Vโ€“6V
Baud Rate (default)9600 bps
ModesMaster / Slave / Loop-back
InterfaceUART (TX, RX)

8.2 Pin Diagram & Connections

  HC-05 Module Pins:
  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  โ”‚  HC-05 Bluetooth     โ”‚
  โ”‚                      โ”‚
  โ”‚  VCC โ”€โ”€โ”€โ”€ 5V Arduino โ”‚
  โ”‚  GND โ”€โ”€โ”€โ”€ GND        โ”‚
  โ”‚  TXD โ”€โ”€โ”€โ”€ Pin 10 (RX)โ”‚
  โ”‚  RXD โ”€โ”€โ”€โ”€ Pin 11 (TX)โ”‚  โš ๏ธ Use voltage divider!
  โ”‚  EN  โ”€โ”€โ”€โ”€ (for AT)   โ”‚     RXD is 3.3V tolerant
  โ”‚  STATE โ”€โ”€ (optional) โ”‚     Use 1K + 2K divider
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
HC-05 PinArduino PinNotes
VCC5VPower supply
GNDGNDCommon ground
TXDPin 10 (Software RX)HC-05 sends data
RXDPin 11 (Software TX)Via voltage divider (5Vโ†’3.3V)

8.3 AT Commands

Hold EN/KEY button while powering ON to enter AT command mode (LED blinks slowly ~2s).

CommandFunctionResponse
ATTest connectionOK
AT+NAME=MyBTSet device nameOK
AT+BAUD4Set baud to 9600OK9600
AT+ROLE=0Set as slaveOK
AT+PSWD=1234Set pairing PINOK
AT+ADDR?Get MAC address+ADDR:...

8.4 Arduino Code: LED Control via Bluetooth

#include <SoftwareSerial.h>

SoftwareSerial BTSerial(10, 11); // RX=10, TX=11
int ledPin = 13;

void setup() {
  Serial.begin(9600);
  BTSerial.begin(9600);
  pinMode(ledPin, OUTPUT);
  Serial.println("Bluetooth LED Control Ready!");
}

void loop() {
  if (BTSerial.available()) {
    char command = BTSerial.read();
    Serial.print("Received: ");
    Serial.println(command);
    
    if (command == '1') {
      digitalWrite(ledPin, HIGH);
      BTSerial.println("LED ON");
      Serial.println("LED turned ON");
    }
    else if (command == '0') {
      digitalWrite(ledPin, LOW);
      BTSerial.println("LED OFF");
      Serial.println("LED turned OFF");
    }
  }
}
๐Ÿ“ฑ Testing: Use "Serial Bluetooth Terminal" app (Android) or MIT App Inventor. Pair with HC-05 (PIN: 1234), connect, send '1' for ON, '0' for OFF.

8.5 Multi-Device Control Project

// Control 4 devices via Bluetooth
// Send: 'A'=LED1 ON, 'a'=LED1 OFF, 'B'=Fan ON, etc.
#include <SoftwareSerial.h>
SoftwareSerial BT(10, 11);

int led1=2, led2=3, fan=4, buzzer=5;

void setup() {
  BT.begin(9600);
  pinMode(led1, OUTPUT); pinMode(led2, OUTPUT);
  pinMode(fan, OUTPUT);  pinMode(buzzer, OUTPUT);
}

void loop() {
  if (BT.available()) {
    char c = BT.read();
    switch(c) {
      case 'A': digitalWrite(led1, HIGH); BT.println("LED1 ON"); break;
      case 'a': digitalWrite(led1, LOW);  BT.println("LED1 OFF"); break;
      case 'B': digitalWrite(fan, HIGH);  BT.println("Fan ON"); break;
      case 'b': digitalWrite(fan, LOW);   BT.println("Fan OFF"); break;
      case 'C': digitalWrite(buzzer, HIGH); BT.println("Buzzer ON"); break;
      case 'c': digitalWrite(buzzer, LOW);  BT.println("Buzzer OFF"); break;
    }
  }
}

8.6 MCQs โ€” Chapter 8 (20 Questions)

Q1. HC-05 operates on which frequency band?
(a) 900 MHz (b) 2.4 GHz โœ“ (c) 5 GHz (d) 433 MHz
Q2. Default baud rate of HC-05?
(a) 4800 (b) 9600 โœ“ (c) 115200 (d) 38400
Q3. HC-05 RXD pin voltage tolerance?
(a) 5V (b) 3.3V โœ“ (c) 1.8V (d) 12V
Q4. AT command to set device name?
(a) AT+BAUD (b) AT+NAME โœ“ (c) AT+ROLE (d) AT+PSWD
Q5. Which library is used for software serial?
(a) Wire.h (b) SoftwareSerial.h โœ“ (c) SPI.h (d) Servo.h
Q6. HC-05 default pairing PIN?
(a) 0000 (b) 1234 โœ“ (c) 9999 (d) 1111
Q7. HC-05 communication range?
(a) 100m (b) ~10m โœ“ (c) 1km (d) 50cm
Q8. Which mode makes HC-05 initiate connection?
(a) Slave (b) Master โœ“ (c) Loop-back (d) Monitor
Q9. AT mode is entered by holding EN pin during?
(a) Reset (b) Power-on โœ“ (c) Data transfer (d) Pairing
Q10. Voltage divider for HC-05 RXD uses which resistors?
(a) 10K+10K (b) 1K+2K โœ“ (c) 100+200 (d) 4.7K+4.7K
Q11. BTSerial.available() returns?
(a) True/False (b) Number of bytes available โœ“ (c) String (d) Void
Q12. HC-05 LED blinks fast in which mode?
(a) AT mode (b) Not connected (waiting) โœ“ (c) Connected (d) Sleep
Q13. Bluetooth protocol version of HC-05?
(a) 4.0 BLE (b) 2.0 + EDR โœ“ (c) 5.0 (d) 3.0
Q14. SoftwareSerial(10,11) โ€” 10 is?
(a) TX (b) RX โœ“ (c) VCC (d) GND
Q15. AT+ROLE=0 sets HC-05 as?
(a) Master (b) Slave โœ“ (c) Bridge (d) Off
Q16. Which app can control Arduino via Bluetooth?
(a) WhatsApp (b) Serial Bluetooth Terminal โœ“ (c) Chrome (d) Calculator
Q17. Maximum data rate of HC-05?
(a) 1 Mbps (b) 2-3 Mbps โœ“ (c) 100 Mbps (d) 10 kbps
Q18. HC-05 uses which modulation?
(a) AM (b) GFSK โœ“ (c) QAM (d) PSK
Q19. BTSerial.read() returns?
(a) String (b) Single byte (char) โœ“ (c) Integer array (d) Float
Q20. HC-05 vs HC-06 main difference?
(a) Frequency (b) HC-05 can be master+slave, HC-06 slave only โœ“ (c) Range (d) Price
Chapter 9

WiFi with Arduino (ESP8266)

๐ŸŒ Why This Matters

ESP8266 gives your Arduino WiFi for โ‚น120! Build web-controlled devices, IoT dashboards, and smart home systems โ€” all accessible from any browser on your network.

EspressifNodeMCUWemosSmart Home

9.1 ESP8266 Module Overview

ParameterValue
CPUTensilica L106, 80/160 MHz
WiFi802.11 b/g/n, 2.4 GHz
Flash512KB โ€“ 4MB
GPIO Pins17 (varies by module)
Operating Voltage3.3V (โš ๏ธ NOT 5V tolerant!)
ModesStation (STA), Access Point (AP), STA+AP
ProtocolsTCP/IP, HTTP, MQTT
  ESP8266 Pin Layout (ESP-01):
  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  โ”‚   ESP-01 Module   โ”‚
  โ”‚                   โ”‚
  โ”‚  VCC โ”€โ”€โ”€ 3.3V     โ”‚  โš ๏ธ MUST be 3.3V!
  โ”‚  GND โ”€โ”€โ”€ GND      โ”‚
  โ”‚  TX  โ”€โ”€โ”€ Pin 10   โ”‚
  โ”‚  RX  โ”€โ”€โ”€ Pin 11   โ”‚  Via voltage divider
  โ”‚  CH_PDโ”€โ”€ 3.3V     โ”‚  Enable pin (pull HIGH)
  โ”‚  RST โ”€โ”€โ”€ 3.3V     โ”‚  Reset (pull HIGH)
  โ”‚  GPIO0โ”€โ”€ Float    โ”‚  LOW = flash mode
  โ”‚  GPIO2โ”€โ”€ Float    โ”‚
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

9.2 AT Commands for ESP8266

CommandFunction
ATTest (response: OK)
AT+CWMODE=1Station mode
AT+CWMODE=2Access Point mode
AT+CWJAP="SSID","password"Connect to WiFi
AT+CIFSRGet IP address
AT+CIPMUX=1Enable multiple connections
AT+CIPSERVER=1,80Start web server on port 80

9.3 Web Server โ€” Control LED from Browser

Using NodeMCU (ESP8266 board) with Arduino IDE:

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

const char* ssid = "YourWiFi";
const char* password = "YourPassword";
int ledPin = D2; // GPIO4

ESP8266WebServer server(80);

void handleRoot() {
  String html = "<!DOCTYPE html><html><head>";
  html += "<title>IoT LED Control</title>";
  html += "<style>body{font-family:Arial;text-align:center;padding:50px;}";
  html += "button{padding:20px 40px;font-size:24px;margin:10px;border-radius:12px;";
  html += "border:none;cursor:pointer;color:white;}";
  html += ".on{background:#10b981;} .off{background:#ef4444;}</style></head>";
  html += "<body><h1>๐Ÿ  Smart LED Control</h1>";
  html += "<p>LED is: " + String(digitalRead(ledPin) ? "ON ๐Ÿ’ก" : "OFF ๐Ÿ”Œ") + "</p>";
  html += "<a href='/on'><button class='on'>Turn ON</button></a>";
  html += "<a href='/off'><button class='off'>Turn OFF</button></a>";
  html += "</body></html>";
  server.send(200, "text/html", html);
}

void handleOn()  { digitalWrite(ledPin, HIGH); server.sendHeader("Location","/"); server.send(303); }
void handleOff() { digitalWrite(ledPin, LOW);  server.sendHeader("Location","/"); server.send(303); }

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
  Serial.println("\nConnected! IP: " + WiFi.localIP().toString());
  
  server.on("/", handleRoot);
  server.on("/on", handleOn);
  server.on("/off", handleOff);
  server.begin();
}

void loop() { server.handleClient(); }
๐Ÿ“ฑ Access: Open browser โ†’ type the IP address shown in Serial Monitor (e.g., 192.168.1.105). Control LED from any device on same WiFi!

9.4 Sending Sensor Data via HTTP

// Send DHT22 data to a web page
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <DHT.h>

DHT dht(D4, DHT22);
ESP8266WebServer server(80);

void handleData() {
  float temp = dht.readTemperature();
  float hum = dht.readHumidity();
  String json = "{\"temperature\":" + String(temp) + 
                ",\"humidity\":" + String(hum) + "}";
  server.send(200, "application/json", json);
}

void setup() {
  dht.begin();
  WiFi.begin("SSID", "PASS");
  while (WiFi.status() != WL_CONNECTED) delay(500);
  server.on("/data", handleData);
  server.begin();
}

void loop() { server.handleClient(); }

9.5 MCQs โ€” Chapter 9 (20 Questions)

Q1. ESP8266 operating voltage?
(a) 5V (b) 3.3V โœ“ (c) 12V (d) 1.8V
Q2. AT+CWMODE=1 sets ESP8266 to?
(a) AP (b) Station โœ“ (c) Mesh (d) Off
Q3. ESP8266 WiFi standard?
(a) 802.11ac (b) 802.11 b/g/n โœ“ (c) 802.11ax (d) 802.15.4
Q4. WiFi.begin() function does?
(a) Stops WiFi (b) Connects to WiFi network โœ“ (c) Creates AP (d) Scans networks
Q5. server.on("/", handler) registers?
(a) Timer (b) URL route handler โœ“ (c) Interrupt (d) Sensor
Q6. WiFi.localIP() returns?
(a) MAC address (b) IP address โœ“ (c) SSID (d) Password
Q7. HTTP status code 200 means?
(a) Not Found (b) OK (Success) โœ“ (c) Redirect (d) Error
Q8. ESP8266 CPU speed?
(a) 16 MHz (b) 80/160 MHz โœ“ (c) 1 GHz (d) 8 MHz
Q9. CH_PD pin should be connected to?
(a) GND (b) 3.3V (HIGH) โœ“ (c) 5V (d) Float
Q10. GPIO0 LOW during boot enters?
(a) Normal mode (b) Flash/Programming mode โœ“ (c) Sleep (d) AT mode
Q11. AT+CIFSR returns?
(a) Mode (b) IP address โœ“ (c) SSID (d) Baud rate
Q12. ESP8266 manufacturer?
(a) Arduino (b) Espressif Systems โœ“ (c) Microchip (d) Intel
Q13. server.handleClient() should be in?
(a) setup() (b) loop() โœ“ (c) Header (d) Global scope
Q14. ESP8266 supports which protocol for IoT?
(a) I2C only (b) TCP/IP, HTTP, MQTT โœ“ (c) CAN only (d) USB only
Q15. NodeMCU is based on?
(a) ATmega328 (b) ESP8266 โœ“ (c) PIC16F (d) STM32
Q16. WiFi.status() == WL_CONNECTED means?
(a) Disconnected (b) Successfully connected โœ“ (c) Error (d) Scanning
Q17. HTTP method for sending form data?
(a) GET (b) POST โœ“ (c) DELETE (d) PATCH
Q18. ESP-01 has how many GPIO pins?
(a) 17 (b) 2 (GPIO0, GPIO2) โœ“ (c) 8 (d) 4
Q19. server.send(200, "text/html", html) โ€” 200 is?
(a) Port (b) HTTP status code โœ“ (c) Delay (d) Pin number
Q20. ESP32 advantage over ESP8266?
(a) Cheaper (b) Dual-core + BLE + more GPIO โœ“ (c) Smaller (d) Less power
Chapter 10

IoT Cloud & Futuristic Technologies

โ˜๏ธ Why This Matters

ThingSpeak lets you visualize sensor data from anywhere in the world โ€” for FREE! AWS IoT and Azure IoT power billions of devices. Silicon Labs kits bring IoT to Indian smart homes.

ThingSpeakAWS IoTAzureSilicon Labs

10.1 ThingSpeak IoT Platform

Steps: 1. Create account at thingspeak.com โ†’ 2. Create Channel โ†’ 3. Note API Key โ†’ 4. Send data from ESP8266

// Send DHT22 data to ThingSpeak
#include <ESP8266WiFi.h>
#include <DHT.h>

const char* ssid = "YourWiFi";
const char* password = "YourPass";
const char* server = "api.thingspeak.com";
String apiKey = "YOUR_WRITE_API_KEY";

DHT dht(D4, DHT22);
WiFiClient client;

void setup() {
  Serial.begin(115200);
  dht.begin();
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) delay(500);
  Serial.println("WiFi Connected! IP: " + WiFi.localIP().toString());
}

void loop() {
  float temp = dht.readTemperature();
  float hum = dht.readHumidity();
  
  if (client.connect(server, 80)) {
    String postStr = "api_key=" + apiKey;
    postStr += "&field1=" + String(temp);
    postStr += "&field2=" + String(hum);
    
    client.println("POST /update HTTP/1.1");
    client.println("Host: api.thingspeak.com");
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.println("Content-Length: " + String(postStr.length()));
    client.println();
    client.print(postStr);
    
    Serial.println("Sent: Temp=" + String(temp) + " Hum=" + String(hum));
  }
  client.stop();
  delay(20000); // ThingSpeak requires 15s minimum between updates
}

10.2 Cloud Platforms Comparison

PlatformFree TierProtocolBest For
ThingSpeakYes (3M messages/yr)HTTP, MQTTLearning, prototyping
AWS IoT Core12 months freeMQTT, HTTP, WebSocketEnterprise scale
Azure IoT Hub8000 msgs/day freeMQTT, AMQP, HTTPMicrosoft ecosystem
Google Cloud IoTLimitedMQTT, HTTPData analytics
BlynkYes (limited)CustomMobile app control

10.3 Smart Home Project

System: ESP8266 + Relay Module + ThingSpeak + Mobile App

// Smart Home: Control relay via ThingSpeak
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

int relayPin = D1;
String readApiKey = "YOUR_READ_API_KEY";

void setup() {
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, HIGH); // Relay OFF (active LOW)
  WiFi.begin("SSID", "PASS");
  while (WiFi.status() != WL_CONNECTED) delay(500);
}

void loop() {
  HTTPClient http;
  String url = "http://api.thingspeak.com/channels/YOUR_CHANNEL/fields/1/last.txt";
  url += "?api_key=" + readApiKey;
  
  http.begin(url);
  int httpCode = http.GET();
  if (httpCode == 200) {
    String payload = http.getString();
    if (payload.toInt() == 1) digitalWrite(relayPin, LOW);  // ON
    else                      digitalWrite(relayPin, HIGH); // OFF
  }
  http.end();
  delay(5000);
}

10.4 Silicon Labs W7230F1 EVB/Kit

Setup Steps:

  1. Download and install Simplicity Studio from silabs.com
  2. Connect W7230F1 EVB via USB
  3. Select board in Simplicity Studio โ†’ Create new project
  4. Use GPIO driver to control onboard LED
  5. For mobile control: Use BLE/WiFi to send commands from phone app
// Pseudocode: Si Labs W7230F1 LED Control
// In Simplicity Studio C project:
#include "em_gpio.h"
#include "em_cmu.h"

void initGPIO(void) {
  CMU_ClockEnable(cmuClock_GPIO, true);
  GPIO_PinModeSet(gpioPortF, 4, gpioModePushPull, 0); // LED0
  GPIO_PinModeSet(gpioPortF, 5, gpioModePushPull, 0); // LED1
}

void toggleLED(int led) {
  if (led == 0) GPIO_PinOutToggle(gpioPortF, 4);
  else          GPIO_PinOutToggle(gpioPortF, 5);
}
// Mobile phone control: BLE GATT service receives ON/OFF
// commands and calls toggleLED() โ€” smart home application

10.5 Future of IoT in India

DomainApplicationIndian Example
Smart CitiesTraffic, parking, wasteSmart Cities Mission (100 cities)
AgricultureSoil moisture, drone sprayFasal, CropIn, Stellapps
HealthcareRemote monitoring, wearablesCOVID telemedicine, SanketLife
Industry 4.0Predictive maintenanceTata Steel, L&T smart factory
EnergySmart grid, solar monitoringEESL smart meters

10.6 MCQs โ€” Chapter 10 (20 Questions)

Q1. ThingSpeak minimum update interval?
(a) 1 second (b) 15 seconds โœ“ (c) 1 minute (d) 5 seconds
Q2. ThingSpeak uses which protocol?
(a) CAN (b) HTTP and MQTT โœ“ (c) I2C (d) SPI
Q3. API key in ThingSpeak is used for?
(a) Login (b) Authentication for data read/write โœ“ (c) Encryption (d) Routing
Q4. AWS IoT primary protocol?
(a) HTTP only (b) MQTT โœ“ (c) FTP (d) SMTP
Q5. Relay module controls?
(a) Only DC (b) Both AC and DC devices โœ“ (c) Only AC (d) Only sensors
Q6. Simplicity Studio is IDE for?
(a) Arduino (b) Silicon Labs โœ“ (c) Raspberry Pi (d) ESP8266
Q7. India's Smart Cities Mission covers?
(a) 10 cities (b) 100 cities โœ“ (c) 500 cities (d) 28 states
Q8. MQTT stands for?
(a) Maximum Query Transfer (b) Message Queuing Telemetry Transport โœ“ (c) Multi Queue TCP (d) Minimal Query Transport
Q9. ThingSpeak channel can have how many fields?
(a) 4 (b) 8 โœ“ (c) 16 (d) Unlimited
Q10. Active LOW relay turns ON when signal is?
(a) HIGH (b) LOW โœ“ (c) Floating (d) PWM
Q11. Digital twin is?
(a) Hardware clone (b) Virtual replica of physical system โœ“ (c) Backup server (d) Mirror website
Q12. Edge computing means?
(a) Cloud processing (b) Processing data near the source โœ“ (c) Central server (d) Manual entry
Q13. Fasal (India) uses IoT for?
(a) Healthcare (b) Agriculture โœ“ (c) Banking (d) Education
Q14. W7230F1 EVB uses which IDE?
(a) Arduino IDE (b) Simplicity Studio โœ“ (c) VS Code (d) Eclipse
Q15. HTTPClient.GET() returns?
(a) String (b) HTTP status code (int) โœ“ (c) Boolean (d) Void
Q16. Blynk platform is designed for?
(a) Web only (b) Mobile app IoT control โœ“ (c) Database (d) Email
Q17. Industry 4.0 refers to?
(a) First industrial revolution (b) Smart manufacturing with IoT/AI โœ“ (c) Steam power (d) Assembly line
Q18. EESL in India deploys?
(a) Solar panels (b) Smart meters โœ“ (c) Drones (d) EVs only
Q19. TinyML means?
(a) Big models (b) Machine learning on microcontrollers โœ“ (c) Cloud ML (d) Database
Q20. NB-IoT stands for?
(a) New Bluetooth (b) Narrowband Internet of Things โœ“ (c) Network Bridge (d) Normal Band
๐Ÿ”ฌ Practicals

Lab Programs (10 Experiments)

Lab 1: LED Brightness Control using PWM

Objective: Control LED brightness using analogWrite()

Components: Arduino UNO, LED, 220ฮฉ resistor, breadboard

ArduinoComponent
Pin 9 (PWM)LED Anode (+) via 220ฮฉ
GNDLED Cathode (โˆ’)
int ledPin = 9;
void setup() { pinMode(ledPin, OUTPUT); }
void loop() {
  for (int i = 0; i <= 255; i += 5) {
    analogWrite(ledPin, i);  // Increase brightness
    delay(30);
  }
  for (int i = 255; i >= 0; i -= 5) {
    analogWrite(ledPin, i);  // Decrease brightness
    delay(30);
  }
}

Viva: 1) What is PWM? 2) analogWrite range? (0-255) 3) Which pins support PWM? (~3,5,6,9,10,11) 4) Duty cycle at analogWrite(127)? (50%) 5) PWM frequency on Arduino? (~490 Hz)

Lab 2: LCD Interfacing

Objective: Display text on 16x2 LCD

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // RS,EN,D4-D7
void setup() { lcd.begin(16, 2); lcd.print("Hello EduArtha!"); lcd.setCursor(0, 1); lcd.print("IoT Lab 2"); }
void loop() {}

Viva: 1) LCD modes? (4-bit, 8-bit) 2) RS pin function? (Register Select) 3) How many chars per line? (16) 4) lcd.setCursor(0,1)? (Row 2, Col 1) 5) V0 pin? (Contrast)

Lab 3: Analog Read and ADC Programming

Objective: Read potentiometer value using ADC

int potPin = A0;
void setup() { Serial.begin(9600); }
void loop() {
  int val = analogRead(potPin);      // 0-1023
  float voltage = val * (5.0/1023.0); // Convert to voltage
  Serial.print("ADC: "); Serial.print(val);
  Serial.print(" | Voltage: "); Serial.println(voltage);
  delay(500);
}

Viva: 1) ADC resolution? (10-bit = 1024 levels) 2) analogRead range? (0-1023) 3) Reference voltage? (5V) 4) Step size? (5/1024 โ‰ˆ 4.88mV) 5) Analog pins? (A0-A5)

Lab 4: DHT22 Temperature & Humidity

#include <DHT.h>
DHT dht(2, DHT22);
void setup() { Serial.begin(9600); dht.begin(); }
void loop() {
  float t = dht.readTemperature();
  float h = dht.readHumidity();
  Serial.print("Temp: "); Serial.print(t); Serial.print("ยฐC | Hum: "); Serial.print(h); Serial.println("%");
  delay(2000);
}

Viva: 1) DHT22 accuracy? (ยฑ0.5ยฐC) 2) Protocol? (Single-wire) 3) Pull-up resistor value? (10Kฮฉ) 4) Min read interval? (2s) 5) DHT11 vs DHT22? (DHT22 more accurate)

Lab 5: LDR, Ultrasonic & IR Sensor

// Ultrasonic HC-SR04
int trigPin = 9, echoPin = 10;
void setup() { Serial.begin(9600); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); }
void loop() {
  digitalWrite(trigPin, LOW); delayMicroseconds(2);
  digitalWrite(trigPin, HIGH); delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  long duration = pulseIn(echoPin, HIGH);
  float distance = duration * 0.034 / 2;
  Serial.print("Distance: "); Serial.print(distance); Serial.println(" cm");
  delay(500);
}

Viva: 1) Speed of sound? (340 m/s) 2) Why divide by 2? (Round trip) 3) HC-SR04 range? (2-400cm) 4) LDR principle? (Resistance โˆ 1/Light) 5) IR sensor output? (Digital HIGH/LOW)

Lab 6: RFID Module (RC522)

#include <SPI.h>
#include <MFRC522.h>
MFRC522 rfid(10, 9); // SS=10, RST=9
void setup() { Serial.begin(9600); SPI.begin(); rfid.PCD_Init(); Serial.println("Scan RFID card..."); }
void loop() {
  if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) return;
  Serial.print("UID: ");
  for (byte i = 0; i < rfid.uid.size; i++) { Serial.print(rfid.uid.uidByte[i], HEX); Serial.print(" "); }
  Serial.println();
  rfid.PICC_HaltA();
}

Viva: 1) RFID frequency? (13.56 MHz) 2) SPI pins? (MOSI=11, MISO=12, SCK=13) 3) UID bytes? (4-7) 4) Active vs Passive tags? 5) Indian use? (FASTag, Metro)

Lab 7: DC Motors with L298N

int ENA=5, IN1=6, IN2=7;
void setup() { pinMode(ENA, OUTPUT); pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); }
void loop() {
  // Forward
  digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); analogWrite(ENA, 200);
  delay(2000);
  // Reverse
  digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); analogWrite(ENA, 200);
  delay(2000);
  // Stop
  digitalWrite(IN1, LOW); digitalWrite(IN2, LOW);
  delay(1000);
}

Viva: 1) L298N channels? (2) 2) Max current per channel? (2A) 3) H-bridge purpose? (Direction control) 4) ENA pin for? (Speed via PWM) 5) Why not connect motor directly? (Current limit)

Lab 8: Bluetooth and WiFi Interfacing

// Bluetooth HC-05: See Chapter 8 code
// WiFi ESP8266: See Chapter 9 code
// Combined: BT for local control, WiFi for remote dashboard

Viva: 1) HC-05 default baud? (9600) 2) ESP8266 voltage? (3.3V) 3) BT range? (~10m) 4) WiFi standard? (802.11 b/g/n) 5) SoftwareSerial purpose? (Extra UART)

Lab 9: Silicon Labs W7230F1 โ€” Simplicity Studio + LED Control

Steps:

  1. Download Simplicity Studio v5 from silabs.com/developers
  2. Install supported packages for W7230F1
  3. Connect EVB via USB, select board in IDE
  4. Create new C project โ†’ Add GPIO driver
  5. Use GPIO_PinOutToggle() to blink onboard LED
  6. Build โ†’ Flash โ†’ Verify LED blinks

Viva: 1) Simplicity Studio based on? (Eclipse) 2) GPIO init function? (GPIO_PinModeSet) 3) Clock enable? (CMU_ClockEnable) 4) Push-pull vs open-drain? 5) Debug interface? (SWD/JTAG)

Lab 10: Silicon Labs Mobile Phone Control (Smart Home)

Steps:

  1. Configure BLE GATT service on W7230F1
  2. Create characteristic for LED ON/OFF command
  3. Use EFR Connect mobile app (Android/iOS) to discover device
  4. Send write command to toggle onboard LED
  5. Extend: Add relay module for AC appliance control

Viva: 1) BLE vs Classic BT? (Low power) 2) GATT? (Generic Attribute Profile) 3) Characteristic? (Data endpoint) 4) EFR Connect app by? (Silicon Labs) 5) Smart home protocol? (BLE/Zigbee/WiFi)

๐Ÿ“Ž Reference

Appendices

Appendix A: Arduino Uno R3 Pin Reference

PinTypeFunction
D0DigitalRX (Serial receive)
D1DigitalTX (Serial transmit)
D2-D7DigitalGeneral purpose I/O
D3,5,6,9,10,11PWManalogWrite() capable (~)
D10-D13SPISS, MOSI, MISO, SCK
A0-A5Analog10-bit ADC (0-1023)
A4, A5I2CSDA, SCL
VINPowerExternal supply (7-12V)
5V, 3.3VPowerRegulated output
GNDPowerGround (3 pins)

Appendix B: Common Libraries Quick Reference

LibraryPurposeKey Functions
LiquidCrystal.h16x2 LCDbegin(), print(), setCursor()
Servo.hServo motorattach(), write(), read()
DHT.hDHT11/22 sensorreadTemperature(), readHumidity()
SPI.hSPI protocolbegin(), transfer()
Wire.hI2C protocolbegin(), requestFrom(), write()
SoftwareSerial.hExtra UARTbegin(), read(), print()
MFRC522.hRFID RC522PCD_Init(), ReadCardSerial()
ESP8266WiFi.hESP8266 WiFibegin(), localIP(), status()
MD_Parola.hLED Matrixbegin(), displayText()

Appendix C: Troubleshooting Guide

ProblemCauseSolution
COM port not detectedDriver missingInstall CH340/CP2102 driver
Upload failedWrong board/portCheck Tools โ†’ Board and Port
Sensor reads NaNWiring or pull-upCheck connections, add 10K pull-up
Motor not spinningInsufficient currentUse external power supply for motor driver
ESP8266 keeps resetting3.3V power insufficientUse dedicated 3.3V regulator (AMS1117)
LCD shows blocksContrast not setAdjust V0 potentiometer
Bluetooth not pairingWrong mode/PINReset HC-05, use AT commands to configure

Appendix D: IoT Project Ideas for Portfolio

#ProjectComponentsDifficulty
1Smart Weather StationDHT22 + LCD + ESP8266 + ThingSpeakโญโญ
2Home Automation (4 devices)ESP8266 + 4-Relay + Web Serverโญโญโญ
3RFID Attendance SystemRC522 + LCD + SD Card + RTCโญโญโญ
4Smart Parking SystemUltrasonic + Servo + LCD + IRโญโญ
5Health Monitor WearableMAX30100 + OLED + BLEโญโญโญโญ
6Smart Agriculture SystemSoil moisture + DHT22 + Relay + ESP8266โญโญโญ
7GPS Vehicle TrackerNEO-6M GPS + SIM800L + Arduinoโญโญโญโญ
8Robot Car with App ControlL298N + 2 DC Motors + HC-05 + Appโญโญโญ

โœ… Programming IoT: COMPLETE!

๐ŸŽ‰ Congratulations! You have completed all 10 chapters covering LCD, Sensors, Motors, RFID, Pulse Oximeter, Bluetooth, WiFi, IoT Cloud, and Futuristic Technologies.

๐Ÿ“Š 200 MCQs solved | ๐Ÿ”ฌ 10 Lab Programs done | ๐Ÿ“Ž 4 Appendices referenced

๐Ÿš€ You are IoT-Ready & Hackathon-Ready!