Advertisement
Guest User

fastled boblight

a guest
Jul 28th, 2015
274
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.05 KB | None | 0 0
  1. #include "FastLED.h"
  2.  
  3. #define NUM_LEDS 270 // Max LED count
  4. #define LED_PIN 10 // arduino output pin - probably not required for WS2801
  5. #define GROUND_PIN 10 // probably not required for WS2801
  6. #define BRIGHTNESS 96 // maximum brightness
  7. #define SPEED 460800 // virtual serial port speed, must be the same in boblight_config
  8.  
  9. CRGB leds[NUM_LEDS];
  10. uint8_t * ledsRaw = (uint8_t *)leds;
  11.  
  12. // A 'magic word' (along with LED count & checksum) precedes each block
  13. // of LED data; this assists the microcontroller in syncing up with the
  14. // host-side software and properly issuing the latch (host I/O is
  15. // likely buffered, making usleep() unreliable for latch). You may see
  16. // an initial glitchy frame or two until the two come into alignment.
  17. // The magic word can be whatever sequence you like, but each character
  18. // should be unique, and frequent pixel values like 0 and 255 are
  19. // avoided -- fewer false positives. The host software will need to
  20. // generate a compatible header: immediately following the magic word
  21. // are three bytes: a 16-bit count of the number of LEDs (high byte
  22. // first) followed by a simple checksum value (high byte XOR low byte
  23. // XOR 0x55). LED data follows, 3 bytes per LED, in order R, G, B,
  24. // where 0 = off and 255 = max brightness.
  25.  
  26. static const uint8_t magic[] = {'A','d','a'};
  27. #define MAGICSIZE sizeof(magic)
  28. #define HEADERSIZE (MAGICSIZE + 3)
  29.  
  30. #define MODE_HEADER 0
  31. #define MODE_DATA 2
  32.  
  33. // If no serial data is received for a while, the LEDs are shut off
  34. // automatically. This avoids the annoying "stuck pixel" look when
  35. // quitting LED display programs on the host computer.
  36. static const unsigned long serialTimeout = 150000; // 150 seconds
  37.  
  38. void setup()
  39. {
  40. // pinMode(GROUND_PIN, OUTPUT);
  41. // digitalWrite(GROUND_PIN, LOW);
  42. FastLED.addLeds<WS2811, LED_PIN, BRG>(leds, NUM_LEDS);
  43. //FastLED.addLeds<WS2801, RGB>(leds, NUM_LEDS);
  44.  
  45. // Dirty trick: the circular buffer for serial data is 256 bytes,
  46. // and the "in" and "out" indices are unsigned 8-bit types -- this
  47. // much simplifies the cases where in/out need to "wrap around" the
  48. // beginning/end of the buffer. Otherwise there'd be a ton of bit-
  49. // masking and/or conditional code every time one of these indices
  50. // needs to change, slowing things down tremendously.
  51. uint8_t
  52. buffer[256],
  53. indexIn = 0,
  54. indexOut = 0,
  55. mode = MODE_HEADER,
  56. hi, lo, chk, i, spiFlag;
  57. int16_t
  58. bytesBuffered = 0,
  59. hold = 0,
  60. c;
  61. int32_t
  62. bytesRemaining;
  63. unsigned long
  64. startTime,
  65. lastByteTime,
  66. lastAckTime,
  67. t;
  68. int32_t outPos = 0;
  69.  
  70. Serial.begin(SPEED); // Teensy/32u4 disregards baud rate; is OK!
  71.  
  72. Serial.print("Ada\n"); // Send ACK string to host
  73.  
  74. startTime = micros();
  75. lastByteTime = lastAckTime = millis();
  76.  
  77. // loop() is avoided as even that small bit of function overhead
  78. // has a measurable impact on this code's overall throughput.
  79.  
  80. for(;;) {
  81.  
  82. // Implementation is a simple finite-state machine.
  83. // Regardless of mode, check for serial input each time:
  84. t = millis();
  85. if((bytesBuffered < 256) && ((c = Serial.read()) >= 0)) {
  86. buffer[indexIn++] = c;
  87. bytesBuffered++;
  88. lastByteTime = lastAckTime = t; // Reset timeout counters
  89. } else {
  90. // No data received. If this persists, send an ACK packet
  91. // to host once every second to alert it to our presence.
  92. if((t - lastAckTime) > 1000) {
  93. Serial.print("Ada\n"); // Send ACK string to host
  94. lastAckTime = t; // Reset counter
  95. }
  96. // If no data received for an extended time, turn off all LEDs.
  97. if((t - lastByteTime) > serialTimeout) {
  98. memset(leds, 0, NUM_LEDS * sizeof(struct CRGB)); //filling Led array by zeroes
  99. FastLED.show();
  100. lastByteTime = t; // Reset counter
  101. }
  102. }
  103.  
  104. switch(mode) {
  105.  
  106. case MODE_HEADER:
  107.  
  108. // In header-seeking mode. Is there enough data to check?
  109. if(bytesBuffered >= HEADERSIZE) {
  110. // Indeed. Check for a 'magic word' match.
  111. for(i=0; (i<MAGICSIZE) && (buffer[indexOut++] == magic[i++]););
  112. if(i == MAGICSIZE) {
  113. // Magic word matches. Now how about the checksum?
  114. hi = buffer[indexOut++];
  115. lo = buffer[indexOut++];
  116. chk = buffer[indexOut++];
  117. if(chk == (hi ^ lo ^ 0x55)) {
  118. // Checksum looks valid. Get 16-bit LED count, add 1
  119. // (# LEDs is always > 0) and multiply by 3 for R,G,B.
  120. bytesRemaining = 3L * (256L * (long)hi + (long)lo + 1L);
  121. bytesBuffered -= 3;
  122. outPos = 0;
  123. memset(leds, 0, NUM_LEDS * sizeof(struct CRGB));
  124. mode = MODE_DATA; // Proceed to latch wait mode
  125. } else {
  126. // Checksum didn't match; search resumes after magic word.
  127. indexOut -= 3; // Rewind
  128. }
  129. } // else no header match. Resume at first mismatched byte.
  130. bytesBuffered -= i;
  131. }
  132. break;
  133.  
  134. case MODE_DATA:
  135.  
  136. if(bytesRemaining > 0) {
  137. if(bytesBuffered > 0) {
  138. if (outPos < sizeof(leds))
  139. ledsRaw[outPos++] = buffer[indexOut++]; // Issue next byte
  140. bytesBuffered--;
  141. bytesRemaining--;
  142. }
  143. // If serial buffer is threatening to underrun, start
  144. // introducing progressively longer pauses to allow more
  145. // data to arrive (up to a point).
  146. } else {
  147. // End of data -- issue latch:
  148. startTime = micros();
  149. mode = MODE_HEADER; // Begin next header search
  150. FastLED.show();
  151. }
  152. } // end switch
  153. } // end for(;;)
  154. }
  155.  
  156. void loop()
  157. {
  158. // Not used. See note in setup() function.
  159. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement