Homepage Background Image

Program Overview

This comprehensive course covers everything from understanding Single Board Computers to building web-controlled home automation systems. Each module builds on the previous one, ensuring you gain practical skills through real-world projects.

Project roadmap: we'll start with a simple LED blink project, then move to an LDR (light sensor) digital test, and finish with a small Automation project using Django to build a web interface and control logic.

Part 1: Raspberry Pi — Imager & VNC Setup

Download Raspberry Pi Imager

Open the official Raspberry Pi software download page and download the Raspberry Pi Imager for your OS:

https://www.raspberrypi.com/software/

Raspberry Pi Imager screenshot
Step-by-step: Flash OS using Raspberry Pi Imager
⚠️ Crucial: The imaging step will erase the selected SD card. If you select the wrong drive, you may lose data and must start the process again. Double-check the target drive before writing.
  1. Run Raspberry Pi Imager you downloaded from the link above. You'll see three main buttons: CHOOSE DEVICE, CHOOSE OS, and CHOOSE STORAGE.
    Raspberry Pi Imager main interface

    Raspberry Pi Imager - Initial Screen

  2. Click CHOOSE DEVICE → select RASPBERRY PI 4 from the list.
  3. Click CHOOSE OS → select RASPBERRY PI OS (64-BIT).
  4. Click CHOOSE STORAGE → select your MicroSD card. Make sure the size and label match the card you intend to flash.
    After selecting device, OS, and storage

  5. After selecting all three options, the NEXT button will become active. Click NEXT.
    OS Customisation prompt

  6. A dialog will appear asking "Would you like to apply OS customisation settings?" Click EDIT SETTINGS to configure:
    • GENERAL tab:
      ⚠️ Crucial: This step requires you to carefully input the correct details for raspberry pi. If you made any mistake with the input and you are unable to login to raspberry pi, you will need to redo the entire formatting again with proper input.
      • Set hostname: Enter any name here but make sure to note this name down. Best to give a simple name.
      • Set username and password: Choose your username and password (Again give an easy name and password and note it down somewhere).
      • Configure wireless LAN: Enter your Wi-Fi SSID (network name) and password. Select your Wireless LAN country (e.g., "IN" for India)
      General settings tab

      GENERAL Tab - Hostname, Username, and WiFi Configuration

    • SERVICES tab:
      • Enable SSH
      • Select "Use password authentication" (recommended for beginners)
      Services tab - SSH settings

    • OPTIONS tab: You can ignore this
  7. Click SAVE at the bottom of the OS Customisation window.
  8. You'll return to the confirmation dialog. Click YES to apply the settings.
  9. Review settings carefully. When ready, click Write to start imaging. Warning: This will erase all data on the selected storage device! Wait until the process completes and shows success.
  10. When finished, safely eject/remove the SD card from your computer and insert it into the Raspberry Pi's SD card slot.
  11. Power up the Raspberry Pi by connecting the power supply. Wait approximately 5 minutes for first-boot tasks to complete (OS expansion, network connection, and service initialization). The Pi will automatically connect to your Wi-Fi network. While waiting, continue with VNC setup below.
VNC: Remote Desktop Access (RealVNC)

VNC allows you to access the Raspberry Pi's desktop remotely from your computer. We'll use RealVNC Viewer for this.

Download RealVNC Viewer

Download RealVNC Viewer for Windows from the official website:

https://www.realvnc.com/en/connect/download/vnc/

RealVNC Download Page

RealVNC Download Page

Install RealVNC Viewer
  1. Run the downloaded RealVNC Viewer installer
  2. Follow the installation wizard and accept the license agreement
  3. Complete the installation and launch RealVNC Viewer
Create New VNC Connection
  1. Open RealVNC"
    RealVNC Viewer - Blank Address Book

  2. Click on File menu at the top → select New connection... (or press Ctrl+N)
    RealVNC File Menu RealVNC New Connection Dialog

  3. A Properties dialog will appear. Fill in the connection details:
    • Address: Enter the hostname you set in Raspberry Pi Imager (e.g., name.local or the Pi's IP address like 192.168.1.123)
    • Name: Give it a friendly identifier (e.g., "My Raspberry Pi" or "Pi 4")
    • Labels: Optional - you can add labels to organize multiple connections
    VNC Properties Dialog

    Important: The address must match exactly what you entered in the Raspberry Pi Imager settings:
    • If you set hostname as "raspberrypi", use: raspberrypi.local
    • If you set hostname as "mypi", use: mypi.local
    • Or use the IP address if you know it: 192.168.x.x
  4. Click OK to save the connection. It will now appear in your Address book.
  5. To connect: Double-click the saved connection in the Address book. You'll be prompted for:
    • Username: The username you set in Raspberry Pi Imager
    • Password: The password you set in Raspberry Pi Imager
We will now move onto SSH so we can connect our RealVNC to Raspberry Pi

SSH Access to Raspberry Pi

SSH (Secure Shell) allows you to access your Raspberry Pi's command line remotely. This is essential for troubleshooting, enabling services like VNC, and managing your Pi without a desktop interface.

Connect via SSH from Windows Command Prompt
  1. Open Command Prompt (CMD) on your Windows PC:
    • Press Windows Key + R
    • Type cmd and press Enter
    Windows Command Prompt

    Windows Command Prompt

  2. Type the SSH connection command using the hostname and username you set in Raspberry Pi Imager:

    SSH Connection Command

    ssh username@hostname.local
    
    # Example: if username is "pi" and hostname is "raspberrypi"
    ssh pi@raspberrypi.local
    
    # Or if you know the IP address:
    ssh username@192.168.1.123
    SSH Login Command

  3. When prompted with "Are you sure you want to continue connecting?", type yes and press Enter to accept the SSH fingerprint
  4. Enter the password you set in the Raspberry Pi Imager advanced settings
    Note: When typing your password, you won't see any characters appear on screen (no asterisks or dots). This is normal for security reasons. Just type your password and press Enter.
  5. Once logged in successfully, you'll see the Raspberry Pi command prompt:
    Successfully connected to Raspberry Pi

Using raspi-config Tool

Now that you're connected via SSH, you can use the raspi-config tool to configure your Raspberry Pi.

  1. Run the Raspberry Pi configuration tool:

    Open raspi-config

    sudo raspi-config
  2. The Raspberry Pi Software Configuration Tool interface will open:
    raspi-config main menu

  3. Navigate to 3 Interface Options and press Enter:
    • Use arrow keys (↑ ↓) to move up and down
    • Press Enter to select
    • Press Tab to move between Select/Finish buttons
  4. Select VNC to enable VNC server:
    Saved VNC profile in Address Book VNC Identity Check dialog

  5. When asked "Would you like the VNC Server to be enabled?", select Yes
  6. You'll see a confirmation message "The VNC Server is enabled". Press Enter to continue
  7. Press Tab to highlight <Finish> and press Enter to exit raspi-config
Open the saved VNC profile and connect

After enabling the VNC interface on the Pi and waiting for it to boot, open RealVNC Viewer and double-click the connection you saved earlier.

Saved VNC profile in Address Book VNC Identity Check dialog
  1. Double-click the saved profile in RealVNC Viewer.
  2. If the Identity Check dialog appears ("Device not recognized"), review the catchphrase/signature and click Continue to trust this device. This only appears the first time you connect.
  3. When prompted, enter the username and password you configured in Raspberry Pi Imager, then click OK or Sign in.
  4. After authentication, the Raspberry Pi desktop will appear in the VNC Viewer window.
VNC Identity Check dialog
Open the terminal

Open the Raspberry Pi terminal (or SSH into the Pi). If using the desktop, press Ctrl+Alt+T or open Terminal from the menu.

Open Terminal

Update the system packages

Update package lists and upgrade installed packages before starting the project:

System Update

sudo apt update
sudo apt upgrade -y
# Optional: install Thonny (recommended for beginners)
sudo apt install thonny -y
# Install GPIO helper libraries
sudo apt install python3-gpiozero python3-rpi.gpio -y
Note
In order to paste codes into raspberry pi, use ctrl+shift+v to paste the code.

Part 2: LED Blynk Project

Note
In order to paste codes into raspberry pi, use ctrl+shift+v to paste the code.

1) Open the Terminal

