Built-in project · Arduino Uno R3

Light theremin on an Arduino Uno

A phototransistor reads the light and a piezo plays it as a pitch, higher for more light: the Arduino Starter Kit theremin. The whole build, an Arduino Uno and 3 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

Beginner Runs in your browser. Free, and no account needed.

Light theremin · Arduino Uno R3live0.000 s 0.00x
Click to open it in the editor
The circuit itself, running here on the simulator. Press what can be pressed; click anything else to open it in the editor.

The code

The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.

sketch.ino · Arduino Uno R3
// Light theremin: a phototransistor reads the light and a piezo plays it as a
// pitch, higher for more light. Move your hand over the sensor and it sings.
//
//   phototransistor   C -> 5 V   E -> A0, and 10 k from A0 to GND
//   piezo             one leg -> pin 8, the other -> GND
//
// A phototransistor is a transistor whose base current is light: the
// collector current follows the light, and the 10 k resistor turns it into a
// voltage the analog pin can read. It is not a resistor like an LDR, so in a
// bright room it saturates and reads near the top, and the useful range is
// from dark to a dim room. Drag the light slider down to "cover" it.
//
// tone() plays the note from a timer, so the loop keeps reading while the note
// sounds. It is only called again when the pitch moves: every call restarts
// the timer, and calling it every 10 ms with the same note would cut a low
// note's cycles short and raise its pitch.

const int SENSOR_PIN = A0;
const int PIEZO_PIN = 8;
const int LOW_PITCH = 120;    // hertz, in the dark
const int HIGH_PITCH = 1500;  // hertz, at full scale

unsigned long printedAt = 0;
int playing = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("Light theremin: move your hand over the sensor");
}

void loop() {
  int light = analogRead(SENSOR_PIN);
  int pitch = map(light, 0, 1023, LOW_PITCH, HIGH_PITCH);
  if (pitch != playing) {
    tone(PIEZO_PIN, pitch);
    playing = pitch;
  }

  if (millis() - printedAt >= 250) {
    printedAt = millis();
    Serial.print("light ");
    Serial.print(light);
    Serial.print(" -> ");
    Serial.print(pitch);
    Serial.println(" Hz");
  }
  delay(10);
}

Parts list

5 parts, plus the jumper wires. Every one is in the editor's parts bin.

How it is wired

4 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.

  • Ground: Arduino Uno R3 pin GND; Resistor, 10k Ω pin 1; Piezo speaker pin 2
  • Arduino Uno R3 pin 8; Piezo speaker pin 1
  • Arduino Uno R3 pin 5V; Phototransistor pin C
  • Arduino Uno R3 pin A0; Phototransistor pin E; Resistor, 10k Ω pin 2

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.

Free forever. Every board and part. Saves your projects. Works on Chromebooks.