将两条led融合为一个显示矩阵

[复制链接]
 楼主| keer_zu 发表于 2025-5-26 15:16 | 显示全部楼层 |阅读模式
代码:

  1. #include <FastLED.h>

  2. // 矩阵配置
  3. #define MATRIX_WIDTH  30
  4. #define MATRIX_HEIGHT 19
  5. #define DATA_PIN_LOWER 15  // 下部区域GPIO15
  6. #define DATA_PIN_UPPER 4   // 上部区域GPIO2

  7. // LED总数计算
  8. #define NUM_LOWER_ROWS  9
  9. #define NUM_UPPER_ROWS  10
  10. #define NUM_LEDS_LOWER (MATRIX_WIDTH*NUM_LOWER_ROWS)   // 下部30x9
  11. #define NUM_LEDS_UPPER (MATRIX_WIDTH*NUM_UPPER_ROWS) // 上部30x10
  12. #define NUM_LEDS (NUM_LEDS_LOWER + NUM_LEDS_UPPER)
  13. CRGB leds[NUM_LEDS];


  14. // 颜色定义
  15. const CRGB BACKGROUND = CRGB(0, 0, 0);  // 浅白色背景
  16. const CRGB CIRCLE_COLOR = CRGB(0, 100, 255);  // 蓝色圆环

  17. #define MAX_WAVES      6  // 增加最大波环数量


  18. //===================== wave ====================================


  19. struct  Wave{
  20.   float radius;
  21.   float intensity;
  22.   bool active;
  23.   uint8_t generation;
  24.   bool hasTriggered;
  25.   float speedVariation;   // 速度随机因子
  26.   float widthVariation;   // 宽度随机因子
  27.   float angleOffset;      // 角度偏移(用于形状随机)
  28. };

  29. Wave waves[MAX_WAVES];

  30. // 调整后的参数
  31. const float BASE_WAVE_SPEED = 0.45;  // 基础速度
  32. const float BASE_WAVE_WIDTH = 2.4f;   // 基础宽度(减小)
  33. const float DECAY_RATE = 0.955f;
  34. const float TRIGGER_DISTANCE = 1.8f;  // 缩短触发距离增加密度

  35. float distanceMap[MATRIX_WIDTH][MATRIX_HEIGHT];
  36. float maxRadius;
  37. uint8_t center_x, center_y;

  38. //===============================================================
  39. // 安全版XY映射
  40. uint16_t XY(uint8_t x, uint8_t y) {
  41.   x = constrain(x, 0, MATRIX_WIDTH-1);
  42.   y = constrain(y, 0, MATRIX_HEIGHT-1);
  43.   
  44.   uint16_t index;
  45.   if(y < NUM_LOWER_ROWS) {
  46.     if(y % 2 == 0) {
  47.       index = y * MATRIX_WIDTH + x;
  48.     } else {
  49.       index = (y + 1) * MATRIX_WIDTH - 1 - x;
  50.     }
  51.   } else {
  52.     if(y % 2 == 0) {
  53.       index = (y-NUM_LOWER_ROWS) * MATRIX_WIDTH + x + NUM_LEDS_LOWER;
  54.     } else {
  55.       index = (y-NUM_LOWER_ROWS + 1) * MATRIX_WIDTH - 1 - x + NUM_LEDS_LOWER;
  56.     }
  57.   }

  58.   return constrain(index, 0, NUM_LEDS-1);
  59. }


  60. void setup() {
  61.   FastLED.addLeds<WS2815, DATA_PIN_LOWER, GRB>(leds, NUM_LEDS_LOWER);
  62.   FastLED.addLeds<WS2815, DATA_PIN_UPPER, GRB>(leds+NUM_LEDS_LOWER, NUM_LEDS_UPPER);
  63.   FastLED.setBrightness(100);
  64.   FastLED.clear();
  65.    //==================== wave ======================
  66.    center_x = (MATRIX_WIDTH-1)/2;
  67.   center_y = (MATRIX_HEIGHT-1)/2;
  68.   
  69.   // 预计算基础距离
  70.   for(uint8_t y=0; y<MATRIX_HEIGHT; y++){
  71.     for(uint8_t x=0; x<MATRIX_WIDTH; x++){
  72.       float dx = x - center_x;
  73.       float dy = y - center_y;
  74.       distanceMap[x][y] = sqrt(dx*dx + dy*dy);
  75.     }
  76.   }
  77.   maxRadius = distanceMap[0][0];

  78.   // 初始化第一个波环
  79.   waves[0] = {
  80.     0.0f,
  81.     1.0f,
  82.     true,
  83.     0,
  84.     false,
  85.     random8(95, 105)/100.0f,  // 初始速度随机
  86.     random8(95, 105)/100.0f,  // 初始宽度随机
  87.     random8(0, 628)/100.0f     // 初始角度偏移(0-2π)
  88.   };
  89.   for(uint8_t i=1; i<MAX_WAVES; i++) waves[i].active = false;

  90.   //================================================
  91. }

  92. // 带随机扰动的距离计算
  93. float perturbedDistance(uint8_t x, uint8_t y, Wave &w) {
  94.   float dx = x - center_x;
  95.   float dy = y - center_y;
  96.   
  97.   // 添加基于角度的随机扰动
  98.   float angle = atan2(dy, dx) + w.angleOffset;
  99.   float perturbation = 0.4f * sin(angle * 3 + w.radius * 0.5f);
  100.   
  101.   return sqrt(dx*dx + dy*dy) * (1.0f + perturbation * 0.08f);
  102. }

  103. void spawnWave(uint8_t gen) {
  104.   for(uint8_t i=0; i<MAX_WAVES; i++){
  105.     if(!waves[i].active){
  106.       waves[i] = {
  107.         0.0f,
  108.         1.0f - gen*0.12f,
  109.         true,
  110.         gen,
  111.         false,
  112.         random8(95, 105)/100.0f,  // 速度随机因子
  113.         random8(90, 110)/100.0f,  // 宽度随机因子
  114.         random8(0, 628)/100.0f    // 新随机角度
  115.       };
  116.       return;
  117.     }
  118.   }
  119. }

  120. void loop() {
  121.   static uint32_t lastFrame = millis();
  122.   float deltaTime = (millis() - lastFrame)/1000.0f;
  123.   lastFrame = millis();

  124.   fadeToBlackBy(leds, NUM_LEDS, 25);  // 加快淡出速度增加密度感

  125.   for(uint8_t i=0; i<MAX_WAVES; i++){
  126.     if(waves[i].active){
  127.       Wave &w = waves[i];
  128.       
  129.       // 应用随机速度
  130.       w.radius += BASE_WAVE_SPEED * w.speedVariation * (1.0f + deltaTime);
  131.       w.intensity *= DECAY_RATE;

  132.       // 触发新波环
  133.       if(w.generation == 0 && !w.hasTriggered && w.radius >= TRIGGER_DISTANCE){
  134.         spawnWave(1);
  135.         w.hasTriggered = true;
  136.       }

  137.       // 波环生命周期管理
  138.       if(w.radius > maxRadius || w.intensity < 0.12f){
  139.         if(w.generation == 0){
  140.           // 重置核心波环并重新随机参数
  141.           w.radius = 0.0f;
  142.           w.intensity = 1.0f;
  143.           w.hasTriggered = false;
  144.           w.speedVariation = random8(95, 105)/100.0f;
  145.           w.widthVariation = random8(90, 110)/100.0f;
  146.           w.angleOffset = random8(0, 628)/100.0f;
  147.         }else{
  148.           w.active = false;
  149.         }
  150.       }

  151.       // 绘制波环
  152.       for(uint8_t y=0; y<MATRIX_HEIGHT; y++){
  153.         for(uint8_t x=0; x<MATRIX_WIDTH; x++){
  154.           // 使用扰动后的距离计算
  155.           float dist = perturbedDistance(x, y, w);
  156.           float delta = abs(dist - w.radius);
  157.          
  158.           // 应用随机宽度
  159.           float effectiveWidth = BASE_WAVE_WIDTH * w.widthVariation;
  160.           float effect = exp(-pow(delta/effectiveWidth, 2.2f)) * w.intensity;
  161.          
  162.           // 中心抑制
  163.           if(x >= center_x-1 && x <= center_x && y >= center_y-1 && y <= center_y){
  164.             effect *= 0.15f;
  165.           }
  166.          
  167.           // 颜色混合(添加轻微随机色相偏移)
  168.           uint8_t hue = 160 + w.generation*18 + w.radius*0.8f;
  169.           leds[XY(x,y)] += CHSV(hue, 210, effect * 220);
  170.         }
  171.       }
  172.     }
  173.   }

  174.   // 强化中心暗区
  175.   for(uint8_t dx=0; dx<2; dx++){
  176.     for(uint8_t dy=0; dy<2; dy++){
  177.       uint16_t idx = XY(center_x-dx, center_y-dy);
  178.       leds[idx].nscale8(40);  // 更暗的中心
  179.     }
  180.   }

  181.   FastLED.show();
  182.   FastLED.delay(28);  // 稍快的刷新率
  183. }
 楼主| keer_zu 发表于 2025-5-26 17:20 | 显示全部楼层
