Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <FastLED.h>
- // --- Neopixel Matrix Settings ---
- #define LED_PIN 2 // Data pin for Neopixel matrix
- #define MATRIX_WIDTH 8
- #define MATRIX_HEIGHT 8
- #define NUM_LEDS (MATRIX_WIDTH * MATRIX_HEIGHT) // 64 LEDs for 8x8
- #define LED_TYPE WS2812B // Or WS2811, SK6812, etc.
- #define COLOR_ORDER GRB // Common for WS2812B
- #define BRIGHTNESS 64 // Set max brightness (0-255) - START LOW!
- CRGB leds[NUM_LEDS];
- // --- MSGEQ7 Settings ---
- #define MSGEQ7_ANALOG_PIN A1 // Analog input from MSGEQ7 'out'
- #define MSGEQ7_STROBE_PIN A3 // Digital output to MSGEQ7 'strobe'
- #define MSGEQ7_RESET_PIN A2 // Digital output to MSGEQ7 'reset'
- #define NUM_BANDS 7 // MSGEQ7 has 7 frequency bands
- int spectrumValue[NUM_BANDS]; // Raw values from MSGEQ7 (0-1023)
- int displayValue[MATRIX_WIDTH]; // Mapped values for display height (0-MATRIX_HEIGHT)
- // --- Noise Filtering & Scaling ---
- // Adjust these values based on your audio input level and noise floor
- const int NOISE_THRESHOLD = 60; // Ignore readings below this (adjust to filter noise) Orig 50
- const int MAX_EXPECTED_VALUE = 500; // Max expected reading (adjust for sensitivity) - rarely reaches 1023 Orig 800
- // --- Setup Function ---
- void setup() {
- Serial.begin(115200); // For debugging output
- Serial.println("MSGEQ7 Neopixel Spectrum Analyzer");
- // Configure MSGEQ7 control pins
- pinMode(MSGEQ7_ANALOG_PIN, INPUT);
- pinMode(MSGEQ7_STROBE_PIN, OUTPUT);
- pinMode(MSGEQ7_RESET_PIN, OUTPUT);
- // Initialize MSGEQ7 control pins
- digitalWrite(MSGEQ7_RESET_PIN, LOW);
- digitalWrite(MSGEQ7_STROBE_PIN, HIGH);
- // Initialize FastLED
- FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
- FastLED.setBrightness(BRIGHTNESS);
- FastLED.clear(); // Start with LEDs off
- FastLED.show();
- // Initial reset for MSGEQ7
- digitalWrite(MSGEQ7_RESET_PIN, HIGH);
- delayMicroseconds(1);
- digitalWrite(MSGEQ7_RESET_PIN, LOW);
- delayMicroseconds(75); // Wait for filter settling time
- }
- // --- Main Loop ---
- void loop() {
- readMSGEQ7();
- mapMSGEQ7ToDisplay();
- updateDisplay();
- FastLED.show();
- delay(10); // Small delay for stability / frame rate control
- }
- // --- Read values from MSGEQ7 ---
- void readMSGEQ7() {
- // Reset MSGEQ7 to start reading from the first band (63Hz)
- digitalWrite(MSGEQ7_RESET_PIN, HIGH);
- delayMicroseconds(1); // Reset pulse width
- digitalWrite(MSGEQ7_RESET_PIN, LOW);
- delayMicroseconds(75); // Wait for output settling time (tOS)
- // Read all 7 bands
- for (int i = 0; i < NUM_BANDS; i++) {
- digitalWrite(MSGEQ7_STROBE_PIN, LOW);
- delayMicroseconds(30); // Strobe pulse width (tWH) + Output settling time (tOS)
- spectrumValue[i] = analogRead(MSGEQ7_ANALOG_PIN);
- // Filter out noise - optional clamping
- if (spectrumValue[i] < NOISE_THRESHOLD) {
- spectrumValue[i] = 0;
- }
- // Optional: You might want to clamp the max value if your scaling assumes it
- // spectrumValue[i] = constrain(spectrumValue[i], 0, MAX_EXPECTED_VALUE);
- digitalWrite(MSGEQ7_STROBE_PIN, HIGH);
- delayMicroseconds(50); // Wait before next strobe (tSH)
- }
- // Optional: Print raw values for debugging/tuning
- for (int i = 0; i < NUM_BANDS; i++) {
- Serial.print(spectrumValue[i]);
- Serial.print(" ");
- }
- Serial.println();
- }
- // --- Map MSGEQ7 values to LED column heights ---
- void mapMSGEQ7ToDisplay() {
- for (int i = 0; i < NUM_BANDS; i++) {
- // Map the filtered value (0 to MAX_EXPECTED_VALUE) to the matrix height (0 to MATRIX_HEIGHT)
- // Using map() function: map(value, fromLow, fromHigh, toLow, toHigh)
- int mappedValue = map(spectrumValue[i], NOISE_THRESHOLD, MAX_EXPECTED_VALUE, 0, MATRIX_HEIGHT);
- // Constrain ensures the value doesn't exceed matrix height, especially if spectrumValue > MAX_EXPECTED_VALUE
- displayValue[i] = constrain(mappedValue, 0, MATRIX_HEIGHT);
- }
- // Handle the 8th column if needed (e.g., leave blank, mirror another column, average?)
- // Here, we'll just leave it blank (its value remains 0 if not explicitly set)
- if (MATRIX_WIDTH > NUM_BANDS) {
- displayValue[NUM_BANDS] = 0; // Explicitly clear the 8th column (index 7)
- }
- // Optional: Print mapped heights for debugging
- for(int i=0; i < MATRIX_WIDTH; i++) {
- Serial.print(displayValue[i]); Serial.print(" ");
- }
- Serial.println();
- }
- // --- Update the Neopixel Matrix Display ---
- void updateDisplay() {
- FastLED.clear(); // Clear the display buffer
- for (int x = 0; x < NUM_BANDS; x++) { // Iterate through the first 7 columns (bands)
- for (int y = 0; y < displayValue[x]; y++) { // Light up LEDs from bottom (y=0) up to the calculated height
- leds[XY(x, y)] = CRGB::Red; // Set the pixel to Red
- }
- }
- // The 8th column (x=7) remains off because displayValue[7] was set to 0 (or wasn't touched)
- }
- // --- XY Mapping Function (for Serpentine Layout) ---
- // Converts matrix coordinates (x, y) to a single LED index.
- // Assumes serpentine layout: starts top-left (0,0), goes right,
- // snakes back left on the next row, etc.
- // **ADJUST THIS FUNCTION IF YOUR MATRIX IS WIRED DIFFERENTLY**
- uint16_t XY(uint8_t x, uint8_t y) {
- uint16_t i;
- if (y % 2 == 0) {
- // Even rows (0, 2, 4, ...): left to right
- i = (y * MATRIX_WIDTH) + x;
- } else {
- // Odd rows (1, 3, 5, ...): right to left
- i = (y * MATRIX_WIDTH) + (MATRIX_WIDTH - 1 - x);
- }
- // Basic bounds check (optional but good practice)
- if (x >= MATRIX_WIDTH || y >= MATRIX_HEIGHT) {
- return NUM_LEDS; // Return an invalid index if out of bounds
- }
- return i;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement