Back to projects
Tier 3 · Code the Real WorldmediumAge 10+60 min

Mini Theremin

Wave your hand over the sensor to play different notes — like a magic instrument.

What you’ll learn

  • Mapping an analog reading to an audible frequency.
  • tone() and noTone() — quick-and-dirty waveform output.
  • How a small change in light becomes a different note.

What you need

ItemQty~CostWhere to buy
Arduino Uno (or Nano clone)1GHS 120.00
Online — official Uno is ~GHS 375; a Nano clone is ~GHS 75.
USB cable for the board1GHS 15.00
Probably already in the kit.
LDR / photoresistor1GHS 7.50
Online.
10 kΩ resistor1GHS 0.75
Online.
Piezo buzzer (passive)1GHS 15.00
Online.
Half-size breadboard + jumpers1GHS 30.00
Online.
Total~GHS 188.25

Build it step by step

  1. LDR voltage divider into A0

    LDR between 5V and A0; 10 kΩ between A0 and GND.

  2. Buzzer on D8

    D8 → buzzer +; buzzer − → −rail.

  3. Upload the code

    Code reads A0 every 50 ms and maps the value to a frequency between 200 Hz and 2000 Hz.

  4. Wave your hand

    Closer = darker = lower note. Farther = brighter = higher note. Free-form melody.

How it works

The LDR + 10 kΩ form a voltage divider. The voltage at A0 changes with light. We pass that 0-1023 value through map() to scale it into a 200-2000 Hz range, then call tone() with the result. tone() handles the waveform generation — your code just keeps updating the frequency.

If something’s not working

Buzzer makes one note no matter what
  • · Active buzzer instead of passive — actives ignore tone() frequency.
  • · A0 wire is loose.
Tone is super high or weirdly limited
  • · Map ranges are off — try map(v, 100, 900, 200, 2000).

Try this next

Quantise to a musical scale: only allow specific frequencies (C, D, E, …).

Add a second LDR for volume — two-handed theremin.

The code

Paste this into the Arduino IDE and hit Upload. Each line tells the board what to do, in order — the more lines you read, the more you understand.

// Mini theremin
const int SENSOR = A0;
const int BUZ    = 8;

void setup() {
  pinMode(BUZ, OUTPUT);
}

void loop() {
  int v = analogRead(SENSOR);
  int freq = map(v, 0, 1023, 200, 2000);
  tone(BUZ, freq);
  delay(50);
}