显示16*16汉字:

  1. #include <FastLED.h>
  2. #include <ArduinoJson.h>

  3. #define COLOR_ORDER GRB
  4. #define CHIPSET     WS2815



  5. //======================================
  6. // 矩阵配置
  7. #define MATRIX_WIDTH  30
  8. #define MATRIX_HEIGHT 19
  9. #define DATA_PIN_LOWER 15  // 下部区域GPIO15
  10. #define DATA_PIN_UPPER 4   // 上部区域GPIO2

  11. // LED总数计算
  12. #define NUM_LOWER_ROWS  9
  13. #define NUM_UPPER_ROWS  10
  14. #define NUM_LEDS_LOWER (MATRIX_WIDTH*NUM_LOWER_ROWS)   // 下部30x9
  15. #define NUM_LEDS_UPPER (MATRIX_WIDTH*NUM_UPPER_ROWS) // 上部30x10
  16. #define NUM_LEDS (NUM_LEDS_LOWER + NUM_LEDS_UPPER)
  17. CRGB leds[NUM_LEDS];
  18. //======================================

  19. #define HAN_BITMAP_HEIGHT 16
  20. #define HAN_START_ROW  2   //只能偶数
  21. #define BITMAP_WIDTH 720
  22. #define BITMAP_WIDTH_BYTE_NUM  (BITMAP_WIDTH/8)




  23. #define BITMAP_INDEX(x,y) ((HAN_BITMAP_HEIGHT - 1 - y)*BITMAP_WIDTH_BYTE_NUM + (x/8) - 1)
  24. #define BITMMAP_POSITION(x) (x%8)


  25. // 颜色定义
  26. const CRGB BACKGROUND_COLOR = CRGB(0x0, 0x0, 0x100); //
  27. const CRGB TEXT_COLOR = CRGB(30,250, 30);       //

  28. // 点阵数据(已转换格式)
  29. /*96 x 15*/
  30. static const unsigned char textBitmap[] = {
  31.     0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x04, 0x40, 0x10, 0x00, 0x10, 0x20, 0x10, 0x20, 0x00, 0x00, 0x00, 0x40, 0x10, 0x40, 0x04, 0x40, 0x00, 0x00, 0x02, 0x00, 0x10, 0x20, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x20, 0x04, 0x40, 0x10, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x04, 0x40, 0x00, 0x80, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x10, 0x00, 0x80, 0x01, 0x10, 0x00, 0x80, 0x00, 0x80, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00,
  32.     0x3f, 0xf8, 0x3f, 0xf8, 0x20, 0x40, 0x20, 0x40, 0x0e, 0x50, 0x10, 0xfc, 0x10, 0x20, 0x10, 0x20, 0x00, 0x00, 0x7c, 0x20, 0x10, 0x40, 0x0e, 0x50, 0x23, 0xfe, 0x04, 0x00, 0x10, 0x20, 0x20, 0x40, 0x20, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x3f, 0xf8, 0x08, 0x20, 0x0e, 0x50, 0x10, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x41, 0x08, 0x3f, 0xf8, 0x00, 0x40, 0x01, 0x00, 0x0e, 0x50, 0x00, 0x80, 0x01, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x01, 0x10, 0x00, 0x40, 0x01, 0x10, 0x20, 0x40, 0x20, 0x40, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00,
  33.     0x01, 0x00, 0x01, 0x00, 0x17, 0xfc, 0x17, 0xfc, 0x78, 0x48, 0x10, 0x04, 0x10, 0x40, 0x10, 0x40, 0x00, 0x00, 0x45, 0xfc, 0x20, 0x40, 0x78, 0x48, 0x12, 0x02, 0x1f, 0xf0, 0x10, 0x3e, 0x17, 0xfc, 0x17, 0xfc, 0x00, 0x00, 0x7f, 0xfe, 0xfc, 0x10, 0x01, 0x00, 0x08, 0x20, 0x78, 0x48, 0x3f, 0x7e, 0x78, 0xa0, 0x78, 0xa0, 0x00, 0x00, 0x21, 0x10, 0x01, 0x00, 0xfc, 0x80, 0x02, 0x80, 0x78, 0x48, 0x78, 0x80, 0x77, 0xc4, 0x79, 0x20, 0x00, 0x00, 0xf7, 0xfc, 0xf7, 0xfc, 0xf7, 0xfc, 0xf7, 0xfc, 0x17, 0xfc, 0x17, 0xfc, 0xf7, 0xfc, 0x00, 0x00, 0x00, 0x00,
  34.     0x01, 0x00, 0x7f, 0xfe, 0x11, 0x10, 0x11, 0x10, 0x08, 0x48, 0x10, 0x08, 0x11, 0xfc, 0x11, 0xfc, 0x00, 0x00, 0x44, 0x88, 0x7e, 0x7c, 0x08, 0x48, 0x14, 0x44, 0x10, 0x10, 0x10, 0x20, 0x10, 0xe0, 0x10, 0xe0, 0x00, 0x00, 0x40, 0x02, 0x11, 0xfe, 0x01, 0x00, 0x7e, 0x20, 0x08, 0x48, 0x28, 0x90, 0x49, 0x10, 0x49, 0x10, 0x00, 0x00, 0x2f, 0xfe, 0x01, 0x00, 0x04, 0xfe, 0x04, 0x40, 0x08, 0x48, 0x48, 0xfc, 0x51, 0x04, 0x49, 0x20, 0x00, 0x00, 0x91, 0x10, 0x91, 0x10, 0x91, 0x10, 0x91, 0x10, 0x11, 0x10, 0x11, 0x10, 0x91, 0x10, 0x00, 0x00, 0x00, 0x00,
  35.     0x01, 0x00, 0x41, 0x02, 0x82, 0x48, 0x82, 0x48, 0x08, 0x40, 0xfc, 0x10, 0x19, 0x04, 0x19, 0x04, 0x00, 0x00, 0x7c, 0x50, 0x42, 0x84, 0x08, 0x40, 0x80, 0x40, 0x1f, 0xf0, 0xfd, 0xfc, 0x81, 0x50, 0x81, 0x50, 0x00, 0x00, 0x88, 0x24, 0x11, 0x12, 0x01, 0x00, 0x08, 0xfc, 0x08, 0x40, 0x45, 0x08, 0x4a, 0x08, 0x4a, 0x08, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x05, 0x08, 0x08, 0x20, 0x08, 0x40, 0x49, 0x04, 0x51, 0x14, 0x49, 0x20, 0x00, 0x00, 0x90, 0xa0, 0x90, 0x40, 0x90, 0xa0, 0x90, 0x40, 0x80, 0xa0, 0x80, 0xa0, 0x90, 0x40, 0x00, 0x00, 0x00, 0x00,
  36.     0x01, 0x00, 0x9d, 0x74, 0x44, 0x84, 0x44, 0x84, 0xff, 0xfe, 0x24, 0x20, 0x55, 0x04, 0x55, 0x04, 0x00, 0x00, 0x43, 0xfe, 0x42, 0x84, 0xff, 0xfe, 0x43, 0xfc, 0x10, 0x10, 0x11, 0x04, 0x42, 0x48, 0x42, 0x48, 0x00, 0x00, 0x11, 0x10, 0x21, 0x14, 0x01, 0x00, 0x08, 0x24, 0xff, 0xfe, 0x80, 0xf0, 0x4c, 0x06, 0x4c, 0x06, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x05, 0x08, 0x37, 0xd8, 0xff, 0xfe, 0x49, 0x08, 0x57, 0xd4, 0x49, 0x20, 0x00, 0x00, 0x97, 0xfc, 0x90, 0xa0, 0x97, 0xfc, 0x90, 0xa0, 0x47, 0xfc, 0x47, 0xfc, 0x90, 0xa0, 0x00, 0x00, 0x00, 0x00,
  37.     0xff, 0xfe, 0x01, 0x00, 0x41, 0x20, 0x41, 0x20, 0x08, 0x40, 0x24, 0x20, 0x51, 0x04, 0x51, 0x04, 0x00, 0x00, 0x7c, 0x20, 0x43, 0x04, 0x08, 0x40, 0x48, 0x80, 0x1f, 0xf2, 0x15, 0xfc, 0x44, 0x46, 0x44, 0x46, 0x00, 0x00, 0x21, 0x48, 0x3d, 0x10, 0xff, 0xfe, 0x08, 0x24, 0x08, 0x40, 0x3f, 0x00, 0x4b, 0xf8, 0x4b, 0xf8, 0x00, 0x00, 0xe4, 0x44, 0xff, 0xfe, 0x06, 0x88, 0xc0, 0x06, 0x08, 0x40, 0x4a, 0x40, 0x55, 0x54, 0x49, 0x20, 0x00, 0x00, 0x94, 0x44, 0x91, 0x10, 0x94, 0x44, 0x91, 0x10, 0x44, 0x44, 0x44, 0x44, 0x91, 0x10, 0x00, 0x00, 0x00, 0x00,
  38.     0x01, 0x00, 0x1d, 0x70, 0x13, 0xf0, 0x13, 0xf0, 0x08, 0x44, 0x25, 0xfe, 0x51, 0x04, 0x51, 0x04, 0x00, 0x00, 0xa5, 0xfc, 0x42, 0x44, 0x08, 0x44, 0x08, 0xa0, 0x10, 0x14, 0x19, 0x04, 0x13, 0xf8, 0x13, 0xf8, 0x00, 0x00, 0x01, 0x20, 0x65, 0xfc, 0x01, 0x00, 0xff, 0x24, 0x08, 0x44, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0x00, 0x24, 0x44, 0x01, 0x00, 0x7c, 0x88, 0x00, 0x00, 0x08, 0x44, 0x4c, 0x40, 0x55, 0x54, 0x49, 0x20, 0x00, 0x00, 0x95, 0xf4, 0x92, 0x08, 0x95, 0xf4, 0x92, 0x08, 0x15, 0xf4, 0x15, 0xf4, 0x92, 0x08, 0x00, 0x00, 0x00, 0x00,
  39.     0x02, 0x80, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x0a, 0x44, 0x24, 0x20, 0x91, 0xfc, 0x91, 0xfc, 0x00, 0x00, 0x24, 0x20, 0x7e, 0x24, 0x0a, 0x44, 0x11, 0x20, 0x10, 0x18, 0x31, 0xfc, 0x12, 0x08, 0x12, 0x08, 0x00, 0x00, 0x01, 0x00, 0x65, 0x44, 0x02, 0x80, 0x10, 0x24, 0x0a, 0x44, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0x00, 0x24, 0x44, 0x02, 0x80, 0x40, 0x88, 0x3e, 0xf8, 0x0a, 0x44, 0x48, 0x40, 0x57, 0xd4, 0x49, 0x20, 0x00, 0x00, 0x94, 0x44, 0x95, 0xf6, 0x94, 0x44, 0x95, 0xf6, 0x14, 0x44, 0x14, 0x44, 0x95, 0xf6, 0x00, 0x00, 0x00, 0x00,
  40.     0x02, 0x80, 0x3f, 0xf8, 0x20, 0x88, 0x20, 0x88, 0x0c, 0x48, 0x48, 0x20, 0x11, 0x04, 0x11, 0x04, 0x00, 0x00, 0x3c, 0x20, 0x42, 0x24, 0x0c, 0x48, 0x11, 0xfc, 0x7f, 0xf0, 0xd1, 0x24, 0x23, 0xf8, 0x23, 0xf8, 0x00, 0x00, 0x7f, 0xfc, 0xa5, 0x44, 0x02, 0x80, 0x10, 0x24, 0x0c, 0x48, 0xff, 0xfe, 0x4b, 0xf8, 0x4b, 0xf8, 0x00, 0x00, 0x27, 0xfc, 0x02, 0x80, 0x40, 0x50, 0x22, 0x88, 0x0c, 0x48, 0x48, 0xa0, 0x51, 0x14, 0x49, 0x10, 0x00, 0x00, 0x95, 0xf4, 0x90, 0x00, 0x95, 0xf4, 0x90, 0x00, 0x25, 0xf4, 0x25, 0xf4, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00,
  41.     0x04, 0x40, 0x21, 0x08, 0xe1, 0x50, 0xe1, 0x50, 0x18, 0x30, 0x28, 0x20, 0x11, 0x04, 0x11, 0x04, 0x00, 0x00, 0x00, 0x00, 0x42, 0x04, 0x18, 0x30, 0xe0, 0x20, 0x00, 0x50, 0x10, 0x20, 0xe2, 0x08, 0xe2, 0x08, 0x18, 0x00, 0x01, 0x00, 0x25, 0x28, 0x04, 0x40, 0x20, 0x24, 0x18, 0x30, 0x01, 0x00, 0x7a, 0x08, 0x7a, 0x08, 0x00, 0x00, 0x20, 0x84, 0x04, 0x40, 0x40, 0x50, 0x22, 0x88, 0x18, 0x30, 0x78, 0xa0, 0x73, 0x94, 0x79, 0x10, 0x00, 0x00, 0xf5, 0x14, 0xf0, 0x00, 0xf5, 0x14, 0xf0, 0x00, 0xe5, 0x14, 0xe5, 0x14, 0xf0, 0x00, 0x18, 0x00, 0x00, 0x00,
  42.     0x04, 0x40, 0x21, 0x08, 0x23, 0x20, 0x23, 0x20, 0x68, 0x22, 0x10, 0x20, 0x11, 0x04, 0x11, 0x04, 0x30, 0x00, 0x7f, 0xf8, 0x42, 0x04, 0x68, 0x22, 0x20, 0x20, 0x00, 0x90, 0x13, 0xfe, 0x23, 0xf8, 0x23, 0xf8, 0x24, 0x00, 0x02, 0x80, 0x25, 0x28, 0x04, 0x40, 0x44, 0x44, 0x68, 0x22, 0x02, 0x80, 0x4a, 0x08, 0x4a, 0x08, 0x30, 0x00, 0x21, 0x00, 0x04, 0x40, 0x44, 0x20, 0x22, 0x88, 0x68, 0x22, 0x49, 0x10, 0x55, 0x54, 0x4a, 0x10, 0x30, 0x00, 0x95, 0x14, 0x93, 0xf8, 0x95, 0x14, 0x93, 0xf8, 0x25, 0x14, 0x25, 0x14, 0x93, 0xf8, 0x24, 0x00, 0x00, 0x00,
  43.     0x08, 0x20, 0x3f, 0xf8, 0x25, 0x10, 0x25, 0x10, 0x08, 0x52, 0x28, 0x20, 0x11, 0x04, 0x11, 0x04, 0x30, 0x00, 0x04, 0x08, 0x42, 0x04, 0x08, 0x52, 0x27, 0xfe, 0x03, 0x10, 0x10, 0x20, 0x22, 0x08, 0x22, 0x08, 0x24, 0x00, 0x04, 0x40, 0x3d, 0x10, 0x08, 0x20, 0xfe, 0x44, 0x08, 0x52, 0x04, 0x40, 0x02, 0x08, 0x02, 0x08, 0x30, 0x00, 0x22, 0x00, 0x08, 0x20, 0x58, 0x50, 0x3e, 0xa8, 0x08, 0x52, 0x01, 0x10, 0x09, 0x44, 0x02, 0x08, 0x30, 0x00, 0x05, 0xf4, 0x02, 0x08, 0x05, 0xf4, 0x02, 0x08, 0x25, 0xf4, 0x25, 0xf4, 0x02, 0x08, 0x24, 0x00, 0x00, 0x00,
  44.     0x10, 0x10, 0x21, 0x08, 0x29, 0x48, 0x29, 0x48, 0x08, 0x8a, 0x44, 0x20, 0x11, 0x04, 0x11, 0x04, 0x10, 0x00, 0x08, 0x08, 0x7e, 0x04, 0x08, 0x8a, 0x20, 0x20, 0x1c, 0x10, 0x10, 0x20, 0x20, 0x00, 0x20, 0x00, 0x18, 0x00, 0x08, 0x20, 0x26, 0x28, 0x10, 0x10, 0x42, 0x84, 0x08, 0x8a, 0x08, 0x20, 0x02, 0x08, 0x02, 0x08, 0x10, 0x00, 0x54, 0x00, 0x10, 0x10, 0x60, 0x88, 0x22, 0x90, 0x08, 0x8a, 0x02, 0x08, 0x01, 0x04, 0x04, 0x08, 0x10, 0x00, 0x04, 0x04, 0x02, 0x08, 0x04, 0x04, 0x02, 0x08, 0x24, 0x04, 0x24, 0x04, 0x02, 0x08, 0x18, 0x00, 0x00, 0x00,
  45.     0x20, 0x08, 0x21, 0x08, 0x21, 0x86, 0x21, 0x86, 0x2b, 0x06, 0x84, 0xa0, 0x11, 0xfc, 0x11, 0xfc, 0x20, 0x00, 0x10, 0x50, 0x42, 0x28, 0x2b, 0x06, 0x20, 0x20, 0xe0, 0x50, 0x50, 0x20, 0x2f, 0xfe, 0x2f, 0xfe, 0x00, 0x00, 0x30, 0x18, 0x22, 0x44, 0x20, 0x08, 0x01, 0x28, 0x2b, 0x06, 0x30, 0x18, 0x03, 0xf8, 0x03, 0xf8, 0x20, 0x00, 0x8f, 0xfe, 0x20, 0x08, 0x41, 0x04, 0x00, 0x80, 0x2b, 0x06, 0x04, 0x04, 0x01, 0x14, 0x08, 0x04, 0x20, 0x00, 0x04, 0x14, 0x03, 0xf8, 0x04, 0x14, 0x03, 0xf8, 0x24, 0x14, 0x24, 0x14, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00,
  46.     0xc0, 0x06, 0x3f, 0xf8, 0x01, 0x00, 0x01, 0x00, 0x10, 0x02, 0x00, 0x40, 0x11, 0x04, 0x11, 0x04, 0x00, 0x00, 0x60, 0x20, 0x00, 0x10, 0x10, 0x02, 0x00, 0x20, 0x00, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x06, 0x04, 0x82, 0xc0, 0x06, 0x02, 0x10, 0x10, 0x02, 0xc0, 0x06, 0x02, 0x08, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x06, 0x02, 0x02, 0x00, 0x80, 0x10, 0x02, 0x08, 0x02, 0x01, 0x08, 0x10, 0x02, 0x00, 0x00, 0x04, 0x08, 0x02, 0x08, 0x04, 0x08, 0x02, 0x08, 0x04, 0x08, 0x04, 0x08, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00
  47. };

  48. static const unsigned char bitmap_alph_nums[] = {
  49.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  50.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  51.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  52.     0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  53.     0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  54.     0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  55.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  56.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  57.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  58.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x3E, 0xF8, 0xFC,
  59.     0xFC, 0x3C, 0xE7, 0x7C, 0x3E, 0xEE, 0xE0, 0xEE, 0xC7, 0x38, 0xFC, 0x38, 0xFC, 0x3E, 0xFE,
  60.     0xE7, 0xE7, 0xD6, 0xE7, 0xEE, 0x7E, 0x18, 0x08, 0x3C, 0x3C, 0x04, 0x7E, 0x18, 0x7E, 0x3C,
  61.     0xC0, 0x06, 0x00, 0x0C, 0xC0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  62.     0xC0, 0x06, 0x00, 0x1E, 0xC0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x7E, 0xFC, 0xFE,
  63.     0xFE, 0x7C, 0xE7, 0x7C, 0x3E, 0xEE, 0xE0, 0xEE, 0xE7, 0x7C, 0xFE, 0x7C, 0xFE, 0x7E, 0xFE,
  64.     0xE7, 0xE7, 0xD6, 0xE7, 0xEE, 0xFE, 0x3C, 0x38, 0x7E, 0x7E, 0x0C, 0x7E, 0x3C, 0x7E, 0x7E,
  65.     0x40, 0x02, 0x00, 0x12, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  66.     0x40, 0x02, 0x00, 0x12, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x42, 0x46, 0x4A,
  67.     0x4A, 0x44, 0x42, 0x10, 0x08, 0x4C, 0x40, 0x6C, 0x62, 0xC6, 0x42, 0xC6, 0x42, 0x42, 0x92,
  68.     0x42, 0x42, 0x54, 0x66, 0x44, 0x84, 0x66, 0x38, 0x42, 0x42, 0x0C, 0x40, 0x64, 0x46, 0x42,
  69.     0x58, 0x3E, 0x7C, 0x7C, 0x3E, 0x5C, 0x70, 0x1C, 0x4E, 0x10, 0xFE, 0xDC, 0x3C, 0xD8, 0x1A,
  70.     0xEE, 0x3E, 0x7C, 0xC6, 0xEE, 0xDB, 0x76, 0xE7, 0x7E, 0x28, 0x7C, 0x80, 0x42, 0x78, 0x78,
  71.     0x80, 0x42, 0x10, 0x08, 0x70, 0x40, 0x6C, 0x52, 0x82, 0x42, 0x82, 0x7E, 0x60, 0x10, 0x42,
  72.     0x64, 0x54, 0x3C, 0x28, 0x08, 0x42, 0x08, 0x06, 0x34, 0x78, 0x5C, 0x0C, 0x66, 0x42, 0x42,
  73.     0x7C, 0x7E, 0x7C, 0x7E, 0x7C, 0x7E, 0x70, 0x1C, 0x4E, 0x10, 0xFF, 0xFE, 0x7E, 0xFC, 0x3E,
  74.     0xFE, 0x7E, 0x7C, 0xC6, 0xEE, 0xDB, 0x76, 0xE7, 0x7E, 0x2C, 0x7C, 0x80, 0x42, 0x78, 0x78,
  75.     0x80, 0x7E, 0x10, 0x08, 0x70, 0x40, 0x6C, 0x5A, 0x82, 0x7E, 0x82, 0x7C, 0x38, 0x10, 0x42,
  76.     0x24, 0x54, 0x18, 0x38, 0x18, 0x42, 0x08, 0x06, 0x1C, 0x24, 0x7C, 0x08, 0x3C, 0x46, 0x7E,
  77.     0x6C, 0x66, 0x62, 0x42, 0x42, 0x10, 0x44, 0x62, 0x10, 0x04, 0x58, 0x10, 0x49, 0x62, 0x42,
  78.     0x66, 0x66, 0x32, 0x42, 0x10, 0x42, 0x6C, 0xCB, 0x76, 0x66, 0x4C, 0x3C, 0x46, 0x42, 0x80,
  79.     0x42, 0x48, 0x48, 0x8E, 0x7E, 0x10, 0x08, 0x58, 0x40, 0x54, 0x4A, 0x82, 0x7C, 0x82, 0x48,
  80.     0x1C, 0x10, 0x42, 0x2C, 0x54, 0x18, 0x10, 0x30, 0x42, 0x08, 0x0C, 0x1C, 0x64, 0x46, 0x18,
  81.     0x3C, 0x42, 0x40, 0x42, 0x7E, 0x10, 0x78, 0x42, 0x10, 0x04, 0x70, 0x10, 0x49, 0x42, 0x42,
  82.     0x42, 0x42, 0x20, 0x7C, 0x10, 0x42, 0x28, 0x5E, 0x18, 0x3C, 0x10, 0x46, 0x42, 0x80, 0x42,
  83.     0x48, 0x48, 0x8E, 0x42, 0x10, 0x08, 0x48, 0x40, 0x54, 0x4E, 0x82, 0x40, 0xB2, 0x44, 0x42,
  84.     0x10, 0x42, 0x38, 0x28, 0x24, 0x10, 0x62, 0x42, 0x08, 0x30, 0x42, 0x7F, 0x42, 0x42, 0x10,
  85.     0x6C, 0x66, 0x62, 0x46, 0x42, 0x10, 0x7C, 0x42, 0x10, 0x04, 0x4C, 0x10, 0x49, 0x42, 0x42,
  86.     0x42, 0x42, 0x20, 0x3E, 0x10, 0x46, 0x38, 0x74, 0x3C, 0x18, 0x32, 0x42, 0x46, 0x46, 0x46,
  87.     0x42, 0x40, 0x44, 0x42, 0x10, 0x08, 0x44, 0x42, 0x54, 0x46, 0xC6, 0x40, 0xFE, 0x46, 0x42,
  88.     0x10, 0x42, 0x18, 0x28, 0x66, 0x10, 0x42, 0x66, 0x08, 0x62, 0x42, 0x04, 0x46, 0x62, 0x10,
  89.     0x7E, 0x7C, 0x3E, 0x7F, 0x7E, 0x7C, 0x7E, 0xE7, 0x7C, 0x04, 0xEE, 0x7C, 0xED, 0xE7, 0x7E,
  90.     0x7C, 0x3E, 0xF8, 0x7E, 0x1E, 0x7F, 0x10, 0x24, 0x6E, 0x18, 0x7E, 0xE7, 0xFC, 0x7C, 0xFC,
  91.     0xFE, 0xE0, 0x7C, 0xE7, 0x7C, 0x08, 0xEE, 0xFE, 0xD6, 0xE6, 0x7C, 0xE0, 0x7C, 0xE3, 0x7E,
  92.     0x38, 0x7E, 0x10, 0x28, 0xE7, 0x38, 0xFE, 0x3C, 0x3E, 0x7E, 0x7E, 0x1F, 0x7C, 0x3E, 0x10,
  93.     0x36, 0x58, 0x1C, 0x3B, 0x3C, 0x7C, 0x42, 0xE7, 0x7C, 0x44, 0xEE, 0x7C, 0xED, 0xE7, 0x3C,
  94.     0x58, 0x1A, 0xF8, 0x7C, 0x0C, 0x3B, 0x10, 0x24, 0x6E, 0x10, 0x7E, 0xE7, 0xF8, 0x38, 0xF8,
  95.     0xFC, 0xE0, 0x38, 0xE7, 0x7C, 0x88, 0xEE, 0xFE, 0xD6, 0xE2, 0x38, 0xE0, 0x3E, 0xE3, 0x7C,
  96.     0x38, 0x3C, 0x10, 0x28, 0xE7, 0x38, 0xFC, 0x18, 0x3E, 0x7E, 0x3C, 0x1F, 0x38, 0x1C, 0x10,
  97.     0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,
  98.     0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,
  99.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00
  100. };

  101. int scrollOffset = 0;


  102. // 安全版XY映射
  103. uint16_t XY(uint8_t x, uint8_t y) {
  104.   x = constrain(x, 0, MATRIX_WIDTH-1);
  105.   y = constrain(y, 0, MATRIX_HEIGHT-1);
  106.   
  107.   uint16_t index;
  108.   if(y < NUM_LOWER_ROWS) {
  109.     if(y % 2 == 0) {
  110.       index = y * MATRIX_WIDTH + x;
  111.     } else {
  112.       index = (y + 1) * MATRIX_WIDTH - 1 - x;
  113.     }
  114.   } else {
  115.     if(y % 2 == 0) {
  116.       index = (y-NUM_LOWER_ROWS) * MATRIX_WIDTH + x + NUM_LEDS_LOWER;
  117.     } else {
  118.       index = (y-NUM_LOWER_ROWS + 1) * MATRIX_WIDTH - 1 - x + NUM_LEDS_LOWER;
  119.     }
  120.   }

  121.   return constrain(index, 0, NUM_LEDS-1);
  122. }

  123. void setup() {
  124.   FastLED.addLeds<WS2815, DATA_PIN_LOWER, GRB>(leds, NUM_LEDS_LOWER);
  125.   FastLED.addLeds<WS2815, DATA_PIN_UPPER, GRB>(leds+NUM_LEDS_LOWER, NUM_LEDS_UPPER);
  126.   FastLED.setBrightness(50);
  127. }

  128. void loop() {
  129.   static unsigned long lastUpdate = 0;
  130.   if (millis() - lastUpdate > 60) {
  131.     lastUpdate = millis();
  132.    
  133.     fill_solid(leds, NUM_LEDS, BACKGROUND_COLOR);

  134.     for (int x = 0; x < MATRIX_WIDTH; x++) {
  135.       int bitmapX = (scrollOffset + x) % BITMAP_WIDTH;
  136.       for (int y = 0; y < HAN_BITMAP_HEIGHT; y++) {
  137.         if ((textBitmap[BITMAP_INDEX(bitmapX,y)] << BITMMAP_POSITION(bitmapX)) &0x80) {
  138.           int ledIndex = XY(x, y);
  139.           if (ledIndex != -1) leds[ledIndex + MATRIX_WIDTH*HAN_START_ROW] = TEXT_COLOR;
  140.         }
  141.       }
  142.     }

  143.     FastLED.show();
  144.     scrollOffset = (scrollOffset + 1) % BITMAP_WIDTH;
  145.   }
  146. }
 楼主| keer_zu 发表于 2025-5-27 08:27 | 显示全部楼层
