{"id":1161,"date":"2012-06-08T06:48:19","date_gmt":"2012-06-08T11:48:19","guid":{"rendered":"http:\/\/nootropicdesign.com\/projectlab\/?p=1161"},"modified":"2018-11-02T08:58:37","modified_gmt":"2018-11-02T13:58:37","slug":"tabasco-lamp","status":"publish","type":"post","link":"https:\/\/nootropicdesign.com\/projectlab\/2012\/06\/08\/tabasco-lamp\/","title":{"rendered":"Tabasco Bottle LED Mood Lamp"},"content":{"rendered":"<p>I love Tabasco and always though that their cute little miniature bottles could be the basis for a great specialty lamp.  I was very happy to find that a 3mm LED fits perfectly in the bottle opening of the miniature bottles.  By designing a custom circuit board I was able to make a lamp that looks like a bundle of dried peppers.<\/p>\n<p><a href=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_both.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_both_sm.jpg\" alt=\"\" title=\"tabascoLamp_both_sm\" width=\"640\" height=\"480\" class=\"alignleft size-full wp-image-1232\" srcset=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_both_sm.jpg 640w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_both_sm-300x225.jpg 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><br \/>\n<br clear=\"all\"\/><br \/>\nEach bottle is individually controlled with a TLC5940 16-channel PWM driver.  The software running on the ATmega328 is Arduino code that implements different lighting effects.  Here it is in action:<\/p>\n<p><iframe loading=\"lazy\" width=\"640\" height=\"480\" src=\"https:\/\/www.youtube.com\/embed\/euULP0kJSsw\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n<h3>Hardware<\/h3>\n<p>I designed a circuit board for the ATmega328 and the TLC5940.  This is basically a custom Arduino and the design files are available below in case you want to make one.  The LEDs connect from the bottom of the board.  I am using a 5V regulated power supply, so there&#8217;s no need for an on-board voltage regulator.  I included a 6-pin serial header for easy Arduino programming and mounting holes on the corners so I can hang it from wires.  I also included a tactile button in case I wanted to allow some input to control the lamp (currently unused).  Also note the Tabasco logo right on the board silkscreen!<\/p>\n<p><a href=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_board.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_board_sm.jpg\" alt=\"\" title=\"tabascoLamp_board_sm\" width=\"640\" height=\"480\" class=\"alignleft size-full wp-image-1198\" srcset=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_board_sm.jpg 640w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_board_sm-300x225.jpg 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><br \/>\n<br clear=\"all\"\/><br \/>\nI photographed the assembly process so you could see how I constructed the lamp.<\/p>\n<table>\n<tr>\n<td valign=\"top\"><a href=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step01.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step01_sm.jpg\" alt=\"\" title=\"tabascoLamp_step01_sm\" width=\"320\" height=\"240\" class=\"alignleft size-full wp-image-1163\" srcset=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step01_sm.jpg 320w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step01_sm-300x225.jpg 300w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><br \/>1. Make two holes in each cap using a small nail<\/td>\n<td valign=\"top\"><a href=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step02.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step02_sm.jpg\" alt=\"\" title=\"tabascoLamp_step02_sm\" width=\"320\" height=\"240\" class=\"alignleft size-full wp-image-1165\" srcset=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step02_sm.jpg 320w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step02_sm-300x225.jpg 300w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><br \/>2. Insert a 3mm LED into the cap<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\"><a href=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step03.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step03_sm.jpg\" alt=\"\" title=\"tabascoLamp_step03_sm\" width=\"320\" height=\"240\" class=\"alignleft size-full wp-image-1167\" srcset=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step03_sm.jpg 320w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step03_sm-300x225.jpg 300w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><br \/>3. Ensure the LED is in the center<\/td>\n<td valign=\"top\"><a href=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step04.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step04_sm.jpg\" alt=\"\" title=\"tabascoLamp_step04_sm\" width=\"320\" height=\"240\" class=\"alignleft size-full wp-image-1169\" srcset=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step04_sm.jpg 320w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step04_sm-300x225.jpg 300w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><br \/>4. Connect wires by bending the leads.  Make sure they don&#8217;t short!<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\"><a href=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step05.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step05_sm.jpg\" alt=\"\" title=\"tabascoLamp_step05_sm\" width=\"320\" height=\"240\" class=\"alignleft size-full wp-image-1182\" srcset=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step05_sm.jpg 320w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step05_sm-300x225.jpg 300w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><br \/>5. Carefully solder and clip the leads.<\/td>\n<td valign=\"top\"><a href=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step06.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step06_sm.jpg\" alt=\"\" title=\"tabascoLamp_step06_sm\" width=\"320\" height=\"240\" class=\"alignleft size-full wp-image-1184\" srcset=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step06_sm.jpg 320w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step06_sm-300x225.jpg 300w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><br \/>6. Enclose in heat shrink tubing.<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\"><a href=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step07.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step07_sm.jpg\" alt=\"\" title=\"tabascoLamp_step07_sm\" width=\"320\" height=\"240\" class=\"alignleft size-full wp-image-1186\" srcset=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step07_sm.jpg 320w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step07_sm-300x225.jpg 300w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><br \/>7. Twist wires and weave together.<\/td>\n<td valign=\"top\"><a href=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step08.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step08_sm.jpg\" alt=\"\" title=\"tabascoLamp_step08_sm\" width=\"320\" height=\"240\" class=\"alignleft size-full wp-image-1188\" srcset=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step08_sm.jpg 320w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step08_sm-300x225.jpg 300w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><br \/>8. Keep going!<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\"><a href=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step09.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step09_sm.jpg\" alt=\"\" title=\"tabascoLamp_step09_sm\" width=\"320\" height=\"240\" class=\"alignleft size-full wp-image-1190\" srcset=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step09_sm.jpg 320w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step09_sm-300x225.jpg 300w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><br \/>9. Insert wires into underside of board.<\/td>\n<td valign=\"top\"><a href=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step10.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step10_sm.jpg\" alt=\"\" title=\"tabascoLamp_step10_sm\" width=\"320\" height=\"240\" class=\"alignleft size-full wp-image-1192\" srcset=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step10_sm.jpg 320w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_step10_sm-300x225.jpg 300w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><\/a><br \/>10. Now just solder and clip the wires.<\/td>\n<\/tr>\n<\/table>\n<p><br clear=\"all\"\/><\/p>\n<h3>Software<\/h3>\n<p>Here is the Arduino code running on the lamp.  I used the <a href=\"http:\/\/code.google.com\/p\/tlc5940arduino\/\">TLC5940 Arduino library<\/a> to control the PWM driver.  You can <a href=\"https:\/\/nootropicdesign.com\/projectlab\/downloads\/TabascoLamp.zip\">download the code from here<\/a>.<\/p>\n<pre class=\"codeblockscroll\">\r\n#include \"Tlc5940.h\"\r\n\r\n#define NPINS 16\r\n#define NVISUALIZATIONS 6\r\n#define NFUNCTIONS 3\r\n#define BUTTON 2\r\n\r\n\/\/ pointers to the current and last visualizations                                    \r\nvoid (*visualization)() = rise;\r\nvoid (*lastVisualization)() = rise;\r\n\r\n\/\/ array of visualizations                                                            \r\nvoid (*visualizations[NVISUALIZATIONS])() = {throb, blinkRandom, onOff, upDown, rise, fall};                        \r\n\r\n\/\/ An array of all the functions.                                                     \r\nint (*allFunctions[NFUNCTIONS])(float x) = {linear, sine, exponential};\r\n\r\n\r\n\/\/ Each pin has a function associated with it.  The function determines how the brightness                                                                                 \r\n\/\/ of the LED changes over time.                                                      \r\nint (*function[NPINS])(float x);\r\n\r\n\/\/ The x values for the function associated with each LED.  The x value is the current position along                                                                      \r\n\/\/ the x axis for the function.  There are are 256 x values on the x axis.  That is, the domain of the                                                                     \r\n\/\/ function is [0-255].                                                               \r\nfloat x[NPINS];\r\n\r\n\/\/ dx describes (for each LED) how the x value changes over time.  If dx=1, then x is increased by 1                                                                       \r\n\/\/ for each duty cycle.  If dx = -1, it is decreased by 1.  If dx=5, then the brightness of the LED will                                                                   \r\n\/\/ change faster according to the function because we are moving along the function curve faster.                                                                          \r\nfloat dx[NPINS];\r\n\r\n\/\/ y is the current value of the function at x.  If the function is 'linear' and x=128, then y=128.                                                                        \r\n\/\/ If the function is 'sine' and x=10, then y=0x03.  See the sineValues array below that defines                                                                           \r\n\/\/ the sine function.                                                                 \r\nint y[NPINS];\r\n\r\n\/\/ For each LED we can specify whether the x value should \"wrap\" around when reaching the end.                                                                             \r\n\/\/ There are 256 possible values for x [0-255].  If we reach 255 and dx=1, then we can wrap around                                                                         \r\n\/\/ back to x=0 if wrapFunction=true.  If false, then adding 1 to 255 keeps x=255.     \r\nboolean wrapFunction[NPINS];\r\n\r\n\/\/ Definition of sine function.  Array lookup executes faster than actually computing the sine.                                                                            \r\nunsigned char sineValues[] = {\r\n  0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,\r\n  0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,\r\n  0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,\r\n  0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c,\r\n  0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,\r\n  0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,\r\n  0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,\r\n  0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,\r\n  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,\r\n  0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,\r\n  0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,\r\n  0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,\r\n  0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,\r\n  0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,\r\n  0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,\r\n  0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00\r\n};\r\n\r\n\r\nvoid setup() {\r\n  randomSeed(analogRead(5));\r\n  pinMode(BUTTON, INPUT);\r\n  digitalWrite(BUTTON, HIGH);\r\n  Tlc.init(0);\r\n}\r\n\r\nvoid loop(){\r\n\r\n  lastVisualization = visualization;\r\n  visualization = visualizations[random(NVISUALIZATIONS)];\r\n\r\n  \/\/ call the current visualization function                                                                                   \r\n  (*visualization)();\r\n\r\n}\r\n\r\n\/\/ Execute n duty cycles.                                                                                                      \r\n\/\/ First we call stepXAll() which adds dx to each x value.  This moves the LED along the x axis                                \r\n\/\/ of its function.                                                                                                            \r\n\/\/ Then, for each LED,  we compute the new y value for the current x value according to which                                  \r\n\/\/ function (linear, sine, exponential) that is associated with the LED.                                                       \r\n\/\/ For any LED that is supposed to be on at all (any pin with a y value greater than 0), we turn it on.                        \r\n\/\/ A duty cycle is a loop of 256 steps executed quickly in succession.  At the beginning of the duty cycle                     \r\n\/\/ each LED that has a value of y>0 will be on.  At each step we see if there are any LEDs that need                           \r\n\/\/ to be turned off for the remainder of the duty cycle.  So if an LED has y=100, we will turn it off at                       \r\n\/\/ step 100.  That LED will have been on for the first 100 steps of the duty cycle and off for the                             \r\n\/\/ remaining 156 steps.  So it is dimmer.  If an LED has y=255, then it will remain on during the whole                        \r\n\/\/ duty cycle and be at full brightness.  An LED with a low value y=10 will be very dim because we turn                        \r\n\/\/ it off very early in the duty cycle.                                                                                        \r\n\/\/ This 256 step cycle is executed n times as specified by the input parameter n.                                              \r\n\r\nvoid dutyCycle(int n) {\r\n  for(int i=0;i&lt;n;i++) {\r\n    stepXAll();\r\n    computePinValueAll();\r\n    for(int p=0;p&lt;NPINS;p++) {\r\n      Tlc.set(p, y[p]*16);\r\n    }\r\n    Tlc.update();\r\n    delay(10);\r\n  }\r\n}\r\n\r\nvoid stepXAll() {\r\n  for(int p=0;p&lt;NPINS;p++) {\r\n    stepX(p);\r\n  }\r\n}\r\n\r\n\/\/ Increment the x value for pin p by the value dx.                                                                            \r\n\/\/ Wrap the function around back to 0 (or back to 255)                                                                         \r\n\/\/ if wrapFunction is true for the pin p.                                                                                      \r\nvoid stepX(int p) {\r\n  x[p] = x[p] + dx[p];\r\n  if (wrapFunction[p]) {\r\n    if (x[p] > 255) {\r\n      x[p] = x[p] - 256;\r\n    } else if (x[p] < 0) {\r\n      x[p] = x[p] + 256;\r\n    }\r\n  } else {\r\n    if (x[p] > 255) {\r\n      x[p] = 255;\r\n    } else if (x[p] < 0) {\r\n      x[p] = 0;\r\n    }\r\n  }\r\n}\r\n\r\n\r\nvoid computePinValueAll() {\r\n  for(int p=0;p&lt;NPINS;p++) {\r\n    computePinValue(p);\r\n  }\r\n}\r\n\r\n\/\/ Compute value y for pin p.                                                                                                  \r\n\/\/ Apply the function by invoking it with the x value.                                                                         \r\nvoid computePinValue(int p) {\r\n  y[p] = (*function[p])(x[p]);\r\n}\r\n\r\n\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/                                             \r\n\/\/ Mathematical Functions                                                                                                      \r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/                                             \r\n\r\nint linear(float x) {\r\n  return (int)(x + 0.5);\r\n}\r\n\r\nint sine(float x) {\r\n  return sineValues[(int)x];\r\n}\r\n\r\nint exponential(float x) {\r\n return (int) (255.0 * pow(50, ((x\/127.5)-2)));\r\n}\r\n\r\n\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/                                             \r\n\/\/ Visualizations                                                                                                              \r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/                                             \r\n\r\n\/\/ Do 30 blinks.  Each LED that is blinked will fade                                                                           \r\n\/\/ quickly down to 0 according to the exponential function.                                                                    \r\nvoid blinkRandom() {\r\n  for(int p=0;p&lt;NPINS;p++) {\r\n    function[p] = exponential;\r\n    wrapFunction[p] = false;\r\n    x[p] = 0;\r\n    dx[p] = -4;\r\n  }\r\n\r\n  for(int i=0;i&lt;30;i++) {\r\n    int p = random(0, NPINS);\r\n    x[p] = 255;\r\n    dutyCycle(10);\r\n  }\r\n}\r\n\r\nvoid onOff() {\r\n  allOff();\r\n\r\n  for(int p=0; p&lt;NPINS; p++) {\r\n    x[p] = 0;\r\n    dx[p] = 0;\r\n    function[p] = linear;\r\n    wrapFunction[p] = false;\r\n  }\r\n\r\n  int on = 0;\r\n  int p;\r\n  int d;\r\n  while (on &lt; NPINS) {\r\n    p = random(0, NPINS);\r\n    if (x[p] == 0) {\r\n      on++;\r\n      x[p] = 255;\r\n      dutyCycle(1);\r\n      d = 200 - (on * 10);\r\n      delay(d);\r\n    }\r\n  }\r\n\r\n  delay(1000);\r\n  while (on &gt; 0) {\r\n    p = random(0, NPINS);\r\n    if (x[p] == 255) {\r\n      on--;\r\n      x[p] = 0;\r\n      dutyCycle(1);\r\n      d = 40 + (on * 10);\r\n      delay(d);\r\n    }\r\n  }\r\n\r\n  delay(100);\r\n}\r\n\r\n\r\nvoid throb() {\r\n  eachDown();\r\n\r\n  float minSpeed = 0.4;\r\n  float maxSpeed = 1.0;\r\n\r\n  \/\/ Set random speeds for LEDs                                                                                                \r\n  for(int i=0;i&lt;NPINS;i++) {\r\n    dx[i] = minSpeed + (random(0, 17) * ((maxSpeed - minSpeed) \/ NPINS));\r\n  }\r\n\r\n  for(int p=0; p&lt;NPINS; p++) {\r\n    function[p] = sine;\r\n    wrapFunction[p] = true;\r\n  }\r\n\r\n  \/\/ Run for a while.  Each pin will throb according to sine wave.                                                             \r\n  dutyCycle(random(500, 2000));\r\n\r\n  eachDown();\r\n  delay(500);\r\n}\r\n\r\n\r\nvoid fall() {\r\n  int down[NPINS] = {5, 0, 15, 9, 11, 4, 2, 3, 7, 12, 14, 1, 8, 6, 10, 13};\r\n\r\n  allOff();\r\n  for(int p=0; p&lt;NPINS; p++) {\r\n    function[down[p]] = linear;\r\n    wrapFunction[down[p]] = false;\r\n    x[down[p]] = 0;\r\n    dx[down[p]] = 8;\r\n    dutyCycle(8);\r\n\r\n  }\r\n  delay(200);\r\n  allOff();\r\n\r\n\r\n}\r\n\r\nvoid rise() {\r\n  int up[NPINS] = {13, 10, 6, 8, 1, 14, 12, 7, 3, 2, 4, 11, 9, 15, 0, 5};\r\n\r\n  allOff();\r\n  for(int p=0; p&lt;NPINS; p++) {\r\n    function[up[p]] = linear;\r\n    wrapFunction[up[p]] = false;\r\n    x[up[p]] = 0;\r\n    dx[up[p]] = 8;\r\n    dutyCycle(8);\r\n\r\n  }\r\n\r\n  delay(200);\r\n  allOff();\r\n\r\n\r\n}\r\nvoid upDown() {\r\n allUp();\r\n allDown();\r\n}\r\n\r\n\r\nvoid allUp() {\r\n  if (lastVisualization == allUp) {\r\n    return;\r\n  }\r\n\r\n  for(int p=0; p&lt;NPINS; p++) {\r\n    x[p] = y[p];\r\n    dx[p] = 1.0;\r\n    function[p] = linear;\r\n  }\r\n  dutyCycle(256);\r\n}\r\n\r\nvoid allDown() {\r\n  if (lastVisualization == allDown) {\r\n    return;\r\n  }\r\n\r\n  for(int p=0; p&lt;NPINS; p++) {\r\n    x[p] = y[p];\r\n    dx[p] = -1.0;\r\n    function[p] = linear;\r\n  }\r\n  dutyCycle(256);\r\n}\r\n\r\n\r\nvoid eachDown() {\r\n  boolean done = true;\r\n\r\n  if (lastVisualization == eachDown) {\r\n    return;\r\n  }\r\n\r\n  for(int p=0; p&lt;NPINS; p++) {\r\n    x[p] = y[p];\r\n    dx[p] = -1;\r\n    function[p] = linear;\r\n    wrapFunction[p] = false;\r\n  }\r\n\r\n  done = false;\r\n  while (!done) {\r\n    dutyCycle(1);\r\n    done = true;\r\n    for(int p=0; p&lt;NPINS; p++) {\r\n      if (y[p] > 0) {\r\n        done = false;\r\n        break;\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\nvoid allOn() {\r\n  for(int p=0; p&lt;NPINS; p++) {\r\n    function[p] = linear;\r\n    x[p] = 255;\r\n    dx[p] = 0;\r\n  }\r\n  dutyCycle(1);\r\n}\r\n\r\nvoid allOff() {\r\n  for(int p=0; p&lt;NPINS; p++) {\r\n    function[p] = linear;\r\n    x[p] = 0;\r\n    dx[p] = 0;\r\n  }\r\n  dutyCycle(1);\r\n}\r\n<\/pre>\n<h3>Hardware Design Files<\/h3>\n<p>The schematic and board design are open source hardware, so you are welcome to have a board fabricated yourself!  <a href=\"https:\/\/nootropicdesign.com\/projectlab\/downloads\/TabascoLampDesign_v1.0.zip\">Download the design files here<\/a>.<\/p>\n<p><a href=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_sch.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_sch_sm.png\" alt=\"\" title=\"tabascoLamp_sch_sm\" width=\"640\" height=\"404\" class=\"alignleft size-full wp-image-1219\" srcset=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_sch_sm.png 640w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_sch_sm-300x189.png 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><br \/>\n<a href=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_brd.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_brd_sm.png\" alt=\"\" title=\"tabascoLamp_brd_sm\" width=\"640\" height=\"634\" class=\"alignleft size-full wp-image-1218\" srcset=\"https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_brd_sm.png 640w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_brd_sm-150x150.png 150w, https:\/\/nootropicdesign.com\/projectlab\/wp-content\/uploads\/2012\/05\/tabascoLamp_brd_sm-300x297.png 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><br \/>\n<br clear=\"all\"\/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I love Tabasco and always though that their cute little miniature bottles could be the basis for a great specialty lamp. I was very happy to find that a 3mm LED fits perfectly in the bottle opening of the miniature bottles. By designing a custom circuit board I was able to make a lamp that [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[3,7],"tags":[],"class_list":["post-1161","post","type-post","status-publish","format-standard","hentry","category-arduino","category-art"],"_links":{"self":[{"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/posts\/1161","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/comments?post=1161"}],"version-history":[{"count":40,"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/posts\/1161\/revisions"}],"predecessor-version":[{"id":1938,"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/posts\/1161\/revisions\/1938"}],"wp:attachment":[{"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/media?parent=1161"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/categories?post=1161"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nootropicdesign.com\/projectlab\/wp-json\/wp\/v2\/tags?post=1161"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}