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