/////////////////////////////////////////////////////////////////////////////// // // rgb.c // // A small ATtiny2313 program to control an RGB LED connected to // pins 0-2 of PORTB // // Switches on pins 0 and 1 of PORTD control the behavior of the LED // The default behavior is to slowly change colors. Alternate behavior is // to show a single color which can be selected. // /////////////////////////////////////////////////////////////////////////////// #include "rgb.h" /////////////////////////////////////////////////////////////////////////////// ISR(TIMER0_OVF_vect) //timer 0 interrupt for the pwm core. { uint8_t temp; static uint8_t count; // PWM count static uint8_t out; // Value to output to Port B count++; out = 0; // Turn pin on or off for each PWM for(temp = 0; temp < NUMBER_OF_PWMS; temp++) { if(pwms[temp] <= count) { out |= _BV(temp); } } // Output PWMs PORTB = out; // Reset interrupt timer TCNT0 = 255; } /////////////////////////////////////////////////////////////////////////////// void initButtons(void) { // Set up input buttons DDRD = 0b00000000; PORTD = 0b00000011; pollStatePrev = BUTTONS_CURRENT; } /////////////////////////////////////////////////////////////////////////////// void pollButtons(void) { pollState = BUTTONS_CURRENT; // Read the buttons pollStatePrev ^= pollState; // Set bits that have changed to 1 pressedButtons = pollStatePrev & pollState; // Set bits that have been pressed to 1 releasedButtons = pollStatePrev & ~pollState; // Set bits that have been released to 1 pollStatePrev = pollState; //Save the buttons for next time } /////////////////////////////////////////////////////////////////////////////// void delay(uint16_t a) { uint16_t b; // Simple delay loop for (b=0; b newpwms[temp]) { pwms[temp] -= 1; } } // If all the PWMs have reached their new colors if (done == NUMBER_OF_PWMS) { // Pick a random color (other than black) // Each pin is either on or off without all pins being off done = (rand() % 6) + 1; // Set up PWMs for each pin for(temp=0; temp < NUMBER_OF_PWMS; temp++) { newpwms[temp] = ((done >> temp) & 0x01) * 255; } } } // Get the state of the buttons on Port D pollButtons(); // If mode button is pressed, change mode if (releasedButtons & BUTTON_MODE) { mode ^= 1; // If solid color mode, set color if (mode) { setColor(); } } // If change button is pressed if (releasedButtons & BUTTON_CHANGE){ // Change speed that colors change if (mode == 0) { speed += 0x40; if (speed > 0x80) { speed = 0; } // Blink LED to show speed: 1 = Fast, 2 = Med, 3 = Slow cli(); for (temp = (speed >> 6) + 1; temp > 0; temp--) { PORTB = 0x00; delay(BLINK_RATE); PORTB = 0x07; delay(BLINK_RATE); } PORTB = 0x00; delay(BLINK_DELAY); sei(); // Or change color of LED } else { color += 1; color &= 0b00000111; if (!color) { color += 1; } setColor(); } } } }