Image of eBits Academy airquality illustration

Photoresistor and Buzzer

  • June 23, 2023
  • |
  • Jonas Rothausen

Welcome to the third exciting Arduino blog in this series! Today we combine light and sound. We will learn to activate a buzzer using a photoresistor, which detects changes in light intensity. This creates an interactive setup where sensor readings determine when the buzzer sounds.

We focus on specific code to achieve the result, explaining it step by step so you can implement it yourself. The code is simple but useful for controlling the buzzer and LED according to the photoresistor reading.

The code uses the reading from the photoresistor to control the buzzer and LED. The relationship between light and the reading from the photoresistor depends on the voltage-divider wiring. The code applies PWM only below a threshold; it does not make sound level and brightness rise continuously with light.

 

 

Project Components


  • KY-018 Photoresistor: A photoresistor, also called a light-dependent resistor, changes resistance according to light intensity. Here the KY-018 provides a light-level input to Arduino UNO.
  • Arduino UNO: The classic Arduino UNO is based on the ATmega328P microcontroller. It acts as the brain, reading the photoresistor and controlling the buzzer and LED from that input.
  • Jumper Wires: Short cables with connectors at both ends connect components on a breadboard or to Arduino UNO. They provide flexible, convenient connections.
  • KY-006 Passive Buzzer: A passive buzzer needs an alternating or pulsed drive signal to produce a sustained tone; steady DC alone does not create a continuous tone. Here it provides sound controlled by the photoresistor reading.

 

KY-018 Photoresistor

A photoresistor’s resistance decreases with more light and increases with less light. A voltage divider converts this resistance change into an analogue voltage related to light intensity.

Use KY-018 to monitor light in different environments or in automated systems responding to changing lighting. Its analogue output provides information about ambient light for making decisions.

KY-018 is an analogue sensor, so use an analogue Arduino input to read its value.

KY-006 Passive Buzzer

The module contains a passive buzzer and 3 male header pins. A commonly specified responsive region is 1.5 to 2.5 kHz, but its useful frequency response depends on the exact part. Drive it with a waveform, using tone() or suitable timed switching.

The buzzer can make sound effects, alerts and status indications. Check the exact module’s voltage and current rating; do not assume a generic 1.5V–15V claim applies. Never apply more than the permitted voltage to Arduino pins, and use a transistor driver when the buzzer requires more current than a GPIO safely supplies.

Controlling switching periods using timing or PWM can produce different tones and rhythms. It can add sound feedback or a simple experimental alarm to Arduino projects.

 

The Project Circuit

This circuit uses Arduino UNO, two digital pins and one analogue pin to control a buzzer and LED. Resistors also play important roles.

We use two digital pins that support pulse-width modulation (PWM), meaning pulses switch between approximately 0 and 5 V with a variable duty cycle. This is not a continuously variable DC output. PWM controls average LED current; buzzer loudness does not necessarily vary linearly with duty cycle.

The buzzer is controlled from pin 11, with its return connected to GND for the active-high example. Follow the module pinout and current rating; use a suitable transistor driver if GPIO drive is not permitted.

The LED is driven from pin 6 through a 220 ohm series resistor to its anode, with its cathode connected to GND. This active-high wiring matches analogWrite(..., 0) meaning off.

Light is measured using a photoresistor (LDR), which acts as a variable resistor. For a bare LDR, use a 10 k ohm resistor to form a divider between 5V and GND, with the junction connected to analogue pin 0 (A0). If using the KY-018 module, check its built-in divider and connect its signal output to A0. The reading direction depends on divider orientation.

Each LED needs its own current-limiting resistor. Buzzer protection and any driver must match its datasheet. All grounds are shared; never use a single shared resistor as universal protection for both loads.

The historical diagram below must be read with the corrected wiring above: connect the active-high loads towards GND, not as pull-ups to 5V.

 

With the circuit and components understood, let’s program Arduino to control the buzzer and LED with the photoresistor.

 

The Code

Earlier blogs introduced the built-in functions and programming concepts used here. We will still go through the code step by step to understand how the photoresistor controls the buzzer and LED.

 

int sensorPin = 14;  // A0 er repræsenteret af det numeriske værdi 14
int buzzerPin = 11;  // Arduino summer interface stift
int ledPin = 6;      // Arduino LED interface stift


void setup() {
  Serial.begin(115200);        // Start Serial monitor i Arduino IDE
  pinMode(buzzerPin, OUTPUT);  // Indstil summerstiften som output
  pinMode(ledPin, OUTPUT);     // Indstil LED-stiften som output
}


void loop() {
  int senValue = analogRead(sensorPin);
  delay(10);
  Serial.println(senValue);


  if (senValue < 500) {
    analogWrite(buzzerPin, senValue / 4);  // Tænd for summeren
    analogWrite(ledPin, senValue / 4);     // Tænd for LED'en
  } else {
    analogWrite(buzzerPin, 0);  // Sluk for summeren
    analogWrite(ledPin, 0);     // Sluk for LED'en
  }
}

 

The code begins by defining sensorPin, buzzerPin and ledPin, representing the analogue input and two digital outputs connected to the photoresistor, buzzer and LED respectively.

In setup(), serial communication is started and buzzerPin and ledPin are set as outputs. Hold on—what is Serial Monitor?


Serial Monitor

