|
Fórum » Színes, animált kijelzésű hangfrekvenciás spektrum-analizátor
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
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
#include <FastLED.h> // You must include FastLED version 3.002.006. This library allows communication with each LED
#include <si5351mcu.h> // Library used to program clock generator IC via I2C
Si5351mcu Si; // Library instantiation as "Si"
//XIAO LÁBKIOSZTÁSOK:
#define HEARTBEAT_PIN 13 // Pin for heartbeat,alaplapi led
#define LED_DI_PIN 7 // Pin for serial communication with LED string.
#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.
#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.
#define ANALOG_PIN1 0
#define ANALOG_PIN2 1
//Si5351mcu SDA pin 4
//Si5351mcu SDA pin 5
#define COLUMN 14 // Number of columns in LED project. (14)
#define ROWS 24 // Number of rows (left to right) in LED project. (21)
#define NUM_LEDS COLUMN * ROWS // Total number of LED's in the project.
#define LEDTYPE WS2812B // Type of LED communication protocol used.
#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.
// It is strongly recommended to keep this number as low as possible. Inexpensive LED strips will have a noticeably shorter life and pull large
// amounts of current unecessarily. Large surges in current could lead to current starvation and possibly erratic operation. Your power supply must be
// 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
// substandard or poorly regulated. For reference, my 294 LED analyzer, with a brightness of 50 and static rainbow columns will average less than
// 0.5 amps @ 5vdc. If you drive the LED's conseratively you will get good results.
// Noise-floor compensator. Set this number to eliminate noise picked up by circuit. When watching serial monitor, data
// should be closer to zero with an audio source connected and no music playing.
#define NOISECOMP 150 // 120 is a good start point. ; My number is 160
// 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
// at high volume.
// Boost works similar to the Arduino "constrain" function but is easier to dial in additional boost for weak input signals.
// Test on 63Hz, 160Hz, 400Hz, & 1000Hz.
#define BOOST 6
bool SeialPrintMODE = 1;
// Matrix Definition
CRGB leds[NUM_LEDS]; // Setup memory block and array for all LED's
typedef struct ledrgb // Structure defining the parameters related to each led
{
int hue;
int sat;
int val;
int nled;
boolean active;
} led;
led colors[COLUMN][ROWS]; // Matrix containing the values of the structure variables.
//Global Variables
int MSGEQ_Bands[COLUMN]; // Setup column array to store instantaneous sample of each band.
byte DELTA; // Variable use to affect scaling of each column
int nlevel; // Level index
int hue_rainbow = 0; // Global variable for the rainbow variable hue.
int long rainbow_time = 0;
int long time_change = 0;
int long heartbeat = 0;
int effect = 1; // Load this color effect on startup
bool toggle = false;
int n = 0;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////------------------- SETUP ----------------------////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
// Serial.begin(57600); // Enable this for serial monitor or troubleshooting
// Start Masterclock configuration; The remainder of this program will fail if this does not initialize!
Si.init(25000000L); // Library procedure to set up for use with non-default 25.000 MHz xtal
Si.setFreq(0, 165000); // Enable the output 0 with specified frequency of 165.000 KHz; Default Pin for SpeckyBoard
Si.setFreq(2, 104000); // Enable the output 1 with specified frequency of 104.000 KHz; Default Pin for SpeckyBoard
Si.setPower(0, SIOUT_8mA); // Set power output level of clock 0
Si.setPower(2, SIOUT_8mA); // Set power output level of clock 1
Si.enable(0); // Enable output 0
Si.enable(2); // Enable output 1
// End Masterclock configuration
pinMode(HEARTBEAT_PIN, OUTPUT);
pinMode(LED_DI_PIN, OUTPUT);
pinMode(STROBE_PIN, OUTPUT);
pinMode(RESET_PIN, OUTPUT);
DELTA = 1024 / ROWS - BOOST; // Do not change this line. Adjust BOOST, defined above, to effect gain
int hb = 0;
for (int hb = 0; hb < 10; hb++)
{
toggle = !toggle;
digitalWrite(HEARTBEAT_PIN, toggle); // Flash Heartbeat LED rapidly; Si5351 clock passed initializiation!
delay(100);
}
int count = 0;
for (int i = 0; i < COLUMN; i++) //Sequentially number the leds
{
for (int j = 0; j < ROWS; j++)
{
colors[i][j].nled = count;
count++;
}
}
FastLED.addLeds<LEDTYPE, LED_DI_PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness( BRIGHTNESS );
rainbow_time = millis();
time_change = millis();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////-------------------- LOOP ----------------------////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop(){
if (SeialPrintMODE=1){
Serial.print(effect);
}
readMSGEQ7(); // Call to function that reads MSGEQ7 IC's via analogue inputs.
if (millis() - time_change > 30000) // Code that establishes how often to change effect. 1000 = 1 Second
{
// effect = 2; // Enable this line to set a fixed mode
effect++; // Enable this line to cycle through different modes
if (effect > 7)
{
effect = 0;
}
time_change = millis();
}
if (millis() - heartbeat > 3000) // Hearbeat LED to indicate that code has passed init and is actually looping through routines
{
toggle = !toggle;
digitalWrite(HEARTBEAT_PIN, toggle);
heartbeat = millis();
}
switch (effect) // Case logic to determine which color effect to use
{
case 0: // Full column; each band different color; color gradient within each band
rainbow_dot();
full_column();
updateHSV();
break;
case 1: // Full column; each band the same color; gradual simultaneous color change across all bands
if (millis() - rainbow_time > 15)
{
dynamic_rainbow();
rainbow_time = millis();
}
full_column();
updateHSV();
break;
case 2: // Full column; each band a different static rainbow color for the specified interval
if (millis() - rainbow_time > 600)
{
rainbow_column();
rainbow_time = millis();
}
full_column();
updateHSV();
break;
case 3: // Full column; all bands same static color
if (millis() - rainbow_time > 15)
{
total_color_hsv(255, 255, 255);
rainbow_time = millis();
}
full_column();
updateHSV();
break;
case 4: // Dot column; each column a different static rainbow color
if (millis() - rainbow_time > 15)
{
rainbow_dot();
rainbow_time = millis();
}
full_column_dot();
updateHSV();
break;
case 5: // Dot column; each band the same color; gradual simultaneous color change across all bands
if (millis() - rainbow_time > 15)
{
dynamic_rainbow();
rainbow_time = millis();
}
full_column_dot();
updateHSV();
break;
case 6: // Dot column; each band a different static rainbow color
if (millis() - rainbow_time > 15)
{
rainbow_column();
rainbow_time = millis();
}
full_column_dot();
updateHSV();
break;
case 7: // Dot column; all bands same static color
total_color_hsv(55, 255, 255);
full_column_dot();
updateHSV();
break;
}
delay(1); // Refresh rate; Values 20 thru 30 should look realistic
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////---------------- FUNCTIONS ---------------------////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void readMSGEQ7(void) // Function that reads the 7 bands of the audio input.
{
digitalWrite(RESET_PIN, HIGH);
digitalWrite(STROBE_PIN, HIGH); // Make sure Strobe line is low before entering loop. EZ NEM VOLT BENNE
delayMicroseconds(22); // MSGEQ7 MIN IDŐ 18uS
digitalWrite(STROBE_PIN, LOW); // Part 1 of Reset Pulse. Reset pulse duration must be 100nS minimum.
delayMicroseconds(22);
digitalWrite(RESET_PIN, LOW); // Part 2 of Reset pulse. These two events consume more than 100nS in CPU time.
digitalWrite(STROBE_PIN, HIGH);
delayMicroseconds(100);
for (int band = 0; band < COLUMN; band++) { // Loop that will increment counter that AnalogRead uses to determine which band to store data for.
digitalWrite(STROBE_PIN, LOW); // Re-Set Strobe to LOW on each iteration of loop.
delayMicroseconds(40); // MSGEQ KIMENET BEÁLLÁSÁNAK AZ IDEJE
MSGEQ_Bands[band] = analogRead(ANALOG_PIN1) - NOISECOMP; // Saves the reading of the amplitude voltage on Analog Pin 0.
band++;
MSGEQ_Bands[band] = analogRead(ANALOG_PIN2) - NOISECOMP; // Saves the reading of the amplitude voltage on Analog Pin 1.
digitalWrite(STROBE_PIN, HIGH);
}
}
void updateHSV(void)
{
for (int i = 0; i < COLUMN; i++) {
for (int j = 0; j < ROWS; j++) {
if (colors[i][j].active == 1) {
leds[colors[i][j].nled] = CHSV(colors[i][j].hue, colors[i][j].sat, colors[i][j].val);
} else {
leds[colors[i][j].nled] = CRGB::Black;
}
}
}
FastLED.show();
}
void full_column(void)
{
nlevel = 0;
for (int i = 0; i < COLUMN; i++) {
nlevel = MSGEQ_Bands[i] / DELTA;
for (int j = 0; j < ROWS; j++) {
if (j <= nlevel) {
colors[i][j].active = 1;
}
else {
colors[i][j].active = 0;
}
}
}
}
void full_column_dot(void)
{
nlevel = 0;
for (int i = 0; i < COLUMN; i++) {
nlevel = MSGEQ_Bands[i] / DELTA;
for (int j = 0; j < ROWS; j++) {
if (j == nlevel) {
colors[i][j].active = 1;
}
else {
colors[i][j].active = 0;
}
}
}
}
void total_color_hsv(int h, int s, int v)
{
for (int i = 0; i < COLUMN; i++) {
for (int j = 0; j < ROWS; j++) {
colors[i][j].hue = h;
colors[i][j].sat = s;
colors[i][j].val = v;
}
}
}
void rainbow_column(void)
{
//int n = 18;
for (int i = 0; i < COLUMN; i++) {
for (int j = 0; j < ROWS; j++) {
colors[i][j].hue = n;
colors[i][j].sat = 230;
colors[i][j].val = 240;
}
n += 18; //36 For 7 Columns
}
}
void rainbow_dot(void)
{
int n = 36;
for (int i = 0; i < COLUMN; i++) {
for (int j = 0; j < ROWS; j++) {
colors[i][j].hue = n;
colors[i][j].sat = 230;
colors[i][j].val = 240;
n += 5;
}
}
}
void dynamic_rainbow(void)
{
for (int i = 0; i < COLUMN; i++) {
for (int j = 0; j < ROWS; j++) {
colors[i][j].hue = hue_rainbow;
colors[i][j].sat = 230;
colors[i][j].val = 240;
}
}
hue_rainbow++;
}
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
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:
#include <FastLED.h>
#define LED_PIN 3
#define COLOR_ORDER GRB
#define CHIPSET WS2811
#define BRIGHTNESS 64
// Helper functions for an two-dimensional XY matrix of pixels.
// Simple 2-D demo code is included as well.
//
// XY(x,y) takes x and y coordinates and returns an LED index number,
// for use like this: leds[ XY(x,y) ] == CRGB::Red;
// No error checking is performed on the ranges of x and y.
//
// XYsafe(x,y) takes x and y coordinates and returns an LED index number,
// for use like this: leds[ XYsafe(x,y) ] == CRGB::Red;
// Error checking IS performed on the ranges of x and y, and an
// index of "-1" is returned. Special instructions below
// explain how to use this without having to do your own error
// checking every time you use this function.
// This is a slightly more advanced technique, and
// it REQUIRES SPECIAL ADDITIONAL setup, described below.
// Params for width and height
const uint8_t kMatrixWidth = 16;
const uint8_t kMatrixHeight = 16;
// Param for different pixel layouts
const bool kMatrixSerpentineLayout = true;
const bool kMatrixVertical = false;
// Set 'kMatrixSerpentineLayout' to false if your pixels are
// laid out all running the same way, like this:
//
// 0 > 1 > 2 > 3 > 4
// |
// .----<----<----<----'
// |
// 5 > 6 > 7 > 8 > 9
// |
// .----<----<----<----'
// |
// 10 > 11 > 12 > 13 > 14
// |
// .----<----<----<----'
// |
// 15 > 16 > 17 > 18 > 19
//
// Set 'kMatrixSerpentineLayout' to true if your pixels are
// laid out back-and-forth, like this:
//
// 0 > 1 > 2 > 3 > 4
// |
// |
// 9 < 8 < 7 < 6 < 5
// |
// |
// 10 > 11 > 12 > 13 > 14
// |
// |
// 19 < 18 < 17 < 16 < 15
//
// Bonus vocabulary word: anything that goes one way
// in one row, and then backwards in the next row, and so on
// is call "boustrophedon", meaning "as the ox plows."
// This function will return the right 'led index number' for
// a given set of X and Y coordinates on your matrix.
// IT DOES NOT CHECK THE COORDINATE BOUNDARIES.
// That's up to you. Don't pass it bogus values.
//
// Use the "XY" function like this:
//
// for( uint8_t x = 0; x < kMatrixWidth; x++) {
// for( uint8_t y = 0; y < kMatrixHeight; y++) {
//
// // Here's the x, y to 'led index' in action:
// leds[ XY( x, y) ] = CHSV( random8(), 255, 255);
//
// }
// }
//
//
uint16_t XY( uint8_t x, uint8_t y)
{
uint16_t i;
if( kMatrixSerpentineLayout == false) {
if (kMatrixVertical == false) {
i = (y * kMatrixWidth) + x;
} else {
i = kMatrixHeight * (kMatrixWidth - (x+1))+y;
}
}
if( kMatrixSerpentineLayout == true) {
if (kMatrixVertical == false) {
if( y & 0x01) {
// Odd rows run backwards
uint8_t reverseX = (kMatrixWidth - 1) - x;
i = (y * kMatrixWidth) + reverseX;
} else {
// Even rows run forwards
i = (y * kMatrixWidth) + x;
}
} else { // vertical positioning
if ( x & 0x01) {
i = kMatrixHeight * (kMatrixWidth - (x+1))+y;
} else {
i = kMatrixHeight * (kMatrixWidth - x) - (y+1);
}
}
}
return i;
}
// Once you've gotten the basics working (AND NOT UNTIL THEN!)
// here's a helpful technique that can be tricky to set up, but
// then helps you avoid the needs for sprinkling array-bound-checking
// throughout your code.
//
// It requires a careful attention to get it set up correctly, but
// can potentially make your code smaller and faster.
//
// Suppose you have an 8 x 5 matrix of 40 LEDs. Normally, you'd
// delcare your leds array like this:
// CRGB leds[40];
// But instead of that, declare an LED buffer with one extra pixel in
// it, "leds_plus_safety_pixel". Then declare "leds" as a pointer to
// that array, but starting with the 2nd element (id=1) of that array:
// CRGB leds_with_safety_pixel[41];
// CRGB* const leds( leds_plus_safety_pixel + 1);
// Then you use the "leds" array as you normally would.
// Now "leds[0..N]" are aliases for "leds_plus_safety_pixel[1..(N+1)]",
// AND leds[-1] is now a legitimate and safe alias for leds_plus_safety_pixel[0].
// leds_plus_safety_pixel[0] aka leds[-1] is now your "safety pixel".
//
// Now instead of using the XY function above, use the one below, "XYsafe".
//
// If the X and Y values are 'in bounds', this function will return an index
// into the visible led array, same as "XY" does.
// HOWEVER -- and this is the trick -- if the X or Y values
// are out of bounds, this function will return an index of -1.
// And since leds[-1] is actually just an alias for leds_plus_safety_pixel[0],
// it's a totally safe and legal place to access. And since the 'safety pixel'
// falls 'outside' the visible part of the LED array, anything you write
// there is hidden from view automatically.
// Thus, this line of code is totally safe, regardless of the actual size of
// your matrix:
// leds[ XYsafe( random8(), random8() ) ] = CHSV( random8(), 255, 255);
//
// The only catch here is that while this makes it safe to read from and
// write to 'any pixel', there's really only ONE 'safety pixel'. No matter
// what out-of-bounds coordinates you write to, you'll really be writing to
// that one safety pixel. And if you try to READ from the safety pixel,
// you'll read whatever was written there last, reglardless of what coordinates
// were supplied.
#define NUM_LEDS (kMatrixWidth * kMatrixHeight)
CRGB leds_plus_safety_pixel[ NUM_LEDS + 1];
CRGB* const leds( leds_plus_safety_pixel + 1);
uint16_t XYsafe( uint8_t x, uint8_t y)
{
if( x >= kMatrixWidth) return -1;
if( y >= kMatrixHeight) return -1;
return XY(x,y);
}
// Demo that USES "XY" follows code below
void loop()
{
uint32_t ms = millis();
int32_t yHueDelta32 = ((int32_t)cos16( ms * (27/1) ) * (350 / kMatrixWidth));
int32_t xHueDelta32 = ((int32_t)cos16( ms * (39/1) ) * (310 / kMatrixHeight));
DrawOneFrame( ms / 65536, yHueDelta32 / 32768, xHueDelta32 / 32768);
if( ms < 5000 ) {
FastLED.setBrightness( scale8( BRIGHTNESS, (ms * 256) / 5000));
} else {
FastLED.setBrightness(BRIGHTNESS);
}
FastLED.show();
}
void DrawOneFrame( uint8_t startHue8, int8_t yHueDelta8, int8_t xHueDelta8)
{
uint8_t lineStartHue = startHue8;
for( uint8_t y = 0; y < kMatrixHeight; y++) {
lineStartHue += yHueDelta8;
uint8_t pixelHue = lineStartHue;
for( uint8_t x = 0; x < kMatrixWidth; x++) {
pixelHue += xHueDelta8;
leds[ XY(x, y)] = CHSV( pixelHue, 255, 255);
}
}
}
void setup() {
FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
FastLED.setBrightness( BRIGHTNESS );
}
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.
Magyarra fordítva érdemes elfelejteni a 21. sávot..
Terveztetnem kell egy 20 oszlopos kiosztást is...
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
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...
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?
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.
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?
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...
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.
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...
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
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.
Köszönöm, minden infóra vevő vagyok!
É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.
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.
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
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.
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!!
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.
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...
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.
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!
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ó.
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.
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.
Érdekeség Egy kis off, pár mintaprogram led mátrixra!
|
|