Click here to see the entire LED FireFly Lights Project.
Now that I’ve got my firefly test LEDs to fade in and out randomly (Project: LED Firefly Lights – Post #4 Random Fade Test) I’ve decided to try to replicate what real fireflies look like when they flash. I’ve found this video on youtube that shows how they flash and it also shows a some LED firefly lights a company in California has made called FireFly Magic.
For the code I mostly just inverted the DelayOn and DelayOff. I did add an extra #define to take the place of the direction 1 or -1 so I could easily change the speed at which I change the LED brightness. I also changed the name of the fade variable in the LED structure to FadeDelay. To see the old version of the code check out Post #4.
Here is what the test fireflies look like now; they don’t blink as fast as real fireflies my wife prefers them to go a bit slower. The speed can easily be changed by changing the #define constants.
Here is the new code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | #include <avr/io.h> #include <avr/interrupt.h> #include <stdlib.h> volatile unsigned int vCount = 0; volatile unsigned char vPORTA = 0; volatile unsigned char vPORTB = 0; volatile unsigned char vPORTC = 0; volatile unsigned char vPORTD = 0; volatile unsigned char vPORTE = 0; #define cLED_CNT 16 #define cFADEDELAY 3 #define cDELAYOFFMAX 1500 #define cDELAYON 1 #define cBRIGHTMAX 100 #define cFADESPEED 5 struct LED { char Port; char Bit; int Brightness; int Direction; int DelayOn; int DelayOff; int FadeDelay; }; volatile struct LED LEDArray[cLED_CNT]; /* Main Function */ int main(void) { int vI; /* Initialize Timer0 */ // Enable timer0 compare interrupt TIMSK0 = (1<<OCIE0A); // Sets the compare value OCR0A = 12; // Set Clear on Timer Compare (CTC) mode, prescaler TCCR0A = (1<<WGM01)|(0<<WGM00)|(3<<CS00); /* Initialize Ports for output */ DDRA = 0xFF; DDRB = 0xFF; DDRC = 0xFF; DDRD = 0xFF; DDRE = 0xFF; /* Initialize LED Array */ for(vI = 0; vI < cLED_CNT; vI++) { if (vI < 8) { LEDArray[vI].Port = 'B'; LEDArray[vI].Bit = vI; } else { LEDArray[vI].Port = 'D'; LEDArray[vI].Bit = vI - 8; } LEDArray[vI].Brightness = 0; LEDArray[vI].Direction = cFADESPEED; LEDArray[vI].DelayOff = (rand() % cDELAYOFFMAX) + 1; LEDArray[vI].DelayOn = cDELAYON; LEDArray[vI].FadeDelay = cFADEDELAY; } // Enable Interrupts sei(); // Main program loop while(1) { } return 0; } /* Handle Timer Interrupt */ ISR (TIMER0_COMP_vect) { int vI = 0; vCount++; if (vCount >= 100) vCount = 0; if (vCount == 0) { //vPORTA = 0xFF; vPORTB = 0xFF; //vPORTC = 0xFF; vPORTD = 0xFF; //vPORTE = 0xFF; } for (vI = 0; vI < cLED_CNT; vI++) { if ((LEDArray[vI].Brightness <= 0) | (LEDArray[vI].Brightness == vCount)) { switch (LEDArray[vI].Port) { case 'A': vPORTA &= ~(1 << LEDArray[vI].Bit);break; case 'B': vPORTB &= ~(1 << LEDArray[vI].Bit);break; case 'C': vPORTC &= ~(1 << LEDArray[vI].Bit);break; case 'D': vPORTD &= ~(1 << LEDArray[vI].Bit);break; case 'E': vPORTE &= ~(1 << LEDArray[vI].Bit);break; } } if (vCount == 0) { LEDArray[vI].DelayOff--; if (LEDArray[vI].DelayOff == 0) { LEDArray[vI].DelayOff = 1; LEDArray[vI].FadeDelay--; if (LEDArray[vI].FadeDelay == 0) { LEDArray[vI].FadeDelay = cFADEDELAY; LEDArray[vI].Brightness += LEDArray[vI].Direction; if (LEDArray[vI].Brightness >= cBRIGHTMAX) { LEDArray[vI].Brightness = cBRIGHTMAX-1; LEDArray[vI].DelayOn--; if (LEDArray[vI].DelayOn == 0) { LEDArray[vI].Direction = -1 * cFADESPEED; LEDArray[vI].DelayOn = cDELAYON; } } if (LEDArray[vI].Brightness <= 0) { LEDArray[vI].Direction = cFADESPEED; LEDArray[vI].DelayOff = (rand() % cDELAYOFFMAX) + 1; } } } } } //PORTA = vPORTA; PORTB = vPORTB; //PORTC = vPORTC; PORTD = vPORTD; //PORTE = vPORTE; } |

