{"id":857,"date":"2018-10-09T15:31:08","date_gmt":"2018-10-09T19:31:08","guid":{"rendered":"http:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/?p=857"},"modified":"2018-10-11T14:47:39","modified_gmt":"2018-10-11T18:47:39","slug":"final-documentation-william-schwartz","status":"publish","type":"post","link":"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wrschwartz\/final-documentation-william-schwartz\/","title":{"rendered":"Final Documentation: William Schwartz"},"content":{"rendered":"<h2>Overview:<\/h2>\n<p>Psycho (the name of the my project) was a super fun project to work on. Psycho is an Audio Visualizer. There is a teensy 3.2 in the back of the neck along with a microphone, the teensy preforms the FFT with the help of teensy&#8217;s audio library. the different frequency bins are then grouped according to base, mid, and treble, and those bins are then sent over to the lights, with the dB of each bin corresponding to the brightness, and the hue determined by a random value with in the range of the bin. This may seem a bit confusing but the way if works is that when the FFT is preformed, we then get 512 bins all with 40Hz of band per bin. This covers the full audio range of human hearing 20Hz to 20KHz. for this project only the frequency from 40Hz to 3.6 kHz are used, and the bands are defined as follows 1-6, 6-12, 13-20, 21-30, 31-40, 40-90, in terms of the &#8220;bins&#8221;. I then iterate though the bins in each band, and look for the bin with the highest amplitude, and the that amplitude gets mapped to the brightness, and the bin number gets mapped to the hue, with a small degree of randomness just to get a little more variance in the color.<\/p>\n<p>example videos of the head working \ud83d\ude42<\/p>\n<p><iframe loading=\"lazy\" width=\"1000\" height=\"750\" src=\"https:\/\/www.youtube.com\/embed\/JU8OloREU7E?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><\/p>\n<p><iframe loading=\"lazy\" width=\"1000\" height=\"750\" src=\"https:\/\/www.youtube.com\/embed\/N2PDXgPbCHg?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><\/p>\n<p><iframe loading=\"lazy\" width=\"1000\" height=\"750\" src=\"https:\/\/www.youtube.com\/embed\/dkp6ehzZVGI?feature=oembed\" frameborder=\"0\" allow=\"autoplay; encrypted-media\" allowfullscreen><\/iframe><\/p>\n<h2>BOM:<\/h2>\n<p><a href=\"https:\/\/www.adafruit.com\/product\/2756\">Teensy 3.2<\/a><\/p>\n<p><a href=\"https:\/\/www.amazon.com\/Panasonic-UR18650NSX-Rechargeable-BD-Electronics\/dp\/B07DTCQ94Y?crid=1EMFWIN4Z6M6U&amp;keywords=18650+3.7v+2600mah&amp;qid=1539111453&amp;sprefix=18650+3.7v+2600mah+battery%2Caps%2C165&amp;sr=8-55&amp;ref=sr_1_55\">Lithium ion battery<\/a>: 18650 2600 mAH or equivalent<\/p>\n<p><a href=\"https:\/\/www.amazon.com\/gp\/product\/B071RG4YWM\/ref=oh_aui_search_detailpage?ie=UTF8&amp;psc=1\">charge controller<\/a><\/p>\n<p><a href=\"https:\/\/www.amazon.com\/NOYITO-MAX9814-Electret-Microphone-Amplifier\/dp\/B07D551Y94?keywords=AGC+microphone&amp;qid=1539111730&amp;s=Electronics&amp;sr=1-1&amp;ref=sr_1_1\">microphone<\/a><\/p>\n<p>Natural PLA 3d printer filament (or any other clear filament that is easy to print)<\/p>\n<p><a href=\"https:\/\/www.amazon.com\/ALITOVE-WS2812B-Programmable-Addressable-Waterproof\/dp\/B018XAELE4?keywords=Neopixel+5v&amp;qid=1539111902&amp;sr=8-21&amp;ref=sr_1_21\">Neo-pixel lights<\/a><\/p>\n<p>Bypass capacitor (330 microF)<\/p>\n<p>On\/Off switch<\/p>\n<p>hot glue<\/p>\n<h2>3D printing:<\/h2>\n<p>here is a rendered photo of the head:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-858\" src=\"http:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/head_rendered.png\" alt=\"\" width=\"420\" height=\"495\" srcset=\"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/head_rendered.png 420w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/head_rendered-255x300.png 255w\" sizes=\"auto, (max-width: 420px) 100vw, 420px\" \/><\/p>\n<p>the STL file(s) for the head are hosted <a href=\"https:\/\/drive.google.com\/drive\/folders\/1VpWqnIurd8mwX1Ryg9nsTMSPrVmfJcd7?usp=sharing\">here<\/a><\/p>\n<p>all the parts were sliced in Cura with no infill, and no bottom layers<\/p>\n<p>the parts need to be positioned so that there are minimum overhands<\/p>\n<p>All of the electronics went into part #6, (in the folder linked above )<\/p>\n<h3>Wiring:<\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-863 size-large\" src=\"http:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/electronics-seated-in-head-3-768x1024.jpg\" alt=\"\" width=\"768\" height=\"1024\" srcset=\"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/electronics-seated-in-head-3-768x1024.jpg 768w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/electronics-seated-in-head-3-600x800.jpg 600w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/electronics-seated-in-head-3-630x840.jpg 630w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/electronics-seated-in-head-3-960x1280.jpg 960w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/electronics-seated-in-head-3-225x300.jpg 225w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/p>\n<p>the wiring is that, the battery was connected to the batter ports of the charge controller<\/p>\n<p>the + output of the charge controller had the switch connected to it, and the other end of the switch was connected to the + of the capacitor<\/p>\n<p>the &#8211; output of the charge controller was connected to the &#8211; terminal of the capacitor.<\/p>\n<p>the + of the capacitor was connected to the Vin of the Teensy, and the input of the Neo-Pixel<\/p>\n<p>the 3.3v pin (on the teensy) was connected to Vdd of the microphone<\/p>\n<p>the &#8211; terminal of the capacitor was connected to the ground of the teensy, the ground of the microphone, and the ground of the Neo-Pixel<\/p>\n<p>the data line of the Neo pixel was connected to pin 5 on the teensy<\/p>\n<p>the output of the mic was connected to A0 (pin 14) on the teensy<\/p>\n<p>3 lights were put into this back piece, and an Ethernet cord was cut to connect the wire the lights together in-between the pieces<\/p>\n<h3>Assembly:<\/h3>\n<p>a hot glue gun was used to melt holes between the parts to wire though, about a foot of wire was used between pieces to give so extra room for soldering. the parts were then hot glued together. this part took the longest, around 30 hours to assemble.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-663\" src=\"http:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/back-of-the-head-1.jpg\" alt=\"\" width=\"3024\" height=\"4032\" srcset=\"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/back-of-the-head-1.jpg 3024w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/back-of-the-head-1-600x800.jpg 600w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/back-of-the-head-1-768x1024.jpg 768w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/back-of-the-head-1-630x840.jpg 630w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/back-of-the-head-1-960x1280.jpg 960w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/back-of-the-head-1-225x300.jpg 225w\" sizes=\"auto, (max-width: 3024px) 100vw, 3024px\" \/> <img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-664\" src=\"http:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/all-red-1.jpg\" alt=\"\" width=\"3024\" height=\"4032\" srcset=\"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/all-red-1.jpg 3024w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/all-red-1-600x800.jpg 600w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/all-red-1-768x1024.jpg 768w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/all-red-1-630x840.jpg 630w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/all-red-1-960x1280.jpg 960w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/all-red-1-225x300.jpg 225w\" sizes=\"auto, (max-width: 3024px) 100vw, 3024px\" \/> <img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-666\" src=\"http:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/my_messy_desk-1.jpg\" alt=\"\" width=\"4032\" height=\"3024\" srcset=\"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/my_messy_desk-1.jpg 4032w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/my_messy_desk-1-800x600.jpg 800w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/my_messy_desk-1-768x576.jpg 768w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/my_messy_desk-1-1024x768.jpg 1024w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/my_messy_desk-1-400x300.jpg 400w\" sizes=\"auto, (max-width: 4032px) 100vw, 4032px\" \/><\/p>\n<h2>Programing:<\/h2>\n<p>I started with the teensy Audio library to perform the FFT, as well as the\u00a0Adafruit_NeoPixel library to control the lights.<\/p>\n<p>I used a separate function to convert the RGB input of the Neo-pixels to HSV so that it was more intuitive to set the color and brightness.<\/p>\n<p>&nbsp;<\/p>\n<p>the code is as follows:<\/p>\n<pre>#include &lt;Adafruit_NeoPixel.h&gt;\r\n#include &lt;Audio.h&gt;\r\n\/\/#include &lt;Wire.h&gt;\r\n\/\/#include &lt;SerialFlash.h&gt;\r\n#ifdef __AVR__\r\n\/\/ #include &lt;avr\/power.h&gt;\r\n#endif\r\n\r\nvoid setLedColorHSV(byte h, byte s, byte v);\r\n\r\n\/\/ Create the Audio components. These should be created in the\r\n\/\/ order data flows, inputs\/sources -&gt; processing -&gt; outputs\r\n\/\/\r\nAudioInputAnalog adc1(A0); \/\/ ADC0 input\r\nAudioAnalyzeFFT1024 myFFT;\r\n\r\n\/\/ Connect either the live input or synthesized sine wave\r\nAudioConnection patchCord1(adc1, 0, myFFT, 0);\r\n\r\n\/\/ Which pin on the Arduino is connected to the NeoPixels?\r\n\/\/ On a Trinket or Gemma we suggest changing this to 1\r\n#define PIN 5\r\nconst int POWER_LED_PIN = 13; \/\/ Output pin for power LED (pin 13 to use Teensy 3.0's onboard LED).\r\nbyte h;\r\nbyte s;\r\nbyte v;\r\nbyte RedLight;\r\nbyte GreenLight;\r\nbyte BlueLight;\r\nint currentlight;\r\n\r\nfloat avg_fft[512]; \r\nint avg_fft_cout = 1;\r\n\r\n#define NUMPIXELS 41\r\n#define NUMCELLS 25\r\nint cells[NUMCELLS] = {3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, 3, 4, 3, 2};\r\n\r\n\/\/ ----------- ALL THE DIFFERENT MAPPINGS THAT I HAVE MADE!!! ---------------------------------------\r\n\/\/ even maping base at the neck\r\nint mapping[NUMCELLS] = {0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0};\r\n\/\/ random mapping\r\n\/\/int mapping[NUMCELLS] = {0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0};\r\n\/\/ random mapping base at the left ear\r\n\/\/int mapping[NUMCELLS] = {0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 5, 5, 5};\r\n\/\/ random mapping base in the neck\r\n\/\/int mapping[NUMCELLS] = {0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 0, 5, 5, 5, 5, 1, 2, 3};\r\n\r\n\/\/ --------------------------------------------------\r\n\r\n\r\n#define freq_bands 6\r\n\r\n\/\/ defines the frequency ranges for each band \r\nint freq_high[freq_bands] = {90, 40, 30, 20, 12, 6};\r\nint freq_low[freq_bands] = {40, 31, 21, 13, 6, 1};\r\n\r\n\/\/ stores the results of going through each band\r\nint freq_max_bin[freq_bands] = {};\r\nfloat freq_max_amp[freq_bands] = {};\r\nfloat prev_freq_max_amp[freq_bands] = {};\r\nbyte freq_hue[freq_bands] = {};\r\nbyte prev_freq_hue[freq_bands] = {};\r\n\r\n\r\n\/\/ When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.\r\n\/\/ Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest\r\n\/\/ example for more information on possible values.\r\nAdafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);\r\n\r\nvoid setup() {\r\n\/\/ Turn on the power indicator LED.\r\npinMode(POWER_LED_PIN, OUTPUT);\r\ndigitalWrite(POWER_LED_PIN, HIGH);\r\nrandomSeed(10);\r\n\r\npixels.begin(); \/\/ This initializes the NeoPixel library.\r\n\/\/ Audio connections require memory to work. For more\r\n\/\/ detailed information, see the MemoryAndCpuUsage example\r\nAudioMemory(12);\r\n\r\n\/\/ Configure the window algorithm to use\r\nmyFFT.windowFunction(AudioWindowHanning1024);\r\n\/\/myFFT.windowFunction(NULL);\r\n}\r\n\r\nvoid loop() {\r\nfloat n;\r\nint i;\r\nint fft_count = 0;\r\n\r\ndelay(10);\r\n\r\n\/\/ ________________________________________________________ \r\n\/\/ copy initial sample\r\nif (myFFT.available()) {\r\nfor (i = 0; i &lt; 512; i++) {\r\navg_fft[i] = myFFT.read(i);\r\n}\r\n\/\/ averge other samples\r\nwhile (fft_count &lt; avg_fft_cout) {\r\nif (myFFT.available()) {\r\nfor (i = 0; i &lt; 512; i++) {\r\navg_fft[i] = (avg_fft[i] + myFFT.read(i))\/2.0;\r\n}\r\nfft_count++;\r\n}\r\n}\r\n}\r\n\/\/ ________________________________________________________\r\n\r\nint f; \/\/ used as intex for band we are in\r\nint bin = 0; \/\/ hold on to the current bin\r\n\r\nfor (f = 0; f &lt; freq_bands; f++) {\r\n\r\nfreq_max_amp[f] = 0;\r\nbin = 0;\r\n\r\nfor (i=freq_high[f]; i &gt; freq_low[f]; i--) {\r\nn = avg_fft[i];\r\nif ( n &gt; 0.01) {\r\nfreq_max_amp[f] = max(freq_max_amp[f], n);\r\n\/\/ recently added might make things worse? we will see...\r\n\/\/if (freq_max_amp[f] == n) {\r\nbin = i;\r\n\/\/}\r\n}\r\n}\r\n\r\nif (bin != 0 &amp;&amp; bin != freq_max_bin[f]){\r\nfreq_max_bin[f] = bin;\r\n\/\/ TODO: the bins are off!! bin 5 should be RED!! currently bin 0 is red\r\nfreq_hue[f] = 252 - ((f+1%6)*42 + random((freq_max_bin[f]-freq_low[f])*(42\/(freq_high[f]-freq_low[f]))));\r\n\r\n}\r\n\r\nif (freq_max_amp[f] == 0){\r\nfreq_max_bin[f] = 0;\r\n}\r\n\r\n\/\/ set the hue to the bin hue\r\nif (freq_max_bin[f] != 0){\r\nSerial.println();\r\nSerial.print(\"BAND \");\r\nSerial.print(f);\r\nSerial.print(\" amplitude is \");\r\nSerial.print(freq_max_amp[f], 20);\r\nSerial.print(\"the bin is \");\r\nSerial.print(freq_max_bin[f]);\r\n}\r\n}\r\n\r\n\/\/ PUSH ALL THE DATA TO THE LIGHTS!!!\r\n\/\/ ________________________________________________________ \r\ncurrentlight = 0;\r\nfor(int i=0;i&lt;NUMCELLS;i++) {\r\n\r\nh = freq_hue[mapping[i]];\r\nif (h != 0 &amp;&amp; prev_freq_hue[mapping[i]] != 0) {\r\nh = (h - prev_freq_hue[mapping[i]])\/3 + prev_freq_hue[mapping[i]];\r\n}\r\nprev_freq_hue[mapping[i]] = h;\r\n\r\ns = 255;\r\nif (freq_max_amp[mapping[i]] != 0.0){\r\n\/\/ v = (int)(freq_max_amp[mapping[i]]*1000.0);\r\nv = (int)(freq_max_amp[mapping[i]]*1000.0);\r\nv = (int) abs(v - prev_freq_max_amp[mapping[i]])\/2 + prev_freq_max_amp[mapping[i]];\r\n\r\nprev_freq_max_amp[mapping[i]] = v\/1.1-1;\r\n} else {\r\n\/\/v = ((int)(prev_freq_max_amp[mapping[i]]*1000.0))\/2-1;\r\nv = prev_freq_max_amp[mapping[i]];\r\nprev_freq_max_amp[mapping[i]] = (int) prev_freq_max_amp[mapping[i]]\/1.1-1;\r\n}\r\nsetLedColorHSV(h,s,v);\r\nfor (int j=0;j&lt;cells[i];j++) {\r\n\/\/ pixels.Color takes RGB values, from 0,0,0 up to 255,255,255\r\npixels.setPixelColor(currentlight, pixels.Color(RedLight, GreenLight, BlueLight));\r\ncurrentlight = currentlight + 1;\r\n}\r\n}\r\nfor (int f=0; f &lt; freq_bands; f++){\r\nif (freq_max_bin[f] != 0){\r\nSerial.println();\r\nSerial.print(\"THIS IS THE LIGHT DATA!!, band is \");\r\nSerial.print(f);\r\nSerial.print(\" hue is \");\r\nSerial.print(freq_max_amp[f], 20);\r\nSerial.print(\"the bin is \");\r\nSerial.print(freq_max_bin[f]);\r\n}\r\n}\r\n\r\npixels.show(); \/\/ This sends the updated pixel color to the hardware.\r\n\/\/ ________________________________________________________\r\n\r\n\r\n}\r\n\r\nvoid setLedColorHSV(byte h, byte s, byte v) {\r\n\/\/ this is the algorithm to convert from RGB to HSV\r\nh = (h * 192) \/ 256; \/\/ 0..191\r\nunsigned int i = h \/ 32; \/\/ We want a value of 0 thru 5\r\nunsigned int f = (h % 32) * 8; \/\/ 'fractional' part of 'i' 0..248 in jumps\r\n\r\nunsigned int sInv = 255 - s; \/\/ 0 -&gt; 0xff, 0xff -&gt; 0\r\nunsigned int fInv = 255 - f; \/\/ 0 -&gt; 0xff, 0xff -&gt; 0\r\nbyte pv = v * sInv \/ 256; \/\/ pv will be in range 0 - 255\r\nbyte qv = v * (256 - s * f \/ 256) \/ 256;\r\nbyte tv = v * (256 - s * fInv \/ 256) \/ 256;\r\n\r\nswitch (i) {\r\ncase 0:\r\nRedLight = v;\r\nGreenLight = tv;\r\nBlueLight = pv;\r\nbreak;\r\ncase 1:\r\nRedLight = qv;\r\nGreenLight = v;\r\nBlueLight = pv;\r\nbreak;\r\ncase 2:\r\nRedLight = pv;\r\nGreenLight = v;\r\nBlueLight = tv;\r\nbreak;\r\ncase 3:\r\nRedLight = pv;\r\nGreenLight = qv;\r\nBlueLight = v;\r\nbreak;\r\ncase 4:\r\nRedLight = tv;\r\nGreenLight = pv;\r\nBlueLight = v;\r\nbreak;\r\ncase 5:\r\nRedLight = v;\r\nGreenLight = pv;\r\nBlueLight = qv;\r\nbreak;\r\n}\r\n}<\/pre>\n<h2>Design Iterations:<\/h2>\n<h4>I started with an initial test to see how the 3D printed parts would work to defuse the light<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-465\" src=\"http:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/09\/55898274358__4E32A666-49B7-4777-9C89-03A5400FBB89-2.jpg\" alt=\"\" width=\"3024\" height=\"4032\" srcset=\"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/09\/55898274358__4E32A666-49B7-4777-9C89-03A5400FBB89-2.jpg 3024w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/09\/55898274358__4E32A666-49B7-4777-9C89-03A5400FBB89-2-600x800.jpg 600w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/09\/55898274358__4E32A666-49B7-4777-9C89-03A5400FBB89-2-768x1024.jpg 768w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/09\/55898274358__4E32A666-49B7-4777-9C89-03A5400FBB89-2-630x840.jpg 630w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/09\/55898274358__4E32A666-49B7-4777-9C89-03A5400FBB89-2-960x1280.jpg 960w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/09\/55898274358__4E32A666-49B7-4777-9C89-03A5400FBB89-2-225x300.jpg 225w\" sizes=\"auto, (max-width: 3024px) 100vw, 3024px\" \/><\/p>\n<p>this was a success, for this test I used 2 neo-pixles, and and the Bottom front two pieces of the neck.<\/p>\n<h4>Next I tested out preforming the FFT:<\/h4>\n<p>for this iteration I did not use the teensy Audio library, and so the FFT was not as good, the lower frequencies were too sensitive. And I believe the mic was always picking up the DC offset of the microphone, for this part I only have a picture showing the different frequency bins, as a test.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-542\" src=\"http:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/09\/55949502041__3D69CCA8-01D8-45B0-B2F2-E5F33B18D3BC-1.jpg\" alt=\"\" width=\"4032\" height=\"3024\" srcset=\"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/09\/55949502041__3D69CCA8-01D8-45B0-B2F2-E5F33B18D3BC-1.jpg 4032w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/09\/55949502041__3D69CCA8-01D8-45B0-B2F2-E5F33B18D3BC-1-800x600.jpg 800w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/09\/55949502041__3D69CCA8-01D8-45B0-B2F2-E5F33B18D3BC-1-768x576.jpg 768w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/09\/55949502041__3D69CCA8-01D8-45B0-B2F2-E5F33B18D3BC-1-1024x768.jpg 1024w, https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/09\/55949502041__3D69CCA8-01D8-45B0-B2F2-E5F33B18D3BC-1-400x300.jpg 400w\" sizes=\"auto, (max-width: 4032px) 100vw, 4032px\" \/><\/p>\n<p>with these two tests complete, and some nice results I felt like I was ready to start assembling the head after all the pieces were printed<\/p>\n<p>images of the assembly are above ^<\/p>\n<p>&nbsp;<\/p>\n<h4>after everything was put together it was time to get the teensy to work:<\/h4>\n<p>there were a lot of iterations in the Code<\/p>\n<p>1 first I just had a script going through and randomly assigning colors to all the lights in the head<\/p>\n<p>then I started playing with the teensy Audio library, which is an amazingly powerful library for audio processing. I found the FFT example, and ran with it.<\/p>\n<p>the documentation was a little limited from what I found online, what was best was going directly into the source files, and from there the code is well documented, and I was able to figure everything out.<\/p>\n<h4>In the lab:<\/h4>\n<p>I found some contradictory information online, the ADC input for the audio library was stated online to require a DC bias of .6 and a max voltage of 1.2 and a min voltage of 0. So I tested this on the board by brining it in to the ECE lab.<\/p>\n<p>I used the function generator and attached it to the analog input that I was using, I try initially with a 10kHz wave of 1.2 V peak-peak, and ran my script, I then tested with a 3.3 V peak-peak and 1.25v offset, and found that the ADC was able to digitize the whole waveform from 0 to 3.3V which is what I expected from the beginning.<\/p>\n<p>with those tests done, I also tests the microphone in different settings, playing with the gain, and the Attack\/Release ratio (not quite sure what it is but it has settings). and found that the default setting gave me the best results.<\/p>\n<h4>bands:<\/h4>\n<p>now that all that nonsense was out of the way, started dividing up the frequency bins in the code<\/p>\n<p>initially I had 6 bins from 40Hz to 20kHz but quickly found that there was not much being picked up at the higher frequencies.<\/p>\n<p>I had by bands divided according to this guide for sound:<\/p>\n<p><a href=\"https:\/\/www.teachmeaudio.com\/mixing\/techniques\/audio-spectrum\/\">https:\/\/www.teachmeaudio.com\/mixing\/techniques\/audio-spectrum\/<\/a><\/p>\n<table>\n<tbody>\n<tr>\n<th>Frequency Range<\/th>\n<th>Frequency Values<\/th>\n<\/tr>\n<tr>\n<td>Sub-bass<\/td>\n<td>20 to 60 Hz<\/td>\n<\/tr>\n<tr>\n<td>Bass<\/td>\n<td>60 to 250 Hz<\/td>\n<\/tr>\n<tr>\n<td>Low midrange<\/td>\n<td>250 to 500 Hz<\/td>\n<\/tr>\n<tr>\n<td>Midrange<\/td>\n<td>500 Hz to 2 kHz<\/td>\n<\/tr>\n<tr>\n<td>Upper midrange<\/td>\n<td>2 to 4 kHz<\/td>\n<\/tr>\n<tr>\n<td>Presence<\/td>\n<td>4 to 6 kHz<\/td>\n<\/tr>\n<tr>\n<td>Brilliance<\/td>\n<td>6 to 20 kHz<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>but I was getting very little presence and brilliance so I scaled all by bands down to make it look better.<\/p>\n<p>and ended up going from 40 Hz to about 3.5KHz and got some good results<\/p>\n<h4>averaging:<\/h4>\n<p>I was trying to average multiple FFT together to try to get rid of some noise, but what I found was that I forgot to check if I was getting the new sample before I was averaging it in, so what this equated to was wasted CPU time that was just sort of a delay, but it looked nice.<\/p>\n<p>So I fixed the code and then I found that by doing this, the lights were flickering a lot, and I tried to apply a moving average to all the samples, but still wasn&#8217;t giving the results that I wanted, so eventually I gave up and put back in the delay. this is something that I plan on fixing in the future, because I want the head to me more responsive to the audio coming it and be able to fade appropriately, I think that is the one thing really missing from the project.<\/p>\n<h4>light layout:<\/h4>\n<p>I played around a bit with the light layout, at first I just mapped all the lights to the different bins in order from 0-5 and repeating till the end of the cells. It gave a pretty nice look, but I like the base, so I decided to make half of the face just dedicated to the base, and then I was happy with the results and think that it looks really cool. So the left half of the face glows red with the base.<\/p>\n<h4>Music:<\/h4>\n<p>finally what was left was to find the songs that I thought make the head look best, for this I recruited my roommate Steve (he has some nice speakers) and we sat in his room listening to music and watching how the head responds. Great experience would recommend<\/p>\n<h4>Future improvements:<\/h4>\n<p>better attempt at the moving average<\/p>\n<p>re-ordering the lights<\/p>\n<p>dividing up the frequency bands a bit better<\/p>\n<p>making more heads<\/p>\n<p>adding the entire process to my GitHub.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Overview: Psycho (the name of the my project) was a super fun project to work on. Psycho is an Audio Visualizer. There is a teensy 3.2 in the back of the neck along with a microphone, the teensy preforms the FFT with the help of teensy&#8217;s audio library. the different frequency bins are then grouped&#8230; <\/p>\n<div class=\"link-more\"><a href=\"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wrschwartz\/final-documentation-william-schwartz\/\">Read More<\/a><\/div>\n","protected":false},"author":87,"featured_media":661,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"cybocfi_hide_featured_image":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-857","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"jetpack_featured_media_url":"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-content\/uploads\/sites\/7\/2018\/10\/almost_all_lite_up.jpg","_links":{"self":[{"href":"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-json\/wp\/v2\/posts\/857","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-json\/wp\/v2\/users\/87"}],"replies":[{"embeddable":true,"href":"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-json\/wp\/v2\/comments?post=857"}],"version-history":[{"count":8,"href":"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-json\/wp\/v2\/posts\/857\/revisions"}],"predecessor-version":[{"id":930,"href":"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-json\/wp\/v2\/posts\/857\/revisions\/930"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-json\/wp\/v2\/media\/661"}],"wp:attachment":[{"href":"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-json\/wp\/v2\/media?parent=857"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-json\/wp\/v2\/categories?post=857"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.joshuarosenstock.com\/teaching\/lightart-a18\/wp-json\/wp\/v2\/tags?post=857"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}