Serial Monitor is an Arduino IDE tool for communicating with Arduino over the serial connection to your computer. Open it using the Serial Monitor control in the IDE.


It lets you send and receive serial data. Send commands or parameters, receive sensor readings, or debug and monitor an application through printed messages and values.

Use Serial.print() or Serial.println() to send text from Arduino to Serial Monitor. Serial.write() can send binary data.

Serial Monitor is useful for checking and debugging programs, monitoring sensor values, testing communication protocols and interacting with other devices or software over serial.

It provides real-time feedback and data, making Arduino projects easier to develop, test and troubleshoot.

 

In loop() the following steps run:

  1. Read the photoresistor with analogRead() and store the value in senValue. We learned analogRead() in earlier blogs in the series.
  2. Add a 10-millisecond delay using delay().
  3. Print senValue in Serial Monitor with Serial.println().

Next check senValue. If it is below 500, the following actions run. Whether lower readings mean light or dark depends on divider wiring; measure and choose a threshold for your setup.

  • Drive the buzzer with analogWrite() and a value equal to one quarter of senValue.
  • Drive the LED in the same way.

If senValue is 500 or higher, set both PWM outputs to 0. This switches the loads off with the corrected active-high wiring above.

We have explored analogue input and PWM to control sound and light according to a light-sensor reading. This offers many possibilities for interactive effects. But there is more!

 

BONUS PROJECT

Great! Another project complete—but the blog is not over. We have prepared a fun bonus. Have you ever dreamed of playing a banana? Worry no more: here is your chance!

This bonus explores making music with capacitive sensing on Arduino and our friend the buzzer. By connecting bananas to Arduino’s digital pins used for capacitive sensing and touching them, we can create different tones because touch changes the sensed capacitance. We are making our own banana piano! Imagine impressing friends and family with your musical banana skills. This project is both entertaining and educational.

The bonus uses the original project’s components except the photoresistor, plus two more “components”:

1M ohm resistors
Bananas

How Does the Banana Piano Work?
The classic Arduino UNO has no dedicated capacitive-touch pins. CapacitiveSensor uses ordinary digital pins and high-value resistors to estimate capacitance from charging time. Touching a conductive object changes that measurement. Phone touchscreens also detect capacitance changes, although their hardware differs.

Our banana piano detects touch using Arduino digital pins and the “CapacitiveSensor” library, which configures and reads the resistor-and-electrode sensing circuits.

The example uses 3 bananas, but more channels require available pins, suitable resistors, wiring and code changes. If the circuit is unclear, see the setup in this YouTube video.

Here Is the Bonus Code:

#include <CapacitiveSensor.h>
#define buzzer 11


// Deklarér variabler til kapacitive sensorer
CapacitiveSensor banan1 = CapacitiveSensor(12, 3);
CapacitiveSensor banan2 = CapacitiveSensor(12, 4);
CapacitiveSensor banan3 = CapacitiveSensor(12, 5);


void setup() {
  // Sluk for autokalibrering på kanal 1 - bare som et eksempel
  banan1.set_CS_AutocaL_Millis(0xFFFFFFFF);
  banan2.set_CS_AutocaL_Millis(0xFFFFFFFF);
  banan3.set_CS_AutocaL_Millis(0xFFFFFFFF);
}


void loop() {
  // Indstil følsomheden for sensorerne
  long touch1 = banan1.capacitiveSensor(1000);
  long touch2 = banan2.capacitiveSensor(1000);
  long touch3 = banan3.capacitiveSensor(1000);


  // Når sensoren berøres, afspilles en tone på summeren
  if (touch1 > 1000) {
    tone(buzzer, 400);
  } else if (touch2 > 1000) {
    tone(buzzer, 600);
  } else if (touch3 > 1000) {
    tone(buzzer, 800);
  } else {
    noTone(buzzer);
  }

  delay(10);
}

    • First include “CapacitiveSensor”, which enables the sensing functions.
    • Define the buzzer pin using #define. This makes the pin easy to change.
    • Create three objects of type CapacitiveSensor by specifying each sensor’s send and receive pins. 
    • In void setup(), automatic baseline recalibration is disabled using set_CS_AutocaL_Millis() for each sensor. Assess whether this suits your setup and calibrate the thresholds yourself.
    • In void loop(), read a capacitive measurement using capacitiveSensor() for each sensor, storing the results in touch1, touch2 and touch3.
    • Then test the sensors in order using if and else if. In this example, a value above 1000 is interpreted as touch; adjust the threshold for your setup. Activate the buzzer with tone() and a frequency defining the note.
    • If no sensor triggers the threshold, switch the buzzer off with noTone().
    • Finally, add a short delay with delay() before reading the sensors again.

    This is a simple code overview. Read the documentation for the CapacitiveSensor library for a deeper understanding if you want to explore further.

    We hope you have enjoyed this Arduino series and learned about electronics and programming. We covered analogue sensors, light control and sound generation.

    The projects explored photoresistors, buzzers, LEDs and capacitive sensors and gave practical experience connecting and programming Arduino to make interactive gadgets.

    This is only the beginning of your electronics and programming journey. Arduino offers endless opportunities to explore and create. Keep learning and trying new projects.

    We hope the series has inspired and motivated your own projects and experiments. Enjoy yourself and experiment safely while exploring Arduino.

    Thanks for following the series. See you next time for a new project! 

      Leave a comment

      Please note, comments need to be approved before they are published.