unsigned long previousMillis = 0; /////////////// R, G, B LEDS /////////////// #define PIN_LED_R 16 #define PIN_LED_G 0 #define PIN_LED_B 1 unsigned long previousMillisPixel = 0; int pin_on = 0; /////////////// RGB LED /////////////// #define PIN_LED_RGB_R 9 #define PIN_LED_RGB_G 10 #define PIN_LED_RGB_B 11 unsigned long previousMillisRGB = 0; unsigned long previousMillisB = 0; bool rgb_b_state = false; int hue_current = 0; byte rgb_r; byte rgb_g; byte rgb_b; //const byte COLOR_BLACK[] = {0,0,0}; //OFF really //const byte COLOR_WHITE[] = {255,255,255}; //const byte COLOR_BLUE[] = {0,0,255}; //const byte COLOR_RED[] = {255,0,0}; //const byte COLOR_GREEN[] = {0,255,0}; // //const byte COLOR_YELLOW[] = {255,228,0}; //const byte COLOR_ORANGE[] = {255,60,0}; //255,119,0 //const byte COLOR_DEEP_PINK[] = {255,20,147}; //const byte COLOR_MAGENTA[] = {255,0,255}; //const byte COLOR_TURQUOISE[] = {64,244,208}; //const byte COLOR_TEAL[] = {0,128,128}; /////////////// IR /////////////// #define PIN_LED_IR 14 #define PIN_PHOTO_IR 15 int base_value_ir = 512; int value_ir = 0; /////////////// CHARLIEPLEXING /////////////// #define PIN_CP_1 2 #define PIN_CP_2 3 #define PIN_CP_3 4 #define PIN_CP_4 5 #define PIN_CONFIG 0 #define PIN_STATE 1 #define LED_NUM 12 int matrix[LED_NUM][2][4] = { // PIN_CONFIG PIN_STATE // 1 2 3 4 1 2 3 4 { { OUTPUT, OUTPUT, INPUT, INPUT }, { HIGH, LOW, LOW, LOW } }, //LED no. 1 { { OUTPUT, OUTPUT, INPUT, INPUT }, { LOW, HIGH, LOW, LOW } }, //2 { { INPUT, OUTPUT, OUTPUT, INPUT }, { LOW, HIGH, LOW, LOW } }, //3 { { INPUT, OUTPUT, OUTPUT, INPUT }, { LOW, LOW, HIGH, LOW } }, //4 { { INPUT, INPUT, OUTPUT, OUTPUT }, { LOW, LOW, HIGH, LOW } }, //5 { { INPUT, INPUT, OUTPUT, OUTPUT }, { LOW, LOW, LOW, HIGH } }, //6 { { OUTPUT, INPUT, OUTPUT, INPUT }, { HIGH, LOW, LOW, LOW } }, //7 { { OUTPUT, INPUT, OUTPUT, INPUT }, { LOW, LOW, HIGH, LOW } }, //8 { { INPUT, OUTPUT, INPUT, OUTPUT }, { LOW, HIGH, LOW, LOW } }, //9 { { INPUT, OUTPUT, INPUT, OUTPUT }, { LOW, LOW, LOW, HIGH } }, //10 { { OUTPUT, INPUT, INPUT, OUTPUT }, { HIGH, LOW, LOW, LOW } }, //11 { { OUTPUT, INPUT, INPUT, OUTPUT }, { LOW, LOW, LOW, HIGH } } //12 }; //Keeps track of which LED is on during the roundCircleLight function byte round_led_num = 0; //Keeps track of the LED and group during the crossLightNoDelay function byte group = 0; byte group_led_num = 0; int loops_passed = 0; int hue_delay = 100; /////////////// CHARLIEPLEXING FUNCTIONS /////////////// ////////////////////////////////////////////// void lightOn( int led ) { pinMode( PIN_CP_1, matrix[led][PIN_CONFIG][0] ); pinMode( PIN_CP_2, matrix[led][PIN_CONFIG][1] ); pinMode( PIN_CP_3, matrix[led][PIN_CONFIG][2] ); pinMode( PIN_CP_4, matrix[led][PIN_CONFIG][3] ); digitalWrite( PIN_CP_1, matrix[led][PIN_STATE][0] ); digitalWrite( PIN_CP_2, matrix[led][PIN_STATE][1] ); digitalWrite( PIN_CP_3, matrix[led][PIN_STATE][2] ); digitalWrite( PIN_CP_4, matrix[led][PIN_STATE][3] ); }//void lightOn ////////////////////////////////////////////// //Turn on all LEDs at one (seemingly) void allLightOn() { //Seemingly all on for(int l = 0; l < LED_NUM; l++) { lightOn(l); delay(1); }//for l }//void allLightOn ////////////////////////////////////////////// //Make a LED run arounda circle void roundCircleLight() { //The "no-delay" option unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= 500 / LED_NUM) { previousMillis = currentMillis; lightOn(round_led_num); round_led_num = (round_led_num + 1) % LED_NUM; //cycle through NUM_LEDs }//if //The "with-delay" option //for(int l = 0; l < LED_NUM; l++) { //lightOn(l); //delay( 500 / LED_NUM ); //}//for l }//void roundCircleLight ////////////////////////////////////////////// //Turn on all LEDs of the same color group void crossLight(int group, int time_on = 250, int del = 3) { int num_loops = time_on/(del*4); for(int i = 0; i < num_loops; i++) { lightOn(group); delay(del); lightOn(group + 3); delay(del); lightOn(group + 6); delay(del); lightOn(group + 9); delay(del); }//for i }//void crossLight //Turn on all LEDs of the same color group void crossLightNoDelay(int time_on = 350, int del = 3) { int num_loops = time_on/(del*4); lightOn(checkGroupTime(group, del)); if(loops_passed >= num_loops) { loops_passed = 0; group = (group + 1) % 3; }//if }//void crossLightNoDelay byte checkGroupTime(int group, int del) { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= del) { previousMillis = currentMillis; if(group_led_num >= 9) loops_passed = loops_passed + 1; group_led_num = (group_led_num + 3) % LED_NUM; }//if return group + group_led_num; }//int checkGroupTime /////////////// RGB LED FUNCTIONS /////////////// void softwarePWM(int led_pin, float brightness = 0.1, float hz = 50) { unsigned long currentMillis = millis(); //A "no-delay" version if(rgb_b_state == false) { if (currentMillis - previousMillisB >= (1000./hz) * brightness) { previousMillisB = currentMillis; rgb_b_state = true; digitalWrite(led_pin, HIGH); }//if } else { if (currentMillis - previousMillisB >= (1000./hz) * (1 - brightness)) { previousMillisB = currentMillis; rgb_b_state = false; digitalWrite(led_pin, LOW); }//if }//else // digitalWrite(led_pin, LOW); // delay((1000./hz) * brightness); // ON for this long // digitalWrite(led_pin, HIGH); // delay((1000./hz) * (1 - brightness)); // OFF for this long }//void softwarePWM void displayColor(byte color[]) { analogWrite(PIN_LED_RGB_R, map(color[0], 0, 255, 255, 0)); analogWrite(PIN_LED_RGB_G, map(color[1], 0, 255, 255, 0)); //analogWrite(PIN_LED_RGB_B, map(color[2], 0, 255, 255, 0)); //The blue LED doesn't support PWM it seems, even though the datasheet seems to indicate so //analogWrite doesn't work, it turns fully on for any value other than OFF //analogWrite(PIN_LED_RGB_B, map(color[2], 0, 255, 0., 1.)); if(color[2] == 0) digitalWrite(PIN_LED_RGB_B, HIGH); //OFF else if(color[2] == 255) digitalWrite(PIN_LED_RGB_B, LOW); //ON else softwarePWM(PIN_LED_RGB_B, color[2]/255., 100); }//void displayColor void rainbowLoop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillisRGB >= hue_delay) { previousMillisRGB = currentMillis; HSVtoRGB(rgb_r, rgb_g, rgb_b, hue_current, 255, 255); hue_current = (hue_current + 1) % 360; //cycle through the hues }//if byte color[3] = {rgb_r, rgb_g, rgb_b}; displayColor(color); }//void rainbowLoop /////////////// SEPARATE R, G, & B LED FUNCTIONS /////////////// //Loop between the R, G & B LEDs, showing each on for 0.5 seconds //Using a "no-delay" version void blinkRGB() { unsigned long currentMillis = millis(); if (currentMillis - previousMillisPixel >= 100) { previousMillisPixel = currentMillis; pin_on = (pin_on + 1) % 3; int r = 0; int g = 0; int b = 0; if(pin_on == 0) { r = 255; } else if(pin_on == 1) { g = 255; } else { b = 255; } analogWrite(PIN_LED_R, r); analogWrite(PIN_LED_G, g); analogWrite(PIN_LED_B, b); }//if }//void blinkRGB ///////////////////////////////////// /////////////// SETUP /////////////// ///////////////////////////////////// void setup() { Serial.begin(9600); //R, G & B LEDs pinMode(PIN_LED_R, OUTPUT); pinMode(PIN_LED_G, OUTPUT); pinMode(PIN_LED_B, OUTPUT); //RGB LED pinMode(PIN_LED_RGB_R, OUTPUT); pinMode(PIN_LED_RGB_G, OUTPUT); pinMode(PIN_LED_RGB_B, OUTPUT); analogWrite(PIN_LED_RGB_R, 255); //= off analogWrite(PIN_LED_RGB_B, 255); analogWrite(PIN_LED_RGB_G, 255); //IR pinMode(PIN_LED_IR, OUTPUT); digitalWrite(PIN_LED_IR, HIGH); pinMode(PIN_PHOTO_IR, INPUT); //Wait a bit before capturing a base value delay(3000); base_value_ir = analogRead(PIN_PHOTO_IR); Serial.print("Base value = "); Serial.println(base_value_ir); }//void setup //////////////////////////////////// /////////////// LOOP /////////////// //////////////////////////////////// void loop() { //////// R, G and B LEDs //////// // digitalWrite(PIN_LED_R, HIGH); // digitalWrite(PIN_LED_G, HIGH); // digitalWrite(PIN_LED_B, HIGH); // analogWrite(PIN_LED_R, 50); // analogWrite(PIN_LED_G, 255); // analogWrite(PIN_LED_B, 100); //////// RGB LED //////// // displayColor(COLOR_DEEP_PINK); rainbowLoop(); //////// CHARLIEPLEXING //////// // allLightOn(); // roundCircleLight(); // //Make all blue LEDs turn on (seemingly) // //and then all the red ones and then the yellow ones // crossLight(0); // crossLight(1); // crossLight(2); // crossLightNoDelay(); //////// IR //////// value_ir = analogRead(PIN_PHOTO_IR); //Serial.println(value_ir); ////////////////////////////////////////////////////////////////// // Switch functions depending on covering up of phototransistor // ////////////////////////////////////////////////////////////////// if(value_ir > (base_value_ir + 20) || value_ir < (base_value_ir - 20)) { roundCircleLight(); hue_delay = 5; blinkRGB(); } else { crossLightNoDelay(); hue_delay = 100; //Show all R, G & B LEDs on analogWrite(PIN_LED_R, 50); analogWrite(PIN_LED_G, 255); analogWrite(PIN_LED_B, 100); }//else //delay(50); }//void loop //From the NeoPixel library void HSVtoRGB(byte & rgb_r, byte & rgb_g, byte & rgb_b, unsigned int hue, byte sat, byte val) { //Set led by hue, saturation, value unsigned char r,g,b; unsigned int H_accent = hue/60; unsigned int bottom = ((255 - sat) * val)>>8; unsigned int top = val; unsigned char rising = ((top-bottom) *(hue%60 ) ) / 60 + bottom; unsigned char falling = ((top-bottom) *(60-hue%60) ) / 60 + bottom; switch(H_accent) { case 0: r = top; g = rising; b = bottom; break; case 1: r = falling; g = top; b = bottom; break; case 2: r = bottom; g = top; b = rising; break; case 3: r = bottom; g = falling; b = top; break; case 4: r = rising; g = bottom; b = top; break; case 5: r = top; g = bottom; b = falling; break; } rgb_r = (byte)r; rgb_g = (byte)g; rgb_b = (byte)b; }//HSVtoRGB