Open the Raspberry Pi terminal (or SSH into the Pi). If using the desktop, press Ctrl+Alt+T or open Terminal from the menu.

Open Terminal

2) Create project

Create blink.py file

nano blink.py

3) LED Blynk Code

Paste or write the following code into blink.py

blink.py

# LED blink
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

LED_PIN = 17  # BCM 17

# Set up the pin as output
GPIO.setup(LED_PIN, GPIO.OUT)

try:
    while True:
        GPIO.output(LED_PIN, GPIO.HIGH)  # Turn LED ON
        time.sleep(1)
        GPIO.output(LED_PIN, GPIO.LOW)   # Turn LED OFF
        time.sleep(1)
except KeyboardInterrupt:
    pass
finally:
    GPIO.cleanup()

  1. Press ctrl+o to save
  2. Then press Enter
  3. Then press ctrl+x to exit

Raspberry Pi 4B - Connections

1) Pin Connections

Open Terminal

2) LED Connection

Connect LED positive (longer leg) to GPIO17 through a resistor, and the negative leg to ground.

Open Terminal

4) Run the code

Run blink.py file

Part 3: LDR Sensor

Note
In order to paste codes into raspberry pi, use ctrl+shift+v to paste the code.

1) Open the Terminal

Open the Raspberry Pi terminal (or SSH into the Pi). If using the desktop, press Ctrl+Alt+T or open Terminal from the menu.

Open Terminal

2) Create project

Create ldr.py file

nano ldr.py

3) LDR code

ldr.py

#!/usr/bin/env python3
import RPi.GPIO as GPIO
import time

LDR_PIN = 27
LED_PIN = 17

GPIO.setmode(GPIO.BCM)
GPIO.setup(LDR_PIN, GPIO.IN)
GPIO.setup(LED_PIN, GPIO.OUT)

print("Mode: DARK → LED ON, BRIGHT → LED OFF\n")

try:
    while True:
        d0 = GPIO.input(LDR_PIN)

        if d0 == 1:   # DARK
            print("DARK  -> LED ON")
            GPIO.output(LED_PIN, GPIO.HIGH)
        else:         # BRIGHT
            print("BRIGHT -> LED OFF")
            GPIO.output(LED_PIN, GPIO.LOW)

        time.sleep(0.2)

except KeyboardInterrupt:
    GPIO.cleanup()
    print("Exit.")

  1. Press ctrl+o to save
  2. Then press Enter
  3. Then press ctrl+x to exit

Raspberry pi 4B - Pin Connections

1) Pin Connections

Open Terminal

2) LDR and LED Connection

  1. Connect LDR module digital output (D0) to GPIO27, VCC to 3.3V, and GND to ground.
  2. Connect LED long leg (positive) to GPIO17 and short leg (negative) to GND.
Open Terminal

4) Run the code

Run ldr.py file

Part 4: Automation (Django)

Note
In order to paste codes into raspberry pi, use ctrl+shift+v to paste the code.

We'll create a small Django app to control the LED and read the LDR. Follow the steps below on your Raspberry Pi inside the project folder.

1) Open the Terminal

Open the Raspberry Pi terminal (or SSH into the Pi). If using the desktop, press Ctrl+Alt+T or open Terminal from the menu.

Open Terminal

2) Create project folder

Create project folder

mkdir pi_led

Change to pi_led folder

cd pi_led

3) Creating Virtual Environment

Creates a Virtual Environment

python -m venv venv

Activates the Virtual Environment

source venv/bin/activate

4) Install Django

Install packages

pip install django

5) Updating pip

Update pip to the latest version

python -m pip install --upgrade pip

6) Install Raspberry Pi GPIO Libraries

Install gpiozero

pip install gpiozero

Update Raspberry Pi OS packages

sudo apt update

Install low-level GPIO driver

sudo apt install -y python3-rpi.gpio

7) Create Django project

Start project (Make sure the dot "." is included)

django-admin startproject pi_web .

8) Create Django app

Start app

python manage.py startapp control

9) Update pi_web/settings.py

Open the file and replace/add these sections exactly:

