Raspberry Pi Zero 2 W Build Guide

Build your own Mailfob

Mailfob is an open source smart mailbox alerter using a Raspberry Pi Zero 2 W, an SW-420 vibration sensor, Home Assistant, MQTT, and an optional Arducam Raspberry Pi Zero camera.

Parts Needed

Everything needed to build the Mailfob mailbox alerter.

Raspberry Pi Zero 2 W

Main computer that runs the Mailfob Python service and connects to Wi-Fi.

SW-420 Vibration Sensor

Detects mailbox vibration when the door moves or mail is dropped inside.

Optional Arducam OV5647

Optional 5MP Raspberry Pi Zero camera module for capturing delivery photos.

MicroSD Card

16GB or larger recommended for Raspberry Pi OS Lite and Mailfob scripts.

Power Source

Use USB power, a battery pack, or a weather-safe outdoor power setup.

Project Box

Protects the Pi and sensor wiring from dust, movement, and moisture.

Pins We Are Going To Use

Mailfob only needs three sensor wires plus the optional camera ribbon cable.

1
3.3V Power

Use for SW-420 VCC


Connects to the VCC pin on the SW-420 sensor module.

6
Ground

Use for SW-420 GND


Connects to the GND pin on the SW-420 sensor module.

11
GPIO17

Use for SW-420 DO


Connects to the DO digital output pin on the SW-420.

Wiring Table

Device Device Pin Raspberry Pi Physical Pin GPIO Name Use
SW-420 Vibration Sensor VCC Pin 1 3.3V Sensor power
SW-420 Vibration Sensor GND Pin 6 Ground Sensor ground
SW-420 Vibration Sensor DO Pin 11 GPIO17 Digital vibration signal
Arducam OV5647 Camera Ribbon Cable CSI Camera Port Camera Interface Optional mailbox photo
Use 3.3V for the SW-420 module when connecting to Raspberry Pi GPIO. Do not send 5V into a Pi GPIO pin.

Raspberry Pi Setup

Install Raspberry Pi OS Lite, enable SSH, connect Wi-Fi, then install the packages needed to run Mailfob.

1 Update the Pi
sudo apt update
sudo apt upgrade -y
2 Install Python Packages
sudo apt install -y python3-pip python3-gpiozero python3-paho-mqtt
3 Optional Camera Packages
sudo apt install -y python3-picamera2 libcamera-apps

Mailfob Python Code

This script listens for vibration on GPIO17 and sends MQTT alerts.

from gpiozero import DigitalInputDevice
from signal import pause
from datetime import datetime
import time
import os
import paho.mqtt.publish as publish

SENSOR_GPIO = 17

MQTT_ENABLED = True
MQTT_HOST = "homeassistant.local"
MQTT_PORT = 1883
MQTT_USERNAME = ""
MQTT_PASSWORD = ""

MQTT_TOPIC_STATE = "mailfob/mailbox/state"
MQTT_TOPIC_EVENT = "mailfob/mailbox/event"

CAMERA_ENABLED = False
PHOTO_DIR = "/home/pi/mailfob/photos"

DEBOUNCE_SECONDS = 60
last_trigger_time = 0

sensor = DigitalInputDevice(SENSOR_GPIO, pull_up=False)

def send_mqtt(topic, payload):
    if not MQTT_ENABLED:
        return

    auth = None

    if MQTT_USERNAME and MQTT_PASSWORD:
        auth = {
            "username": MQTT_USERNAME,
            "password": MQTT_PASSWORD
        }

    publish.single(
        topic,
        payload,
        hostname=MQTT_HOST,
        port=MQTT_PORT,
        auth=auth
    )

def take_photo():
    if not CAMERA_ENABLED:
        return None

    os.makedirs(PHOTO_DIR, exist_ok=True)

    timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
    photo_path = f"{PHOTO_DIR}/mail_{timestamp}.jpg"

    os.system(f"libcamera-still -o {photo_path} --width 1280 --height 720 --timeout 1000")

    return photo_path

def mail_detected():
    global last_trigger_time

    now = time.time()

    if now - last_trigger_time < DEBOUNCE_SECONDS:
        return

    last_trigger_time = now

    timestamp = datetime.now().isoformat()
    print(f"Mailfob detected mailbox movement at {timestamp}")

    photo_path = take_photo()

    send_mqtt(MQTT_TOPIC_STATE, "mail_detected")
    send_mqtt(MQTT_TOPIC_EVENT, f"time={timestamp}, photo={photo_path if photo_path else 'none'}")

sensor.when_activated = mail_detected

print("Mailfob is running...")
print("Using SW-420 on GPIO17 / physical pin 11")
print("Waiting for mailbox vibration...")

send_mqtt(MQTT_TOPIC_STATE, "online")

pause()

Home Assistant MQTT

Mailfob publishes to MQTT so Home Assistant can show mailbox status and send phone notifications.

MQTT Sensor
mqtt:
  sensor:
    - name: "Mailfob Mailbox"
      state_topic: "mailfob/mailbox/state"
      icon: mdi:mailbox
Notification Automation
alias: Mailfob Mail Delivered Alert
description: Sends a notification when Mailfob detects mailbox movement
trigger:
  - platform: mqtt
    topic: mailfob/mailbox/state
    payload: mail_detected
action:
  - service: notify.mobile_app_your_phone
    data:
      title: "Mailfob"
      message: "Mail was detected in your mailbox."
mode: single

Mounting Tips

Place the parts where they can detect mail but stay protected.

Sensor Location

Mount the SW-420 near the mailbox door, inside wall, or bottom rear of the mailbox.

Weather Protection

Put the Pi in a small project box and keep wiring away from water and bare metal.

Sensitivity

Adjust the blue screw on the SW-420 so wind does not trigger it, but mail delivery does.