🌸 开心快乐每一天 文车网(wche.cn),载文而行,采用静态建站系统,页面干净、加载快、更利于搜索引擎收录。

8*8led点阵屏+陀螺仪模块

文章横幅

#include <Wire.h> #include <Adafruit_NeoPixel.h> #define PIN        0 #define NUMPIXELS  64 #define SDA        21 #define SCL        20 #define MPU_ADDR   0x68 Adafruit_NeoPixel pixels(NUMPIXELS,

8*8led点阵屏+陀螺仪模块


#include <Wire.h>
#include <Adafruit_NeoPixel.h>


#define PIN        0
#define NUMPIXELS  64
#define SDA        21
#define SCL        20
#define MPU_ADDR   0x68


Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);


float h[8][8];
float ax, ay;
float vx, vy;


uint8_t r = 0, g = 40, b = 200;
unsigned long lastColor = 0;


// 正确水量:刚好 16 灯
const float TARGET = 4.0f;


void setup() {
  Serial.begin(115200);
  Wire.begin(SDA, SCL);
  pixels.begin();
  pixels.setBrightness(30);  // 👈 亮度改小了,其他完全不动
  pixels.clear();


  Wire.beginTransmission(MPU_ADDR);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission();


  // 初始:底部两行 = 16灯
  for (int y=0;y<8;y++) {
    for (int x=0;x<8;x++) {
      h[y][x] = (y >= 6) ? 1.0f : 0.0f;
    }
  }
}


void loop() {
  readSensor();
  simulateWater();
  normalizeWater();
  shakeChangeColor();
  draw();


  pixels.show();
  delay(20);
}


// 读取传感器
void readSensor() {
  Wire.beginTransmission(MPU_ADDR);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_ADDR, 6);


  int16_t rax = Wire.read() << 8 | Wire.read();
  int16_t ray = Wire.read() << 8 | Wire.read();


  float gx = rax / 16384.0f;
  float gy = ray / 16384.0f;


  ax = ax * 0.7f + gx * 0.3f;
  ay = ay * 0.7f + gy * 0.3f;


  vx += ax * 0.22f;
  vy += ay * 0.22f;
  vx *= 0.88f;
  vy *= 0.88f;
}


// 正确水流物理(边界不会黑!)
void simulateWater() {
  float fx = ax + vx;
  float fy = ay + vy;


  for (int y=0;y<8;y++) {
    for (int x=0;x<8;x++) {
      float dx = x - 3.5f;
      float dy = y - 3.5f;
      float change = fx * dx * 0.12f + fy * dy * 0.12f;
      h[y][x] += change;
      h[y][x] = constrain(h[y][x], 0.0f, 2.0f);
    }
  }


  // 弱平滑 → 不丢灯
  float t[8][8];
  memcpy(t, h, sizeof(t));
  for (int y=1;y<7;y++) {
    for (int x=1;x<7;x++) {
      h[y][x] = t[y][x] * 0.9 + t[y-1][x]*0.025 + t[y+1][x]*0.025 + t[y][x-1]*0.025 + t[y][x+1]*0.025;
    }
  }
}


// 强制 16 灯,绝不乱变
void normalizeWater() {
  float sum = 0;
  for (int y=0;y<8;y++)
    for (int x=0;x<8;x++)
      sum += h[y][x];


  float scale = TARGET / sum;
  for (int y=0;y<8;y++)
    for (int x=0;x<8;x++)
      h[y][x] *= scale;
}


// 晃一下变色
void shakeChangeColor() {
  float s = abs(vx) + abs(vy);
  if (s > 0.5f && millis() - lastColor > 600) {
    lastColor = millis();
    int c = random(5);
    if (c==0) { r=0; g=40; b=220; }   // 蓝
    if (c==1) { r=0; g=150; b=150; }  // 青
    if (c==2) { r=160; g=20; b=180; } // 紫
    if (c==3) { r=0; g=180; b=40; }   // 绿
    if (c==4) { r=200; g=80; b=0; }   // 橙
  }
}


// 渲染:低阈值 = 倾斜/竖起来 都不黑灯!
void draw() {
  pixels.clear();
  for (int y=0;y<8;y++) {
    for (int x=0;x<8;x++) {
      if (h[y][x] > 0.02f) {  // 极低阈值 = 不丢灯
        pixels.setPixelColor(y*8+x, pixels.Color(r, g, b));
      }
    }
  }
}



"凡是过往,皆为序章;凡是未来,皆有可期。"

← 上一篇
节奏大灯源码
📌 文章永久地址:https://wche.cn/storage/article/8-8led.html