Edit with nano

nano pi_web/settings.py

Then open file pi_web/settings.py

settings.py

from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-3t=_%gj)t$y)5uxx4fxlh-ai%529v!1ts2t0!-m-zpu47tr2*3'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*']


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'control'
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.common.CommonMiddleware',
]

ROOT_URLCONF = 'pi_web.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
	'DIRS': [ BASE_DIR / 'control' / 'templates' ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'pi_web.wsgi.application'


# Database
# https://docs.djangoproject.com/en/5.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}


# Password validation
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/5.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.2/howto/static-files/

STATIC_URL = 'static/'

# Default primary key field type
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
STATICFILES_DIRS = [ BASE_DIR / 'control' / 'static' ]

  1. Press ctrl+o to save
  2. Then press Enter
  3. Then press ctrl+x to exit

10) Configure URLs

Using your preferred editor, open pi_web/urls.py and edit

Edit with nano

nano pi_web/urls.py

Then open file pi_web/urls.py

pi_web/urls.py

from django.urls import path, include

urlpatterns = [
    path('', include('control.urls')),
]

  1. Press ctrl+o to save
  2. Then press Enter
  3. Then press ctrl+x to exit

11) Create control/urls.py

Using your preferred editor, create control/urls.py and edit

control/urls.py

nano control/urls.py
                                

Then open control/urls.py

control/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('api/state/', views.api_state),
    path('api/led/', views.api_led),
    path('api/auto/', views.api_auto),
]

  1. Press ctrl+o to save
  2. Then press Enter
  3. Then press ctrl+x to exit

12) Create GPIO hardware file

(Inverted LDR logic example)

Using your preferred editor, create control/gpio_hw.py and edit

control/urls.py

nano control/gpio_hw.py
                                

Then open control/gpio_hw.py

control/gpio_hw.py

import threading, time
import RPi.GPIO as GPIO

LED_PIN = 17
LDR_PIN = 27

_state = {
    'led_on': False,
    'auto': False,
    'ldr_d0': 1,
    'stop': False
}

GPIO.setmode(GPIO.BCM)
GPIO.setup(LDR_PIN, GPIO.IN)
GPIO.setup(LED_PIN, GPIO.OUT)
GPIO.output(LED_PIN, GPIO.LOW)

def poll():
    while not _state['stop']:
        d0 = GPIO.input(LDR_PIN)   # YOUR MODULE: 1 = DARK, 0 = BRIGHT
        _state['ldr_d0'] = d0

        if _state['auto']:
            if d0 == 1:  # DARK → LED ON
                GPIO.output(LED_PIN, GPIO.HIGH)
                _state['led_on'] = True
            else:
                GPIO.output(LED_PIN, GPIO.LOW)
                _state['led_on'] = False
        
        time.sleep(0.2)

threading.Thread(target=poll, daemon=True).start()

def set_led(on):
    GPIO.output(LED_PIN, GPIO.HIGH if on else GPIO.LOW)
    _state['led_on'] = on

def set_auto(on):
    _state['auto'] = on

def get_state():
    return _state

  1. Press ctrl+o to save
  2. Then press Enter
  3. Then press ctrl+x to exit

13) Create views

Using your preferred editor, create control/views.py and edit

control/views.py

nano control/views.py
                                

Then open control/views.py

control/views.py

from django.shortcuts import render
from django.http import JsonResponse
from . import gpio_hw

def index(request):
    return render(request, 'control/index.html')

def api_state(request):
    return JsonResponse(gpio_hw.get_state())

def api_led(request):
    action = request.GET.get('action')
    if action == 'on':
        gpio_hw.set_led(True)
    elif action == 'off':
        gpio_hw.set_led(False)
    return JsonResponse(gpio_hw.get_state())

def api_auto(request):
    mode = request.GET.get('mode')
    if mode == 'on':
        gpio_hw.set_auto(True)
    elif mode == 'off':
        gpio_hw.set_auto(False)
    return JsonResponse(gpio_hw.get_state())

  1. Press ctrl+o to save
  2. Then press Enter
  3. Then press ctrl+x to exit

14) Create templates

