A wearable ornament that can respond to music (spectrograph mode) or dancing (shaker mode). Based on an Adafruit Circuit Playground Bluefruit
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. """
  2. Spectroshaker by The Dod:
  3. Adafruit CircuitPlayground Bluefruit dual-mode "bling"
  4. (selectable via the slider switch).
  5. The RGB levels of neopixels around the circuit indicate:
  6. - Low/Mid/High sound levels (spectrogram mode)
  7. - X/Y/Z acceleration (shaker mode)
  8. TO BE CONTINUED ...
  9. """
  10. import math
  11. import time
  12. from adafruit_circuitplayground import cp
  13. from teaandtechtime_fft import spectrogram
  14. NUM_PIXELS = 10
  15. # Like a clock, with connectors at 12 (USB) and 6 (power)
  16. LED_ANGLES = [
  17. i*math.pi/6.0
  18. for i in [11, 10, 9, 8, 7, 5, 4, 3, 2, 1]]
  19. minx = miny = minz = -5.0
  20. maxx = maxy = maxz = 5.0
  21. fft_size = 8 # power of 2
  22. samples = [0.0+0.0j]*fft_size
  23. MAX_2FREQ = 10.0 # After testing this a bit in the wild
  24. cp.pixels.brightness = 0.1
  25. def angles2level(led, val):
  26. led_angle = LED_ANGLES[led]
  27. val_angle = val * 2.0 * math.pi
  28. angle = led_angle - val_angle
  29. while angle>2*math.pi:
  30. angle -= 2*math.pi
  31. # the pow() makes sin() values sharper
  32. return int(255*pow(math.sin(angle/2), 4))
  33. while True:
  34. if cp.button_a:
  35. cp.pixels.brightness = max(0.05, cp.pixels.brightness*0.9)
  36. elif cp.button_b:
  37. cp.pixels.brightness = min(0.95, 1.0-(1.0-cp.pixels.brightness)*0.9)
  38. samples.pop(0)
  39. samples.append(cp.sound_level+0.0j)
  40. x, y, z = cp.acceleration
  41. if x<minx: minx = x
  42. if y<miny: miny = y
  43. if z<minz: minz = z
  44. if x>maxx: maxx = x
  45. if y>maxy: maxy = y
  46. if z>maxx: maxz = z
  47. if cp.switch: # accelerometer mode
  48. vals = (
  49. (x-minx)/(maxx-minx),
  50. (y-miny)/(maxy-miny),
  51. (z-minz)/(maxz-minz))
  52. else: # spectrogram mode
  53. raw_freqs = spectrogram(samples)
  54. pairs = [raw_freqs[i]+raw_freqs[i+1] for i in range(fft_size//2)]
  55. vals = [min(1.0, abs(x/MAX_2FREQ)) for x in pairs[:3]]
  56. for i in range(NUM_PIXELS):
  57. cp.pixels[i] = (
  58. angles2level(i, vals[0]),
  59. angles2level(i, vals[1]),
  60. angles2level(i, vals[2]))
  61. time.sleep(0.01)