Guest User

Non-dynamic ampli-tie

a guest
Feb 12th, 2017
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.42 KB | None | 0 0
  1. /*
  2. LED VU meter for Arduino and Adafruit NeoPixel LEDs.
  3.  
  4. Hardware requirements:
  5. - Most Arduino or Arduino-compatible boards (ATmega 328P or better).
  6. - Adafruit Electret Microphone Amplifier (ID: 1063)
  7. - Adafruit Flora RGB Smart Pixels (ID: 1260)
  8. OR
  9. - Adafruit NeoPixel Digital LED strip (ID: 1138)
  10. - Optional: battery for portable use (else power through USB or adapter)
  11. Software requirements:
  12. - Adafruit NeoPixel library
  13.  
  14. Connections:
  15. - 3.3V to mic amp +
  16. - GND to mic amp -
  17. - Analog pin to microphone output (configurable below)
  18. - Digital pin to LED data input (configurable below)
  19. See notes in setup() regarding 5V vs. 3.3V boards - there may be an
  20. extra connection to make and one line of code to enable or disable.
  21.  
  22. Written by Adafruit Industries. Distributed under the BSD license.
  23. This paragraph must be included in any redistribution.
  24.  
  25. fscale function:
  26. Floating Point Autoscale Function V0.1
  27. Written by Paul Badger 2007
  28. Modified from code by Greg Shakar
  29.  
  30. */
  31.  
  32. #include <Adafruit_NeoPixel.h>
  33. #include <math.h>
  34.  
  35. #define N_PIXELS 16 // Number of pixels in strand
  36. #define MIC_PIN A9 // Microphone is attached to this analog pin
  37. #define LED_PIN 6 // NeoPixel LED strand is connected to this pin
  38. #define SAMPLE_WINDOW 10 // Sample window for average level
  39. #define PEAK_HANG 24 //Time of pause before peak dot falls
  40. #define PEAK_FALL 4 //Rate of falling peak dot
  41. #define INPUT_FLOOR 10 //Lower range of analogRead input
  42. #define INPUT_CEILING 300 //Max range of analogRead input, the lower the value the more sensitive (1023 = max)
  43.  
  44.  
  45.  
  46. byte peak = 16; // Peak level of column; used for falling dots
  47. unsigned int sample;
  48.  
  49. byte dotCount = 0; //Frame counter for peak dot
  50. byte dotHangCount = 0; //Frame counter for holding peak dot
  51.  
  52. Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_PIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);
  53.  
  54. void setup()
  55. {
  56. // This is only needed on 5V Arduinos (Uno, Leonardo, etc.).
  57. // Connect 3.3V to mic AND TO AREF ON ARDUINO and enable this
  58. // line. Audio samples are 'cleaner' at 3.3V.
  59. // COMMENT OUT THIS LINE FOR 3.3V ARDUINOS (FLORA, ETC.):
  60. // analogReference(EXTERNAL);
  61.  
  62. // Serial.begin(9600);
  63. strip.begin();
  64. strip.show(); // Initialize all pixels to 'off'
  65.  
  66. }
  67.  
  68. void loop()
  69. {
  70. unsigned long startMillis= millis(); // Start of sample window
  71. float peakToPeak = 0; // peak-to-peak level
  72.  
  73. unsigned int signalMax = 0;
  74. unsigned int signalMin = 1023;
  75. unsigned int c, y;
  76.  
  77.  
  78. // collect data for length of sample window (in mS)
  79. while (millis() - startMillis < SAMPLE_WINDOW)
  80. {
  81. sample = analogRead(MIC_PIN);
  82. if (sample < 1024) // toss out spurious readings
  83. {
  84. if (sample > signalMax)
  85. {
  86. signalMax = sample; // save just the max levels
  87. }
  88. else if (sample < signalMin)
  89. {
  90. signalMin = sample; // save just the min levels
  91. }
  92. }
  93. }
  94. peakToPeak = signalMax - signalMin; // max - min = peak-peak amplitude
  95.  
  96. // Serial.println(peakToPeak);
  97.  
  98.  
  99. //Fill the strip with rainbow gradient
  100. for (int i=0;i<=strip.numPixels()-1;i++){
  101. strip.setPixelColor(i,Wheel(map(i,0,strip.numPixels()-1,30,150)));
  102. }
  103.  
  104.  
  105. //Scale the input logarithmically instead of linearly
  106. c = fscale(INPUT_FLOOR, INPUT_CEILING, strip.numPixels(), 0, peakToPeak, 2);
  107.  
  108.  
  109.  
  110.  
  111. if(c < peak) {
  112. peak = c; // Keep dot on top
  113. dotHangCount = 0; // make the dot hang before falling
  114. }
  115. if (c <= strip.numPixels()) { // Fill partial column with off pixels
  116. drawLine(strip.numPixels(), strip.numPixels()-c, strip.Color(0, 0, 0));
  117. }
  118.  
  119. // Set the peak dot to match the rainbow gradient
  120. y = strip.numPixels() - peak;
  121.  
  122. strip.setPixelColor(y-1,Wheel(map(y,0,strip.numPixels()-1,30,150)));
  123.  
  124. strip.show();
  125.  
  126. // Frame based peak dot animation
  127. if(dotHangCount > PEAK_HANG) { //Peak pause length
  128. if(++dotCount >= PEAK_FALL) { //Fall rate
  129. peak++;
  130. dotCount = 0;
  131. }
  132. }
  133. else {
  134. dotHangCount++;
  135. }
  136. }
  137.  
  138. //Used to draw a line between two points of a given color
  139. void drawLine(uint8_t from, uint8_t to, uint32_t c) {
  140. uint8_t fromTemp;
  141. if (from > to) {
  142. fromTemp = from;
  143. from = to;
  144. to = fromTemp;
  145. }
  146. for(int i=from; i<=to; i++){
  147. strip.setPixelColor(i, c);
  148. }
  149. }
  150.  
  151.  
  152. float fscale( float originalMin, float originalMax, float newBegin, float
  153. newEnd, float inputValue, float curve){
  154.  
  155. float OriginalRange = 0;
  156. float NewRange = 0;
  157. float zeroRefCurVal = 0;
  158. float normalizedCurVal = 0;
  159. float rangedValue = 0;
  160. boolean invFlag = 0;
  161.  
  162.  
  163. // condition curve parameter
  164. // limit range
  165.  
  166. if (curve > 10) curve = 10;
  167. if (curve < -10) curve = -10;
  168.  
  169. curve = (curve * -.1) ; // - invert and scale - this seems more intuitive - postive numbers give more weight to high end on output
  170. curve = pow(10, curve); // convert linear scale into lograthimic exponent for other pow function
  171.  
  172. /*
  173. Serial.println(curve * 100, DEC); // multply by 100 to preserve resolution
  174. Serial.println();
  175. */
  176.  
  177. // Check for out of range inputValues
  178. if (inputValue < originalMin) {
  179. inputValue = originalMin;
  180. }
  181. if (inputValue > originalMax) {
  182. inputValue = originalMax;
  183. }
  184.  
  185. // Zero Refference the values
  186. OriginalRange = originalMax - originalMin;
  187.  
  188. if (newEnd > newBegin){
  189. NewRange = newEnd - newBegin;
  190. }
  191. else
  192. {
  193. NewRange = newBegin - newEnd;
  194. invFlag = 1;
  195. }
  196.  
  197. zeroRefCurVal = inputValue - originalMin;
  198. normalizedCurVal = zeroRefCurVal / OriginalRange; // normalize to 0 - 1 float
  199.  
  200. // Check for originalMin > originalMax - the math for all other cases i.e. negative numbers seems to work out fine
  201. if (originalMin > originalMax ) {
  202. return 0;
  203. }
  204.  
  205. if (invFlag == 0){
  206. rangedValue = (pow(normalizedCurVal, curve) * NewRange) + newBegin;
  207.  
  208. }
  209. else // invert the ranges
  210. {
  211. rangedValue = newBegin - (pow(normalizedCurVal, curve) * NewRange);
  212. }
  213.  
  214. return rangedValue;
  215. }
  216.  
  217.  
  218. // Input a value 0 to 255 to get a color value.
  219. // The colours are a transition r - g - b - back to r.
  220. uint32_t Wheel(byte WheelPos) {
  221. if(WheelPos < 85) {
  222. return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  223. }
  224. else if(WheelPos < 170) {
  225. WheelPos -= 85;
  226. return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  227. }
  228. else {
  229. WheelPos -= 170;
  230. return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  231. }
  232. }
Advertisement
Add Comment
Please, Sign In to add comment