Using your preferred editor, create control/template/control/index.html and edit

Create directory

mkdir -p control/templates/control
                                

Create HTML file

nano control/templates/control/index.html
                                

index.html

<!DOCTYPE html>
<html>
<head>
  <title>Pi LED Control</title>

  <style>
    body {
      font-family: Arial, sans-serif;
      background: #f3f4f6;
      margin: 0;
      padding: 40px;
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    h1 {
      margin-bottom: 20px;
      color: #1f2937;
      font-size: 32px;
    }

    p {
      font-size: 18px;
      color: #374151;
      margin: 18px 0 10px;
    }

    button {
      padding: 10px 18px;
      margin: 4px;
      border: none;
      border-radius: 8px;
      font-size: 16px;
      cursor: pointer;
      font-weight: 600;
      transition: 0.2s ease;
    }

    button[onclick*="on"] {
      background: #10b981;
      color: white;
    }
    button[onclick*="on"]:hover {
      background: #0a8f62;
    }

    button[onclick*="off"] {
      background: #ef4444;
      color: white;
    }
    button[onclick*="off"]:hover {
      background: #c73232;
    }

    button[onclick*="autoMode('on')"] {
      background: #3b82f6;
      color: white;
    }
    button[onclick*="autoMode('on')"]:hover {
      background: #2563eb;
    }

    button[onclick*="autoMode('off')"] {
      background: #f59e0b;
      color: white;
    }
    button[onclick*="autoMode('off')"]:hover {
      background: #d97706;
    }

    #led, #auto, #ldr {
      font-weight: bold;
      color: #111827;
      padding: 3px 6px;
      background: #e5e7eb;
      border-radius: 4px;
    }
  </style>
</head>

<body>
  <h1>Pi LED + LDR</h1>

  <p>LED: <span id="led">...</span></p>
  <button onclick="led('on')">ON</button>
  <button onclick="led('off')">OFF</button>

  <p>Auto Mode: <span id="auto">...</span></p>
  <button onclick="autoMode('on')">Enable</button>
  <button onclick="autoMode('off')">Disable</button>

  <p>LDR D0: <span id="ldr">...</span> (1 = DARK)</p>

  <script src="/static/control/control.js"></script>
</body>
</html>


  1. Press ctrl+o to save
  2. Then press Enter
  3. Then press ctrl+x to exit

15) Create static JS

Using your preferred editor, create control/static/control/control.js and edit

control/static/control/

mkdir -p control/static/control
                                

control/static/control/control.js

nano control/static/control/control.js
                                

control/static/control/control.js

async function state(){
  let r = await fetch('/api/state/');
  let s = await r.json();
  document.getElementById('led').innerText = s.led_on ? "ON" : "OFF";
  document.getElementById('auto').innerText = s.auto ? "ON" : "OFF";
  document.getElementById('ldr').innerText = s.ldr_d0;
}

async function led(a){ await fetch('/api/led/?action='+a); state(); }
async function autoMode(a){ await fetch('/api/auto/?mode='+a); state(); }

setInterval(state, 500);
state();

  1. Press ctrl+o to save
  2. Then press Enter
  3. Then press ctrl+x to exit

16) pip install RPI

RPI.gpio

pip install RPI.gpio

17) Migrate DB

Migrate

python manage.py migrate

18) Run Django

Runserver

python manage.py runserver 0.0.0.0:8000
Server Running! Open your browser and visit:

http://<your-pi-ip>:8000/
Note: The example above uses python3-rpi.gpio and accesses GPIO directly. Run the Django server under a user with permission to access the GPIO pins (usually the default "pi" user). On some systems you may prefer to run the gpio poller as a system service.

Raspberry pi 4B - Pin Connections

1) Pin Connections

Open Terminal

2) LDR and LED Connection

  1. Connect LDR module digital output (D0) to GPIO27, VCC to 3.3V, and GND to ground.
  2. Connect LED long leg (positive) to GPIO17 and short leg (negative) to GND.
Open Terminal

Run the code

After doing the Connections, run your server and have fun with automation with Django!

A special thanks to

Coordinators, Audience, and Everyone Who Helped Make This Session Possible