更多显示效果:

  1. #include <stdint.h>
  2. //#include <math.h>
  3. #include "led_functions.h"

  4. #define ROTATION_SPEED 0.5  // 旋转速度(弧度/秒)


  5. // 定义主色和辅助色的HSV范围(H:0-255对应0-360度)
  6. const uint8_t MAIN_HUE = 0;     // 主色Hue(例如红色)
  7. const uint8_t ACCENT_HUE = 32;  // 辅助色Hue(例如橙色)
  8. const uint8_t HUE_RANGE = 16;   // 主辅色之间的过渡范围

  9. // 动态参数
  10. uint8_t baseBrightness = 128;   // 基础亮度
  11. uint8_t brightnessJitter = 50;  // 亮度波动范围
  12. uint8_t saturation = 200;       // 饱和度(0-255)
  13. uint8_t spreadRatio = 50;       // 主色占比(%)

  14. //===================== wave ====================================
  15. #define MAX_WAVES      6  // 增加最大波环数量


  16. struct Wave {
  17.   float radius;
  18.   float intensity;
  19.   bool active;
  20.   uint8_t generation;
  21.   bool hasTriggered;
  22.   float speedVariation;   // 速度随机因子
  23.   float widthVariation;   // 宽度随机因子
  24.   float angleOffset;      // 角度偏移(用于形状随机)
  25. };
  26. Wave waves[MAX_WAVES];

  27. // 调整后的参数
  28. const float BASE_WAVE_SPEED = 0.45;  // 基础速度
  29. const float BASE_WAVE_WIDTH = 2.4f;   // 基础宽度(减小)
  30. const float DECAY_RATE = 0.955f;
  31. const float TRIGGER_DISTANCE = 1.8f;  // 缩短触发距离增加密度

  32. float distanceMap[MATRIX_WIDTH][MATRIX_HEIGHT];
  33. float maxRadius;
  34. uint8_t center_x, center_y;

  35. void spawnWave(uint8_t gen);
  36. //===============================================================

  37. // 颜色定义
  38. const CRGB coreColor1 = CRGB(0x66, 0x99, 0xFF);  // #6699FF
  39. const CRGB coreColor2 = CRGB(0xAE, 0xEE, 0xEE);  // #AEEEEE
  40. const CRGB bgColor = CRGB(0x00, 0x33, 0x66);     // #003366
  41. CRGB mainColor = CRGB(0x00, 0x88, 0xFF);         // 主过渡色

  42. float distanceFromCenter(uint8_t x, uint8_t y);
  43. // 随机种子初始化
  44. unsigned long seed = 0;
  45. uint8_t randomness = 0;   // 随机种子

  46. void random_init()
  47. {
  48.   //randomSeed(analogRead(0)); // 使用模拟输入初始化随机种子
  49.   //seed = random(10000); // 创建基础随机种子
  50.   //randomness = random(64);   // 创建基础随机层
  51.   //random16_set_seed(esp_random()); // 使用ESP32硬件随机数
  52.   
  53.   //==================== wave ======================
  54.    center_x = (MATRIX_WIDTH-1)/2;
  55.   center_y = (MATRIX_HEIGHT-1)/2;
  56.   
  57.   // 预计算基础距离
  58.   for(uint8_t y=0; y<MATRIX_HEIGHT; y++){
  59.     for(uint8_t x=0; x<MATRIX_WIDTH; x++){
  60.       float dx = x - center_x;
  61.       float dy = y - center_y;
  62.       distanceMap[x][y] = sqrt(dx*dx + dy*dy);
  63.     }
  64.   }
  65.   maxRadius = distanceMap[0][0];

  66.   // 初始化第一个波环
  67.   waves[0] = {
  68.     0.0f,
  69.     1.0f,
  70.     true,
  71.     0,
  72.     false,
  73.     random8(95, 105)/100.0f,  // 初始速度随机
  74.     random8(95, 105)/100.0f,  // 初始宽度随机
  75.     random8(0, 628)/100.0f     // 初始角度偏移(0-2π)
  76.   };
  77.   for(uint8_t i=1; i<MAX_WAVES; i++) waves[i].active = false;

  78.   //================================================
  79. }

  80. //example
  81. #if 1
  82. void show_rainbow()
  83. {
  84.   static uint8_t hue = 0;
  85.   for (int x = 0; x < MATRIX_WIDTH; x++) {
  86.     for (int y = 0; y < MATRIX_HEIGHT; y++) {
  87.       // 根据坐标生成色相和明度波浪
  88.       uint8_t ledHue = hue + x * 10 + y * 5;
  89.        uint8_t targetHue = map(ledHue, -32768, 32767, 96, 225);
  90.       uint8_t brightness = sin8(x * 20 + y * 20 + hue);
  91.       leds[XY(x, y)] = CHSV(targetHue, 255, brightness);
  92.     }
  93.   }
  94.   FastLED.show();
  95.   hue += 2;
  96.   delay(20);
  97. }
  98. #else
  99. void show_rainbow() {
  100.   static uint8_t wavePhase = 0;  // 波形相位控制

  101.   for (int x = 0; x < MATRIX_WIDTH; x++) {
  102.     for (int y = 0; y < MATRIX_HEIGHT; y++) {
  103.       // 生成动态波形色相(核心逻辑)
  104.       uint8_t waveHue = sin8(wavePhase + x * 15 + y * 8);  // 空间波形叠加
  105.       uint8_t targetHue = map(waveHue, 0, 255, 150, 255);  // 映射到目标范围

  106.       // 亮度波浪(与色相不同步增强立体感)
  107.       uint8_t brightness = sin8(x * 30 + y * 20 + wavePhase * 2);

  108.       leds[XY(x, y)] = CHSV(targetHue, 255, brightness);
  109.     }
  110.   }

  111.   FastLED.show();
  112.   wavePhase += 1;  // 控制波形运动速度
  113.   delay(20);
  114. }

  115. void show_rainbow() {
  116.   static uint16_t timeBase = 0;
  117.   static uint8_t xNoise[MATRIX_WIDTH];
  118.   static uint8_t yNoise[MATRIX_HEIGHT];
  119.   
  120.   // 亮度平滑滤波器
  121.   static uint8_t lastBrightness[MATRIX_WIDTH][MATRIX_HEIGHT] = {{0}};

  122.   // 噪声混合参数(20%更新强度)
  123.   #define NOISE_BLEND_AMOUNT 51  // 近似20% (51/255 ≈ 0.2)

  124.   EVERY_N_MILLISECONDS(50) {
  125.     for (int x = 0; x < MATRIX_WIDTH; x++) {
  126.       xNoise[x] = xNoise[x] + (random8() - xNoise[x]) * NOISE_BLEND_AMOUNT / 255;
  127.     }
  128.     for (int y = 0; y < MATRIX_HEIGHT; y++) {
  129.       yNoise[y] = yNoise[y] + (random8() - yNoise[y]) * NOISE_BLEND_AMOUNT / 255;
  130.     }
  131.   }

  132.   for (int x = 0; x < MATRIX_WIDTH; x++) {
  133.     for (int y = 0; y < MATRIX_HEIGHT; y++) {
  134.       // 获取当前噪声值
  135.       uint8_t currentXNoise = xNoise[x];
  136.       uint8_t currentYNoise = yNoise[y];

  137.       // 动态色相生成(保持120-255范围)
  138.       uint8_t baseHue = map(sin8(timeBase/3 + x*8), 0, 255, 120, 200);
  139.       uint8_t finalHue = (baseHue +
  140.                          map(currentXNoise, 0, 255, -15, 15) +
  141.                          map(currentYNoise, 0, 255, -10, 10)) % 136 + 120;

  142.       // 亮度处理(核心修改部分)
  143.       uint8_t rawBrightness = inoise8(x*30, y*30, timeBase);  // 降低噪声频率
  144.       
  145.       // 映射到40-200范围并添加平滑滤波
  146.       uint8_t targetBrightness = map(rawBrightness, 0, 255, 40, 200);
  147.       uint8_t brightness = (targetBrightness * 3 + lastBrightness[x][y] * 7) / 10; // 70%历史值权重
  148.       lastBrightness[x][y] = brightness;

  149.       leds[XY(x, y)] = CHSV(finalHue, 240, brightness);
  150.     }
  151.   }

  152.   FastLED.show();
  153.   timeBase += 2;  // 降低整体变化速度
  154.   delay(20);
  155. }
  156. #endif

  157. void random_vision()
  158. {
  159.   // 随机生成动态参数
  160.   uint8_t currentHue = random(MAIN_HUE - HUE_RANGE, MAIN_HUE + HUE_RANGE);
  161.   uint8_t currentBrightness = baseBrightness + random(-brightnessJitter, brightnessJitter);
  162.   uint8_t currentSpread = random(0, 100); // 用于范围控制

  163.   // 更新所有LED颜色
  164.   for (int i = 0; i < NUM_LEDS; i++) {
  165.     // 根据spreadRatio决定使用主色还是辅助色
  166.     uint8_t hue = (currentSpread < spreadRatio) ?
  167.                   random(currentHue - 5, currentHue + 5) :  // 主色微抖动
  168.                   random(ACCENT_HUE - 5, ACCENT_HUE + 5);    // 辅助色微抖动

  169.     // 生成最终颜色
  170.     leds[i] = CHSV(
  171.       hue,
  172.       saturation,
  173.       constrain(currentBrightness + random(-20, 20), 0, 255) // 亮度叠加噪声
  174.     );
  175.   }

  176.   FastLED.show();
  177.   delay(50 + random(0, 100)); // 随机刷新间隔
  178. }

  179. void smooth_vision()
  180. {
  181.     uint8_t currentBrightness = baseBrightness + random(-brightnessJitter, brightnessJitter);
  182.     static CRGBPalette16 currentPalette;
  183.   if (random(0, 100) > 90) { // 10%概率切换色板
  184.     currentPalette = CRGBPalette16(
  185.       CHSV(random(MAIN_HUE - HUE_RANGE, MAIN_HUE + HUE_RANGE), 255, 255),
  186.       CHSV(random(ACCENT_HUE - HUE_RANGE, ACCENT_HUE + HUE_RANGE), 255, 255)
  187.     );
  188.   }
  189.   
  190.   // 使用色板插值
  191.   for (int i = 0; i < NUM_LEDS; i++) {
  192.     leds[i] = ColorFromPalette(
  193.       currentPalette,
  194.       random8(), // 随机位置采样色板
  195.       currentBrightness,
  196.       LINEARBLEND
  197.     );
  198.   }
  199.   FastLED.show();
  200.   delay(30);
  201. }

  202. #if 1
  203. void optim_vision()
  204. {
  205.   static uint8_t breathPhase = 0;
  206.   static uint8_t rotationPhase = 0;
  207.   static uint8_t globalRandom = 0;
  208.   
  209.   breathPhase += 1;
  210.   rotationPhase += 2;
  211.   globalRandom = (globalRandom + 1) % 256; // 缓慢变化的随机种子
  212.   
  213.   for (int y = 0; y < MATRIX_HEIGHT; y++) {
  214.     for (int x = 0; x < MATRIX_WIDTH; x++) {
  215.       int index = getLEDIndex(x, y);
  216.       CRGB& pixel = leds[index];
  217.       
  218.       // 中心点计算(蛇形坐标)
  219.       int centerX = MATRIX_WIDTH / 2;
  220.       int centerY = MATRIX_HEIGHT / 2;
  221.       float dx = abs(x - centerX);
  222.       float dy = abs(y - centerY);
  223.       float distance = sqrt(dx*dx + dy*dy);
  224.       
  225.       // 带随机性的呼吸效果
  226.       float breathVal = (sin(breathPhase * 0.1 + (random(3)-1)*0.5) + 1) * 64;
  227.       breathVal += (random(5) - 2) * 0.5; // 微小随机波动
  228.       
  229.       uint8_t baseHue = 240; // 主色调深蓝
  230.       uint8_t hueVariance = 10; // 色调随机范围
  231.       
  232.       // 主色调背景(带柔和渐变)
  233.       if (distance > 10) {
  234.         pixel = CHSV(baseHue + random(-hueVariance, hueVariance),
  235.                     80 + random(10),
  236.                     breathVal / 2);
  237.       } else {
  238.         // 紫色光晕(等级1限制,柔和混合)
  239.         float ratio = constrain(distance / 10, 0, 1);
  240.         uint8_t h1 = baseHue;
  241.         uint8_t s1 = 100;
  242.         uint8_t v1 = breathVal;
  243.         
  244.         uint8_t h2 = 255;
  245.         uint8_t s2 = 20 + random(5);
  246.         uint8_t v2 = breathVal * 2 + random(3);
  247.         
  248.         CRGB color1 = CHSV(h1, s1, v1);
  249.         CRGB color2 = CHSV(h2, s2, v2);
  250.         
  251.         // 使用立方贝塞尔曲线实现平滑过渡
  252.         float t = pow(ratio, 0.5);
  253.         CRGB blended = blend(color1, color2, t*t*(3-2*t));
  254.         
  255.         // 添加随机噪声纹理
  256.         float noiseVal = (inoise8(x * 3 + seed, y * 3 + seed + rotationPhase) - 128) / 256.0;
  257.         blended.g += noiseVal * 15;
  258.         blended.b += noiseVal * 10;
  259.         
  260.         pixel = blended;
  261.         
  262.         // 动态波纹(带随机相位)
  263.         float time = (millis() / 1000.0) + rotationPhase * 0.05 + (random(5)-2)*0.1;
  264.         float wave = sin((distance + time) * 0.5 + (random(10)-5)*0.05) * 2;
  265.         pixel.blue += wave;
  266.         pixel.green += wave / 2;
  267.         
  268.         // 结构纹理(模拟波纹)
  269.         float detail = sin((x + y + time) * 3 + (random(3)-1)*0.2) * 5;
  270.         pixel.red += detail;
  271.       }
  272.     }
  273.   }
  274.   
  275.   FastLED.show();
  276.   delay(random(20, 40)); // 随机延时增加自然感
  277. }
  278. #endif

  279. void random_rainbow()
  280. {
  281.     static uint8_t hue = 180; // 初始色相设定在青色区间
  282.   static uint8_t randomness = 0; // 随机种子控制变量
  283.   
  284.   // 动态调整随机种子
  285.   randomness = (randomness + 1) % 64;
  286.   
  287.   for (int x = 0; x < MATRIX_WIDTH; x++) {
  288.     for (int y = 0; y < MATRIX_HEIGHT; y++) {
  289.       // 计算基础色相
  290.       uint8_t baseHue = hue + x * 10 + y * 5;
  291.       
  292.       // 添加可控随机偏移(±3范围内)
  293.       uint8_t hueOffset = random(61) - 30; // 生成-30到+29的随机数
  294.       uint8_t ledHue = baseHue + hueOffset;
  295.       
  296.       // 强制限制在青蓝紫区间(180-300度)
  297.       ledHue = ledHue % 360;
  298.       if (ledHue < 180) ledHue += 180;
  299.       else if (ledHue > 300) ledHue -= 120;
  300.       
  301.       // 生成动态亮度(带波浪噪声)
  302.       uint8_t brightness = sin8(x * 20 + y * 20 + hue + randomness);
  303.       brightness = qadd8(brightness, random(32)); // 最多叠加31的随机亮度
  304.       
  305.       // 创建柔和过渡的色彩
  306.       CRGB color = CHSV(ledHue, 255, brightness);
  307.       color.fadeToBlackBy(255 - (random(64) + 192)); // 随机透明度
  308.       
  309.       leds[XY(x, y)] = color;
  310.     }
  311.   }
  312.   
  313.   FastLED.show();
  314.   
  315.   // 随机呼吸式延迟
  316.   uint8_t delayTime = random(15, 45);
  317.   delay(delayTime);
  318.   
  319.   // 更新主色相(缓慢变化)
  320.   hue += 1;
  321.   if (hue >= 360) hue -= 360;
  322. }
  323. // 中心点坐标(蛇形布局需调整)
  324. int centerX = MATRIX_WIDTH / 2;
  325. int centerY = MATRIX_HEIGHT / 2;

  326. // 动态参数
  327. uint8_t hueBase = 180;    // 初始色相(青色)
  328. uint8_t flowSpeed = 1;    // 流动速度(1-5)

  329. void centor_rainbow()
  330. {
  331.   static uint8_t time = 0;
  332.   
  333.   // 时间推进与随机扰动
  334.   time++;
  335.   randomness = (randomness + 1) % 64;
  336.   
  337.   for (int y = 0; y < MATRIX_HEIGHT; y++) {
  338.     for (int x = 0; x < MATRIX_WIDTH; x++) {
  339.       int index = y * MATRIX_WIDTH + x;
  340.       CRGB& pixel = leds[index];
  341.       
  342.       // 蛇形布局修正(如需平面布局可注释)
  343.       if (y % 2 != 0) x = MATRIX_WIDTH - 1 - x;
  344.       
  345.       // 计算到中心点的距离
  346.       float dx = x - centerX;
  347.       float dy = y - centerY;
  348.       float distance = sqrt(dx*dx + dy*dy);
  349.       
  350.       // 生成基础半径和随机涨落
  351.       float baseRadius = (time * flowSpeed) / 2.0;
  352.       float radiusFluctuation = (random(21) - 10) * 0.5; // ±5范围随机
  353.       float currentRadius = baseRadius + radiusFluctuation;
  354.       
  355.       // 判断是否在扩散范围内
  356.       if (distance <= currentRadius) {
  357.         // 计算色相(强制青蓝紫范围)
  358.         float hueRange = 120; // 180-300度
  359.         float hueOffset = (distance / currentRadius) * hueRange;
  360.         uint8_t hue = hueBase + hueOffset;
  361.         hue = constrain(hue, 180, 300);
  362.         
  363.         // 添加噪声纹理
  364.         uint8_t noiseVal = inoise8(x * 4 + randomness, y * 4 + time + randomness);
  365.         hue += (noiseVal - 128) / 64; // ±0.5色相偏移
  366.         
  367.         // 生成颜色(柔和渐变)
  368.         uint8_t saturation = 255;
  369.         uint8_t value = 255 - (distance / currentRadius * 255);
  370.         
  371.         CRGB color = CHSV(hue, saturation, value);
  372.         pixel = color;
  373.       } else {
  374.         pixel = CRGB::Black;
  375.       }
  376.     }
  377.   }
  378.   
  379.   FastLED.show();
  380.   
  381.   // 动态延迟控制
  382.   uint8_t delayTime = random(10, 30) + (randomness % 5);
  383.   delay(delayTime);
  384. }


  385. const CRGB palette[] = {
  386.   CRGB(0x2A, 0x5B, 0x8C), // 深蓝
  387.   CRGB(0x3E, 0xB7, 0xA0), // 青绿
  388.   CRGB(0x80, 0x00, 0x80), // 紫
  389.   CRGB(0xFF, 0xC0, 0xCB)  // 粉
  390. };

  391. void renderGradient(int style) {
  392.   switch (style) {
  393.     case 0: // 对角线线性渐变(第1张图)
  394.       for (int y = 0; y < MATRIX_HEIGHT; y++) {
  395.         for (int x = 0; x < MATRIX_WIDTH; x++) {
  396.           float ratio = (x + y) / (float)(MATRIX_WIDTH + MATRIX_HEIGHT - 2);
  397.           leds[y * MATRIX_WIDTH + x] = blend(palette[0], palette[2], ratio * 255);
  398.         }
  399.       }
  400.       break;
  401.     case 1: // 流体渐变(第5张图)
  402.       static uint16_t z;
  403.       for (int i = 0; i < NUM_LEDS; i++) {
  404.         uint8_t noise = inoise8(i % MATRIX_WIDTH * 30, i / MATRIX_WIDTH * 30, z);
  405.         leds[i] = ColorFromPalette(CRGBPalette16(palette), noise);
  406.       }
  407.       z += 10;
  408.       break;
  409.   }
  410.   FastLED.show();
  411. }

  412. void test_vision()
  413. {
  414.    for (int i = 0; i < 4; i++) { // 循环切换4种渐变
  415.     renderGradient(i % 2);
  416.     delay(20);
  417.   }
  418. }

  419. #if 1
  420. // 马尔科夫链状态结构体(修正字段类型)
  421. struct MarkovState {
  422.   uint8_t baseHue;     // 改为8位存储
  423.   uint8_t speed;       // 速度范围1-5
  424.   int8_t direction;    // 风向
  425.   uint8_t intensity;   // 强度范围
  426. };

  427. // 初始化状态(调整参数)
  428. MarkovState currentState = {200, 3, 1, 150}; // 提高初始baseHue

  429. // 简化转移概率矩阵
  430. const uint8_t transitionProb[4][4] = {
  431.   {80, 10, 5, 5},   
  432.   {15, 70, 10, 5},  
  433.   {10, 5, 80, 5},  
  434.   {5, 5, 5, 85}   
  435. };

  436. // 噪声参数
  437. uint16_t z = 0;
  438. const uint8_t scale = 30;
  439. const uint8_t blurAmount = 64;


  440. // 马尔科夫状态转移实现
  441. void applyMarkovTransition() {
  442.   uint8_t randVal = random8();
  443.   uint8_t probSum = 0;
  444.   
  445.   // 选择要改变的状态维度
  446.   uint8_t targetDim = 0;
  447.   for(; targetDim<4; targetDim++) {
  448.     probSum += transitionProb[targetDim][targetDim];
  449.     if(randVal < probSum) break;
  450.   }
  451.   
  452.   // 执行状态转移(有限差分法)
  453.   switch(targetDim) {
  454.     case 0: // 基础色调变化
  455.       currentState.baseHue += random8(3) - 1; // ±1微调
  456.       currentState.baseHue = constrain(currentState.baseHue, 180, 255);
  457.       break;
  458.       
  459.     case 1: // 速度变化
  460.       currentState.speed = constrain(
  461.         currentState.speed + random8(3) - 1, 1, 5);
  462.       break;
  463.       
  464.     case 2: // 方向变化
  465.       if(random8() < 30) currentState.direction *= -1;
  466.       break;
  467.       
  468.     case 3: // 强度变化
  469.       currentState.intensity = constrain(
  470.         currentState.intensity + random8(21) - 10, 100, 200);
  471.       break;
  472.   }
  473. }

  474. // 基于状态的图案生成
  475. void generateWindPattern() {
  476.   for(uint8_t y=0; y<MATRIX_HEIGHT; y++) {
  477.     for(uint8_t x=0; x<MATRIX_WIDTH; x++) {
  478.       uint8_t noise = inoise8(
  479.         (x * scale) / 2 + (currentState.direction * z),
  480.         y * scale + z/2,
  481.         currentState.intensity * 10
  482.       );
  483.       
  484.       // 修正色调计算(添加循环处理)
  485.       uint8_t hue = currentState.baseHue + map(noise, 0,255, -20,20);
  486.       hue = (hue < 180) ? hue + 75 : hue; // 确保在180-255范围
  487.       
  488.       // 修正亮度计算(移除错误处理)
  489.       uint8_t val = map(noise, 50, 205, 30, 230);
  490.       val = constrain(val, 30, 230); // 硬约束
  491.       
  492.       leds[XY(x,y)] = CHSV(hue, 230, val);
  493.     }
  494.   }
  495.   
  496.   blur2d(leds, MATRIX_WIDTH, MATRIX_HEIGHT, blurAmount);
  497.   z += 2;//currentState.speed;   //速度均匀
  498. }



  499. void wind_vision() {
  500.   static uint32_t lastUpdate = 0;
  501.   static uint8_t hueShift = 0;

  502.   if(millis() - lastUpdate > 50) { // 降低更新频率
  503.     lastUpdate = millis();
  504.    
  505.     // 马尔科夫状态转移
  506.     applyMarkovTransition();
  507.    
  508.     // 生成动态风场
  509.     generateWindPattern();
  510.    
  511.     FastLED.show();
  512.     delay(10);
  513.   }
  514. }
  515. #else



  516. // 马尔科夫链增强平滑版本
  517. struct MarkovState {
  518.   uint8_t baseHue;     // 当前色相
  519.   uint8_t targetHue;   // 目标色相(新增)
  520.   uint8_t speed;
  521.   uint8_t targetSpeed; // 新增目标速度
  522.   int8_t direction;
  523.   float directionF;    // 新增浮点方向(用于平滑过渡)
  524.   uint8_t intensity;
  525. };

  526. MarkovState currentState = {200, 200, 3, 3, 1, 1.0f, 150};
  527. const uint8_t transitionProb[4][4] = {
  528.   {90, 5, 3, 2},     // 提高保持色相的概率
  529.   {10, 85, 3, 2},    // 降低速度变化频率
  530.   {5, 5, 88, 2},     // 增强方向稳定性
  531.   {3, 2, 2, 93}      // 提高强度保持率
  532. };

  533. uint32_t z = 0;       // 改为32位防溢出
  534. const float DIRECTION_TRANSITION = 0.1f; // 方向过渡系数

  535. void applyMarkovTransition() {
  536.   static uint32_t lastChange = 0;
  537.   const uint32_t CHANGE_INTERVAL = 3000; // 延长状态变化间隔
  538.   
  539.   if(millis() - lastChange < CHANGE_INTERVAL) return;
  540.   lastChange = millis();

  541.   uint8_t randVal = random8();
  542.   uint8_t probSum = 0;
  543.   uint8_t targetDim = 0;
  544.   
  545.   // 概率累计方式优化
  546.   while(targetDim < 4 && randVal > (probSum += transitionProb[targetDim][targetDim])) {
  547.     targetDim++;
  548.   }

  549.   // 有限渐变状态转移
  550.   switch(targetDim) {
  551.     case 0: // 色相渐变
  552.       currentState.targetHue = constrain(currentState.baseHue + random8(-8, 9), 180, 255);
  553.       break;
  554.       
  555.     case 1: // 速度渐变
  556.       currentState.targetSpeed = constrain(currentState.speed + random8(-1, 2), 1, 5);
  557.       break;
  558.       
  559.     case 2: // 方向平滑过渡
  560.       currentState.directionF = -currentState.directionF; // 缓慢反转
  561.       break;
  562.       
  563.     case 3: // 强度渐变
  564.       currentState.intensity = constrain(currentState.intensity + random8(-8, 9), 100, 200);
  565.       break;
  566.   }
  567. }

  568. void smoothUpdateStates() {
  569.   // 色相线性插值
  570.   currentState.baseHue = lerp8by8(currentState.baseHue, currentState.targetHue, 10);
  571.   
  572.   // 速度指数平滑
  573.   currentState.speed = (currentState.speed * 7 + currentState.targetSpeed * 1) / 8;
  574.   
  575.   // 方向浮点过渡
  576.   currentState.directionF += (currentState.direction - currentState.directionF) * DIRECTION_TRANSITION;
  577. }

  578. void generateWindPattern() {
  579.   const float dirFactor = currentState.directionF; // 使用浮点方向因子


  580.   for(uint8_t y=0; y<MATRIX_HEIGHT; y++) {
  581.     for(uint8_t x=0; x<MATRIX_WIDTH; x++) {
  582.       // 改进的噪声参数(增加Z轴细分)
  583.       uint8_t noise = inoise8(
  584.         (x * 25) + (z * dirFactor * 0.7f),
  585.         y * 35 + z * 0.3f,
  586.         currentState.intensity * 8 + (z >> 6)
  587.       );
  588.       
  589.       // 循环色相映射(替代硬约束)
  590.       uint8_t hue = currentState.baseHue + map(noise, 0,255, -15,15);
  591.       hue = 180 + ((hue - 180) % 76); // 180-255循环
  592.       
  593.       // 亮度S曲线处理
  594.       uint8_t val = cubicwave8(noise);
  595.       val = map(val, 30, 225, 50, 220);  // 压缩两端
  596.       
  597.       leds[XY(x,y)] = CHSV(hue, 235, val);
  598.     }
  599.   }
  600.   
  601.    // 使用标准二维模糊 + 逐行模糊替代方案
  602.   blur2d(leds, MATRIX_WIDTH, MATRIX_HEIGHT, 64);
  603.   
  604.   // 手动实现行模糊
  605.   for(uint8_t y=0; y<MATRIX_HEIGHT; y++) {
  606.     CRGB* rowStart = &leds[XY(0, y)];
  607.     blur1d(rowStart, MATRIX_WIDTH, 32);
  608.   }
  609.   
  610.   z += currentState.speed;
  611. }

  612. void wind_vision() {
  613.   static uint32_t lastUpdate = 0;
  614.   
  615.   if(millis() - lastUpdate > 33) { // 30FPS
  616.     lastUpdate = millis();
  617.    
  618.     smoothUpdateStates();  // 先更新状态
  619.     applyMarkovTransition();
  620.     generateWindPattern();
  621.    
  622.     // 添加残影效果
  623.     fadeToBlackBy(leds, NUM_LEDS, 220);
  624.     FastLED.show();
  625.   }
  626. }
  627. #endif



  628. // 动画参数
  629. uint8_t noiseScale = 20;
  630. uint8_t noiseSpeed = 12;
  631. uint16_t zOffset = 0;

  632. #define COLS       30
  633. #define ROWS       15

  634. // 坐标转换函数
  635. void getXY(uint16_t i, uint8_t &x, uint8_t &y) {
  636.   x = i % COLS;
  637.   y = i / COLS;
  638.   if (y % 2) x = (COLS - 1) - x;
  639. }
  640. #define FRAME_RATE 10
  641. void fluidAnimation() {
  642.   for (int i = 0; i < NUM_LEDS; i++) {
  643.     uint8_t x, y;
  644.     getXY(i, x, y);
  645.    
  646.     // 生成三维噪声
  647.     uint16_t noise = inoise16(x * noiseScale * 10,
  648.                              y * noiseScale * 10,
  649.                              zOffset);
  650.    
  651.     // 动态色相映射
  652.     uint8_t hue = (noise >> 8) + millis() / 100; // 叠加整体色相漂移
  653.     hue = 180 + ((hue - 160) % 76); // 160-255循环
  654.     // 亮度波动
  655.     uint8_t val = 100 + (noise % 55);
  656.    
  657.     leds[i] = CHSV(hue, 240, val);
  658.   }
  659.   zOffset += noiseSpeed * 256;
  660. }

  661. void fluor_vision() {
  662.   fluidAnimation();
  663.   FastLED.show();
  664.   FastLED.delay(1000 / FRAME_RATE);
  665. }

  666. //======================  wave ======================

  667. // 带随机扰动的距离计算
  668. float perturbedDistance(uint8_t x, uint8_t y, Wave &w) {
  669.   float dx = x - center_x;
  670.   float dy = y - center_y;
  671.   
  672.   // 添加基于角度的随机扰动
  673.   float angle = atan2(dy, dx) + w.angleOffset;
  674.   float perturbation = 0.4f * sin(angle * 3 + w.radius * 0.5f);
  675.   
  676.   return sqrt(dx*dx + dy*dy) * (1.0f + perturbation * 0.08f);
  677. }

  678. void spawnWave(uint8_t gen) {
  679.   for(uint8_t i=0; i<MAX_WAVES; i++){
  680.     if(!waves[i].active){
  681.       waves[i] = {
  682.         0.0f,
  683.         1.0f - gen*0.12f,
  684.         true,
  685.         gen,
  686.         false,
  687.         random8(95, 105)/100.0f,  // 速度随机因子
  688.         random8(90, 110)/100.0f,  // 宽度随机因子
  689.         random8(0, 628)/100.0f    // 新随机角度
  690.       };
  691.       return;
  692.     }
  693.   }
  694. }

  695. void wave_vision() {
  696.   static uint32_t lastFrame = millis();
  697.   float deltaTime = (millis() - lastFrame)/1000.0f;
  698.   lastFrame = millis();

  699.   fadeToBlackBy(leds, NUM_LEDS, 25);  // 加快淡出速度增加密度感

  700.   for(uint8_t i=0; i<MAX_WAVES; i++){
  701.     if(waves[i].active){
  702.       Wave &w = waves[i];
  703.       
  704.       // 应用随机速度
  705.       w.radius += BASE_WAVE_SPEED * w.speedVariation * (1.0f + deltaTime);
  706.       w.intensity *= DECAY_RATE;

  707.       // 触发新波环
  708.       if(w.generation == 0 && !w.hasTriggered && w.radius >= TRIGGER_DISTANCE){
  709.         spawnWave(1);
  710.         w.hasTriggered = true;
  711.       }

  712.       // 波环生命周期管理
  713.       if(w.radius > maxRadius || w.intensity < 0.12f){
  714.         if(w.generation == 0){
  715.           // 重置核心波环并重新随机参数
  716.           w.radius = 0.0f;
  717.           w.intensity = 1.0f;
  718.           w.hasTriggered = false;
  719.           w.speedVariation = random8(95, 105)/100.0f;
  720.           w.widthVariation = random8(90, 110)/100.0f;
  721.           w.angleOffset = random8(0, 628)/100.0f;
  722.         }else{
  723.           w.active = false;
  724.         }
  725.       }

  726.       // 绘制波环
  727.       for(uint8_t y=0; y<MATRIX_HEIGHT; y++){
  728.         for(uint8_t x=0; x<MATRIX_WIDTH; x++){
  729.           // 使用扰动后的距离计算
  730.           float dist = perturbedDistance(x, y, w);
  731.           float delta = abs(dist - w.radius);
  732.          
  733.           // 应用随机宽度
  734.           float effectiveWidth = BASE_WAVE_WIDTH * w.widthVariation;
  735.           float effect = exp(-pow(delta/effectiveWidth, 2.2f)) * w.intensity;
  736.          
  737.           // 中心抑制
  738.           if(x >= center_x-1 && x <= center_x && y >= center_y-1 && y <= center_y){
  739.             effect *= 0.15f;
  740.           }
  741.          
  742.           // 颜色混合(添加轻微随机色相偏移)
  743.           uint8_t hue = 160 + w.generation*18 + w.radius*0.8f;
  744.           leds[XY(x,y)] += CHSV(hue, 210, effect * 220);
  745.         }
  746.       }
  747.     }
  748.   }

  749.   // 强化中心暗区
  750.   for(uint8_t dx=0; dx<2; dx++){
  751.     for(uint8_t dy=0; dy<2; dy++){
  752.       uint16_t idx = XY(center_x-dx, center_y-dy);
  753.       leds[idx].nscale8(40);  // 更暗的中心
  754.     }
  755.   }


  756.   //LedDelay(200);
  757.   FastLED.delay(28);  // 稍快的刷新率
  758. }
 楼主| keer_zu 发表于 2025-5-27 10:13 | 显示全部楼层
