├── LICENSE ├── README.md ├── arduino_to_processing_v10.ino ├── old_version ├── arduino_to_processing_v8.ino ├── readme.txt └── test_serial_from_arduino_v8.pde └── test_serial_from_arduino_v10.pde /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Marc Miller 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FastLED_2_Processing 2 | Sketches for sending FastLED pixel data to Processing (via serial connection) 3 | 4 | *NOTE: This requires the older version of Processing 2.2.1* 5 | 6 | FastLED Library info can be be found here: [fastled.io](http://fastled.io/) 7 | 8 | And be sure to check out the wiki: [github.com/FastLED/FastLED/wiki/Overview](https://github.com/FastLED/FastLED/wiki/Overview) 9 | 10 | 11 | Download the current FastLED library from: [github.com/FastLED/FastLED](https://github.com/FastLED/FastLED) 12 | (Use "Download Zip" link on right side.) 13 | 14 | 15 | 16 | 17 | -Marc Miller, 18 | Febuary 2015 19 | -------------------------------------------------------------------------------- /arduino_to_processing_v10.ino: -------------------------------------------------------------------------------- 1 | /*=============================================================== 2 | arduino_to_processing_v10.ino 3 | Marc Miller, April 2015 4 | 5 | ================================================================ 6 | This program is setup to send FastLED pixel data a Processing 7 | sketch. Processing can then display that data and simlulate a 8 | pixel strip. 9 | To test, upload this sketch to your arduino, and then run the 10 | Processing sketch: 11 | test_serial_from_arduino_v10.pde 12 | 13 | Simulating a pixel display in Processing could be useful when 14 | creating patterns but a LED strip is not available or hooked up. 15 | An Arduino is still required to run your arduino code and send 16 | it to Processing though. 17 | 18 | Note: The way colored dots are displayed on a computer monitor 19 | is visually very different then looking at actual LEDs. This 20 | setup is probably not great for trying to dial in specific 21 | colors, but it does allow varifing if the pixels are receiving a 22 | red vs blue color for example. 23 | 24 | Note: You can not use the serial monitor while using Processing 25 | to display the pixel data since it connects to the Arduino over 26 | a serial connection. This could make debugging a pixel pattern 27 | more difficult if you like to use the serial monitor to print 28 | out feed back while creating patterns. (This might still be 29 | possible with an Arduino Mega which has more then one serial 30 | monitor but I have not been able to test this.) 31 | 32 | --------------------------------------------------------------- 33 | I have marked all the code bits below that are needed to send 34 | the pixel data to Processing. Search for '****' (no quotes) to 35 | find each needed section to copy to another arduino sketch. 36 | 37 | Anywhere FastLED.show() is called you'll also need to add the 38 | function call that sends the pixel data to Processing. An easy 39 | way to add this is to use find and replace. 40 | Find: FastLED.show(); 41 | Replace with: FastLED.show(); SendToProcessing(); 42 | 43 | The FastLED library is by Daniel Garcia and Mark Kriegsman and 44 | can be found at http://fastled.io/ 45 | 46 | 47 | ================================================================*/ 48 | 49 | #include "FastLED.h" 50 | #define LED_TYPE NEOPIXEL // *Update to your strip type. NEOPIXEL, APA102, LPD8806, etc.. 51 | #define DATA_PIN 6 // *Set this to your data pin. 52 | //#define CLOCK_PIN 13 // *Set this to your clock pin if needed. 53 | #define NUM_LEDS 12 // *Update to the number of pixels in your strip. 54 | //#define COLOR_ORDER BGR 55 | #define MASTER_BRIGHTNESS 255 // Master brightness range is 0-255. 56 | CRGB leds[NUM_LEDS]; 57 | 58 | 59 | /****Variables needed for sending to Processing. */ 60 | uint16_t sendDelay = 10; // [Milliseconds] To slow stuff down if needed. 61 | boolean testing = false; // Default is false. [Ok to change for testing.] 62 | // Can temporarily change testing to true to check output in serial monitor. 63 | // Must set back to false to allow Processing to connect and receive data. 64 | 65 | boolean linkedUp = false; // Initially set linkup status false. [Do Not change.] 66 | /****End of variables needed for sending Processing. */ 67 | 68 | 69 | // This variable only needed for this demo. 70 | int pick = 99; // Set to 0 to loop demo patterns, or 99 to only run default choice. 71 | 72 | 73 | //--------------------------------------------------------------- 74 | void setup() { 75 | delay(1500); // Startup delay 76 | FastLED.addLeds(leds, NUM_LEDS); // ***For Clock-less strips. 77 | //FastLED.addLeds(leds, NUM_LEDS); // ***For strips using Clock. 78 | FastLED.setBrightness(MASTER_BRIGHTNESS); 79 | 80 | 81 | /****Stuff needed in setup() section for sending to Processing. */ 82 | Serial.begin(115200); // Allows serial output. 83 | while (!Serial){ ; } // Wait for serial connection. Only needed for Leonardo board. 84 | firstContact(); // Connect with Processing. Hello, is anyone out there? 85 | /****End of stuff to put in your setup() section for Processing. */ 86 | 87 | 88 | }//end of setup 89 | 90 | 91 | //--------------------------------------------------------------- 92 | void loop() { 93 | 94 | /****This tests if serial is connected. Needed for sending to Processing. */ 95 | if (linkedUp == true) { /****Check to see if connected with Processing. */ 96 | 97 | // Run through various color data examples and display. 98 | switch(pick){ 99 | case 0:{ // Test HSV 'rainbow' colors. 100 | FastLED.clear(); 101 | delay(300); 102 | leds[0] = CHSV( 0,255,255); // HSV Red 103 | leds[1] = CHSV( 32,255,255); 104 | leds[2] = CHSV( 64,255,255); 105 | leds[3] = CHSV( 96,255,255); // HSV Green 106 | leds[4] = CHSV(128,255,255); 107 | leds[5] = CHSV(160,255,255); // HSV Blue 108 | leds[6] = CHSV(192,255,255); 109 | leds[7] = CHSV(224,255,255); 110 | leds[8] = CHSV( 0, 0,255); // HSV White 111 | FastLED.show(); SendToProcessing(); // Show and send pixel data to Processing. 112 | delay(3000); 113 | FastLED.clear(); // Clear the strip (set to Black). 114 | FastLED.show(); SendToProcessing(); // Show and send pixel data to Processing. 115 | delay(500); 116 | break; 117 | } 118 | case 1:{ // Test RGB colors. 119 | uint8_t pixelNumber = 0; // Stores pixel number. 120 | for (int i=0; i < 9; i++){ 121 | leds[(pixelNumber+0) % NUM_LEDS] = CRGB(255,255,255); // RGB White 122 | leds[(pixelNumber+1) % NUM_LEDS] = CRGB(255, 0, 0); // RGB Red 123 | leds[(pixelNumber+2) % NUM_LEDS] = CRGB( 0,255, 0); // RGB Green 124 | leds[(pixelNumber+3) % NUM_LEDS] = CRGB( 0, 0,255); // RGB Blue 125 | leds[(pixelNumber+4) % NUM_LEDS] = CRGB(255,255,255); // RGB White 126 | leds[(pixelNumber+5) % NUM_LEDS] = CRGB(255,255, 0); // RGB Yellow 127 | leds[(pixelNumber+6) % NUM_LEDS] = CRGB(255, 0,255); // RGB Purple 128 | leds[(pixelNumber+7) % NUM_LEDS] = CRGB( 0,255,255); // RGB Cyan 129 | FastLED.show(); SendToProcessing(); // Show and send pixel data to Processing. 130 | delay(800); 131 | leds[pixelNumber % NUM_LEDS] = CRGB( 0, 0, 0); // RGB Black 132 | pixelNumber++; 133 | if (pixelNumber >= NUM_LEDS){ pixelNumber = 0; } 134 | } 135 | fill_solid(leds, NUM_LEDS, CRGB::Black); // Black out strip. 136 | FastLED.show(); SendToProcessing(); // Show and send pixel data to Processing. 137 | delay(300); 138 | break; 139 | } 140 | case 2:{ // Random pixels and random colors. 141 | unsigned long currentMillis = millis(); // Used to store current sketch run time. 142 | unsigned long startMillis = currentMillis; // Used to store a start time. 143 | while ((currentMillis - startMillis) < 4000) { // Check if enough time has passed 144 | currentMillis = millis(); 145 | for (int x=0; x < NUM_LEDS; x++){ 146 | leds[random16(NUM_LEDS)] = CRGB::Black; // Randomly turn one off. 147 | leds[random16(NUM_LEDS)] = CRGB(random8(), random8(), random8()); 148 | FastLED.show(); SendToProcessing(); // Show and send pixel data to Processing. 149 | delay(120); 150 | } 151 | } 152 | break; 153 | } 154 | case 3:{ // Moving dots with limited range random colors. 155 | uint16_t i,j,k; 156 | unsigned long currentMillis = millis(); // Used to store current sketch run time. 157 | unsigned long startMillis = currentMillis; // Used to store a start time. 158 | while ((currentMillis - startMillis) < 5000) { // Check if enough time has passed 159 | currentMillis = millis(); 160 | for (i=0; i < NUM_LEDS; i++){ 161 | j = (i + (NUM_LEDS/3)) % NUM_LEDS; 162 | k = (i + (2*NUM_LEDS/3)) % NUM_LEDS; 163 | leds[i] = CRGB(random8(80,255), random8(90,200), random8(0,80)); 164 | leds[j] = CRGB(random8(80,255), random8(90,200), random8(0,80)); 165 | leds[k] = CRGB(random8(80,255), random8(90,200), random8(0,80)); 166 | FastLED.show(); SendToProcessing(); // Show and send pixel data to Processing. 167 | leds[i] = CRGB::Black; 168 | leds[j] = CRGB::Black; 169 | leds[k] = CRGB::Black; 170 | delay(150); 171 | } 172 | } 173 | break; 174 | } 175 | case 4:{ // Rainbowygoodness. Then fades out half the pixels. 176 | unsigned long currentMillis = millis(); // Used to store current sketch run time. 177 | unsigned long startMillis = currentMillis; // Used to store a start time. 178 | while ((currentMillis - startMillis) < random16(4000,8000)) { // Check if enough time has passed 179 | currentMillis = millis(); 180 | fill_rainbow( leds, NUM_LEDS, millis()/20); 181 | FastLED.show(); SendToProcessing(); // Show and send pixel data to Processing. 182 | delay(100); 183 | } 184 | for (int i=0; i<120; i++) { // Fade out half the pixels. 185 | fadeToBlackBy( leds, NUM_LEDS/2, 5); delay(40); 186 | FastLED.show(); SendToProcessing(); // Show and send pixel data to Processing. 187 | } 188 | fill_solid(leds, NUM_LEDS, CRGB::Black); // Black out strip. 189 | FastLED.show(); SendToProcessing(); // Show and send pixel data to Processing. 190 | delay(500); 191 | break; 192 | } 193 | default:{ // Sequentially fill pixel strip over and over. 194 | int hueStart = random8(); 195 | for (uint16_t i=0; i <= NUM_LEDS; i++){ 196 | fill_rainbow( leds, i, hueStart); 197 | FastLED.show(); SendToProcessing(); // Show and send pixel data to Processing. 198 | delay(25); 199 | } 200 | delay(500); 201 | FastLED.clear(); // Clear the strip (set to Black). 202 | FastLED.show(); SendToProcessing(); // Show and send pixel data to Processing. 203 | delay(50); 204 | pick = 99; 205 | break; 206 | } 207 | }//end of switch(pick) 208 | 209 | pick++; 210 | if (pick == 5){ pick = 0; } // Reset to go through picks again. 211 | 212 | 213 | } //****End of Processing 'linkedUp' check. */ 214 | 215 | 216 | }//end of main loop 217 | //--------------------------------------------------------------- 218 | 219 | 220 | 221 | /****The below two functions are needed for sending to Processing. */ 222 | // Copy from here to the bottom. 223 | //-------------------- 224 | // Waits for Processing to respond and then sends the number of pixels. 225 | void firstContact() { 226 | uint16_t nLEDS = NUM_LEDS; // Number to send to Processing. (Allows up to 65,535 pixels) 227 | if (testing == true){ 228 | linkedUp = true; // If testing, pretend we are already connected to Processing. 229 | Serial.print("NUM_LEDS: "); Serial.println(nLEDS); // Number of pixels in our LED strip. 230 | Serial.print(" High Byte = "); Serial.print(highByte(nLEDS)); // The high byte. 231 | Serial.print(" x 256 = "); Serial.println(highByte(nLEDS) * 256); 232 | Serial.print(" Low Byte = "); Serial.println(lowByte(nLEDS)); // The low byte. 233 | delay(3000); 234 | } 235 | else { 236 | while (Serial.available() <= 0) { // Repeats until Processing responds. Hello? 237 | Serial.print('A'); // send an ASCII A (byte of value 65) 238 | delay(100); 239 | } 240 | // Once Processing responds send the number of pixels as two bytes. 241 | Serial.write(highByte(nLEDS)); // Send the high byte to Processing. 242 | Serial.write(lowByte(nLEDS)); // Send the low byte to Processing. 243 | Serial.print('#'); // send an ASCII # (byte of value 35) as a flag for Processing. 244 | linkedUp = true; // Now that Processing knows number of pixels set linkedUp to true. 245 | delay(500); 246 | } 247 | } 248 | 249 | //-------------------- 250 | // This function sends ALL the pixel data to Processing. 251 | void SendToProcessing() { 252 | if (testing == true){ // Print pixel data. If NUM_LEDS is large this will be a lot of data! 253 | Serial.println("-------------------------------------------------------"); 254 | for (uint16_t d=0; d < NUM_LEDS; d++){ 255 | Serial.print("p: "); Serial.print(d); 256 | Serial.print("\tr: "); Serial.print(leds[d].r); 257 | Serial.print("\tg: "); Serial.print(leds[d].g); 258 | Serial.print("\tb: "); Serial.println(leds[d].b); 259 | } 260 | Serial.println(" "); 261 | delay(500); // Add some extra delay while testing. 262 | } 263 | else { // Send ALL the pixel data to Processing! 264 | for (uint16_t d=0; d < NUM_LEDS; d++){ 265 | Serial.write(d); // Pixel number 266 | Serial.write(leds[d].r); // Red channel data 267 | Serial.write(leds[d].g); // Green channel data 268 | Serial.write(leds[d].b); // Blue channel data 269 | } 270 | delay(sendDelay); // Delay to slow things down if needed. 271 | } 272 | } 273 | 274 | //-------------------- 275 | /****End of the functions needed for sending to Processing.*/ 276 | -------------------------------------------------------------------------------- /old_version/arduino_to_processing_v8.ino: -------------------------------------------------------------------------------- 1 | /*=============================================================== 2 | arduino_to_processing_v8 3 | ================================================================ 4 | This program sends an ASCII leter A (byte of value 65) on startup 5 | and repeats that until it gets a response (a letter back) from Processing. 6 | Then it sends bytes continuously to Processing, a pixel number and 7 | it's HSV values, then the next. 8 | 9 | Please use the Processing sketch test_serial_from_arduino_v8.pde in 10 | conjunction with this sketch for testing things out. 11 | 12 | For the time beeing the code is limited to only being able to send 13 | data for 255 pixels (ie. NUM_LEDS should not be more then 255). 14 | For larger values of NUM_LEDS a lot of data is sent to Processing. 15 | You might want to leave it set to the current 12 pixels until you 16 | follow what's going on. 17 | 18 | I've tried to mark all the things below I think would need to be 19 | copied to another Arduino sketch to be able to send it's data to 20 | Processing. You can search for '****' (no quotes) to find each bit. 21 | 22 | In the sketch, anywhere FastLED.show() is called, then you should also 23 | call the function SendToProcessing() right after it. For example: 24 | 25 | leds[0] = CRGB::Red; 26 | FastLED.show(); 27 | SendToProcessing(); // Send all the pixel data to Processing. 28 | 29 | 30 | Marc Miller 31 | Feb. 11, 2015 32 | ================================================================*/ 33 | 34 | #include "FastLED.h" 35 | #define LED_TYPE NEOPIXEL // *Update to your strip type. NEOPIXEL, APA102, LPD8806, etc.. 36 | #define DATA_PIN 6 // *Remember to set this to your data pin. 37 | //#define CLOCK_PIN 13 // *Remember to set this to your clock pin. 38 | #define NUM_LEDS 12 // *Remember to update. [***PLEASE LIMIT TO 256 PIXELS FOR NOW***] 39 | // You might want to leave this number smallish to start with 40 | // until you see how this works on the Processing side. 41 | //#define COLOR_ORDER BGR 42 | #define MASTER_BRIGHTNESS 255 // Master brightness range is 0-255. 43 | CRGB leds[NUM_LEDS]; 44 | 45 | //**** 46 | //****Variables needed for sending to Processing 47 | uint16_t holdTime = 50; // [Milliseconds] To slow stuff down if needed. Try zero! 48 | boolean linkedUp = false; // Initially set linkup status false. [Do Not change.] 49 | boolean testing = false; // Default is false. [Ok to change for testing.] 50 | // Can temporarily change to true to check output in serial monitor. 51 | // Must set back to false to allow Processing to get data. 52 | //****End of variables needed for sending Processing 53 | //**** 54 | 55 | 56 | uint8_t pixelNumber = 0; // Stores pixel number. 57 | int pick = 0; // Stores switch case pick. 58 | 59 | 60 | //--------------------------------------------------------------- 61 | void setup() { 62 | delay(1000); // Startup delay 63 | FastLED.addLeds(leds, NUM_LEDS); // ***For Clock-less strips. 64 | //FastLED.addLeds(leds, NUM_LEDS); // ***For strips using Clock. 65 | FastLED.setBrightness(MASTER_BRIGHTNESS); 66 | 67 | //**** 68 | //****Stuff needed in setup() section for sending to Processing 69 | Serial.begin(115200); // Allows serial output (check baud rate) 70 | while (!Serial) { 71 | ; // Wait for serial port to connect. Only needed for Leonardo board. 72 | } 73 | firstContact(); // Attemp to contact Processing. Hello, is anyone out there? 74 | 75 | if (testing == true){ 76 | linkedUp = true; // Pretend we've connected with Processing while testing. 77 | Serial.print("NUM_LEDS = "); Serial.print(NUM_LEDS); // Number of pixels in our LED strip. 78 | //Serial.print(", Binary: "); Serial.print(NUM_LEDS,BIN); // Number of pixels in our LED strip. 79 | Serial.println(" "); 80 | } 81 | //****End of stuff to put in your setup() section for Processing 82 | //**** 83 | 84 | } //End of setup 85 | 86 | 87 | //--------------------------------------------------------------- 88 | void loop() { 89 | 90 | //**** 91 | //****This tests if serial is connected. Needed for sending to Processing 92 | if (linkedUp == true) { // Check to see if connected with Processing. 93 | //**** 94 | //**** 95 | 96 | switch(pick){ // Run through various color data examples and display it. 97 | case 0:{ // Test HSV 'rainbow' colors. 98 | FastLED.clear(); 99 | delay(300); 100 | leds[0] = CHSV( 0,255,255); // HSV Red 101 | leds[1] = CHSV( 32,255,255); 102 | leds[2] = CHSV( 64,255,255); 103 | leds[3] = CHSV( 96,255,255); // HSV Green 104 | leds[4] = CHSV(128,255,255); 105 | leds[5] = CHSV(160,255,255); // HSV Blue 106 | leds[6] = CHSV(192,255,255); 107 | leds[7] = CHSV(224,255,255); 108 | leds[8] = CHSV( 0, 0,255); // HSV White 109 | FastLED.show(); 110 | SendToProcessing(); // Send all the pixel data to Processing. 111 | delay(4000); 112 | FastLED.clear(); 113 | delay(500); 114 | break; 115 | } 116 | case 1:{ // Test RGB colors. 117 | for (int i=0; i < 5; i++){ 118 | leds[pixelNumber % NUM_LEDS] = CRGB(255, 0, 0); // RGB Red 119 | leds[pixelNumber+1 % NUM_LEDS] = CRGB( 0,255, 0); // RGB Green 120 | leds[pixelNumber+2 % NUM_LEDS] = CRGB( 0, 0,255); // RGB Blue 121 | leds[pixelNumber+3 % NUM_LEDS] = CRGB(255, 0,255); 122 | leds[pixelNumber+4 % NUM_LEDS] = CRGB( 0,255,255); 123 | leds[pixelNumber+5 % NUM_LEDS] = CRGB(255,255, 0); 124 | leds[pixelNumber+6 % NUM_LEDS] = CRGB(255,255,255); // RGB White 125 | FastLED.show(); 126 | SendToProcessing(); // Send all the pixel data to Processing. 127 | delay(1500); 128 | leds[pixelNumber % NUM_LEDS] = CRGB( 0, 0, 0); // RGB Black 129 | pixelNumber++; 130 | if (pixelNumber > NUM_LEDS){ pixelNumber = 0; } 131 | } 132 | fill_solid(leds, NUM_LEDS, CRGB::Black); // Black out strip. 133 | FastLED.show(); 134 | SendToProcessing(); // Send all the pixel data to Processing. 135 | break; 136 | } 137 | case 2:{ // Random colors. 138 | for (int i=0; i < 2; i++){ 139 | for (int x=0; x < NUM_LEDS; x++){ 140 | leds[random(NUM_LEDS)] = CRGB::Black; // Randomly turn on off. 141 | leds[random(NUM_LEDS)] = CRGB(random8(), random8(), random8()); 142 | FastLED.show(); 143 | SendToProcessing(); // Send all the pixel data to Processing. 144 | } 145 | delay(400); 146 | } 147 | break; 148 | } 149 | case 3:{ // Moving dots. 150 | for (int j=0; j < 2; j++){ 151 | for (int i=0; i < NUM_LEDS; i++){ 152 | int j = (i + (NUM_LEDS/3)) % NUM_LEDS; 153 | int k = (i + (2*NUM_LEDS/3)) % NUM_LEDS; 154 | leds[i] = CRGB(random8(80,255), random8(90,200), random8(0,80)); 155 | leds[j] = CRGB(random8(80,255), random8(90,200), random8(0,80)); 156 | leds[k] = CRGB(random8(80,255), random8(90,200), random8(0,80)); 157 | FastLED.show(); 158 | SendToProcessing(); // Send all the pixel data to Processing. 159 | leds[i] = CRGB::Black; 160 | leds[j] = CRGB::Black; 161 | leds[k] = CRGB::Black; 162 | delay(120); 163 | } 164 | } 165 | break; 166 | } 167 | case 4:{ // Rainbowygoodness. 168 | for (int i=0; i < 70; i++){ 169 | fill_rainbow( leds, NUM_LEDS, millis()/20); 170 | FastLED.show(); 171 | SendToProcessing(); // Send all the pixel data to Processing. 172 | delay(100); 173 | } 174 | fill_solid(leds, NUM_LEDS, CRGB::Black); // Black out strip. 175 | FastLED.show(); 176 | SendToProcessing(); // Send all the pixel data to Processing. 177 | delay(200); 178 | break; 179 | } 180 | default: 181 | pick = 0; 182 | } 183 | pick++; 184 | if (pick > 4){ pick = 0; } 185 | pixelNumber = 0; 186 | 187 | //**** 188 | } //****End of Processing 'linkedUp' check. 189 | //**** 190 | 191 | } //End of main loop 192 | //--------------------------------------------------------------- 193 | 194 | 195 | //**** 196 | //****The below two functions are needed for sending to Processing 197 | //-------------------- 198 | void firstContact() { 199 | if (testing == true){ 200 | linkedUp = true; // If testing, pretenct we've connected with Processing. 201 | } else { 202 | while (Serial.available() <= 0) { // Repeats until Processing responds. Hello? 203 | Serial.print('A'); // send an ASCII A (byte of value 65) 204 | delay(100); 205 | } 206 | // Once Processing responds send the number of pixels in our strip. 207 | Serial.write(NUM_LEDS); // Send then number of pixels in our LED strip. 208 | linkedUp = true; // Once connected with Processing set linkedUp to true. 209 | delay(500); 210 | } 211 | } 212 | 213 | //-------------------- 214 | // Whenever this function is called it sends ALL the pixel data to Processing. 215 | void SendToProcessing() { 216 | // Output verbose details when testing is true. 217 | // If NUM_LEDS is large this will be a lot of data! 218 | if (testing == true){ 219 | Serial.println("-------------------------------------------------------"); 220 | for (uint16_t d=0; d < NUM_LEDS; d++){ 221 | Serial.print("p: "); Serial.print(d); 222 | Serial.print("\tr: "); Serial.print(leds[d].r); 223 | Serial.print("\tg: "); Serial.print(leds[d].g); 224 | Serial.print("\tb: "); Serial.print(leds[d].b); 225 | Serial.println(" "); 226 | } 227 | Serial.println(" "); 228 | delay(50); // Add some extra delay when testing here. 229 | 230 | } else { 231 | // SEND ALL THE PIXEL DATA TO PROCESSING. 232 | for (uint16_t d=0; d < NUM_LEDS; d++){ 233 | Serial.write(d); // Pixel number 234 | Serial.write(leds[d].r); // Red channel data 235 | Serial.write(leds[d].g); // Green channel data 236 | Serial.write(leds[d].b); // Blue channel data 237 | } 238 | delay(holdTime); // Delay to slow things down if needed. 239 | } 240 | } 241 | 242 | //-------------------- 243 | //****End of the functions needed for sending to Processing 244 | //**** 245 | 246 | 247 | 248 | 249 | -------------------------------------------------------------------------------- /old_version/readme.txt: -------------------------------------------------------------------------------- 1 | Just some old versions saved in this folder. 2 | -------------------------------------------------------------------------------- /old_version/test_serial_from_arduino_v8.pde: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | test_serial_from_arduino_v8 3 | **************************************************************** 4 | This program receives data from the Arduino sketch: 5 | test_arduino_to_processing_v8.ino 6 | 7 | It listens for an ASCII letter A over serial and then responds with 8 | a letter A to confirm the connection. Once connected then it 9 | receives NUM_LEDS so it knows how many pixels are in the LED strip. 10 | 11 | Then it continues receiving the serial data as it's sent. Whenever 12 | it has accumulated **ALL the bytes for the LED strip it displays it 13 | on the simulated strip. It then goes back to receving data again. 14 | 15 | **ALL the data for a strip is 4 x NUM_LEDS worth of bytes, since for 16 | each pixel the Arduino is sending pixel number, red, green, blue 17 | values. This could get large if there are a lot of pixels! 18 | 19 | To run this Processing sketch, first upload the Arduino sketch onto 20 | your controller. Then you can play this Processing sketch. 21 | 22 | I've left the variable testing = true below. It will display a lot 23 | of data in the Processing monitor if NUM_LEDS is large. For testing 24 | things out and understanding how things work you might want to 25 | limit NUM_LEDS in your Arduino sketch to a smallish number. 26 | 27 | Every once in awhile while I've been testing this when I run the 28 | sketch I'll get an error (serial connection error?), but stopping 29 | and restarting it has always made it run fine again. 30 | 31 | Marc Miller 32 | Feb. 11, 2015 33 | *****************************************************************/ 34 | 35 | import processing.serial.*; 36 | 37 | Serial myPort; // The serial port. 38 | int[] serialInArray = new int[256*4]; // Where we'll put the data we receive. [***LIMITING TO 255 PIXELS FOR NOW***] 39 | // It's the number of pixels x 4 since we store _position and color_ data for pixel. 40 | int serialCount = 0; // A count of how many bytes we receive. 41 | int pixelCount = 0; // Count our pixels. 42 | boolean firstContact = false; // Whether we've heard from the microcontroller. Initially false. 43 | 44 | int stageWidth = 1100; // Width of stage draw area. 45 | int stageHeight = 128; // Height of stage draw area. 46 | int bgcolor = 42; // Stage background color. 47 | int pixelSize = 20; // Width and height of pixel. 48 | int pixelOffset = 30; // Pixel spacing (measured from center to center). 49 | int xstart = 40; // Position from left edge to center of first pixel. 50 | int xpos; // Stores a horizontal position. 51 | int xTemp; 52 | int ypos = 40; // Vertial position of pixel row (measured from top down). 53 | int pixelNumber = -1; // Pixel number from serial data. Initally set as -1 as a flag to trigger drawing of blank pixels. 54 | int redChan; // Red value (0-255) 55 | int greenChan; // Green value (0-255) 56 | int blueChan; // Blue value (0-255) 57 | int NUM_LEDS; // Number of pixels in strip. [***CURRENTLY BEING LIMITED TO 255 FOR NOW***] 58 | 59 | boolean testing = true; // Turn on/off testing mode. Shows pixelNumber and color data. [Ok to change.] 60 | boolean testing_verbose = false; // Verbose detail of incoming data. Default is false. [Ok to change.] 61 | 62 | 63 | //--------------------------------------------------------------- 64 | void setup() { 65 | size(stageWidth, stageHeight); // Stage size. 66 | noStroke(); // No border when drawing. 67 | //colorMode(RGB, 255); // Use Red, Green, Blue mode, using range from 0-255. 68 | colorMode(HSB, 255); // Use Hue, Saturation, Brightness(Value) mode, using range from 0-255. 69 | background(bgcolor); // Set stage bg color. 70 | rectMode(CENTER); // Rectangles are positioned based on their center. 71 | ellipseMode(CENTER); // Ellipses are positioned based on their center. 72 | 73 | // Print a list of the serial ports available (Useful for debugging). 74 | printArray(Serial.list()); 75 | 76 | // Open the port you're using by changing the number in brackets [n]. 77 | String portName = Serial.list()[0]; 78 | myPort = new Serial(this, portName, 115200); // Create the serial port. 79 | myPort.clear(); // Clear the serial port buffer. 80 | } 81 | 82 | 83 | //--------------------------------------------------------------- 84 | void draw() { 85 | // Nothing needed here since we only draw pixels as needed below 86 | } 87 | 88 | 89 | //--------------------------------------------------------------- 90 | void serialEvent(Serial myPort) { 91 | 92 | // Read a byte from the serial port. 93 | int inByte = myPort.read(); // Read the incoming data. Nom nom nom. 94 | if (testing_verbose == true) { 95 | print("inByte = " + inByte + " \t "); // Show what was nommed. 96 | } 97 | 98 | // If this is the first byte received, and will be an A. If true, 99 | // clear buffer, update firstContact, and draw empty(off) pixels. 100 | // Otherwise, start collecting the incoming bytes of pixel data. 101 | if (firstContact == false) { 102 | 103 | if (inByte == 'A') { 104 | myPort.write('A'); // Tell the arduino you're connect and want more. 105 | println("Contact established... "); 106 | 107 | } else { 108 | NUM_LEDS = inByte; 109 | println("NUM_LEDS = " + NUM_LEDS); 110 | 111 | myPort.clear(); // Clear the serial port buffer. 112 | firstContact = true; // First contact from the microcontroller established! 113 | 114 | if (pixelNumber == -1){ // Draw initial row of pixels (only happens once). 115 | for (int i=0; i> serialInArray[" + serialCount + "] = " + serialInArray[serialCount] + " <-- pixel number"); 135 | } 136 | if (serialCount % 4 != 0) { // Test if number not divisible by 4, aka the color data. 137 | println(" serialInArray[" + serialCount + "] = " + serialInArray[serialCount] + " "); 138 | } 139 | } 140 | 141 | serialCount++; // Increment count of the number of bytes stored in the array. 142 | 143 | if (serialCount == (NUM_LEDS*4)) { // True when we have all the data for the LED strip. 144 | 145 | if (testing == true) { println("--------------------------------------------------------------------------------"); } // Print when debugging 146 | 147 | for (int p=0; p < NUM_LEDS; p++) { 148 | xpos = xstart + (pixelOffset * serialInArray[4*p]); // Find pixel's horizontal draw position. 149 | redChan = serialInArray[(4*p)+1]; // Red value. 150 | greenChan = serialInArray[(4*p)+2]; // Green value. 151 | blueChan = serialInArray[(4*p)+3]; // Blue value. 152 | 153 | if (testing == true) { // Print values for debugging 154 | println(" pixelNumber " + p + "\t\t redChan " + redChan + "\t greenChan " + greenChan + "\t blueChan " + blueChan); 155 | } 156 | 157 | colorMode(RGB, 255); // Use Red, Green, Blue mode, using range from 0-255. 158 | fill(redChan,greenChan,blueChan); // Set fill color based on the RGB data we received. 159 | 160 | ellipse(xpos,ypos,pixelSize,pixelSize); // center x, center y, width, height 161 | } 162 | 163 | serialCount = 0; // Reset serial count before starting to receive data again. 164 | myPort.clear(); // Clear the serial port buffer. 165 | } 166 | } 167 | } //end serialEvent loop 168 | 169 | 170 | /*--------------------------------------------------------------- 171 | 172 | 173 | TODO ideas: 174 | - Double check that pixel color data is being correctly transfers and interpreted. 175 | Lit up LEDs look _SO_ different (glowing!) then colored dots on a monitor, 176 | it sometimes appears incorrect. 177 | 178 | - Update to allow pixel strip length greater then 255. 179 | 180 | - Wrap drawing of pixel row to multiple rows if there are more pixels then fit on monitor width. 181 | - Maybe auto scale size of pixels (and stage drawing area?) based on NUM_LEDS. 182 | 183 | - Add some info text to stage draw area? Maybe the pixel numbers? 184 | Probably something needed if multiple rows get drawn to help clarify pixel numbers. 185 | 186 | - Investigate drawing continuously by using the draw() section? Process a pixel imadiately once 4 bytes arive? 187 | 188 | - Add some sort of error checking if needed. Maybe send a response back to Arduino telling 189 | it to send next string of data (A continuous back and forth sort of talk). 190 | 191 | - Add a "glow" effect to lit pixels for extra fancyness! 192 | 193 | - FastLED's MASTER_BRIGHTNESS does not effect brightness in Processing. Maybe not really needed? 194 | 195 | - 196 | 197 | ----------------------------------------------------------------*/ 198 | 199 | 200 | -------------------------------------------------------------------------------- /test_serial_from_arduino_v10.pde: -------------------------------------------------------------------------------- 1 | /*============================================================================== 2 | test_serial_from_arduino_v10.pde 3 | Marc Miller, April 2015 4 | 5 | *** Note: You need to run this with the older Processing 2.2.1 *** 6 | ================================================================================ 7 | This Processing program receives pixel data from an Arduino sketch running 8 | FastLED. An Arduino demo sketch can be used to test it out: 9 | arduino_to_processing_v10.ino 10 | 11 | There are several user changeable variables to allow Processing to draw 12 | a pixel setup similar to what your physical pixel arrangement looks like, 13 | including drawing the pixels as a horizontal or verical strip, circular 14 | arrangement, or as a matrix of pixels. 15 | 16 | To use, first upload the Arduino sketch to your controler board. Then 17 | enter the number of pixels in your LED strip and run. Processing will 18 | connect to the Arduino and receive the pixel data, drawing a simulated 19 | LED strip. 20 | 21 | Note: Besides the user variables, another variable that might need to be 22 | changed is the port number for the serial connection. Change the number 23 | in [brackets] as needed on line 92. 24 | 25 | 26 | ================================================================================ 27 | ------------------------------------------------------------------------------*/ 28 | import processing.serial.*; 29 | 30 | 31 | //------------------------------------------------------------------------------ 32 | //============================================================================== 33 | // *** User variables. Change as needed to match your setup. *** 34 | int NUM_LEDS = 12; // Number of pixels in strip. 35 | String layout = "H"; // Pixel layout: [H]orizontal, [V]ertical, [M]atrix, or [C]ircular. 36 | String direction = "F"; // Numbering direction: [F]orward or [R]everse. 37 | 38 | // *** Additional variables for Matrix layout only. *** 39 | int numberColumns = 4; // Number of pixels across. 40 | int numberRows = 3; // Number of pixels vertically. 41 | String scanStart = "T"; // Matrix scan starts from: [T]op or [B]ottom. 42 | String path = "Z"; // Path type: [Z]igzag or [S]erpintine. 43 | 44 | 45 | boolean testing = false; // Testing mode, shows pixelNumber and color data. [default: false] 46 | boolean testing_verbose = false; // Verbose detail. Shows incoming data. [default: false] 47 | boolean checkNUM_LEDS = true; // Force check of NUM_LEDS vs pixels from MCU. [default: true] 48 | 49 | // End of user variables. 50 | //============================================================================== 51 | //------------------------------------------------------------------------------ 52 | 53 | 54 | //------------------------------------------------------------------------------ 55 | Serial myPort; // The serial port. 56 | int[] serialArray = new int[65535*4]; // To store the data we receive. [Limited to max 65,535 pixels.] 57 | // The above number is max pixels x 4, to save the position and R, G, B color data for each pixel. 58 | int inByte; // For storing incoming serial data. 59 | int serialCount = 0; // A count of how many bytes we receive. 60 | int receivedNUM_LEDS; // Number of pixels sent to Processing from MCU. Used for sanity check. 61 | int pixelCount = 0; // Count our pixels. 62 | int pixelNumber = -1; // Pixel number from serial data. Initally -1 to act as trigger. 63 | boolean firstContact = false; // Whether we've heard from the microcontroller. Initially false. 64 | int stageMin = 140; // Minimum stage size. 65 | int stageW = stageMin; // Initial stage width for draw area. 66 | int stageH = stageMin; // Initial stage height for draw area. 67 | int pixelSize = 20; // Width and height of a pixel. 68 | int offset = 30; // Pixel spacing (measured from pixel center to center). 69 | float xpos, ypos; // X and Y pixel position in the draw area. 70 | float dx,dy = 0; // X and Y delta from the stage center in circular layouts. 71 | int cCount = 0; // Used to keep track of column while drawing pixel matrix. 72 | int rCount = 0; // Used to keep track of row while drawing pixel matrix. 73 | float r = 1; // Radius for circular layout. Size is calculated elsewhere. 74 | float degrees = 0; // Degrees to rotate pixel boarder when drawing circular layout. 75 | int dir = 1; // Assigns draw direction a value. [1=Forward, -1=Reverse] 76 | int dirM = 1; // Assigns value to matrix scan start position. [1=Top, -1=Bottom] 77 | int bgcolor = 42; // Stage background color. 78 | int redChan; // Pixel's red value (0-255) 79 | int greenChan; // Pixel's green value (0-255) 80 | int blueChan; // Pixel's blue value (0-255) 81 | //============================================================================== 82 | 83 | 84 | //------------------------------------------------------------------------------ 85 | void setup() { 86 | 87 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 88 | // Print list of available serial ports (Useful for debugging). 89 | println ("Available serial ports: "); 90 | printArray(Serial.list()); 91 | println (" "); 92 | 93 | // Serial port to be used. Change number in [brackets] as needed. 94 | String portName = Serial.list()[0]; // <--- *port number* 95 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 96 | 97 | 98 | myPort = new Serial(this, portName, 115200); // Create the serial port. 99 | myPort.clear(); // Clear the serial port buffer. 100 | 101 | // Figure out how large to make the stage based on the layout and number of pixels. 102 | if (layout == "C") { 103 | // This seems to give a decent size based on the number of pixels in a circle. 104 | stageW = int(float((210 * NUM_LEDS)/19) + float(1800/19)); // width of stage draw area. 105 | stageH = stageW; // Make the stage square for circles. 106 | } 107 | if (layout == "H") { 108 | stageW = (NUM_LEDS + 1) * offset; // width of stage draw area. 109 | } 110 | if (layout == "V") { 111 | stageH = (NUM_LEDS + 1) * offset; // height of stage draw area. 112 | } 113 | if (layout == "M") { 114 | stageW = (numberColumns + 1) * offset; // width of stage draw area. 115 | stageH = (numberRows + 1) * offset; // height of stage draw area. 116 | } 117 | if (stageW < stageMin) { stageW = stageMin; } // Force at least a minimum stage width. 118 | if (stageH < stageMin) { stageH = stageMin; } // Force at least a minimum stage height. 119 | 120 | size(stageW,stageH); // Set the stage size. 121 | background(bgcolor); // Set stage bg color. 122 | smooth(); // Use anti-aliasing. 123 | noStroke(); // No border when drawing shapes. 124 | //colorMode(RGB, 255); // Use Red, Green, Blue color mode. Range from 0-255. 125 | colorMode(HSB, 255); // Use Hue, Saturation, Brightness color mode. Range from 0-255. 126 | rectMode(CENTER); // Rectangles are positioned based on their center. 127 | ellipseMode(CENTER); // Ellipses are positioned based on their center. 128 | 129 | if (direction == "R") { // If direction is Reverse, make dir variable negitive. 130 | dir = -1; 131 | } 132 | if (scanStart == "B") { // 133 | dirM = -1; 134 | } 135 | if (layout == "C" || layout == "V") { // Special case for circular layout. 136 | dir = dir * -1; // Make circular "forward" travel clockwise. 137 | } 138 | }//end setup() 139 | 140 | 141 | //------------------------------------------------------------------------------ 142 | void draw() { 143 | // Inital draw of pixel boarders (the white part) and "off" (dark) pixels. 144 | // This first conditional check will only be true once, thus the pixel 145 | // boarders are only drawn one time at start and not over and over again. 146 | if (pixelNumber == 0 && firstContact == false){ 147 | 148 | int boarderColor = 255; // Pixel board color for first pixel. 149 | if (layout == "C") { // Draw circular layout. 150 | degrees = 0; // Angle to rotate pixel while drawing around the circular layout. 151 | r = NUM_LEDS * 5; // Seems like a good ratio for scaling cirlce size based on number of pixels. 152 | translate(stageW/2, stageH/2); // Temporarily move grid 0,0 to center of stage draw area. 153 | for (int i=0; i (numberColumns * numberRows)) { 307 | println("**********************************************************************"); 308 | println(" NUM_LEDS is greater then numberColumns * numberRows [ " + (numberColumns * numberRows) + " ]"); 309 | println(" Please check the values of these variables. Processing halted."); 310 | println("**********************************************************************"); 311 | exit(); // Exit the program. 312 | } 313 | } 314 | 315 | delay(200); // *Required short delay* to guarantee "draw pixel boarders" in draw() becomes true. 316 | firstContact = true; // First contact info from the microcontroller finished! 317 | delay(100); 318 | } 319 | } 320 | }//End of initail first contact and receiving number of pixels. 321 | 322 | 323 | else { // Add the byte data for pixel info to the serial storage array. 324 | serialArray[serialCount] = inByte; // Nom nom nom! 325 | 326 | if (testing_verbose == true) { // Print a bunch of values for debugging 327 | if (serialCount % 4 == 0) { // Test if number is divisible by 4, aka a pixel numbers. 328 | println(" --> serialArray[" + serialCount + "] = " + serialArray[serialCount] + " <-- pixel number"); 329 | } 330 | else { // number is not divisible by 4, aka pixel color data. 331 | println(" serialArray[" + serialCount + "] = " + serialArray[serialCount] + " "); 332 | } 333 | }//end testing stuff. 334 | 335 | serialCount++; // Increment count of the number of bytes stored in the array. 336 | if (serialCount == (NUM_LEDS*4)) { // True when we have all the data for the LED strip. 337 | if (testing == true) { println("--------------------------------------------------------------------------------"); } // Print when debugging 338 | 339 | for (int p=0; p < NUM_LEDS; p++) { // Loop over pixels 340 | // Find pixel's R,G,B values. 341 | redChan = serialArray[(4*p)+1]; // Red value. 342 | greenChan = serialArray[(4*p)+2]; // Green value. 343 | blueChan = serialArray[(4*p)+3]; // Blue value. 344 | if (testing == true) { // Print values for debugging 345 | print(" pixelNumber " + p); 346 | println("\t\t redChan " + redChan + "\t greenChan " + greenChan + "\t blueChan " + blueChan); 347 | } 348 | colorMode(RGB, 255); // Specify color mode, using range from 0-255. 349 | fill(redChan,greenChan,blueChan); // Set fill color based on the RGB data we received. 350 | 351 | if (layout == "C") { // Draw circular pixels. 352 | dx = r * cos(radians(degrees)); 353 | dy = dir * r * sin(radians(degrees)); 354 | xpos = (float(stageW)/2.0)+dx; // x postion from center stage. 355 | ypos = (float(stageH)/2.0)+dy; // y postion from center stage. 356 | degrees = degrees - (360.0 / NUM_LEDS); // Rotate to next position around the circle. 357 | } 358 | 359 | if (layout == "H") { 360 | xpos = (stageW/2) - (dir*((NUM_LEDS-1) * offset)/2) + (serialArray[4*p] * offset * dir); 361 | ypos = stageH/2; 362 | } 363 | 364 | if (layout == "V") { 365 | xpos = stageW/2; 366 | ypos = (stageH/2) - (dir*((NUM_LEDS-1) * offset)/2) + (serialArray[4*p] * offset * dir); 367 | } 368 | 369 | if (layout == "M") { 370 | xpos = (float(stageW)/2.0) - (dir*float((numberColumns-1))/2.0*offset) + (dir*offset*cCount); 371 | ypos = (float(stageH)/2.0) - (dirM*float((numberRows-1))/2.0*offset) + (dirM*offset*rCount); 372 | //print(" cCount: " + cCount + " rCount: " + rCount); 373 | //print(" "+(cCount+1)+"+"+(rCount*numberColumns)+"="+(cCount+1+(rCount*numberColumns))); 374 | //println(" xpos: " + xpos + " ypos: " + ypos); 375 | cCount++; // Increment column counter. 376 | if ((cCount+(rCount*numberColumns)) == NUM_LEDS) { // If matrix is larger then NUM_LEDS, only draw actual pixels. 377 | cCount = 0; 378 | rCount = 0; 379 | } 380 | else if (cCount == (numberColumns)) { 381 | cCount = 0; // Reset column counter. 382 | rCount++; // Increment to move to next row. 383 | if (rCount == numberRows) { rCount = 0; } // Reset to zero. 384 | } 385 | } 386 | 387 | // Draw the pixel! 388 | ellipse(xpos,ypos,pixelSize,pixelSize); // center x, center y, width, height 389 | 390 | }//end of looping over pixels 391 | serialCount = 0; // Reset serial count before receiving more data. 392 | myPort.clear(); // Clear the serial port buffer. 393 | } 394 | } 395 | } //end serialEvent loop 396 | 397 | 398 | //============================================================================== 399 | 400 | 401 | /*------------------------------------------------------------------------------ 402 | TODO/ideas: 403 | - Impliment "Serpentine" path option. 404 | - Option for specifying pixel zero location (ie. 90,180,etc, degrees) on circlular layouts. 405 | - Matrix with vertical strips option? 406 | - CC colors in Processing to better match LEDs? Maybe gamma correction option? 407 | - Add some info text to stage draw area? 408 | A few pixel numbers or "->" to show layout direciton? 409 | - Do we need to send NUM_LEDS and pixel number from MCU to Processing? 410 | Or would just the color data be fine when specify the NUM_LEDS in Processing? 411 | - Any sort of error checking needed? 412 | - Check use of casting int to float. (float)n vs float(n) 413 | - 414 | 415 | ------------------------------------------------------------------------------*/ 416 | --------------------------------------------------------------------------------