Dirty Video Mirror 1.0

What if getting closer made things more messy? The Dirty Video Mirror is an interactive analog video installation that crossfades between two live camera feeds based on how close you are to the display. You are both the observer and the subject. The closer you get, the more your reflection distorts.

Let’s see how this was made!

How It Works

At the heart of the project is a digital potentiometer IC (such as the AD5256) wired as a video crossfader between two analog camera inputs. This is basically a 1k potentiometer controlled not by your hand but by a microcontroller. This approach draws directly from the popular Dirty Video Mixer project. The twist here is an ultrasonic distance sensor that continuously reads how far the subject is from the screen. An ESP32 microcontroller takes that distance reading and sweeps the pot’s wiper accordingly.

The result is a live analog glitch: as a person walks toward the screen, the output image gradually bleeds from one source to the other. As the cameras are placed on top of the screen, the installation invites the subject to explore which camera truly sees him and how to access the view from the other camera by getting closer.

Hardware

Here’s what’s needed:

  • Any ESP32 dev board, I used the Dasduino CONNECTPLUS by Soldered, you can make this project with any basic Arduino-compatible board!
  • 1k digital potentiometer e.g. AD5256 or equivalent
  • Ultrasonic Distance Sensor by Soldered (or any preferred distance sensor, I’m using the Qwiic version for easy connecting)
  • Two analog cameras, I used cheap FPV drone cameras from AliExpress
  • Analog TV or composite monitor as the output display

Wiring It Up

The digital pot’s I2C pins connect to the ESP32’s SDA/SCL lines. The two camera outputs feed into the A and B terminals of the pot, and the wiper output goes to the monitor. All camera grounds need to be tied together.

The Code

The core logic is straightforward: read distance, map it to a wiper value from 0–127, and write that value to the digipot over I2C at roughly 4 Hz.

const uint8_t  WIPER_MIN  = 0;     // Side A (0%)
const uint8_t  WIPER_MAX  = 127;   // Side B (100%)

const float    DIST_FAR   = 500.0; // cm — start of crossfade range
const float    DIST_NEAR  = 30.0;  // cm — full Side B

These four constants at the top of the sketch are all you need to fine tune everything. This is the main loop of the ESP32 and how it continuously reads from the proximity sensor, maps the value and then writes it to the digipot:

void loop()
{
  hc.takeMeasure();  // Trigger an ultrasonic pulse
  delay(50);         // Wait for the echo (sensor needs up to 38 ms)

  float dist = hc.getDistance(); // Distance in cm

  uint8_t wiperValue;
  if (dist > DIST_FAR) {
    // Subject is out of range — hold at Side A
    wiperValue = WIPER_MIN;
  } else if (dist <= DIST_NEAR) {
    // Subject is very close — hold at Side B
    wiperValue = WIPER_MAX;
  } else {
    // Linearly interpolate: t goes from 0 (at 500 cm) to 1 (at 30 cm)
    float t = (DIST_FAR - dist) / (DIST_FAR - DIST_NEAR);
    wiperValue = (uint8_t)(t * WIPER_MAX + 0.5f);
  }

  writeWiper(wiperValue);

  delay(200); // Update rate ~4 Hz (50 ms measure + 200 ms settle)
}

What’s next?

I’ll probably add an optional audio input on this, making it reactive to bass in an audio signal! That or a better proximity sensor. Stay tuned for that!