尝试速度可控,还存在问题:

  1. #include <stdint.h>
  2. //#include <math.h>
  3. #include "led_functions.h"

  4. #define ROTATION_SPEED 0.5  // 旋转速度(弧度/秒)


  5. // 定义主色和辅助色的HSV范围(H:0-255对应0-360度)
  6. const uint8_t MAIN_HUE = 0;     // 主色Hue(例如红色)
  7. const uint8_t ACCENT_HUE = 32;  // 辅助色Hue(例如橙色)
  8. const uint8_t HUE_RANGE = 16;   // 主辅色之间的过渡范围

  9. // 动态参数
  10. uint8_t baseBrightness = 128;   // 基础亮度
  11. uint8_t brightnessJitter = 50;  // 亮度波动范围
  12. uint8_t saturation = 200;       // 饱和度(0-255)
  13. uint8_t spreadRatio = 50;       // 主色占比(%)

  14. //===================== wave ====================================
  15. #define MAX_WAVES      24  // 增加最大波环数量
  16. const float NOISE_INTENSITY = 0.6f;   // 空白区域噪声强度

  17. struct Wave {
  18.   float radius;
  19.   float intensity;
  20.   bool active;
  21.   uint8_t generation;
  22.   bool hasTriggered;
  23.   float speedVariation;   // 速度随机因子
  24.   float widthVariation;   // 宽度随机因子
  25.   float angleOffset;      // 角度偏移(用于形状随机)
  26. };
  27. Wave waves[MAX_WAVES];

  28. // 调整后的参数
  29. const float BASE_WAVE_SPEED = 0.45;  // 基础速度
  30. const float BASE_WAVE_WIDTH = 2.4f;   // 基础宽度(减小)
  31. const float DECAY_RATE = 0.955f;
  32. const float TRIGGER_DISTANCE = 0.8f;  // 缩短触发距离增加密度

  33. float distanceMap[MATRIX_WIDTH][MATRIX_HEIGHT];
  34. float maxRadius;
  35. uint8_t center_x, center_y;

  36. void spawnWave(uint8_t gen);
  37. //===============================================================

  38. // 颜色定义
  39. const CRGB coreColor1 = CRGB(0x66, 0x99, 0xFF);  // #6699FF
  40. const CRGB coreColor2 = CRGB(0xAE, 0xEE, 0xEE);  // #AEEEEE
  41. const CRGB bgColor = CRGB(0x00, 0x33, 0x66);     // #003366
  42. CRGB mainColor = CRGB(0x00, 0x88, 0xFF);         // 主过渡色

  43. float distanceFromCenter(uint8_t x, uint8_t y);
  44. // 随机种子初始化
  45. unsigned long seed = 0;
  46. uint8_t randomness = 0;   // 随机种子

  47. //================= globalSpeedFactor ======================
  48. float globalSpeedFactor=1.0f;

  49. void SetGlobalSpeedFactor(float speed)
  50. {
  51.   globalSpeedFactor = constrain(speed, 0.1f, 5.0f);
  52. }
  53. //==========================================================

  54. void random_init()
  55. {
  56.   //randomSeed(analogRead(0)); // 使用模拟输入初始化随机种子
  57.   //seed = random(10000); // 创建基础随机种子
  58.   //randomness = random(64);   // 创建基础随机层
  59.   //random16_set_seed(esp_random()); // 使用ESP32硬件随机数
  60.   
  61.   //==================== wave ======================
  62.    center_x = (MATRIX_WIDTH-1)/2;
  63.   center_y = (MATRIX_HEIGHT-1)/2;
  64.   
  65.   // 预计算基础距离
  66.   for(uint8_t y=0; y<MATRIX_HEIGHT; y++){
  67.     for(uint8_t x=0; x<MATRIX_WIDTH; x++){
  68.       float dx = x - center_x;
  69.       float dy = y - center_y;
  70.       distanceMap[x][y] = sqrt(dx*dx + dy*dy);
  71.     }
  72.   }
  73.   maxRadius = distanceMap[0][0];

  74.   // 初始化第一个波环
  75.   waves[0] = {
  76.     0.0f,
  77.     1.0f,
  78.     true,
  79.     0,
  80.     false,
  81.     random8(95, 105)/100.0f,  // 初始速度随机
  82.     random8(95, 105)/100.0f,  // 初始宽度随机
  83.     random8(0, 628)/100.0f     // 初始角度偏移(0-2π)
  84.   };
  85.   for(uint8_t i=1; i<MAX_WAVES; i++) waves[i].active = false;

  86.   //================================================
  87. }

  88. //example
  89. #if 1
  90. void show_rainbow()
  91. {
  92.   static uint8_t hue = 0;
  93.   for (int x = 0; x < MATRIX_WIDTH; x++) {
  94.     for (int y = 0; y < MATRIX_HEIGHT; y++) {
  95.       // 根据坐标生成色相和明度波浪
  96.       uint8_t ledHue = hue + x * 10 + y * 5;
  97.        uint8_t targetHue = map(ledHue, -32768, 32767, 96, 225);
  98.       uint8_t brightness = sin8(x * 20 + y * 20 + hue);
  99.       leds[XY(x, y)] = CHSV(targetHue, 255, brightness);
  100.     }
  101.   }
  102.   FastLED.show();
  103.   hue += 2;
  104.   delay(20);
  105. }
  106. #else
  107. void show_rainbow() {
  108.   static uint8_t wavePhase = 0;  // 波形相位控制

  109.   for (int x = 0; x < MATRIX_WIDTH; x++) {
  110.     for (int y = 0; y < MATRIX_HEIGHT; y++) {
  111.       // 生成动态波形色相(核心逻辑)
  112.       uint8_t waveHue = sin8(wavePhase + x * 15 + y * 8);  // 空间波形叠加
  113.       uint8_t targetHue = map(waveHue, 0, 255, 150, 255);  // 映射到目标范围

  114.       // 亮度波浪(与色相不同步增强立体感)
  115.       uint8_t brightness = sin8(x * 30 + y * 20 + wavePhase * 2);

  116.       leds[XY(x, y)] = CHSV(targetHue, 255, brightness);
  117.     }
  118.   }

  119.   FastLED.show();
  120.   wavePhase += 1;  // 控制波形运动速度
  121.   delay(20);
  122. }

  123. void show_rainbow() {
  124.   static uint16_t timeBase = 0;
  125.   static uint8_t xNoise[MATRIX_WIDTH];
  126.   static uint8_t yNoise[MATRIX_HEIGHT];
  127.   
  128.   // 亮度平滑滤波器
  129.   static uint8_t lastBrightness[MATRIX_WIDTH][MATRIX_HEIGHT] = {{0}};

  130.   // 噪声混合参数(20%更新强度)
  131.   #define NOISE_BLEND_AMOUNT 51  // 近似20% (51/255 ≈ 0.2)

  132.   EVERY_N_MILLISECONDS(50) {
  133.     for (int x = 0; x < MATRIX_WIDTH; x++) {
  134.       xNoise[x] = xNoise[x] + (random8() - xNoise[x]) * NOISE_BLEND_AMOUNT / 255;
  135.     }
  136.     for (int y = 0; y < MATRIX_HEIGHT; y++) {
  137.       yNoise[y] = yNoise[y] + (random8() - yNoise[y]) * NOISE_BLEND_AMOUNT / 255;
  138.     }
  139.   }

  140.   for (int x = 0; x < MATRIX_WIDTH; x++) {
  141.     for (int y = 0; y < MATRIX_HEIGHT; y++) {
  142.       // 获取当前噪声值
  143.       uint8_t currentXNoise = xNoise[x];
  144.       uint8_t currentYNoise = yNoise[y];

  145.       // 动态色相生成(保持120-255范围)
  146.       uint8_t baseHue = map(sin8(timeBase/3 + x*8), 0, 255, 120, 200);
  147.       uint8_t finalHue = (baseHue +
  148.                          map(currentXNoise, 0, 255, -15, 15) +
  149.                          map(currentYNoise, 0, 255, -10, 10)) % 136 + 120;

  150.       // 亮度处理(核心修改部分)
  151.       uint8_t rawBrightness = inoise8(x*30, y*30, timeBase);  // 降低噪声频率
  152.       
  153.       // 映射到40-200范围并添加平滑滤波
  154.       uint8_t targetBrightness = map(rawBrightness, 0, 255, 40, 200);
  155.       uint8_t brightness = (targetBrightness * 3 + lastBrightness[x][y] * 7) / 10; // 70%历史值权重
  156.       lastBrightness[x][y] = brightness;

  157.       leds[XY(x, y)] = CHSV(finalHue, 240, brightness);
  158.     }
  159.   }

  160.   FastLED.show();
  161.   timeBase += 2;  // 降低整体变化速度
  162.   delay(20);
  163. }
  164. #endif

  165. void random_vision()
  166. {
  167.   // 随机生成动态参数
  168.   uint8_t currentHue = random(MAIN_HUE - HUE_RANGE, MAIN_HUE + HUE_RANGE);
  169.   uint8_t currentBrightness = baseBrightness + random(-brightnessJitter, brightnessJitter);
  170.   uint8_t currentSpread = random(0, 100); // 用于范围控制

  171.   // 更新所有LED颜色
  172.   for (int i = 0; i < NUM_LEDS; i++) {
  173.     // 根据spreadRatio决定使用主色还是辅助色
  174.     uint8_t hue = (currentSpread < spreadRatio) ?
  175.                   random(currentHue - 5, currentHue + 5) :  // 主色微抖动
  176.                   random(ACCENT_HUE - 5, ACCENT_HUE + 5);    // 辅助色微抖动

  177.     // 生成最终颜色
  178.     leds[i] = CHSV(
  179.       hue,
  180.       saturation,
  181.       constrain(currentBrightness + random(-20, 20), 0, 255) // 亮度叠加噪声
  182.     );
  183.   }

  184.   FastLED.show();
  185.   delay(50 + random(0, 100)); // 随机刷新间隔
  186. }

  187. void smooth_vision()
  188. {
  189.     uint8_t currentBrightness = baseBrightness + random(-brightnessJitter, brightnessJitter);
  190.     static CRGBPalette16 currentPalette;
  191.   if (random(0, 100) > 90) { // 10%概率切换色板
  192.     currentPalette = CRGBPalette16(
  193.       CHSV(random(MAIN_HUE - HUE_RANGE, MAIN_HUE + HUE_RANGE), 255, 255),
  194.       CHSV(random(ACCENT_HUE - HUE_RANGE, ACCENT_HUE + HUE_RANGE), 255, 255)
  195.     );
  196.   }
  197.   
  198.   // 使用色板插值
  199.   for (int i = 0; i < NUM_LEDS; i++) {
  200.     leds[i] = ColorFromPalette(
  201.       currentPalette,
  202.       random8(), // 随机位置采样色板
  203.       currentBrightness,
  204.       LINEARBLEND
  205.     );
  206.   }
  207.   FastLED.show();
  208.   delay(30);
  209. }

  210. #if 1
  211. void optim_vision()
  212. {
  213.   static uint8_t breathPhase = 0;
  214.   static uint8_t rotationPhase = 0;
  215.   static uint8_t globalRandom = 0;
  216.   
  217.   breathPhase += 1;
  218.   rotationPhase += 2;
  219.   globalRandom = (globalRandom + 1) % 256; // 缓慢变化的随机种子
  220.   
  221.   for (int y = 0; y < MATRIX_HEIGHT; y++) {
  222.     for (int x = 0; x < MATRIX_WIDTH; x++) {
  223.       int index = getLEDIndex(x, y);
  224.       CRGB& pixel = leds[index];
  225.       
  226.       // 中心点计算(蛇形坐标)
  227.       int centerX = MATRIX_WIDTH / 2;
  228.       int centerY = MATRIX_HEIGHT / 2;
  229.       float dx = abs(x - centerX);
  230.       float dy = abs(y - centerY);
  231.       float distance = sqrt(dx*dx + dy*dy);
  232.       
  233.       // 带随机性的呼吸效果
  234.       float breathVal = (sin(breathPhase * 0.1 + (random(3)-1)*0.5) + 1) * 64;
  235.       breathVal += (random(5) - 2) * 0.5; // 微小随机波动
  236.       
  237.       uint8_t baseHue = 240; // 主色调深蓝
  238.       uint8_t hueVariance = 10; // 色调随机范围
  239.       
  240.       // 主色调背景(带柔和渐变)
  241.       if (distance > 10) {
  242.         pixel = CHSV(baseHue + random(-hueVariance, hueVariance),
  243.                     80 + random(10),
  244.                     breathVal / 2);
  245.       } else {
  246.         // 紫色光晕(等级1限制,柔和混合)
  247.         float ratio = constrain(distance / 10, 0, 1);
  248.         uint8_t h1 = baseHue;
  249.         uint8_t s1 = 100;
  250.         uint8_t v1 = breathVal;
  251.         
  252.         uint8_t h2 = 255;
  253.         uint8_t s2 = 20 + random(5);
  254.         uint8_t v2 = breathVal * 2 + random(3);
  255.         
  256.         CRGB color1 = CHSV(h1, s1, v1);
  257.         CRGB color2 = CHSV(h2, s2, v2);
  258.         
  259.         // 使用立方贝塞尔曲线实现平滑过渡
  260.         float t = pow(ratio, 0.5);
  261.         CRGB blended = blend(color1, color2, t*t*(3-2*t));
  262.         
  263.         // 添加随机噪声纹理
  264.         float noiseVal = (inoise8(x * 3 + seed, y * 3 + seed + rotationPhase) - 128) / 256.0;
  265.         blended.g += noiseVal * 15;
  266.         blended.b += noiseVal * 10;
  267.         
  268.         pixel = blended;
  269.         
  270.         // 动态波纹(带随机相位)
  271.         float time = (millis() / 1000.0) + rotationPhase * 0.05 + (random(5)-2)*0.1;
  272.         float wave = sin((distance + time) * 0.5 + (random(10)-5)*0.05) * 2;
  273.         pixel.blue += wave;
  274.         pixel.green += wave / 2;
  275.         
  276.         // 结构纹理(模拟波纹)
  277.         float detail = sin((x + y + time) * 3 + (random(3)-1)*0.2) * 5;
  278.         pixel.red += detail;
  279.       }
  280.     }
  281.   }
  282.   
  283.   FastLED.show();
  284.   delay(random(20, 40)); // 随机延时增加自然感
  285. }
  286. #endif

  287. void random_rainbow()
  288. {
  289.     static uint8_t hue = 180; // 初始色相设定在青色区间
  290.   static uint8_t randomness = 0; // 随机种子控制变量
  291.   
  292.   // 动态调整随机种子
  293.   randomness = (randomness + 1) % 64;
  294.   
  295.   for (int x = 0; x < MATRIX_WIDTH; x++) {
  296.     for (int y = 0; y < MATRIX_HEIGHT; y++) {
  297.       // 计算基础色相
  298.       uint8_t baseHue = hue + x * 10 + y * 5;
  299.       
  300.       // 添加可控随机偏移(±3范围内)
  301.       uint8_t hueOffset = random(61) - 30; // 生成-30到+29的随机数
  302.       uint8_t ledHue = baseHue + hueOffset;
  303.       
  304.       // 强制限制在青蓝紫区间(180-300度)
  305.       ledHue = ledHue % 360;
  306.       if (ledHue < 180) ledHue += 180;
  307.       else if (ledHue > 300) ledHue -= 120;
  308.       
  309.       // 生成动态亮度(带波浪噪声)
  310.       uint8_t brightness = sin8(x * 20 + y * 20 + hue + randomness);
  311.       brightness = qadd8(brightness, random(32)); // 最多叠加31的随机亮度
  312.       
  313.       // 创建柔和过渡的色彩
  314.       CRGB color = CHSV(ledHue, 255, brightness);
  315.       color.fadeToBlackBy(255 - (random(64) + 192)); // 随机透明度
  316.       
  317.       leds[XY(x, y)] = color;
  318.     }
  319.   }
  320.   
  321.   FastLED.show();
  322.   
  323.   // 随机呼吸式延迟
  324.   uint8_t delayTime = random(15, 45);
  325.   delay(delayTime);
  326.   
  327.   // 更新主色相(缓慢变化)
  328.   hue += 1;
  329.   if (hue >= 360) hue -= 360;
  330. }
  331. // 中心点坐标(蛇形布局需调整)
  332. int centerX = MATRIX_WIDTH / 2;
  333. int centerY = MATRIX_HEIGHT / 2;

  334. // 动态参数
  335. uint8_t hueBase = 180;    // 初始色相(青色)
  336. uint8_t flowSpeed = 1;    // 流动速度(1-5)

  337. void centor_rainbow()
  338. {
  339.   static uint8_t time = 0;
  340.   
  341.   // 时间推进与随机扰动
  342.   time++;
  343.   randomness = (randomness + 1) % 64;
  344.   
  345.   for (int y = 0; y < MATRIX_HEIGHT; y++) {
  346.     for (int x = 0; x < MATRIX_WIDTH; x++) {
  347.       int index = y * MATRIX_WIDTH + x;
  348.       CRGB& pixel = leds[index];
  349.       
  350.       // 蛇形布局修正(如需平面布局可注释)
  351.       if (y % 2 != 0) x = MATRIX_WIDTH - 1 - x;
  352.       
  353.       // 计算到中心点的距离
  354.       float dx = x - centerX;
  355.       float dy = y - centerY;
  356.       float distance = sqrt(dx*dx + dy*dy);
  357.       
  358.       // 生成基础半径和随机涨落
  359.       float baseRadius = (time * flowSpeed) / 2.0;
  360.       float radiusFluctuation = (random(21) - 10) * 0.5; // ±5范围随机
  361.       float currentRadius = baseRadius + radiusFluctuation;
  362.       
  363.       // 判断是否在扩散范围内
  364.       if (distance <= currentRadius) {
  365.         // 计算色相(强制青蓝紫范围)
  366.         float hueRange = 120; // 180-300度
  367.         float hueOffset = (distance / currentRadius) * hueRange;
  368.         uint8_t hue = hueBase + hueOffset;
  369.         hue = constrain(hue, 180, 300);
  370.         
  371.         // 添加噪声纹理
  372.         uint8_t noiseVal = inoise8(x * 4 + randomness, y * 4 + time + randomness);
  373.         hue += (noiseVal - 128) / 64; // ±0.5色相偏移
  374.         
  375.         // 生成颜色(柔和渐变)
  376.         uint8_t saturation = 255;
  377.         uint8_t value = 255 - (distance / currentRadius * 255);
  378.         
  379.         CRGB color = CHSV(hue, saturation, value);
  380.         pixel = color;
  381.       } else {
  382.         pixel = CRGB::Black;
  383.       }
  384.     }
  385.   }
  386.   
  387.   FastLED.show();
  388.   
  389.   // 动态延迟控制
  390.   uint8_t delayTime = random(10, 30) + (randomness % 5);
  391.   delay(delayTime);
  392. }


  393. const CRGB palette[] = {
  394.   CRGB(0x2A, 0x5B, 0x8C), // 深蓝
  395.   CRGB(0x3E, 0xB7, 0xA0), // 青绿
  396.   CRGB(0x80, 0x00, 0x80), // 紫
  397.   CRGB(0xFF, 0xC0, 0xCB)  // 粉
  398. };

  399. void renderGradient(int style) {
  400.   switch (style) {
  401.     case 0: // 对角线线性渐变(第1张图)
  402.       for (int y = 0; y < MATRIX_HEIGHT; y++) {
  403.         for (int x = 0; x < MATRIX_WIDTH; x++) {
  404.           float ratio = (x + y) / (float)(MATRIX_WIDTH + MATRIX_HEIGHT - 2);
  405.           leds[y * MATRIX_WIDTH + x] = blend(palette[0], palette[2], ratio * 255);
  406.         }
  407.       }
  408.       break;
  409.     case 1: // 流体渐变(第5张图)
  410.       static uint16_t z;
  411.       for (int i = 0; i < NUM_LEDS; i++) {
  412.         uint8_t noise = inoise8(i % MATRIX_WIDTH * 30, i / MATRIX_WIDTH * 30, z);
  413.         leds[i] = ColorFromPalette(CRGBPalette16(palette), noise);
  414.       }
  415.       z += 10;
  416.       break;
  417.   }
  418.   FastLED.show();
  419. }

  420. void test_vision()
  421. {
  422.    for (int i = 0; i < 4; i++) { // 循环切换4种渐变
  423.     renderGradient(i % 2);
  424.     delay(20);
  425.   }
  426. }

  427. #if 1
  428. // 马尔科夫链状态结构体(修正字段类型)
  429. struct MarkovState {
  430.   uint8_t baseHue;     // 改为8位存储
  431.   uint8_t speed;       // 速度范围1-5
  432.   int8_t direction;    // 风向
  433.   uint8_t intensity;   // 强度范围
  434. };

  435. // 初始化状态(调整参数)
  436. MarkovState currentState = {200, 3, 1, 150}; // 提高初始baseHue

  437. // 简化转移概率矩阵
  438. const uint8_t transitionProb[4][4] = {
  439.   {80, 10, 5, 5},   
  440.   {15, 70, 10, 5},  
  441.   {10, 5, 80, 5},  
  442.   {5, 5, 5, 85}   
  443. };

  444. // 噪声参数
  445. uint16_t z = 0;
  446. const uint8_t scale = 30;
  447. const uint8_t blurAmount = 64;


  448. // 马尔科夫状态转移实现
  449. void applyMarkovTransition() {
  450.   uint8_t randVal = random8();
  451.   uint8_t probSum = 0;
  452.   
  453.   // 选择要改变的状态维度
  454.   uint8_t targetDim = 0;
  455.   for(; targetDim<4; targetDim++) {
  456.     probSum += transitionProb[targetDim][targetDim];
  457.     if(randVal < probSum) break;
  458.   }
  459.   
  460.   // 执行状态转移(有限差分法)
  461.   switch(targetDim) {
  462.     case 0: // 基础色调变化
  463.       currentState.baseHue += random8(3) - 1; // ±1微调
  464.       currentState.baseHue = constrain(currentState.baseHue, 180, 255);
  465.       break;
  466.       
  467.     case 1: // 速度变化
  468.       currentState.speed = constrain(
  469.         currentState.speed + random8(3) - 1, 1, 5);
  470.       break;
  471.       
  472.     case 2: // 方向变化
  473.       if(random8() < 30) currentState.direction *= -1;
  474.       break;
  475.       
  476.     case 3: // 强度变化
  477.       currentState.intensity = constrain(
  478.         currentState.intensity + random8(21) - 10, 100, 200);
  479.       break;
  480.   }
  481. }

  482. // 基于状态的图案生成
  483. void generateWindPattern() {
  484.   for(uint8_t y=0; y<MATRIX_HEIGHT; y++) {
  485.     for(uint8_t x=0; x<MATRIX_WIDTH; x++) {
  486.       uint8_t noise = inoise8(
  487.         (x * scale) / 2 + (currentState.direction * z),
  488.         y * scale + z/2,
  489.         currentState.intensity * 10
  490.       );
  491.       
  492.       // 修正色调计算(添加循环处理)
  493.       uint8_t hue = currentState.baseHue + map(noise, 0,255, -20,20);
  494.       hue = (hue < 180) ? hue + 75 : hue; // 确保在180-255范围
  495.       
  496.       // 修正亮度计算(移除错误处理)
  497.       uint8_t val = map(noise, 50, 205, 30, 230);
  498.       val = constrain(val, 30, 230); // 硬约束
  499.       
  500.       leds[XY(x,y)] = CHSV(hue, 230, val);
  501.     }
  502.   }
  503.   
  504.   blur2d(leds, MATRIX_WIDTH, MATRIX_HEIGHT, blurAmount);
  505.   z += 2;//currentState.speed;   //速度均匀
  506. }



  507. void wind_vision() {
  508.   static uint32_t lastUpdate = 0;
  509.   static uint8_t hueShift = 0;

  510.   if(millis() - lastUpdate > 50) { // 降低更新频率
  511.     lastUpdate = millis();
  512.    
  513.     // 马尔科夫状态转移
  514.     applyMarkovTransition();
  515.    
  516.     // 生成动态风场
  517.     generateWindPattern();
  518.    
  519.     FastLED.show();
  520.     delay(10);
  521.   }
  522. }
  523. #else



  524. // 马尔科夫链增强平滑版本
  525. struct MarkovState {
  526.   uint8_t baseHue;     // 当前色相
  527.   uint8_t targetHue;   // 目标色相(新增)
  528.   uint8_t speed;
  529.   uint8_t targetSpeed; // 新增目标速度
  530.   int8_t direction;
  531.   float directionF;    // 新增浮点方向(用于平滑过渡)
  532.   uint8_t intensity;
  533. };

  534. MarkovState currentState = {200, 200, 3, 3, 1, 1.0f, 150};
  535. const uint8_t transitionProb[4][4] = {
  536.   {90, 5, 3, 2},     // 提高保持色相的概率
  537.   {10, 85, 3, 2},    // 降低速度变化频率
  538.   {5, 5, 88, 2},     // 增强方向稳定性
  539.   {3, 2, 2, 93}      // 提高强度保持率
  540. };

  541. uint32_t z = 0;       // 改为32位防溢出
  542. const float DIRECTION_TRANSITION = 0.1f; // 方向过渡系数

  543. void applyMarkovTransition() {
  544.   static uint32_t lastChange = 0;
  545.   const uint32_t CHANGE_INTERVAL = 3000; // 延长状态变化间隔
  546.   
  547.   if(millis() - lastChange < CHANGE_INTERVAL) return;
  548.   lastChange = millis();

  549.   uint8_t randVal = random8();
  550.   uint8_t probSum = 0;
  551.   uint8_t targetDim = 0;
  552.   
  553.   // 概率累计方式优化
  554.   while(targetDim < 4 && randVal > (probSum += transitionProb[targetDim][targetDim])) {
  555.     targetDim++;
  556.   }

  557.   // 有限渐变状态转移
  558.   switch(targetDim) {
  559.     case 0: // 色相渐变
  560.       currentState.targetHue = constrain(currentState.baseHue + random8(-8, 9), 180, 255);
  561.       break;
  562.       
  563.     case 1: // 速度渐变
  564.       currentState.targetSpeed = constrain(currentState.speed + random8(-1, 2), 1, 5);
  565.       break;
  566.       
  567.     case 2: // 方向平滑过渡
  568.       currentState.directionF = -currentState.directionF; // 缓慢反转
  569.       break;
  570.       
  571.     case 3: // 强度渐变
  572.       currentState.intensity = constrain(currentState.intensity + random8(-8, 9), 100, 200);
  573.       break;
  574.   }
  575. }

  576. void smoothUpdateStates() {
  577.   // 色相线性插值
  578.   currentState.baseHue = lerp8by8(currentState.baseHue, currentState.targetHue, 10);
  579.   
  580.   // 速度指数平滑
  581.   currentState.speed = (currentState.speed * 7 + currentState.targetSpeed * 1) / 8;
  582.   
  583.   // 方向浮点过渡
  584.   currentState.directionF += (currentState.direction - currentState.directionF) * DIRECTION_TRANSITION;
  585. }

  586. void generateWindPattern() {
  587.   const float dirFactor = currentState.directionF; // 使用浮点方向因子


  588.   for(uint8_t y=0; y<MATRIX_HEIGHT; y++) {
  589.     for(uint8_t x=0; x<MATRIX_WIDTH; x++) {
  590.       // 改进的噪声参数(增加Z轴细分)
  591.       uint8_t noise = inoise8(
  592.         (x * 25) + (z * dirFactor * 0.7f),
  593.         y * 35 + z * 0.3f,
  594.         currentState.intensity * 8 + (z >> 6)
  595.       );
  596.       
  597.       // 循环色相映射(替代硬约束)
  598.       uint8_t hue = currentState.baseHue + map(noise, 0,255, -15,15);
  599.       hue = 180 + ((hue - 180) % 76); // 180-255循环
  600.       
  601.       // 亮度S曲线处理
  602.       uint8_t val = cubicwave8(noise);
  603.       val = map(val, 30, 225, 50, 220);  // 压缩两端
  604.       
  605.       leds[XY(x,y)] = CHSV(hue, 235, val);
  606.     }
  607.   }
  608.   
  609.    // 使用标准二维模糊 + 逐行模糊替代方案
  610.   blur2d(leds, MATRIX_WIDTH, MATRIX_HEIGHT, 64);
  611.   
  612.   // 手动实现行模糊
  613.   for(uint8_t y=0; y<MATRIX_HEIGHT; y++) {
  614.     CRGB* rowStart = &leds[XY(0, y)];
  615.     blur1d(rowStart, MATRIX_WIDTH, 32);
  616.   }
  617.   
  618.   z += currentState.speed;
  619. }

  620. void wind_vision() {
  621.   static uint32_t lastUpdate = 0;
  622.   
  623.   if(millis() - lastUpdate > 33) { // 30FPS
  624.     lastUpdate = millis();
  625.    
  626.     smoothUpdateStates();  // 先更新状态
  627.     applyMarkovTransition();
  628.     generateWindPattern();
  629.    
  630.     // 添加残影效果
  631.     fadeToBlackBy(leds, NUM_LEDS, 220);
  632.     FastLED.show();
  633.   }
  634. }
  635. #endif



  636. // 动画参数
  637. uint8_t noiseScale = 20;
  638. uint8_t noiseSpeed = 12;
  639. uint16_t zOffset = 0;

  640. #define COLS       30
  641. #define ROWS       15

  642. // 坐标转换函数
  643. void getXY(uint16_t i, uint8_t &x, uint8_t &y) {
  644.   x = i % COLS;
  645.   y = i / COLS;
  646.   if (y % 2) x = (COLS - 1) - x;
  647. }
  648. #define FRAME_RATE 10
  649. void fluidAnimation() {
  650.   for (int i = 0; i < NUM_LEDS; i++) {
  651.     uint8_t x, y;
  652.     getXY(i, x, y);
  653.    
  654.     // 生成三维噪声
  655.     uint16_t noise = inoise16(x * noiseScale * 10,
  656.                              y * noiseScale * 10,
  657.                              zOffset);
  658.    
  659.     // 动态色相映射
  660.     uint8_t hue = (noise >> 8) + millis() / 100; // 叠加整体色相漂移
  661.     hue = 180 + ((hue - 160) % 76); // 160-255循环
  662.     // 亮度波动
  663.     uint8_t val = 100 + (noise % 55);
  664.    
  665.     leds[i] = CHSV(hue, 240, val);
  666.   }
  667.   zOffset += noiseSpeed * 256;
  668. }

  669. void fluor_vision() {
  670.   fluidAnimation();
  671.   FastLED.show();
  672.   FastLED.delay(1000 / FRAME_RATE);
  673. }

  674. //======================  wave ======================

  675. // 带随机扰动的距离计算
  676. float perturbedDistance(uint8_t x, uint8_t y, Wave &w) {
  677.   float dx = x - center_x;
  678.   float dy = y - center_y;
  679.   
  680.   // 添加基于角度的随机扰动
  681.   float angle = atan2(dy, dx) + w.angleOffset;
  682.   float perturbation = 0.4f * sin(angle * 3 + w.radius * 0.5f);
  683.   
  684.   return sqrt(dx*dx + dy*dy) * (1.0f + perturbation * 0.08f);
  685. }

  686. #if 0
  687. void spawnWave(uint8_t gen) {
  688.   for(uint8_t i=0; i<MAX_WAVES; i++){
  689.     if(!waves[i].active){
  690.       waves[i] = {
  691.         0.0f,
  692.         1.0f - gen*0.12f,
  693.         true,
  694.         gen,
  695.         false,
  696.         random8(95, 105)/100.0f,  // 速度随机因子
  697.         random8(90, 110)/100.0f,  // 宽度随机因子
  698.         random8(0, 628)/100.0f    // 新随机角度
  699.       };
  700.       return;
  701.     }
  702.   }
  703. }


  704. void wave_vision() {
  705.   static uint32_t lastFrame = millis();
  706.   float deltaTime = (millis() - lastFrame)/1000.0f;
  707.   lastFrame = millis();

  708.   fadeToBlackBy(leds, NUM_LEDS, 25);  // 加快淡出速度增加密度感

  709.   for(uint8_t i=0; i<MAX_WAVES; i++){
  710.     if(waves[i].active){
  711.       Wave &w = waves[i];
  712.       
  713.       // 应用随机速度
  714.       w.radius += BASE_WAVE_SPEED * w.speedVariation * (1.0f + deltaTime);//BASE_WAVE_SPEED * w.speedVariation * (1.0f + deltaTime);
  715.       w.intensity *= DECAY_RATE;

  716.       // 触发新波环
  717.       if(w.generation == 0 && !w.hasTriggered && w.radius >= TRIGGER_DISTANCE){
  718.         spawnWave(1);
  719.         w.hasTriggered = true;
  720.       }

  721.       // 波环生命周期管理
  722.       if(w.radius > maxRadius || w.intensity < 0.12f){
  723.         if(w.generation == 0){
  724.           // 重置核心波环并重新随机参数
  725.           w.radius = 0.0f;
  726.           w.intensity = 1.0f;
  727.           w.hasTriggered = false;
  728.           w.speedVariation = random8(95, 105)/100.0f;
  729.           w.widthVariation = random8(90, 110)/100.0f;
  730.           w.angleOffset = random8(0, 628)/100.0f;
  731.         }else{
  732.           w.active = false;
  733.         }
  734.       }

  735.       // 绘制波环
  736.       for(uint8_t y=0; y<MATRIX_HEIGHT; y++){
  737.         for(uint8_t x=0; x<MATRIX_WIDTH; x++){
  738.           // 使用扰动后的距离计算
  739.           float dist = perturbedDistance(x, y, w);
  740.           float delta = abs(dist - w.radius);
  741.          
  742.           // 应用随机宽度
  743.           float effectiveWidth = BASE_WAVE_WIDTH * w.widthVariation;
  744.           float effect = exp(-pow(delta/effectiveWidth, 2.2f)) * w.intensity;
  745.          
  746.           // 中心抑制
  747.           if(x >= center_x-1 && x <= center_x && y >= center_y-1 && y <= center_y){
  748.             effect *= 0.15f;
  749.           }
  750.          
  751.           // 颜色混合(添加轻微随机色相偏移)
  752.           uint8_t hue = 160 + w.generation*18 + w.radius*0.8f;
  753.           leds[XY(x,y)] += CHSV(hue, 210, effect * 220);
  754.         }
  755.       }
  756.     }
  757.   }

  758.   // 强化中心暗区
  759.   for(uint8_t dx=0; dx<2; dx++){
  760.     for(uint8_t dy=0; dy<2; dy++){
  761.       uint16_t idx = XY(center_x-dx, center_y-dy);
  762.       leds[idx].nscale8(40);  // 更暗的中心
  763.     }
  764.   }


  765.   //LedDelay(200);
  766.   FastLED.delay(28);  // 稍快的刷新率
  767. }
  768. #else


  769. const uint8_t WAVE_OVERLAP = 3;      // 波环叠加层数

  770. // 全局控制变量

  771. uint32_t noiseZ = 0;

  772. // ================= 波环视觉核心 =================
  773. void wave_vision() {
  774.   static uint32_t lastFrame = millis();
  775.   uint32_t currentFrame = millis();
  776.   float deltaTime = (currentFrame - lastFrame) / 1000.0f;
  777.   lastFrame = currentFrame;

  778.   // 全屏基础噪声填充(先于波环绘制)
  779.   for(uint8_t y=0; y<MATRIX_HEIGHT; y++){
  780.     for(uint8_t x=0; x<MATRIX_WIDTH; x++){
  781.       uint8_t noise = inoise8(x*20, y*20, noiseZ);
  782.       leds[XY(x,y)] = CHSV(200, 50, noise*0.2f); // 低饱和度背景噪声
  783.     }
  784.   }

  785.   // ================= 高密度波环系统 =================
  786.   for(uint8_t i=0; i<MAX_WAVES; i++){
  787.     if(waves[i].active){
  788.       Wave &w = waves[i];
  789.       w.radius += BASE_WAVE_SPEED * w.speedVariation * globalSpeedFactor * deltaTime;

  790.       // 动态波环生成(三重触发机制)
  791.       float effectiveTriggerDist = TRIGGER_DISTANCE / globalSpeedFactor;
  792.       if(w.generation < WAVE_OVERLAP && w.radius >= effectiveTriggerDist*(w.generation+1)){
  793.         spawnWave(w.generation+1);
  794.         w.hasTriggered = true;
  795.       }

  796.       // 持续能量补充机制
  797.       if(w.intensity < 0.8f && random8() < 30){
  798.         w.intensity += 0.15f; // 随机能量增强
  799.       }

  800.       // 波环绘制(三重叠加)
  801.       for(uint8_t n=0; n<WAVE_OVERLAP; n++){
  802.         for(uint8_t y=0; y<MATRIX_HEIGHT; y++){
  803.           for(uint8_t x=0; x<MATRIX_WIDTH; x++){
  804.             float dx = x - center_x;
  805.             float dy = y - center_y;
  806.             float angle = atan2(dy, dx) + w.angleOffset + n*1.047f; // 120度相位差
  807.             float perturbation = 0.6f * sin(angle*5 + w.radius*0.7f);
  808.             float dist = sqrt(dx*dx + dy*dy) * (1.0f + perturbation*0.12f);
  809.             
  810.             float delta = abs(dist - (w.radius + n*0.8f)); // 叠加偏移
  811.             float effectiveWidth = BASE_WAVE_WIDTH * (w.widthVariation - n*0.1f);
  812.             float effect = exp(-pow(delta/effectiveWidth, 1.8f)) * w.intensity;

  813.             // 颜色混合(多世代渐变)
  814.             uint8_t hue = 160 + w.generation*12 + (w.radius + n*2.0f)*0.9f;
  815.             uint8_t sat = 220 - w.generation*15;
  816.             leds[XY(x,y)] += CHSV(hue, sat, effect*255 * (0.7f - n*0.15f));
  817.           }
  818.         }
  819.       }
  820.       
  821.       // 生命周期管理(延长存在时间)
  822.       if(w.radius > maxRadius*1.5f || w.intensity < 0.08f){
  823.         if(w.generation == 0){
  824.           w.radius = 0.0f;
  825.           w.intensity = 1.0f;
  826.           w.speedVariation = random8(85, 115)/100.0f;
  827.           w.widthVariation = random8(80, 120)/100.0f;
  828.         }else{
  829.           w.active = false;
  830.         }
  831.       }
  832.     }
  833.   }

  834.   // ================= 动态高频噪声 =================
  835.   noiseZ += 4 * globalSpeedFactor;
  836.   for(uint8_t i=0; i<NUM_LEDS; i++){
  837.     uint8_t highFreqNoise = inoise8(i*10, noiseZ);
  838.     leds[i] += CHSV(210, 180, highFreqNoise*NOISE_INTENSITY); // 高频闪烁噪声
  839.     leds[i].nscale8(240); // 防止过曝
  840.   }

  841.   FastLED.delay(28);
  842. }

  843. // ================= 辅助函数优化 =================
  844. void spawnWave(uint8_t gen) {
  845.   for(uint8_t i=0; i<MAX_WAVES; i++){
  846.     if(!waves[i].active){
  847.       waves[i] = {
  848.         0.0f,
  849.         1.0f - gen*0.08f,  // 更缓慢的强度衰减
  850.         true,
  851.         gen,
  852.         false,
  853.         random8(80, 120)/100.0f,  // 更大速度变化范围
  854.         random8(75, 125)/100.0f,  // 更大宽度变化
  855.         random8(0, 628)/100.0f
  856.       };
  857.       return;
  858.     }
  859.   }
  860. }

  861. #endif
 楼主| keer_zu 发表于 2025-5-28 04:50 | 显示全部楼层
想做一个渐入淡出的效果:
  1. #include <FastLED.h>

  2. #define LED_PIN1 15
  3. #define LED_PIN2 4
  4. #define NUM_LEDS1 270  // 30x9
  5. #define NUM_LEDS2 300  // 30x10
  6. #define MATRIX_WIDTH 30
  7. #define MATRIX_HEIGHT 19
  8. #define MAX_BRIGHTNESS 180
  9. #define EFFECT_DURATION 20000  // 20秒
  10. #define FADE_TIME 3000         // 3秒

  11. CRGB leds1[NUM_LEDS1];
  12. CRGB leds2[NUM_LEDS2];

  13. enum Effect { RAINBOW, CIRCLE };
  14. Effect currentEffect = RAINBOW;
  15. unsigned long effectStartTime = 0;

  16. void setup() {
  17.   FastLED.addLeds<WS2815, LED_PIN1>(leds1, NUM_LEDS1);
  18.   FastLED.addLeds<WS2815, LED_PIN2>(leds2, NUM_LEDS2);
  19.   FastLED.setBrightness(MAX_BRIGHTNESS);
  20.   effectStartTime = millis();
  21. }

  22. void loop() {
  23.   unsigned long currentTime = millis();
  24.   unsigned long elapsed = currentTime - effectStartTime;
  25.   
  26.   // 效果切换判断
  27.   if (elapsed >= EFFECT_DURATION) {
  28.     currentEffect = (currentEffect == RAINBOW) ? CIRCLE : RAINBOW;
  29.     effectStartTime = currentTime;
  30.     elapsed = 0;
  31.   }

  32.   // 亮度计算
  33.   float brightness = 1.0;
  34.   if (elapsed < FADE_TIME) {  // 淡入
  35.     brightness = (float)elapsed / FADE_TIME;
  36.   } else if (elapsed < (EFFECT_DURATION - FADE_TIME)) {  // 正常
  37.     brightness = 1.0;
  38.   } else {  // 淡出
  39.     brightness = 1.0 - (float)(elapsed - (EFFECT_DURATION - FADE_TIME)) / FADE_TIME;
  40.   }

  41.   // 设置全局亮度
  42.   FastLED.setBrightness(MAX_BRIGHTNESS * brightness);

  43.   // 执行当前效果
  44.   if (currentEffect == RAINBOW) {
  45.     rainbow_vision();
  46.   } else {
  47.     circle_vision();
  48.   }

  49.   FastLED.show();
  50. }

  51. // 滚动彩虹效果
  52. void rainbow_vision() {
  53.   static uint8_t hue = 0;
  54.   fill_rainbow(leds1, NUM_LEDS1, hue);
  55.   fill_rainbow(leds2, NUM_LEDS2, hue + NUM_LEDS1);
  56.   hue += 2;
  57. }

  58. // 中心扩散圆环效果
  59. void circle_vision() {
  60.   static uint8_t hue = 0;
  61.   static unsigned long startTime = millis();
  62.   
  63.   float radius = (millis() - startTime) / 50.0f;  // 控制扩散速度
  64.   float maxRadius = sqrt(pow(14.5, 2) + pow(9.0, 2));

  65.   if (radius > maxRadius) {
  66.     startTime = millis();
  67.     hue += 50;
  68.   }

  69.   // 处理上半部分(leds1)
  70.   for (int i = 0; i < NUM_LEDS1; i++) {
  71.     int row = i / MATRIX_WIDTH;
  72.     int col = (row % 2 == 0) ? (i % MATRIX_WIDTH) : (MATRIX_WIDTH - 1 - (i % MATRIX_WIDTH));
  73.     float dx = col - 14.5;
  74.     float dy = row - 9.0;
  75.     float distance = sqrt(dx*dx + dy*dy);
  76.    
  77.     if (distance >= radius-1 && distance <= radius+1) {
  78.       leds1[i] = CHSV(hue, 255, 255);
  79.     } else {
  80.       leds1[i] = CRGB::Black;
  81.     }
  82.   }

  83.   // 处理下半部分(leds2)
  84.   for (int i = 0; i < NUM_LEDS2; i++) {
  85.     int row = 9 + (i / MATRIX_WIDTH);
  86.     int col = (row % 2 == 0) ? (i % MATRIX_WIDTH) : (MATRIX_WIDTH - 1 - (i % MATRIX_WIDTH));
  87.     float dx = col - 14.5;
  88.     float dy = row - 9.0;
  89.     float distance = sqrt(dx*dx + dy*dy);
  90.    
  91.     if (distance >= radius-1 && distance <= radius+1) {
  92.       leds2[i] = CHSV(hue, 255, 255);
  93.     } else {
  94.       leds2[i] = CRGB::Black;
  95.     }
  96.   }
  97. }
 楼主| keer_zu 发表于 2025-5-28 04:51 | 显示全部楼层
