A wearable ornament that can respond to music (spectrograph mode) or dancing (shaker mode). Based on an Adafruit Circuit Playground Bluefruit
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. """
  2. Spectroshaker by The Dod:
  3. Adafruit CircuitPlayground Bluefruit dual-mode "bling"
  4. The RGB levels of neopixels around the circuit indicate:
  5. - Low/Mid/High sound levels (spectrogram mode)
  6. - X/Y/Z acceleration (shaker mode)
  7. Controls:
  8. slider switch: normal/standby mode
  9. button a: toggle between spectrogram/shaker mode
  10. button b: cycle between 4 brightness levels
  11. """
  12. import math
  13. import time
  14. from adafruit_circuitplayground import cp
  15. from teaandtechtime_fft import spectrogram
  16. NUM_PIXELS = 10
  17. # Like a clock, with connectors at 12 (USB) and 6 (power)
  18. LED_ANGLES = [
  19. i*math.pi/6.0
  20. for i in [11, 10, 9, 8, 7, 5, 4, 3, 2, 1]]
  21. minx = miny = minz = -5.0
  22. maxx = maxy = maxz = 5.0
  23. fft_size = 8 # power of 2
  24. samples = [0.0+0.0j]*fft_size
  25. MAX_2FREQ = 10.0 # After testing this a bit in the wild
  26. cp.pixels.brightness = 0.1
  27. MODE_SPECTRO = 1
  28. MODE_SHAKER = 2
  29. current_mode = MODE_SHAKER
  30. is_standby = cp.switch
  31. last_click = 0
  32. DEBOUNCE = 0.25
  33. def angles2level(led, val):
  34. led_angle = LED_ANGLES[led]
  35. val_angle = val * 2.0 * math.pi
  36. angle = led_angle - val_angle
  37. while angle > 2 * math.pi:
  38. angle -= 2*math.pi
  39. # the pow() makes sin() values sharper
  40. return int(255*pow(math.sin(angle/2), 4))
  41. while True:
  42. if time.monotonic() > last_click+DEBOUNCE:
  43. if is_standby != cp.switch:
  44. is_standby = cp.switch
  45. last_click = time.monotonic()
  46. if is_standby:
  47. for i in range(NUM_PIXELS):
  48. cp.pixels[i] = (0, 0, 0)
  49. if cp.button_a:
  50. last_click = time.monotonic()
  51. current_mode = (
  52. current_mode == MODE_SHAKER and MODE_SPECTRO
  53. or MODE_SHAKER)
  54. elif cp.button_b:
  55. last_click = time.monotonic()
  56. is_standby = False
  57. if cp.pixels.brightness >= 0.4:
  58. cp.pixels.brightness = 0.1
  59. else:
  60. cp.pixels.brightness += 0.1
  61. if not is_standby:
  62. samples.pop(0)
  63. samples.append(cp.sound_level+0.0j)
  64. x, y, z = cp.acceleration
  65. if x < minx:
  66. minx = x
  67. if y < miny:
  68. miny = y
  69. if z < minz:
  70. minz = z
  71. if x > maxx:
  72. maxx = x
  73. if y > maxy:
  74. maxy = y
  75. if z > maxz:
  76. maxz = z
  77. if current_mode == MODE_SHAKER: # accelerometer mode
  78. vals = (
  79. (x-minx)/(maxx-minx),
  80. (y-miny)/(maxy-miny),
  81. (z-minz)/(maxz-minz))
  82. else: # spectrogram mode
  83. raw_freqs = spectrogram(samples)
  84. pairs = [raw_freqs[i]+raw_freqs[i+1] for i in range(fft_size//2)]
  85. vals = [min(1.0, abs(x/MAX_2FREQ)) for x in pairs[:3]]
  86. for i in range(NUM_PIXELS):
  87. cp.pixels[i] = (
  88. angles2level(i, vals[0]),
  89. angles2level(i, vals[1]),
  90. angles2level(i, vals[2]))
  91. time.sleep(0.01)