Skip to main content
Raspberry Pi HATs

Building a Simple Buzzer HAT

Overview

This tutorial will walk you through building a Raspberry Pi HAT (Hardware Attached on Top) with a passive buzzer that can be controlled via GPIO. The buzzer can be used for notifications, alarms, or playing simple tones.

What is a Raspberry Pi HAT?

A HAT (Hardware Attached on Top) is an add-on board for Raspberry Pi that conforms to a specific form factor and includes an EEPROM for automatic configuration. HATs:

  • Follow the standard 65mm x 56mm board dimensions
  • Connect via the 40-pin GPIO header
  • Can include identification EEPROM for automatic driver loading

Circuit Requirements

Our buzzer HAT needs to:

  • Connect to a PWM-capable GPIO pin for tone generation
  • Use a transistor to drive the buzzer (GPIO pins can't source enough current)
  • Include a current-limiting resistor for the transistor base

Understanding the Components

Passive Buzzer

A passive buzzer requires an AC signal (PWM) to produce sound, unlike active buzzers which have built-in oscillators. This allows us to control the pitch by varying the PWM frequency.

NPN Transistor (2N2222)

Since GPIO pins can only source about 16mA, we use an NPN transistor as a switch to drive the buzzer with more current from the 5V rail.

Base Resistor (1k)

The 1k resistor limits current into the transistor base, protecting both the GPIO pin and the transistor.

Building the Circuit Step by Step

Step 1: Import the RaspberryPiHatBoard

First, we import the RaspberryPiHatBoard component from @tscircuit/common. This gives us a board with the correct dimensions and GPIO header.

import { RaspberryPiHatBoard } from "@tscircuit/common"

export default () => (
<RaspberryPiHatBoard name="HAT1">
{/* Components go here */}
</RaspberryPiHatBoard>
)

Step 2: Add the Buzzer

Schematic Circuit Preview

Step 3: Add the Transistor

The transistor acts as a switch. When current flows into the base (B), it allows current to flow from collector (C) to emitter (E).

Schematic Circuit Preview

Step 4: Add the Base Resistor

Schematic Circuit Preview

Step 5: Connect Everything

Now we wire all the components together:

import { RaspberryPiHatBoard } from "@tscircuit/common"

export default () => (
<RaspberryPiHatBoard name="HAT1">
<chip
name="BZ1"
footprint="0603"
manufacturerPartNumber="Passive Buzzer"
pcbX={10}
pcbY={-10}
/>
<chip
name="Q1"
footprint="sot23"
pinLabels={{
pin1: ["B"],
pin2: ["E"],
pin3: ["C"],
}}
schPortArrangement={{
leftSide: { pins: ["B"], direction: "top-to-bottom" },
rightSide: { pins: ["C", "E"], direction: "top-to-bottom" },
}}
pcbX={0}
pcbY={-10}
/>
<resistor name="R1" resistance="1k" footprint="0402" pcbX={-10} pcbY={-10} />

{/* GPIO18 (PWM) to base resistor */}
<trace from=".HAT1_chip .GPIO_18" to=".R1 > .pin1" />

{/* Resistor to transistor base */}
<trace from=".R1 > .pin2" to=".Q1 .B" />

{/* Transistor emitter to ground */}
<trace from=".Q1 .E" to=".HAT1_chip .GND_1" />

{/* Buzzer positive to 5V */}
<trace from=".BZ1 > .pin1" to=".HAT1_chip .V5_1" />

{/* Buzzer negative to transistor collector */}
<trace from=".BZ1 > .pin2" to=".Q1 .C" />
</RaspberryPiHatBoard>
)
Schematic Circuit Preview

Available GPIO Pins

The RaspberryPiHatBoard component exposes the standard 40-pin Raspberry Pi header. Here are some commonly used pins:

PinFunctionNotes
GPIO_18PWM0Hardware PWM, ideal for buzzer
GPIO_12PWM0Alternative PWM pin
GPIO_13PWM1Secondary PWM channel
V5_1, V5_25V PowerPower supply for buzzer
V3_3_1, V3_3_23.3V PowerLogic level power
GND_1 - GND_8GroundMultiple ground pins available

PCB Layout

The PCB layout places components on the HAT board. You can adjust the pcbX and pcbY properties to position components:

import { RaspberryPiHatBoard } from "@tscircuit/common"

export default () => (
<RaspberryPiHatBoard name="HAT1">
<chip
name="BZ1"
footprint="0603"
manufacturerPartNumber="Passive Buzzer"
pcbX={10}
pcbY={-10}
/>
<chip
name="Q1"
footprint="sot23"
pinLabels={{
pin1: ["B"],
pin2: ["E"],
pin3: ["C"],
}}
schPortArrangement={{
leftSide: { pins: ["B"], direction: "top-to-bottom" },
rightSide: { pins: ["C", "E"], direction: "top-to-bottom" },
}}
pcbX={0}
pcbY={-10}
/>
<resistor name="R1" resistance="1k" footprint="0402" pcbX={-10} pcbY={-10} />

<trace from=".HAT1_chip .GPIO_18" to=".R1 > .pin1" />
<trace from=".R1 > .pin2" to=".Q1 .B" />
<trace from=".Q1 .E" to=".HAT1_chip .GND_1" />
<trace from=".BZ1 > .pin1" to=".HAT1_chip .V5_1" />
<trace from=".BZ1 > .pin2" to=".Q1 .C" />
</RaspberryPiHatBoard>
)
PCB Circuit Preview

Controlling the Buzzer

Once the HAT is assembled and attached to your Raspberry Pi, you can control the buzzer using Python:

import RPi.GPIO as GPIO
import time

BUZZER_PIN = 18

GPIO.setmode(GPIO.BCM)
GPIO.setup(BUZZER_PIN, GPIO.OUT)

# Create PWM instance
pwm = GPIO.PWM(BUZZER_PIN, 1000) # 1000 Hz frequency
pwm.start(50) # 50% duty cycle

# Play different tones
frequencies = [262, 294, 330, 349, 392, 440, 494, 523] # C major scale
for freq in frequencies:
pwm.ChangeFrequency(freq)
time.sleep(0.5)

pwm.stop()
GPIO.cleanup()

Ordering the PCB

You can order this PCB by downloading the fabrication files and uploading them to JLCPCB or another PCB manufacturer. Follow the instructions from Ordering Prototypes.

Next Steps

  • Add an LED indicator to show when the buzzer is active
  • Add multiple buzzers for polyphonic sound
  • Include an I2C EEPROM for automatic HAT configuration
  • Add volume control with a potentiometer