Advertisement
candale

LED Smooth Transition - Arduino

Jun 16th, 2014
294
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.40 KB | None | 0 0
  1. /* ==============================================================
  2.  *  ORIGINAL
  3.  *      http://forum.arduino.cc/index.php?topic=102040.0
  4. */ ==============================================================
  5.  
  6. /*
  7.  RGB LED - Automatic Smooth Color Cycling
  8.  
  9.  Marco Colli
  10.  April 2012
  11.  
  12.  Uses the properties of the RGB Colour Cube
  13.  The RGB colour space can be viewed as a cube of colour. If we assume a cube of dimension 1, then the
  14.  coordinates of the vertices for the cubve will range from (0,0,0) to (1,1,1) (all black to all white).
  15.  The transitions between each vertex will be a smooth colour flow and we can exploit this by using the
  16.  path coordinates as the LED transition effect.
  17. */
  18. // Output pins for PWM
  19. #define  R_PIN  3  // Red LED
  20. #define  G_PIN  5  // Green LED
  21. #define  B_PIN  6  // Blue LED
  22.  
  23. // Constants for readability are better than magic numbers
  24. // Used to adjust the limits for the LED, especially if it has a lower ON threshold
  25. #define  MIN_RGB_VALUE  10   // no smaller than 0.
  26. #define  MAX_RGB_VALUE  255  // no bigger than 255.
  27.  
  28. // Slowing things down we need ...
  29. #define  TRANSITION_DELAY  70   // in milliseconds, between individual light changes
  30. #define  WAIT_DELAY        500  // in milliseconds, at the end of each traverse
  31. //
  32. // Total traversal time is ((MAX_RGB_VALUE - MIN_RGB_VALUE) * TRANSITION_DELAY) + WAIT_DELAY
  33. // eg, ((255-0)*70)+500 = 18350ms = 18.35s
  34.  
  35. // Structure to contain a 3D coordinate
  36. typedef struct
  37. {
  38.   byte  x, y, z;
  39. } coord;
  40.  
  41. static coord  v; // the current rgb coordinates (colour) being displayed
  42.  
  43. /*
  44.  Vertices of a cube
  45.      
  46.     C+----------+G
  47.     /|        / |
  48.   B+---------+F |
  49.    | |       |  |    y  
  50.    |D+-------|--+H   ^  7 z
  51.    |/        | /     | /
  52.   A+---------+E      +--->x
  53.  
  54. */
  55. const coord vertex[] =
  56. {
  57.  //x  y  z      name
  58.   {0, 0, 0}, // A or 0
  59.   {0, 1, 0}, // B or 1
  60.   {0, 1, 1}, // C or 2
  61.   {0, 0, 1}, // D or 3
  62.   {1, 0, 0}, // E or 4
  63.   {1, 1, 0}, // F or 5
  64.   {1, 1, 1}, // G or 6
  65.   {1, 0, 1}  // H or 7
  66. };
  67.  
  68. /*
  69.  A list of vertex numbers encoded 2 per byte.
  70.  Hex digits are used as vertices 0-7 fit nicely (3 bits 000-111) and have the same visual
  71.  representation as decimal, so bytes 0x12, 0x34 ... should be interpreted as vertex 1 to
  72.  v2 to v3 to v4 (ie, one continuous path B to C to D to E).
  73. */
  74. const byte path[] =
  75. {
  76.   0x01, 0x23, 0x76, 0x54, 0x03, 0x21, 0x56, 0x74,  // trace the edges
  77.   0x13, 0x64, 0x16, 0x02, 0x75, 0x24, 0x35, 0x17, 0x25, 0x70,  // do the diagonals
  78. };
  79.  
  80. #define  MAX_PATH_SIZE  (sizeof(path)/sizeof(path[0]))  // size of the array
  81.  
  82. void setup()
  83. {
  84.   pinMode(R_PIN, OUTPUT);   // sets the pins as output
  85.   pinMode(G_PIN, OUTPUT);  
  86.   pinMode(B_PIN, OUTPUT);
  87. }
  88.  
  89. void traverse(int dx, int dy, int dz)
  90. // Move along the colour line from where we are to the next vertex of the cube.
  91. // The transition is achieved by applying the 'delta' value to the coordinate.
  92. // By definition all the coordinates will complete the transition at the same
  93. // time as we only have one loop index.
  94. {
  95.   if ((dx == 0) && (dy == 0) && (dz == 0))   // no point looping if we are staying in the same spot!
  96.     return;
  97.    
  98.   for (int i = 0; i < MAX_RGB_VALUE-MIN_RGB_VALUE; i++, v.x += dx, v.y += dy, v.z += dz)
  99.   {
  100.     // set the colour in the LED
  101.     analogWrite(R_PIN, v.x);
  102.     analogWrite(G_PIN, v.y);
  103.     analogWrite(B_PIN, v.z);
  104.    
  105.     delay(TRANSITION_DELAY);  // wait fot the transition delay
  106.   }
  107.  
  108.   delay(WAIT_DELAY);          // give it an extra rest at the end of the traverse
  109. }
  110.  
  111. void loop()
  112. {
  113.   int    v1, v2=0;    // the new vertex and the previous one
  114.  
  115.   // initialise the place we start from as the first vertex in the array
  116.   v.x = (vertex[v2].x ? MAX_RGB_VALUE : MIN_RGB_VALUE);
  117.   v.y = (vertex[v2].y ? MAX_RGB_VALUE : MIN_RGB_VALUE);
  118.   v.z = (vertex[v2].z ? MAX_RGB_VALUE : MIN_RGB_VALUE);
  119.  
  120.   // Now just loop through the path, traversing from one point to the next
  121.   for (int i = 0; i < 2*MAX_PATH_SIZE; i++)
  122.   {
  123.     // !! loop index is double what the path index is as it is a nybble index !!
  124.     v1 = v2;
  125.     if (i&1)  // odd number is the second element and ...
  126.       v2 = path[i>>1] & 0xf;  // ... the bottom nybble (index /2) or ...
  127.     else      // ... even number is the first element and ...
  128.       v2 = path[i>>1] >> 4;  // ... the top nybble
  129.      
  130.     traverse(vertex[v2].x-vertex[v1].x,
  131.              vertex[v2].y-vertex[v1].y,
  132.              vertex[v2].z-vertex[v1].z);
  133.   }
  134. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement