Untitled

 avatar
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