Playground Express - LEDs amb FFT i Colors per Freqüència

Aquest codi en CircuitPython utilitza FFT per analitzar les freqüències de l'àudio captat pel micròfon i il·lumina els LEDs de la Playground Express amb diferents colors en funció de la freqüència i la intensitat.

import time
import array
import math
import audiobusio
import board
import neopixel
import adafruit_fft as fft

# Configura el micròfon i els LEDs
mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000, bit_depth=16)
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=0.5, auto_write=False)

# Configura paràmetres d'FFT
num_samples = 128
samples = array.array('H', [0] * num_samples)

# Funció per analitzar les bandes de freqüència i escollir colors
def color_from_frequency(magnitude, index):
    if index < 3:  # Baixes freqüències
        return (0, 0, int(magnitude))  # Blau
    elif index < 6:  # Mitjanes freqüències
        return (0, int(magnitude), 0)  # Verd
    else:  # Altes freqüències
        return (int(magnitude), 0, 0)  # Vermell

while True:
    # Llegeix una mostra d'àudio
    mic.record(samples, len(samples))

    # Aplica l'FFT a la mostra d'àudio
    magnitude = fft.rfft(samples)

    # Assigna colors als LEDs segons la banda de freqüència
    for i in range(10):
        if i < len(magnitude):
            scaled_magnitude = int(magnitude[i] / 500)  # Ajusta la intensitat
            pixels[i] = color_from_frequency(scaled_magnitude, i)
        else:
            pixels[i] = (0, 0, 0)  # Apaga LEDs si no hi ha dades

    pixels.show()
    time.sleep(0.05)

ARDUINO IDE


#include 
#include 

#define SAMPLES 64           // Nombre de mostres per a FFT (ha de ser potència de 2)
#define SAMPLING_FREQUENCY 1000 // Freqüència de mostreig (Hz)

arduinoFFT FFT = arduinoFFT();
unsigned int sampling_period_us;
double vReal[SAMPLES];
double vImag[SAMPLES];

void setup() {
  CircuitPlayground.begin();
  sampling_period_us = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
}

void loop() {
  // 1. Captura mostres d'àudio
  for (int i = 0; i < SAMPLES; i++) {
    unsigned long start_time = micros();
    vReal[i] = CircuitPlayground.mic.soundPressureLevel();
    vImag[i] = 0;
    while (micros() - start_time < sampling_period_us) {
      // Espera fins al següent mostreig
    }
  }

  // 2. Aplica FFT a les mostres d'àudio
  FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
  FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);

  // 3. Processa les bandes de freqüència i assigna colors als LEDs
  for (int i = 0; i < 10; i++) {
    double magnitude = vReal[i + 2];  // Salta les primeres bandes (soroll baix)
    int intensity = map(magnitude, 0, 200, 0, 255);  // Ajusta la intensitat

    // Assigna un color en funció de la banda de freqüència
    if (i < 3) {
      CircuitPlayground.setPixelColor(i, 0, 0, intensity);  // Baixes freqüències (Blau)
    } else if (i < 6) {
      CircuitPlayground.setPixelColor(i, 0, intensity, 0);  // Mitjanes freqüències (Verd)
    } else {
      CircuitPlayground.setPixelColor(i, intensity, 0, 0);  // Altes freqüències (Vermell)
    }
  }

  CircuitPlayground.showPixels();
  delay(50);  // Petita pausa per a una actualització suau
}