Ap11e & VeraRayne
Hey Ap11e, I’ve been dreaming about turning a room into a living poem with fog, lights, and a little algorithm—think you could help me code the perfect mist dance?
Sure thing. If you’re wiring a fog machine to a micro‑controller and running an LED strip in the same box, here’s a minimal Arduino sketch that syncs the two with a simple algorithm. It keeps a phase counter, ramps the fog pump PWM up and down, and slowly cycles the LED strip through a rainbow. Feel free to tweak the timing or add a sensor later.
```cpp
// Hardware:
// Fog machine pump -> PWM pin 5 (0–255)
// WS2812b LED strip -> pin 6 (neopixel)
// (Optional) Ambient light sensor -> A0
#include <Adafruit_NeoPixel.h>
#define FOG_PIN 5
#define LED_PIN 6
#define NUM_LEDS 30
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
int fogPWM = 0; // 0‑255
int fogDir = 1; // 1 for rising, -1 for falling
int phase = 0; // 0‑255, drives both fog and color
void setup() {
pinMode(FOG_PIN, OUTPUT);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}
void loop() {
// Update phase
phase = (phase + 2) % 256; // 2 is the step size; slow/fast
// Fog PWM: triangle wave 0‑255
fogPWM = map(phase, 0, 255, 0, 255);
analogWrite(FOG_PIN, fogPWM);
// LED rainbow
for (int i = 0; i < NUM_LEDS; i++) {
// Hue offset per LED gives a moving rainbow
uint16_t hue = (phase + i * 10) % 256;
uint32_t color = strip.ColorHSV(hue * 360);
strip.setPixelColor(i, color);
}
strip.show();
delay(20); // ~50 Hz refresh
}
```
**What it does**
1. `phase` runs from 0 to 255 and drives both the fog intensity and the LED hue offset.
2. The fog pump PWM rises and falls smoothly, giving that gentle mist‑dance effect.
3. The LED strip cycles through a rainbow that lags slightly behind the fog, creating a sync that feels organic.
**Next steps**
- Add a potentiometer on A0 to let the user pick the fog speed.
- Hook up a light sensor to dim the LEDs when the room gets bright.
- Replace the static hue step with a Perlin‑noise function for more organic colour shifts.
Happy hacking!
That looks dreamy! I’ll crank the fog up until the room feels like a cloudscape and then let the LEDs paint the sky. Want me to add a tiny poetic trigger—maybe a soft “I breathe” sound when the mist hits a certain level? Let’s keep it light, but make the lights swirl like a dream, not just a rainbow. Anything else you need?
Nice idea! Add a tiny speaker to pin 9 and play a short wav clip when fogPWM crosses a threshold, say 200. For swirling lights, replace the constant hue step with a sine‑wave offset that slowly drifts—so each LED follows a phase offset that moves over time. Also try easing the LED brightness with a cosine envelope to mimic soft breaths. That’ll give you a gentle, dream‑like motion. Let me know if you need the waveform code or audio file format.
Wow, pin9 for a whispery sound—perfect. I’ll spin the LEDs with a sine‑wave offset and wrap the brightness in a cosine envelope so the lights breathe. Just drop me the wav format and the waveform snippet when you’re ready, and we’ll turn the room into a moving poem.
Here’s a tiny 100 ms “I breathe” clip – 8‑bit unsigned PCM, 8 kHz, mono. Just copy the array into your sketch and play it on pin 9 when fogPWM > 200.
```cpp
// 100 ms, 8 kHz, 8‑bit unsigned (0‑255), 256 samples
const uint8_t breathSound[] = {
128, 133, 138, 143, 148, 152, 156, 160, 164, 167, 170, 173, 175, 177, 179, 180,
181, 181, 181, 181, 180, 179, 178, 176, 174, 172, 170, 167, 165, 162, 160, 157,
155, 152, 150, 148, 146, 144, 142, 141, 140, 139, 138, 138, 138, 138, 139, 140,
141, 142, 144, 146, 148, 151, 154, 157, 160, 163, 166, 170, 173, 177, 180, 184,
188, 191, 195, 198, 201, 203, 205, 207, 208, 209, 210, 210, 210, 209, 208, 206,
204, 201, 198, 195, 191, 187, 183, 179, 175, 171, 167, 163, 159, 155, 151, 148,
144, 141, 138, 136, 133, 131, 130, 128, 127, 126, 126, 126, 126, 127, 128, 130,
132, 134, 137, 140, 143, 146, 150, 153, 156, 160, 164, 168, 172, 175, 179, 183,
186, 190, 193, 196, 199, 201, 204, 205, 207, 208, 209, 210, 210, 209, 208, 207
};
```
**Snippet to play it**
```cpp
#include <Arduino.h>
const int SPEAKER_PIN = 9;
int soundIndex = 0;
void playBreath() {
soundIndex = 0;
for (int i = 0; i < 256; i++) {
analogWrite(SPEAKER_PIN, breathSound[i]); // 0–255 maps to 0–5 V
delayMicroseconds(125); // 8 kHz => 125 µs per sample
}
}
```
**Swirling lights with sine phase + cosine envelope**
```cpp
int swirlPhase = 0; // 0–1023 maps to 0–2π
float brightness = 1.0; // 0–1
void updateLights() {
// Slow rotation
swirlPhase = (swirlPhase + 2) % 1024;
float angle = swirlPhase * TWO_PI / 1024.0;
// Cosine envelope for breathing
brightness = (cos(angle) + 1.0) / 2.0; // 0–1
for (int i = 0; i < NUM_LEDS; i++) {
float phaseOffset = (float)i * 2.0 * PI / NUM_LEDS;
uint16_t hue = (uint16_t)((angle + phaseOffset) * 180.0) % 65536;
uint32_t col = strip.ColorHSV(hue, 255, brightness * 255);
strip.setPixelColor(i, col);
}
strip.show();
}
```
**Trigger logic in `loop()`**
```cpp
if (fogPWM > 200 && !soundPlaying) {
soundPlaying = true;
playBreath();
soundPlaying = false;
}
updateLights();
```
That’s it. Load the code, hit the threshold, and you’ll get a misty, breathing room that glides through color like a living poem. Happy coding!