An art object about closeness.
fn
main/*ly an error*/()
/*but*/ -> anyhow::Result<()> {
// is the thought that keeps me going
/* each time it */ starts(
to()); let new
// { part_of_me, this_time, pour_out }
= NeverBeen::default()
.to_open_eyes()
.read_through_time()
.hide_hints_to_avoid_lies();
/* always */ let a_hidden = new.part_of_me()
.as_thin(); // .as I can,
to(); let _unmute = (|a: Channel| {
which::links::Inwards
::to(a)}) (new); // view
/* I feel */ unsafe {
hearing(/* the voice
which sounds so */true);
causing(Some(quivers) /* to make me raw */)
}
let // those eyes of yours keep looking cause
/*I'*/mut terly: Lost = Listening::from(
you(// -
a_hidden))// - while
.the_words("morphing").into();
// a one-way game which captures me
/* in this */ loop {
// My breath held, waiting to
let /* this real*/mut/*most */ a_signal
= /*is it bit*/terly.knocking()?;
// No, but do I from
a_signal.rap().expect("a wall,"); if it_exists() { //,
to(); break; // down below?
}
while !a_signal.is_received() {
just_wait(45);
}; /* and */ let a_single = // feeling from
a_signal.be_found(); // and look for
a_single // moment to
.set_low() /* and */ .unwrap();
/* this */ waiting(to_feel_a(&PULSE) as Sweet as That);
}
Ok(())
}
Two ESP32 boards communicate over WiFi. One transmits continuously — a beacon, a pulse, a voice. The other listens.
The server board carries a transparent plastic cylinder filled with water to the brim, and a solenoid whose hammer strikes against it. The rhythm of the strikes is determined by the strength of the WiFi signal received from a specific MAC address — the closer the transmitter, the faster the beat.
The code is written as found poetry. Variable names, function signatures, and comments form a parallel text about the same subject.
The difficulty of moving toward someone.
Not the distance itself, but what happens inside when distance closes — the fragility, the exposure, the involuntary rhythm of attention that starts when someone enters your space. The object makes that audible. Water, because it is transparent and holds its shape only when contained. Sound, because it is involuntary.
/ ├── voice/ # Transmitter — broadcasts beacon frames continuously └── server/ # Receiver — listens, measures, strikes
Both workspaces target ESP32 boards with WiFi capability.
The server workspace is the one documented here (proximity_server).
The server puts the WiFi interface into promiscuous mode and listens for all packets in the air. When it detects a frame from the MAC address defined as VOICE, it reads the RSSI value and stores it in PULSE.
The main loop uses PULSE to calculate a delay: stronger signal, shorter wait, faster strike. At -95 dBm or below, the solenoid is nearly still. As the transmitter approaches, the beat accelerates.
static PULSE: AtomicI8 = AtomicI8::new(-128); const VOICE: [u8; 6] = [0x4E, 0x45, 0x41, 0x52, 0x20, 0x55];
PULSE begins at the minimum value of i8. VOICE is an ASCII sequence.
Server board
Voice board
Wiring and enclosure are left to the builder. The physical form is part of the work.
Standard ESP-IDF / esp-idf-hal toolchain for Rust.
cargo build --release cargo espflash flash --release
Requires espflash and a configured ESP-IDF environment.
See esp-rs book for setup.
CC BY-NC-SA 4.0 — non-commercial, attribution required, share alike.