keer_zu 发表于 2025-5-27 10:13
尝试速度可控,还存在问题:

似乎淡出可以,渐入不行
 楼主| keer_zu 发表于 2025-5-28 17:12 | 显示全部楼层
非阻塞的跑马灯和呼吸灯:

  1. #include <FastLED.h>

  2. #define LED_PIN     2
  3. #define NUM_LEDS    165
  4. #define LED_TYPE    WS2815
  5. #define COLOR_ORDER GRB
  6. #define BRIGHTNESS  100

  7. CRGB leds[NUM_LEDS];

  8. // 效果状态结构体
  9. struct EffectState {
  10.   unsigned long startTime;
  11.   bool isRunning;
  12.   uint8_t currentPos;
  13.   float brightness;
  14.   bool breathingUp;
  15. };

  16. EffectState fastChaseState = {0, false, 0, 0, true};
  17. EffectState clockwiseState = {0, false, 0, 0, true};
  18. EffectState anticlockwiseState = {0, false, 0, 0, true};
  19. EffectState fastBreathState = {0, false, 0, 0, true};
  20. EffectState slowBreathState = {0, false, 0, 0, true};

  21. void setup() {
  22.   FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS);
  23.   FastLED.setBrightness(BRIGHTNESS);
  24.   FastLED.clear();
  25.   FastLED.show();
  26. }

  27. // 1. 快速跑马效果 (3秒一圈)
  28. void startFastChase() {
  29.   fastChaseState.startTime = millis();
  30.   fastChaseState.isRunning = true;
  31.   fastChaseState.currentPos = 0;
  32. }

  33. void updateFastChase() {
  34.   if (!fastChaseState.isRunning) return;
  35.   
  36.   unsigned long elapsed = millis() - fastChaseState.startTime;
  37.   float progress = fmod((float)elapsed / 3000.0, 1.0); // 3秒周期
  38.   fastChaseState.currentPos = (uint8_t)(progress * NUM_LEDS);
  39.   
  40.   // 清除所有LED
  41.   fill_solid(leds, NUM_LEDS, CRGB::Black);
  42.   
  43.   // 设置当前LED为白光
  44.   leds[fastChaseState.currentPos] = CRGB(255, 255, 255);
  45.   
  46.   FastLED.show();
  47. }

  48. // 2. 顺时针拖尾跑马 (8秒一圈)
  49. void startClockwiseChase() {
  50.   clockwiseState.startTime = millis();
  51.   clockwiseState.isRunning = true;
  52.   clockwiseState.currentPos = 0;
  53. }

  54. void updateClockwiseChase() {
  55.   if (!clockwiseState.isRunning) return;
  56.   
  57.   unsigned long elapsed = millis() - clockwiseState.startTime;
  58.   float progress = fmod((float)elapsed / 8000.0, 1.0); // 8秒周期
  59.   uint16_t headPos = (uint16_t)(progress * NUM_LEDS);
  60.   
  61.   // 拖尾参数
  62.   const uint8_t trailLength = 30;
  63.   
  64.   for (int i = 0; i < NUM_LEDS; i++) {
  65.     // 计算与头灯的距离(顺时针方向)
  66.     int distance = (i + NUM_LEDS - headPos) % NUM_LEDS;
  67.    
  68.     if (distance < trailLength) {
  69.       // 指数衰减拖尾
  70.       float decay = pow(0.7, distance);
  71.       uint8_t brightness = (uint8_t)(255 * decay);
  72.       leds[i] = CRGB(brightness, brightness, brightness);
  73.     } else {
  74.       leds[i] = CRGB::Black;
  75.     }
  76.   }
  77.   
  78.   FastLED.show();
  79. }

  80. // 3. 快速呼吸效果 (4秒一轮)
  81. void startFastBreathing() {
  82.   fastBreathState.startTime = millis();
  83.   fastBreathState.isRunning = true;
  84.   fastBreathState.brightness = 0;
  85.   fastBreathState.breathingUp = true;
  86. }

  87. void updateFastBreathing() {
  88.   if (!fastBreathState.isRunning) return;
  89.   
  90.   unsigned long elapsed = millis() - fastBreathState.startTime;
  91.   float cycleProgress = fmod((float)elapsed / 4000.0, 1.0); // 4秒周期
  92.   
  93.   // 使用正弦波实现平滑呼吸
  94.   float brightness = 128 + 127 * sin(cycleProgress * 2 * PI);
  95.   
  96.   fill_solid(leds, NUM_LEDS, CRGB(brightness, brightness, brightness));
  97.   FastLED.show();
  98. }

  99. // 4. 逆时针拖尾跑马 (8秒一圈)
  100. void startAnticlockwiseChase() {
  101.   anticlockwiseState.startTime = millis();
  102.   anticlockwiseState.isRunning = true;
  103.   anticlockwiseState.currentPos = 0;
  104. }

  105. void updateAnticlockwiseChase() {
  106.   if (!anticlockwiseState.isRunning) return;
  107.   
  108.   unsigned long elapsed = millis() - anticlockwiseState.startTime;
  109.   float progress = fmod((float)elapsed / 8000.0, 1.0); // 8秒周期
  110.   uint16_t headPos = NUM_LEDS - (uint16_t)(progress * NUM_LEDS);
  111.   
  112.   // 拖尾参数
  113.   const uint8_t trailLength = 30;
  114.   
  115.   for (int i = 0; i < NUM_LEDS; i++) {
  116.     // 计算与头灯的距离(逆时针方向)
  117.     int distance = (headPos + NUM_LEDS - i) % NUM_LEDS;
  118.    
  119.     if (distance < trailLength) {
  120.       // 指数衰减拖尾
  121.       float decay = pow(0.7, distance);
  122.       uint8_t brightness = (uint8_t)(255 * decay);
  123.       leds[i] = CRGB(brightness, brightness, brightness);
  124.     } else {
  125.       leds[i] = CRGB::Black;
  126.     }
  127.   }
  128.   
  129.   FastLED.show();
  130. }

  131. // 5. 缓慢呼吸效果 (8秒一轮)
  132. void startSlowBreathing() {
  133.   slowBreathState.startTime = millis();
  134.   slowBreathState.isRunning = true;
  135.   slowBreathState.brightness = 0;
  136.   slowBreathState.breathingUp = true;
  137. }

  138. void updateSlowBreathing() {
  139.   if (!slowBreathState.isRunning) return;
  140.   
  141.   unsigned long elapsed = millis() - slowBreathState.startTime;
  142.   float cycleProgress = fmod((float)elapsed / 8000.0, 1.0); // 8秒周期
  143.   
  144.   // 使用正弦波实现平滑呼吸
  145.   float brightness = 128 + 127 * sin(cycleProgress * 2 * PI);
  146.   
  147.   fill_solid(leds, NUM_LEDS, CRGB(brightness, brightness, brightness));
  148.   FastLED.show();
  149. }

  150. // 停止所有效果
  151. void stopAllEffects() {
  152.   fastChaseState.isRunning = false;
  153.   clockwiseState.isRunning = false;
  154.   anticlockwiseState.isRunning = false;
  155.   fastBreathState.isRunning = false;
  156.   slowBreathState.isRunning = false;
  157.   FastLED.clear();
  158.   FastLED.show();
  159. }

  160. void loop() {
  161.   // 非阻塞式更新所有活动效果
  162.   updateFastChase();
  163.   updateClockwiseChase();
  164.   updateFastBreathing();
  165.   updateAnticlockwiseChase();
  166.   updateSlowBreathing();
  167.   
  168.   // 简单的效果切换逻辑(每10秒切换一个效果)
  169.   static unsigned long lastChange = 0;
  170.   if (millis() - lastChange > 10000) {
  171.     lastChange = millis();
  172.     static uint8_t currentEffect = 0;
  173.    
  174.     stopAllEffects();
  175.    
  176.     switch (currentEffect) {
  177.       case 0: startFastChase(); break;
  178.       case 1: startClockwiseChase(); break;
  179.       case 2: startFastBreathing(); break;
  180.       case 3: startAnticlockwiseChase(); break;
  181.       case 4: startSlowBreathing(); break;
  182.     }
  183.    
  184.     currentEffect = (currentEffect + 1) % 5;
  185.   }
  186.   
  187.   // 保持低延迟
  188.   delay(20);
  189. }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1478

主题

12912

帖子

55

粉丝
快速回复 在线客服 返回列表 返回顶部

1478

主题

12912

帖子

55

粉丝
快速回复 在线客服 返回列表 返回顶部