ProjectNo. 03 of 06Kinetic / mechatronic sculpture
The Kinetic Sculpture
Printed atD.P.E.A.Santa Barbara, Calif.
Vol. 3The engineering portfolio of Adam Gelman
Programmable electromechanical sculpture using rotating moiré geometry, custom transmission parts, sensing, machining, and embedded control
The project
A programmable sculpture of rotating moiré disks: two laser-cut patterns turn against each other on machined hex axles, and the interference between them becomes the motion you see. Flip POWER on the panel to run it, then work through the firmware's eight modes.
- Type
- Kinetic / mechatronic sculpture
- Core tools
- SolidWorks, lathe, laser, Arduino
- Systems
- Motion + optics + sensing + control
From the build37 photographs + drawings · choose one to enlarge
The codeEight light-and-motion programs, picked by three binary switches and run by an Arduino Mega.
- Board
- Arduino Mega 2560
- Mode switches
- Pins 63, 64, 65 (bits 1, 2, 4), INPUT_PULLUP
- Front disc motor
- Left motor: direction 15, PWM 11, tachometer 19
- Back disc motor
- Right motor: direction 14, PWM 12, tachometer 18
- Motor PWM
- Inverted (255 = off), Timer 1 at 31.25 kHz so it can't be heard
- LED strip
- Red 6, green 8, blue 7, through a 256-step gamma table
- Ultrasonic sensor
- HC-SR04: trigger 4, echo 3 (58 µs of echo per cm)
- Disc calibration
- Disc(motor, 40, 25): 40 % minimum power, 25 RPM at full
| Select | Mode | What the code does | Run |
|---|---|---|---|
| 000 | Forest glowmode0() | A mint-green glow held for 1.5 s, a 150 ms blink off, the same green 20 points brighter, then a 50 ms blink. It never touches the motors, so the discs keep whatever the last mode set. | |
| 001 | Breathing counter-rotationmode1() | Speed swells from 5 to 60 % and back over 8 s with the discs turning opposite ways, then the directions swap. The green brightens with speed and washes toward white when the discs are slow. | |
| 010 | Colour strobemode2() | Blue, green, purple, yellow and pink, 70 ms each, with the discs at 80 %. Every 6 s the discs stop, the strip fades to white twice, and the discs reverse. | |
| 011 | Hand sensormode3() | Reads the ultrasonic sensor every 100 ms. Closer than 15 cm: red at full speed. Under 30 cm: orange at 60 %. Under 60 cm: yellow at 30 %. Farther: the motors coast and the strip rests green. | |
| 100 | Heartbeatmode4() | Two magenta beats with the discs pulsing at 40 %, then a pause that shrinks from 800 to 150 ms and grows back, so the heart speeds up and slows down. | |
| 101 | Beat sweepmode5() | A white flash every 475 ms (126 BPM) over a fade from magenta to teal. The discs ramp between 15 and 90 % and reverse only at their slowest. Press play in the model to run it with One More Time. | |
| 110 | Random driftmode6() | Each disc picks a random speed from 20 to 90 % and holds it for 0.5 to 2 s; the green follows the faster disc. The sketch never calls randomSeed(), so every power-up replays the same sequence. | |
| 111 | Blue wavemode7() | Speeds build from 20 to 40 to 80 to 100 % through deepening blues to an icy flash, then the discs reverse at 40 and 20 % for twice as long. |
#include "globals.h"
bool modeChanged(int startMode) {
return getSwitchState() != startMode;
}
void setup() {
setupGlobals();
}
void loop() {
int modeNum = getSwitchState();
Serial.print("Mode: ");
Serial.println(modeNum);
if (modeNum == 0) mode0(modeNum);
else if (modeNum == 1) mode1(modeNum);
else if (modeNum == 2) mode2(modeNum);
else if (modeNum == 3) mode3(modeNum);
else if (modeNum == 4) mode4(modeNum);
else if (modeNum == 5) mode5(modeNum);
else if (modeNum == 6) mode6(modeNum);
else mode7(modeNum);
}
int getSwitchState() {
int b3 = digitalRead(BIT_3_SWITCH_PIN);
int b2 = digitalRead(BIT_2_SWITCH_PIN);
int b1 = digitalRead(BIT_1_SWITCH_PIN);
return 4 * b3 + 2 * b2 + b1;
}
void setColor(int r, int g, int b) {