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 2 / 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 1 /
 
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...
(#) dB_Thunder hozzászólása Ápr 3, 2022 /
 
Fejlemények: sajnos pár hónapja be se kapcsoltam a kis cuccot!
Mechanikai kivitelezést terveztem meg, gyártást kell megoldanom, mert nincs kedvem 480 furatot kézzel kivitelezni.
Közben egyre inkább húz a szívem a teljes digitális jelfeldolgozás felé!
Rátaláltam erre:STM32F401CCU6
valamilyen Black Pill klón, én ezek közt nem találtam meg.
Ez tud pár DSP utasítást, illetve a lebegőpontos számítás is megy neki.

Találtam egy érdekes projektet ami jó lehet alapnak: EZ

Illetve a LEDek meghajtásához EZT
(#) dB_Thunder válasza dB_Thunder hozzászólására (») Ápr 3, 2022 /
 
Elindítottam Arduino alatt ezt a STM32 lapot, soros monitoron az alábbi névvel jelentkezik be:
STM32F411CE WeAct CoreBoard
Ez van benne gyárilag, mert még szűz...
(#) Pali79 hozzászólása Szept 15, 2024 /
 
Szia!
A témát olvasva azt látom, hogy kicsit magányos maradtál ebben a projektben és pár éve nincs is élet itt. Mi lett a vége? Született valami működő megoldás?
(#) dB_Thunder válasza Pali79 hozzászólására (») Szept 15, 2024 /
 
Szia!
Persze! Gyakorlatilag az első perctől kezdve volt működőképes verzió! Igaz megrekedt deszkamodell kivitelnél, de ez bármikor 10 perc alatt üzembe helyezhető
Egy kicsit nem úgy haladnak a dolgaim, hogy ráérjek erre, vannak tervek, majd látom hogy alakul. Dobozolni kellene a ledeket, az elektronikát, programot lehetne utána is fejlesztgetni.
(#) Pali79 válasza dB_Thunder hozzászólására (») Szept 15, 2024 /
 
Az elv érdekelne pár szóban, ha szabad. Én egy kicsit más kivitelben gondolkodom, de az MSGEQ7 alap szimpatikusnak tűnik. A több IC alkalmazásának pontosan mi a feltétele? Annyit kihámoztam, hogy a 8-as lábra adunk különböző frekvenciájú órajelet, így megvalósítva a különböző frekvenciáciák vizsgálatát. Ezt meg tudod mondani, hogy több IC-nél (4-5db) milyen frekvenciákat használnak?
(#) dB_Thunder válasza Pali79 hozzászólására (») Szept 15, 2024 /
 
Bővebben: Link
Nem erőltetném a 3-nál több MSGEQ-t, mert az egyes csatornák sávszélességét is csökkenteni kellene, ami viszont az ic belsejében eleve eldőlt!
Egyik fejlesztési irány elhagyni ezeket az IC-ket, és FHT-val megcsinálni a "szűrő"-ket. Szerencsére bontott készülékekből lett ehhez elég gyors processzorom...
(#) Pali79 válasza dB_Thunder hozzászólására (») Szept 15, 2024 /
 
Hát lehet mégsem ez az én utam. Nézegettem a FFT-t, de nekem magas, nem is kicsit. Egyébként nem hiszem, hogy a hardver lenne a szűk keresztmetszet. Találtam projektet amit PIC17-re írtak ami 32MHz-en járt. De az a kód is nagyon hosszú és bonyolult.
(#) dB_Thunder válasza Pali79 hozzászólására (») Szept 16, 2024 /
 
Nem kell ezt nulláról megírni!
A FHT-hez is van könyvtár, és a led meghajtáshoz is, sőt biztos vagyok benne, hogy ezt már valaki megírta! Meg kell néznem a leveles ládámat, ott is rengeteg infót gyűjtöttem.
Egyébként meg eladók az MSGEQ-k...
(#) Gafly válasza Pali79 hozzászólására (») Szept 16, 2024 /
 
Józsi bácsi nagy koponya volt szerintem.

Valószínűleg készen beimportált szoftverek helyett, a felesleges részeket kihagyva/átírva gyorsabb is, és karcsúbb is lehetne ám.
A hozzászólás módosítva: Szept 16, 2024
(#) wbt válasza Pali79 hozzászólására (») Szept 16, 2024 /
 
Szia, WS2812-hez van 10 oszlopos programom, nem foglalkoztam vele, anno csak LED-számokat kellett átírni egy Ausztrál ismerősnek, de biztosan működik. Van itt egy könyvtárban egy vödör megoldás, ha van kedved mazsolázni.
(#) Pali79 válasza wbt hozzászólására (») Szept 16, 2024 /
 
Köszönöm, minden infóra vevő vagyok!
(#) Pali79 válasza dB_Thunder hozzászólására (») Szept 16, 2024 /
 
Én egy kicsit máskét vagyok bekötve.
Nem szeretem az olyan kész dolgokat, amiknek a működését nem látom át. Persze jó az ha valaki már megírta letesztelte előtte, de érteni akarom a működését. Pláne mert más felhasználásba változtatni kell rajta, akkor az fel tudja adni a leckét.
Az IC-k ügyében írok PM.
(#) Pali79 válasza Gafly hozzászólására (») Szept 16, 2024 /
 
Teljesen egyetértek de nekem nem kicsit magas. Integrálokkal jó régen foglalkoztam utoljára, még fősulis koromban. Ezt még átvinni egy µC-be, az már nagyon nagy feladat.
(#) dB_Thunder válasza Pali79 hozzászólására (») Szept 16, 2024 /
 
Akkor olvasd el ezt a topicot az elejétől...
Én is megpróbálom a napokban felvenni a fonalat, és megnézni miről nem írtam!

Bővebben: Link
(#) Massawa válasza Pali79 hozzászólására (») Szept 16, 2024 /
 
Akkor egy kicsit nehez fába vágtad a fejszéd. Egy spektrum analizátor még a profiknak is elég nagy feladat volt, és mekkora kö esett le sokak szivéröl amikor megjelentek a digitális procik, amik szinte melléktermékként adták az FFT analizist.
(#) dB_Thunder válasza dB_Thunder hozzászólására (») Szept 21, 2024 /
 
Kicsit megállt az élet 2022 áprilisa után.
Hát fojtassuk.. Pontosabban zárjunk le egy epizódot, mivelhogy ma Pali79 átvette tőlem az MSGEQ-kat, így nálam az irány most már véglegesen a digitális jelfeldolgozás!!
Belenéztem hát miket mentettem le a leveles ládámba!
Lássuk:
23-ban találtam rá a Mark Donners munkájára, ez is MSGEQ-t használ, teljes projekt a mellékletben!

Illetve találtam 22-ben egy digitális jelfeldolgozású projektet:
https://projecthub.arduino.cc/janux/fht-audio-spectrum-visualizer-bf58ec
Ezen a vonalon megyek tovább!!
(#) Pali79 hozzászólása Szept 23, 2024 /
 
Szerintem tűzzünk egy értelmes célt, hogy egyfelé evezzünk. Személy szerint a 32 sávost favorizálom.
Ebben az esetben a "szokásos" felbontás:
16, 20, 25, 31.5, 40, 50, 63, 80, 100, 125, 160, 200, 250, 315, 400, 500, 630, 800, 1k, 1.25k, 1.6k, 2k, 2.5k, 3.15k, 4k, 5k, 6.3k, 8k, 10k, 12.5k, 16k, 20k.

Két kérdés merül fel így az elején:
1. hány LED "magas" legyen egy frekihez tartozó oszlop? Elméletben végiggondolva úgy egyszerű a program ha minden egyes LED-et minden alkalommal megszólítunk, akár kell világítania, akár nem. Ez viszont kapacitást igényel a vezérlés részéről.
2. milyen gyorsnak kell lennie a kijelzésnek? Tehát kijelzünk egy értéket egy oszlopra, mennyi idő múlva küldjük a következőt?

Ezek alapján ki tudom számolni, hogy meg tudom-e valósítani a fiókban lévő eszközökkel vagy tovább kell gondolni a történetet.
(#) dB_Thunder válasza Pali79 hozzászólására (») Szept 23, 2024 /
 
Idézet:
„úgy egyszerű a program ha minden egyes LED-et minden alkalommal megszólítunk, akár kell világítania, akár nem.”

Nincs lehetőség a WS28B12 esetén, hogy "kihagyjunk" a sorból bármelyiket is, hiszen ezek nem címezhetőek egyedileg, minden IC, pixel teljesen azonos!! A működésük és a lánckapcsolásuk segítségével lehet végigcímezni őket!!

Csináltam számításokat, talán még méréseket is, hogy mennyi ideig tart végigírni a több száz IC-t!
Első körben nem biztos hogy kiemelném problémának a ledek információval való feltöltését, mert ott van még feladatnak a MSGEQ-k kiolvasása, a számítások elvégzése, kezelőszervek beolvasása...
(#) Pali79 válasza dB_Thunder hozzászólására (») Szept 23, 2024 /
 
Idézet:
„Nincs lehetőség a WS28B12 esetén, hogy "kihagyjunk" a sorból bármelyiket is, hiszen ezek nem címezhetőek egyedileg, minden IC, pixel teljesen azonos!! A működésük és a lánckapcsolásuk segítségével lehet végigcímezni őket!!”

Igaz én már tovább gondoltam, de nem biztos, hogy jó irányban. Az jutott eszembe, hogy nem lenne muszáj az összes LED-et egy lábon vezérelni, lehetne akár oszloponként is egy láb a vezérlésre, de nem biztos, hogy nyerünk vele bármit is. Ezen még gondolkodom.

Ami az időt illeti, az adatlap szerint 1,25µs idő kell egy bit átviteléhez, ami azt jelenti, hogy egy LED címzése 30µs idő kell, tehát 1000db LED címzéséhez 0,03 másodperc idő szükséges. Ehhez elegendő 20MHz órajel.

Még nem állt össze fejben teljesen, de úgy látom így elsőre, hogy nem igényel ez a dolog olyan nagy számítási kapacitást mint azt elsőre gondoltam.

Holnap kapom kézhez a rendelésem a hestoretól és ki tudom próbálni a MSGEQ-kat élőben. Igaz WS2812 LEDjeim nincsenek egyenlőre csak egy 8×8-as LED mátrixon tudok egyenlőre próbálkozni.
(#) dB_Thunder válasza Pali79 hozzászólására (») Szept 25, 2024 /
 
Nos, a FastLED lib. támogatja a több (párhuzamos) adat láb kezelését!!
FastLED Parallel-Output
Érdemes átfutni az egész lib. leírását, szerintem egy nagyon átgondolt jól használható könyvtár!
(#) Pali79 válasza dB_Thunder hozzászólására (») Szept 26, 2024 /
 
Na sikerült végre az MSGEQ-kat beüzemelnem saját kóddal, de egyenlőre csak sima LED mátrix kijelzővel.

Átnéztem és átgondoltam ez a párhuzamos meghajtású dolgot. Szerintem ebben az alkalmazásban nincs akkora jelenlősége. Ha egy kivetítőt szeretnénk összerakni belle akkor a folyamatos, gyors mozgások szép megjelenítése miatt érdemes gondoklodni benne, de amíg LED-ek összmennyisége nem olyan durva. A 800kHz-es frekvencia nem olyan kevés ha vizuális dolgokról van szó.
(#) wbt válasza Pali79 hozzászólására (») Szept 27, 2024 /
 
kb 1300db / 25Hz frissítéssel, felesleges a szegmentált kiküldés. MSGEQ-t itthon vetted? Amiket anno én rendeltem (olcsó kicsi kínai) valamelyik csatornája hibás volt.
(#) Pali79 válasza wbt hozzászólására (») Szept 27, 2024 /
 
Idézet:
„kb 1300db / 25Hz frissítéssel, felesleges a szegmentált kiküldés.”

Egyetértek, én is erre jutottam.

Az MSGEQ-kat dB_Thunder kollégától vettem át. Ő is befürdött a kínaiakkal. Bár nem sokat kerestem, de szerintem itthon nem kapható jelenleg. Talán Csehországban találtam megbízhatónak tűnő helyen.
Következő: »»   2 / 2
Bejelentkezés

Belépés

Hirdetés
XDT.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