Adding code the NeoPixel Mini VU Meter Learn Guide. Using a QT Py RP2040, PDM mic and strip of 16 neopixels
84 lines
2.3 KiB
Python
84 lines
2.3 KiB
Python
# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
import time
|
|
import array
|
|
import math
|
|
import board
|
|
import audiobusio
|
|
import simpleio
|
|
import neopixel
|
|
|
|
# neopixel setup
|
|
pixel_pin = board.A0
|
|
|
|
pixel_num = 16
|
|
|
|
pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.1, auto_write=False)
|
|
|
|
# function to average mic levels
|
|
def mean(values):
|
|
return sum(values) / len(values)
|
|
|
|
# function to return mic level
|
|
def normalized_rms(values):
|
|
minbuf = int(mean(values))
|
|
samples_sum = sum(
|
|
float(sample - minbuf) * (sample - minbuf)
|
|
for sample in values
|
|
)
|
|
|
|
return math.sqrt(samples_sum / len(values))
|
|
|
|
# mic setup
|
|
mic = audiobusio.PDMIn(board.TX,
|
|
board.A1, sample_rate=16000, bit_depth=16)
|
|
samples = array.array('H', [0] * 160)
|
|
|
|
# variable to hold previous mic level
|
|
last_input = 0
|
|
|
|
# neopixel colors
|
|
GREEN = (0, 127, 0)
|
|
RED = (127, 0, 0)
|
|
YELLOW = (127, 127, 0)
|
|
OFF = (0, 0, 0)
|
|
|
|
# array of colors for VU meter
|
|
colors = [GREEN, GREEN, GREEN, GREEN, GREEN, GREEN, GREEN, GREEN,
|
|
GREEN, YELLOW, YELLOW, YELLOW, YELLOW, YELLOW, RED, RED]
|
|
|
|
# begin with pixels off
|
|
pixels.fill(OFF)
|
|
pixels.show()
|
|
|
|
while True:
|
|
# take in audio
|
|
mic.record(samples, len(samples))
|
|
# magnitude holds the value of the mic level
|
|
magnitude = normalized_rms(samples)
|
|
# uncomment to see the levels in the REPL
|
|
# print((magnitude,))
|
|
|
|
# mapping the volume range (125-500) to the 16 neopixels
|
|
# volume range is optimized for music. you may want to adjust the range
|
|
# based on the type of audio that you're trying to show
|
|
mapped_value = simpleio.map_range(magnitude, 125, 500, 0, 16)
|
|
# converting the mapped range to an integer
|
|
input_val = int(mapped_value)
|
|
|
|
# if the mic input has changed from the last input value...
|
|
if last_input != input_val:
|
|
for i in range(input_val):
|
|
# if the level is lower...
|
|
if last_input > input_val:
|
|
for z in range(last_input):
|
|
# turn those pixels off
|
|
pixels[z] = (OFF)
|
|
# turn on pixels using the colors array
|
|
pixels[i] = (colors[i])
|
|
pixels.show()
|
|
# update last_input
|
|
last_input = input_val
|
|
|
|
time.sleep(0.01)
|