Fórum témák

» Több friss téma
Fórum » Színes, animált kijelzésű hangfrekvenciás spektrum-analizátor
Lapozás: OK   2 / 2
(#) dB_Thunder hozzászólása Máj 17, 2021 1 / 2
 
Egy kicsit megállt az élet...Dehogy!

Fejlemények: újabb laptopom fél év használat után elhalálozott, elő kellett vennem a régit.

Közben egy új hardver is beesett a képbe, Seeeduino XIAO képében!
Úgy döntöttem erre írom meg az alap "simple" programot!
Miért?
Kisebb, olcsóbb, gyorsabb! Pont elég a 14 sávhoz.

Később ezen ki lehet próbálni a IIR vagy FIR szűrőket. Van benne DAC, így talán meghallgatni is meglehet majd!
A hozzászólás módosítva: Máj 17, 2021
(#) dB_Thunder hozzászólása Júl 4, 2021 /
 
Update:
A platinum szoftverje kicsit bonyolult, ezért a Generatorlabs egyszerűbb szoftverjét húztam át a XIAO-ra.
Ez a verzió nem tudja a Peak-hold funkciót, cserébe van benne pár animáció. Ez FastLED lib-et használ, soros monitoron meg lehet nézni épp melyik mód fut.
Sajnos laptopom még mindig nincs ezért a kölköknél kell a gépüket bitorolnom

  1. #include <FastLED.h>            // You must include FastLED version 3.002.006. This library allows communication with each LED
  2. #include <si5351mcu.h>          // Library used to program clock generator IC via I2C
  3. Si5351mcu Si;                   // Library instantiation as "Si"
  4.  
  5. //XIAO LÁBKIOSZTÁSOK:
  6. #define HEARTBEAT_PIN 13        // Pin for heartbeat,alaplapi led
  7. #define LED_DI_PIN 7            // Pin for serial communication with LED string.
  8. #define STROBE_PIN 2            // Pin to instruct MSGEQ7 IC's(4) to inspect next band (band 0 thru 6). Default Pin on SpeckyBoard_One is Pin 7.
  9. #define RESET_PIN 3             // Pin to instruct MSGEQ7 IC's(7) to return to band zero and inspect it. Default Pin on SpeckyBoard_One is Pin 6.
  10. #define ANALOG_PIN1 0        
  11. #define ANALOG_PIN2 1
  12. //Si5351mcu SDA pin 4
  13. //Si5351mcu SDA pin 5
  14.  
  15.  
  16. #define COLUMN 14               // Number of columns in LED project. (14)
  17. #define ROWS 24                 // Number of rows (left to right) in LED project. (21)
  18. #define NUM_LEDS COLUMN * ROWS  // Total number of LED's in the project.
  19. #define LEDTYPE WS2812B         // Type of LED communication protocol used.
  20. #define BRIGHTNESS  50          // Intensity of LED's. The lower the number the longer LED's will last. LED's do have a finite life span when run hard.
  21. // It is strongly recommended to keep this number as low as possible. Inexpensive LED strips will have a noticeably shorter life and pull large
  22. // amounts of current unecessarily. Large surges in current could lead to current starvation and possibly erratic operation. Your power supply must be
  23. // sized correctly. A string of 300 LED's could potentially require a 18 amp power supply! Avoid drawing white as a color if your power supply is
  24. // substandard or poorly regulated. For reference, my 294 LED analyzer, with a brightness of 50 and static rainbow columns will average less than
  25. // 0.5 amps @ 5vdc. If you drive the LED's conseratively you will get good results.
  26.  
  27. // Noise-floor compensator. Set this number to eliminate noise picked up by circuit. When watching serial monitor, data
  28. // should be closer to zero with an audio source connected and no music playing.
  29. #define NOISECOMP 150   // 120 is a good start point. ; My number is 160  
  30.  
  31. // Use a frequency generator app on a smart phone to adjust BOOST. All led's should in selected band should light up when sweeping frequencies
  32. // at high volume.
  33. // Boost works similar to the Arduino "constrain" function but is easier to dial in additional boost for weak input signals.
  34. // Test on 63Hz, 160Hz, 400Hz, & 1000Hz.
  35. #define BOOST 6
  36.  
  37. bool SeialPrintMODE = 1;
  38.  
  39. // Matrix Definition
  40. CRGB leds[NUM_LEDS];      // Setup memory block and array for all LED's
  41. typedef struct ledrgb     // Structure defining the parameters related to each led
  42. {
  43.   int hue;
  44.   int sat;
  45.   int val;
  46.   int nled;
  47.   boolean active;
  48. } led;
  49. led colors[COLUMN][ROWS];   // Matrix containing the values of the structure variables.
  50.  
  51. //Global Variables
  52. int MSGEQ_Bands[COLUMN];    // Setup column array to store instantaneous sample of each band.
  53. byte DELTA;                 // Variable use to affect scaling of each column
  54. int nlevel;                 // Level index
  55. int hue_rainbow = 0;        // Global variable for the rainbow variable hue.
  56. int long rainbow_time = 0;
  57. int long time_change = 0;
  58. int long heartbeat = 0;
  59. int effect = 1;             // Load this color effect on startup
  60. bool toggle = false;
  61. int n = 0;
  62.  
  63. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  64. /////------------------- SETUP ----------------------////////////////////////////////////////////////////////////////////////
  65. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  66.  
  67. void setup()
  68. {
  69.   // Serial.begin(57600);      // Enable this for serial monitor or troubleshooting
  70.  
  71.   // Start Masterclock configuration; The remainder of this program will fail if this does not initialize!
  72.   Si.init(25000000L);               // Library procedure to set up for use with non-default 25.000 MHz xtal
  73.   Si.setFreq(0, 165000);            // Enable the output 0  with specified frequency of 165.000 KHz; Default Pin for SpeckyBoard
  74.   Si.setFreq(2, 104000);            // Enable the output 1  with specified frequency of 104.000 KHz; Default Pin for SpeckyBoard
  75.   Si.setPower(0, SIOUT_8mA);        // Set power output level of clock 0
  76.   Si.setPower(2, SIOUT_8mA);        // Set power output level of clock 1
  77.   Si.enable(0);                     // Enable output 0
  78.   Si.enable(2);                     // Enable output 1
  79.   // End Masterclock configuration
  80.  
  81.   pinMode(HEARTBEAT_PIN, OUTPUT);
  82.   pinMode(LED_DI_PIN, OUTPUT);
  83.   pinMode(STROBE_PIN, OUTPUT);
  84.   pinMode(RESET_PIN, OUTPUT);
  85.  
  86.   DELTA = 1024 / ROWS - BOOST;      // Do not change this line. Adjust BOOST, defined above, to effect gain
  87.  
  88.   int hb = 0;
  89.   for (int hb = 0; hb < 10; hb++)
  90.   {
  91.     toggle = !toggle;
  92.     digitalWrite(HEARTBEAT_PIN, toggle);    // Flash Heartbeat LED rapidly; Si5351 clock passed initializiation!
  93.     delay(100);
  94.   }
  95.  
  96.   int count = 0;
  97.   for (int i = 0; i < COLUMN; i++)          //Sequentially number the leds
  98.   {
  99.     for (int j = 0; j < ROWS; j++)
  100.     {
  101.       colors[i][j].nled = count;
  102.       count++;
  103.     }
  104.   }
  105.  
  106.   FastLED.addLeds<LEDTYPE, LED_DI_PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  107.   FastLED.setBrightness( BRIGHTNESS );
  108.   rainbow_time = millis();
  109.   time_change = millis();
  110. }
  111.  
  112. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  113. /////-------------------- LOOP ----------------------////////////////////////////////////////////////////////////////////////
  114. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  115.  
  116. void loop(){
  117.  if (SeialPrintMODE=1){
  118.      Serial.print(effect);
  119.     }
  120.  
  121.   readMSGEQ7();                                  // Call to function that reads MSGEQ7 IC's via analogue inputs.
  122.  
  123.   if (millis() - time_change > 30000)             // Code that establishes how often to change effect. 1000 = 1 Second
  124.   {
  125.    // effect = 2;                                  // Enable this line to set a fixed mode
  126.     effect++;                                  // Enable this line to cycle through different modes
  127.     if (effect > 7)
  128.     {
  129.       effect = 0;
  130.     }
  131.     time_change = millis();
  132.   }
  133.  
  134.   if (millis() - heartbeat > 3000)               // Hearbeat LED to indicate that code has passed init and is actually looping through routines
  135.   {
  136.     toggle = !toggle;
  137.     digitalWrite(HEARTBEAT_PIN, toggle);
  138.     heartbeat = millis();
  139.   }
  140.  
  141.  
  142.   switch (effect)           // Case logic to determine which color effect to use
  143.   {
  144.  
  145.  
  146.     case 0:                                      // Full column; each band different color; color gradient within each band
  147.       rainbow_dot();
  148.       full_column();
  149.       updateHSV();
  150.       break;
  151.  
  152.     case 1:                                      // Full column; each band the same color; gradual simultaneous color change across all bands
  153.       if (millis() - rainbow_time > 15)
  154.       {
  155.         dynamic_rainbow();
  156.         rainbow_time = millis();
  157.       }
  158.       full_column();
  159.       updateHSV();
  160.       break;
  161.  
  162.     case 2:                                      // Full column; each band a different static rainbow color for the specified interval
  163.       if (millis() - rainbow_time > 600)
  164.       {
  165.         rainbow_column();
  166.         rainbow_time = millis();
  167.       }
  168.       full_column();
  169.       updateHSV();
  170.       break;
  171.  
  172.     case 3:                                      // Full column; all bands same static color
  173.       if (millis() - rainbow_time > 15)
  174.       {
  175.         total_color_hsv(255, 255, 255);
  176.         rainbow_time = millis();
  177.       }
  178.       full_column();
  179.       updateHSV();
  180.       break;
  181.  
  182.     case 4:                                      // Dot column; each column a different static rainbow color
  183.       if (millis() - rainbow_time > 15)
  184.       {
  185.         rainbow_dot();
  186.         rainbow_time = millis();
  187.       }
  188.       full_column_dot();
  189.       updateHSV();
  190.       break;
  191.     case 5:                                      // Dot column; each band the same color; gradual simultaneous color change across all bands
  192.       if (millis() - rainbow_time > 15)
  193.       {
  194.         dynamic_rainbow();
  195.         rainbow_time = millis();
  196.       }
  197.       full_column_dot();
  198.       updateHSV();
  199.       break;
  200.  
  201.     case 6:                                      // Dot column; each band a different static rainbow color
  202.       if (millis() - rainbow_time > 15)
  203.       {
  204.         rainbow_column();
  205.         rainbow_time = millis();
  206.       }
  207.       full_column_dot();
  208.       updateHSV();
  209.       break;
  210.  
  211.     case 7:                                      // Dot column; all bands same static color
  212.       total_color_hsv(55, 255, 255);
  213.       full_column_dot();
  214.       updateHSV();
  215.       break;
  216.   }
  217.   delay(1);                                     // Refresh rate; Values 20 thru 30 should look realistic
  218. }
  219.  
  220. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  221. /////---------------- FUNCTIONS ---------------------////////////////////////////////////////////////////////////////////////
  222. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  223.  
  224. void readMSGEQ7(void)                               // Function that reads the 7 bands of the audio input.
  225. {
  226.   digitalWrite(RESET_PIN, HIGH);
  227.   digitalWrite(STROBE_PIN, HIGH);                 // Make sure Strobe line is low before entering loop. EZ NEM VOLT BENNE
  228.   delayMicroseconds(22);                      // MSGEQ7 MIN IDŐ 18uS
  229.   digitalWrite(STROBE_PIN, LOW);                    // Part 1 of Reset Pulse. Reset pulse duration must be 100nS minimum.
  230.   delayMicroseconds(22);
  231.   digitalWrite(RESET_PIN, LOW);     // Part 2 of Reset pulse. These two events consume more than 100nS in CPU time.
  232.   digitalWrite(STROBE_PIN, HIGH);
  233.   delayMicroseconds(100);
  234.   for (int band = 0; band < COLUMN; band++) {       // Loop that will increment counter that AnalogRead uses to determine which band to store data for.
  235.     digitalWrite(STROBE_PIN, LOW);                  // Re-Set Strobe to LOW on each iteration of loop.
  236.     delayMicroseconds(40);                         // MSGEQ KIMENET BEÁLLÁSÁNAK AZ IDEJE
  237.     MSGEQ_Bands[band] = analogRead(ANALOG_PIN1) - NOISECOMP;  // Saves the reading of the amplitude voltage on Analog Pin 0.
  238.     band++;
  239.     MSGEQ_Bands[band] = analogRead(ANALOG_PIN2) - NOISECOMP;  // Saves the reading of the amplitude voltage on Analog Pin 1.
  240. digitalWrite(STROBE_PIN, HIGH);
  241.   }
  242. }
  243.  
  244. void updateHSV(void)
  245. {
  246.   for (int i = 0; i < COLUMN; i++) {
  247.     for (int j = 0; j < ROWS; j++) {
  248.       if (colors[i][j].active == 1) {
  249.         leds[colors[i][j].nled] = CHSV(colors[i][j].hue, colors[i][j].sat, colors[i][j].val);
  250.       } else {
  251.         leds[colors[i][j].nled] = CRGB::Black;
  252.       }
  253.  
  254.     }
  255.   }
  256.   FastLED.show();
  257. }
  258.  
  259. void full_column(void)
  260. {
  261.   nlevel = 0;
  262.   for (int i = 0; i < COLUMN; i++) {
  263.     nlevel = MSGEQ_Bands[i] / DELTA;
  264.     for (int j = 0; j < ROWS; j++) {
  265.       if (j <= nlevel) {
  266.         colors[i][j].active = 1;
  267.       }
  268.       else {
  269.         colors[i][j].active = 0;
  270.       }
  271.     }
  272.   }
  273. }
  274.  
  275. void full_column_dot(void)
  276. {
  277.   nlevel = 0;
  278.   for (int i = 0; i < COLUMN; i++) {
  279.     nlevel = MSGEQ_Bands[i] / DELTA;
  280.     for (int j = 0; j < ROWS; j++) {
  281.       if (j == nlevel) {
  282.         colors[i][j].active = 1;
  283.       }
  284.       else {
  285.         colors[i][j].active = 0;
  286.       }
  287.     }
  288.   }
  289. }
  290.  
  291. void total_color_hsv(int h, int s, int v)
  292. {
  293.   for (int i = 0; i < COLUMN; i++) {
  294.     for (int j = 0; j < ROWS; j++) {
  295.       colors[i][j].hue = h;
  296.       colors[i][j].sat = s;
  297.       colors[i][j].val = v;
  298.     }
  299.   }
  300. }
  301.  
  302. void rainbow_column(void)
  303. {
  304.   //int n = 18;
  305.   for (int i = 0; i < COLUMN; i++) {
  306.     for (int j = 0; j < ROWS; j++) {
  307.       colors[i][j].hue = n;
  308.       colors[i][j].sat = 230;
  309.       colors[i][j].val = 240;
  310.     }
  311.     n += 18;  //36 For 7 Columns
  312.   }
  313. }
  314.  
  315. void rainbow_dot(void)
  316. {
  317.   int n = 36;
  318.   for (int i = 0; i < COLUMN; i++) {
  319.     for (int j = 0; j < ROWS; j++) {
  320.       colors[i][j].hue = n;
  321.       colors[i][j].sat = 230;
  322.       colors[i][j].val = 240;
  323.       n += 5;
  324.     }
  325.   }
  326. }
  327.  
  328. void dynamic_rainbow(void)
  329. {
  330.   for (int i = 0; i < COLUMN; i++) {
  331.     for (int j = 0; j < ROWS; j++) {
  332.       colors[i][j].hue = hue_rainbow;
  333.       colors[i][j].sat = 230;
  334.       colors[i][j].val = 240;
  335.     }
  336.   }
  337.   hue_rainbow++;
  338. }
(#) dB_Thunder hozzászólása Dec 3, 2021 /
 
Sziasztok!

Nézzük most hol tartok, és merre megyek!! Vagy nem, de valami csak lesz

Generatorlabs-nak van egy olyan kódja ami már tudja a PEAK-HOLD funkciót, ezt gyúrtam tovább:
PeakHold.zip

Ez egy egyszerű program, nincsenek benne receptek, vizualizációk, szépen folyamatosan változik az egész színe.

Első dolog volt amit megvalósítottam, hogy PEAK-HOLD led színét egy potival tudjam állítani, ami aránylag egyszerű ha telített színekkel elégedettek vagyunk. Én nem, ezért 4 lépcsőben lehet a telítettséget csökkenteni, ugyanazzal a színbeállító potival! Az utolsó telítettség már fehér. Érdemes elolvasni a LastLED leírását! Nekem nagyon tetszik az elgondolásuk, az egyedi színkezelésük!

A folyamatos szín fadding-ot kivettem, helyette a soroknak más a színe, nekem ez jobban bejön.

Beállítható az "erősítés" azaz a jelszinthez képest be lehet állítani a kivezérlést. Itt jött is egy gubanc, az alapzajt le kell vágni, de erősítés függvényében változóan. Ezen még van mit csiszolnom.

Beállítható a fényerő is egy 3. potival.

Amit viszont hiányolok az a PEAK-HOlD led esés sebességének állíthatóságának a hiánya!! Ezt még meg kellene csinálni.... Bár lassan elfogy a szabad lába a XIAO-nak.

Ha,... de nem biztos, hogy tovább fogom kínozni ezt a programot! Már most nézegetem, gyűjtöm az infókat, hogy az MSGEQ7 ic-k helyett szoftveres jelfeldolgozás legyen!

A másik fele a projektnek!
El kell dönteni a végleges formáját, kivitelét legalább a kijelző résznek!!
A plexikocka tornyokat elvetetem! Ugyan nagyon tetszetős, de az ára...másrészt az egész egy porfogó!! Biztos megőrülnék ha minden lapocskát törölgetni kellene hetente!! Vitrinbe nem teszem, az az egész látványt megöli.
Maradt az infinity mirror !! Méghozzá 21x24 leddel! Igen! Tovább lépek a 14 sávnál, több kell. Led szalag van elég...

Meg lett tervezve a kijelző rész kiosztása is, 14, és 21 sávra is. Itt még lehet változás, lehet hogy csak 20 oszlop lesz...ezt nagyon gyorsan el kellene döntenem. Igazából ha megoldható a szoftveres szűrésnél a 21 sáv, gyorsan futó egyszerű programmal, akkor én arra szavaznék!

Frekvenciák 21 sávnál:
22, 63, 100, 120, 150, 200, 275, 350, 500, 650, 800, 1k, 2k, 4k, 6k, 8k, 10k, 12k, 14k, 16k, 18k


Frekvenciák 20 sávnál:
20, 40, 90, 150, 220, 320, 450, 600, 800, 1,2k, 2k, 3k, 4,5k, 6k, 8k, 10k, 12k, 14k, 17k, 20k

Ez is egy elég suta kiosztás, létező EQ-ról loptam.. Mi a kócnak 20k poti?? Mi van ott, denevérsikoly?? Bőven elég utolsónak 18k.. Én már 13k felett nem hallok...

FFT guruk!!
Melyik kiosztást szerencsésebb megvalósítani? Esetleg más frekvenciák a 21 sávos felosztáshoz?
A hozzászólás módosítva: Dec 3, 2021
(#) dB_Thunder válasza dB_Thunder hozzászólására (») Dec 3, 2021 /
 
Még egy részprobléma, gondolat ami foglalkoztat:
Led szalagok összekötése! Most az egész egy dróthalmaz!
Az oszlop utolsó ledjétől vissza kell kábelezni a következő oszlop elejéig, aljáig.
Vannak olyan kész led panelek is ami a következő oszlop fent kezdődik, az előző végénél, és visszafelé halad, nincs visszavezetékezve alulra.

Ezeknek a panelek kezelését is megoldották a FastLED-be!!
Ezt a megoldás én is szeretném a végleges fizikai megvalósítás előtt, de még nem teljesen értettem meg:

  1. #include <FastLED.h>
  2.  
  3. #define LED_PIN  3
  4.  
  5. #define COLOR_ORDER GRB
  6. #define CHIPSET     WS2811
  7.  
  8. #define BRIGHTNESS 64
  9.  
  10. // Helper functions for an two-dimensional XY matrix of pixels.
  11. // Simple 2-D demo code is included as well.
  12. //
  13. //     XY(x,y) takes x and y coordinates and returns an LED index number,
  14. //             for use like this:  leds[ XY(x,y) ] == CRGB::Red;
  15. //             No error checking is performed on the ranges of x and y.
  16. //
  17. //     XYsafe(x,y) takes x and y coordinates and returns an LED index number,
  18. //             for use like this:  leds[ XYsafe(x,y) ] == CRGB::Red;
  19. //             Error checking IS performed on the ranges of x and y, and an
  20. //             index of "-1" is returned.  Special instructions below
  21. //             explain how to use this without having to do your own error
  22. //             checking every time you use this function.  
  23. //             This is a slightly more advanced technique, and
  24. //             it REQUIRES SPECIAL ADDITIONAL setup, described below.
  25.  
  26.  
  27. // Params for width and height
  28. const uint8_t kMatrixWidth = 16;
  29. const uint8_t kMatrixHeight = 16;
  30.  
  31. // Param for different pixel layouts
  32. const bool    kMatrixSerpentineLayout = true;
  33. const bool    kMatrixVertical = false;
  34.  
  35. // Set 'kMatrixSerpentineLayout' to false if your pixels are
  36. // laid out all running the same way, like this:
  37. //
  38. //     0 >  1 >  2 >  3 >  4
  39. //                         |
  40. //     .----<----<----<----'
  41. //     |
  42. //     5 >  6 >  7 >  8 >  9
  43. //                         |
  44. //     .----<----<----<----'
  45. //     |
  46. //    10 > 11 > 12 > 13 > 14
  47. //                         |
  48. //     .----<----<----<----'
  49. //     |
  50. //    15 > 16 > 17 > 18 > 19
  51. //
  52. // Set 'kMatrixSerpentineLayout' to true if your pixels are
  53. // laid out back-and-forth, like this:
  54. //
  55. //     0 >  1 >  2 >  3 >  4
  56. //                         |
  57. //                         |
  58. //     9 <  8 <  7 <  6 <  5
  59. //     |
  60. //     |
  61. //    10 > 11 > 12 > 13 > 14
  62. //                        |
  63. //                        |
  64. //    19 < 18 < 17 < 16 < 15
  65. //
  66. // Bonus vocabulary word: anything that goes one way
  67. // in one row, and then backwards in the next row, and so on
  68. // is call "boustrophedon", meaning "as the ox plows."
  69.  
  70.  
  71. // This function will return the right 'led index number' for
  72. // a given set of X and Y coordinates on your matrix.  
  73. // IT DOES NOT CHECK THE COORDINATE BOUNDARIES.  
  74. // That's up to you.  Don't pass it bogus values.
  75. //
  76. // Use the "XY" function like this:
  77. //
  78. //    for( uint8_t x = 0; x < kMatrixWidth; x++) {
  79. //      for( uint8_t y = 0; y < kMatrixHeight; y++) {
  80. //      
  81. //        // Here's the x, y to 'led index' in action:
  82. //        leds[ XY( x, y) ] = CHSV( random8(), 255, 255);
  83. //      
  84. //      }
  85. //    }
  86. //
  87. //
  88. uint16_t XY( uint8_t x, uint8_t y)
  89. {
  90.   uint16_t i;
  91.  
  92.   if( kMatrixSerpentineLayout == false) {
  93.     if (kMatrixVertical == false) {
  94.       i = (y * kMatrixWidth) + x;
  95.     } else {
  96.       i = kMatrixHeight * (kMatrixWidth - (x+1))+y;
  97.     }
  98.   }
  99.  
  100.   if( kMatrixSerpentineLayout == true) {
  101.     if (kMatrixVertical == false) {
  102.       if( y & 0x01) {
  103.         // Odd rows run backwards
  104.         uint8_t reverseX = (kMatrixWidth - 1) - x;
  105.         i = (y * kMatrixWidth) + reverseX;
  106.       } else {
  107.         // Even rows run forwards
  108.         i = (y * kMatrixWidth) + x;
  109.       }
  110.     } else { // vertical positioning
  111.       if ( x & 0x01) {
  112.         i = kMatrixHeight * (kMatrixWidth - (x+1))+y;
  113.       } else {
  114.         i = kMatrixHeight * (kMatrixWidth - x) - (y+1);
  115.       }
  116.     }
  117.   }
  118.  
  119.   return i;
  120. }
  121.  
  122.  
  123. // Once you've gotten the basics working (AND NOT UNTIL THEN!)
  124. // here's a helpful technique that can be tricky to set up, but
  125. // then helps you avoid the needs for sprinkling array-bound-checking
  126. // throughout your code.
  127. //
  128. // It requires a careful attention to get it set up correctly, but
  129. // can potentially make your code smaller and faster.
  130. //
  131. // Suppose you have an 8 x 5 matrix of 40 LEDs.  Normally, you'd
  132. // delcare your leds array like this:
  133. //    CRGB leds[40];
  134. // But instead of that, declare an LED buffer with one extra pixel in
  135. // it, "leds_plus_safety_pixel".  Then declare "leds" as a pointer to
  136. // that array, but starting with the 2nd element (id=1) of that array:
  137. //    CRGB leds_with_safety_pixel[41];
  138. //    CRGB* const leds( leds_plus_safety_pixel + 1);
  139. // Then you use the "leds" array as you normally would.
  140. // Now "leds[0..N]" are aliases for "leds_plus_safety_pixel[1..(N+1)]",
  141. // AND leds[-1] is now a legitimate and safe alias for leds_plus_safety_pixel[0].
  142. // leds_plus_safety_pixel[0] aka leds[-1] is now your "safety pixel".
  143. //
  144. // Now instead of using the XY function above, use the one below, "XYsafe".
  145. //
  146. // If the X and Y values are 'in bounds', this function will return an index
  147. // into the visible led array, same as "XY" does.
  148. // HOWEVER -- and this is the trick -- if the X or Y values
  149. // are out of bounds, this function will return an index of -1.
  150. // And since leds[-1] is actually just an alias for leds_plus_safety_pixel[0],
  151. // it's a totally safe and legal place to access.  And since the 'safety pixel'
  152. // falls 'outside' the visible part of the LED array, anything you write
  153. // there is hidden from view automatically.
  154. // Thus, this line of code is totally safe, regardless of the actual size of
  155. // your matrix:
  156. //    leds[ XYsafe( random8(), random8() ) ] = CHSV( random8(), 255, 255);
  157. //
  158. // The only catch here is that while this makes it safe to read from and
  159. // write to 'any pixel', there's really only ONE 'safety pixel'.  No matter
  160. // what out-of-bounds coordinates you write to, you'll really be writing to
  161. // that one safety pixel.  And if you try to READ from the safety pixel,
  162. // you'll read whatever was written there last, reglardless of what coordinates
  163. // were supplied.
  164.  
  165. #define NUM_LEDS (kMatrixWidth * kMatrixHeight)
  166. CRGB leds_plus_safety_pixel[ NUM_LEDS + 1];
  167. CRGB* const leds( leds_plus_safety_pixel + 1);
  168.  
  169. uint16_t XYsafe( uint8_t x, uint8_t y)
  170. {
  171.   if( x >= kMatrixWidth) return -1;
  172.   if( y >= kMatrixHeight) return -1;
  173.   return XY(x,y);
  174. }
  175.  
  176.  
  177. // Demo that USES "XY" follows code below
  178.  
  179. void loop()
  180. {
  181.     uint32_t ms = millis();
  182.     int32_t yHueDelta32 = ((int32_t)cos16( ms * (27/1) ) * (350 / kMatrixWidth));
  183.     int32_t xHueDelta32 = ((int32_t)cos16( ms * (39/1) ) * (310 / kMatrixHeight));
  184.     DrawOneFrame( ms / 65536, yHueDelta32 / 32768, xHueDelta32 / 32768);
  185.     if( ms < 5000 ) {
  186.       FastLED.setBrightness( scale8( BRIGHTNESS, (ms * 256) / 5000));
  187.     } else {
  188.       FastLED.setBrightness(BRIGHTNESS);
  189.     }
  190.     FastLED.show();
  191. }
  192.  
  193. void DrawOneFrame( uint8_t startHue8, int8_t yHueDelta8, int8_t xHueDelta8)
  194. {
  195.   uint8_t lineStartHue = startHue8;
  196.   for( uint8_t y = 0; y < kMatrixHeight; y++) {
  197.     lineStartHue += yHueDelta8;
  198.     uint8_t pixelHue = lineStartHue;      
  199.     for( uint8_t x = 0; x < kMatrixWidth; x++) {
  200.       pixelHue += xHueDelta8;
  201.       leds[ XY(x, y)]  = CHSV( pixelHue, 255, 255);
  202.     }
  203.   }
  204. }
  205.  
  206.  
  207. void setup() {
  208.   FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
  209.   FastLED.setBrightness( BRIGHTNESS );
  210. }
(#) Peter65 válasza dB_Thunder hozzászólására (») Dec 3, 2021 /
 
Akkor lehet FFT-t használni, ha a sávok egész számú többszörösei az alapnak. Általában a hallható hangterjedelmet 10 oktávra szokták felosztani. Ha kettő eltolt alapot választasz egész számú felharmonikusokkal, akkor így 20 sáv adódik. Értelem szerűen fél oktáv szélességű sávszűrőket kell kialakítani.
(#) dB_Thunder válasza Peter65 hozzászólására (») Dec 3, 2021 /
 
Magyarra fordítva érdemes elfelejteni a 21. sávot..
Terveztetnem kell egy 20 oszlopos kiosztást is...
Következő: »»   2 / 2
Bejelentkezés

Belépés

Hirdetés
Lapoda.hu     XDT.hu     HEStore.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem