Untitled
unknown
plain_text
9 months ago
4.7 kB
11
Indexable
// ===== Daniel's ESP32 LED Controller (14 IC/m) =====
// WS2811 12V COB strip • MPU6050 accel • MAX4466 mic • Bluetooth control
// Wiring: LED DI <- GPIO23 (through 470Ω), GND shared; MPU6050 SDA=21 SCL=22; MIC OUT=34
#include <Wire.h>
#include <FastLED.h>
#include "BluetoothSerial.h" // <-- REQUIRED
BluetoothSerial SerialBT; // <-- REQUIRED object
// ---------- STRIP SETUP ----------
#define LED_PIN 23
#define CHIPSET WS2811
#define LED_ORDER GRB
// 14 IC per meter • 5 m = 70 sections.
// If you used less: 14 × (meters you used)
const int TOTAL_SECTIONS = 70;
CRGB leds[TOTAL_SECTIONS];
uint8_t BRIGHT = 160; // 0..255 (use + / - over Bluetooth)
// ---------- SENSORS ----------
#define MPU_SDA 21
#define MPU_SCL 22
#define MIC_PIN 34
// ---------- MODES ----------
uint8_t mode = 1; // 0=off, 1=accel rainbow, 2=solid, 3=music, 4=blend
CRGB solidColor = CRGB::White;
// ---------- MPU6050 ----------
#define MPU_ADDR 0x68
float ax, ay, az, ax0=0, ay0=0, az0=0;
unsigned long lastMPUms = 0;
void mpuReadOnce() {
Wire.beginTransmission(MPU_ADDR); Wire.write(0x3B); Wire.endTransmission(false);
Wire.requestFrom(MPU_ADDR, 6, true);
int16_t axr=(Wire.read()<<8)|Wire.read();
int16_t ayr=(Wire.read()<<8)|Wire.read();
int16_t azr=(Wire.read()<<8)|Wire.read();
ax=axr/16384.0f; ay=ayr/16384.0f; az=azr/16384.0f;
}
void mpuInitAndCalibrate() {
Wire.begin(MPU_SDA, MPU_SCL);
Wire.beginTransmission(MPU_ADDR); Wire.write(0x6B); Wire.write(0); Wire.endTransmission(true);
delay(150);
float sx=0,sy=0,sz=0;
for(int i=0;i<50;i++){ mpuReadOnce(); sx+=ax; sy+=ay; sz+=az; delay(20); }
ax0=sx/50.0f; ay0=sy/50.0f; az0=sz/50.0f;
}
// 0..1 accel factor (higher=faster)
float accel01() {
if (millis()-lastMPUms>10){ mpuReadOnce(); lastMPUms=millis(); }
float dx=ax-ax0, dy=ay-ay0;
float mag=sqrtf(dx*dx+dy*dy); // fore/aft + lateral accel
float g_min=0.00f, g_max=0.20f; // tweak sensitivity: bigger g_max = less sensitive
float t=(mag-g_min)/(g_max-g_min);
if(t<0)t=0; if(t>1)t=1;
static float f=0; f=0.85f*f+0.15f*t; // smooth
return f;
}
// ---------- MIC ENVELOPE ----------
float env=0.0f;
float mic01() {
int raw=analogRead(MIC_PIN); // 0..4095
float v=raw/4095.0f;
float attack=0.20f, decay=0.90f;
if(v>env) env += attack*(v-env); else env = env*decay + (1.0f-decay)*v;
float gate=0.03f; // raise if cabin is noisy
float out=(env>gate)?(env-gate)/(1.0f-gate):0.0f;
if(out<0)out=0; if(out>1)out=1;
return out;
}
// ---------- EFFECT HELPERS ----------
uint16_t factorToDelay(float f){
int d_fast=18, d_slow=160;
int d=d_slow + (int)((d_fast - d_slow)*f);
return (d<1)?1:d;
}
void showSolid(CRGB c){ fill_solid(leds, TOTAL_SECTIONS, c); FastLED.show(); }
void rainbowStep(uint16_t dly){
static uint8_t hue=0;
for(int i=0;i<TOTAL_SECTIONS;i++) leds[i]=CHSV(hue + i*4, 255, 255);
FastLED.show(); hue++; delay(dly);
}
void accelRainbow(){ rainbowStep(factorToDelay(accel01())); }
void musicPulse(){
float v=mic01(); uint8_t level=(uint8_t)(v*255);
uint8_t hue=map(level,0,255,160,0); // quiet→blue, loud→red
for(int i=0;i<TOTAL_SECTIONS;i++) leds[i]=CHSV(hue,255,max<uint8_t>(40,level));
FastLED.show(); delay(20);
}
void blendAccelMusic(){
float f=0.6f*accel01() + 0.4f*mic01(); // 60% accel, 40% music
rainbowStep(factorToDelay(f));
}
// ---------- BLUETOOTH ----------
void handleBT(){
while(SerialBT.available()){
char c=SerialBT.read();
if(c=='0') mode=0;
if(c=='1') mode=1;
if(c=='2') mode=2;
if(c=='3') mode=3;
if(c=='m'||c=='M') mode=4;
if(c=='+'){ BRIGHT=(BRIGHT>230)?255:BRIGHT+25; FastLED.setBrightness(BRIGHT); }
if(c=='-'){ BRIGHT=(BRIGHT< 25)?0 :BRIGHT-25; FastLED.setBrightness(BRIGHT); }
if(c=='r'||c=='R') solidColor=CRGB::Red;
if(c=='g'||c=='G') solidColor=CRGB::Green;
if(c=='b'||c=='B') solidColor=CRGB::Blue;
if(c=='w'||c=='W') solidColor=CRGB::White;
}
}
// ---------- SETUP / LOOP ----------
void setup(){
Serial.begin(115200);
SerialBT.begin("ESP32_LED"); // Pair from phone (PIN 0000 or 1234)
analogReadResolution(12);
FastLED.addLeds<CHIPSET, LED_PIN, LED_ORDER>(leds, TOTAL_SECTIONS);
FastLED.setBrightness(BRIGHT);
mpuInitAndCalibrate();
// small power-on indicator
showSolid(CRGB(10,0,20)); delay(300);
}
void loop(){
handleBT();
switch(mode){
case 0: showSolid(CRGB::Black); delay(20); break;
case 1: accelRainbow(); break;
case 2: showSolid(solidColor); delay(20); break;
case 3: musicPulse(); break;
case 4: blendAccelMusic(); break;
}
}Editor is loading...
Leave a Comment