One Button Timer – An Easy Programming Project?

Posted: January 27, 2012 in Hard Projects, Programming, Projects
Tags: , ,

Hello again! Seems like its been awhile since I’ve done a blog post! But maybe there’s a chance I’ll continue this time…

So, I decided to make a quick project, a one button timer, or per-say, a one button reprogrammable timer. How does it work?



As you can see from the photo from above, when you plug in the device, its starts flashing the red LED every 1 second (+- slight inaccuracy). But you can change the flash rate by pressing the white button! Click it 3 times fast, and it will speed up. Click it and hold the button down for a few seconds 3 times, and it will slow down!

Now you may be wondering, why make a one button timer? By itself, it doesn’t have much use. But it is a good training project for bigger projects. For example, the Yamaha M7CL uses a similar timer for delaying sound output for sound fx. Like echo, you can press the button several times, and set how fast or slow the voice repeats. You could also use this timer for guitar pedals. Am I planning to make a sound board anytime soon? Probably not. Could I make a guitar pedal in the future? Most likely, once I figure out how to decode my MIDI Guitar for Rock Band and able to play it separate from the video game without paying a lot of money for a MIDI decoder.

So what in the world am I making this for, and why am I taking so long to tell you? I’m planning a cheater for Rock Band 3. I’ve seen a similar project at some point on the web, but there were a few problems:

  1. Not Open Source
  2. Expensive, for the amount of electronics – $60.00!
  3. I can’t say I made it…

The goals of this future project is to make it Open Source. As you will notice below, I have posted all the code for this timer program. Also, the project doesn’t require many components, so why charge so much? Maybe I should try making a professional board when its done, and sell it on ebay or something. And last, its a good accomplishment, furthers my knowledge in programming, and more so Electrical Engineering.

Here’s the code:

/*****

CrBy: Michael Cherry

DATE: 2612A

REVS: 1.21

NTES: 
	
	Open Source! OSHW. (CC) Michael Cherry. All rights reserved.

        Feel free to use and modify this code, just make sure to mention that you 
             got it from me or from my blog: mlccStudios.wordpress.com

	mills() = 8000 = close to 1 second

*****/
// ---------- Includes ----------- //
#include <avr/io.h>

#include <avr/interrupt.h>
#include <stdbool.h>

// ---------- Variables ---------- //
int Rate = 124;								// Rate for OCR1A
volatile unsigned long milliseconds;		// Holds count from Timer1

long btnHoldtime = 0;
long LEDrate1 = 8000;						// Holds LEDrate for flashing led
long LEDrate2 = 8000;
long LEDrate3 = 8000;
//long LEDrate4 = 8000;						// Not used in current version

int btnPresses = 1;							// Counts how many times a user pressed button
int rateUsage = 0;

bool rate1used = false;						// Checks if a specific rate has been used yet
bool rate2used = true;
bool rate3used = true;
//bool rate4used = true;					// Not used in current version
bool btnPressed = false;					// Checks if user is currently pressing button
bool enableLED = true;						// Enables the LED to flash

// ---------- Functions ---------- //
void Prgm_Init(void);						// Setup Program
void resetMillis(void);						// Reset millisecond counter
unsigned long millis(void);					// volatile millis that gets milliseconds count

int main (void) {				// Main Loop
		
	Prgm_Init();				// Setup Program
	
	for (;;) {					// Infinite For Loop
		
		// Check if button has been pressed
		if ( btnPressed == true ) {
			if ( bit_is_clear(PINB,PB1) ) {
				if ( btnPresses == 1 ) {
					PORTB ^= (1<<PB0);
					LEDrate1 = millis() - btnHoldtime;
					btnPressed = false;
					btnPresses++;
				}
				else if ( btnPresses == 2 ) {
					PORTB ^= (1<<PB0);
					LEDrate2 = millis() - btnHoldtime;
					btnPressed = false;
					btnPresses++;
				}
				else if ( btnPresses == 3 ) {
					PORTB ^= (1<<PB0);
					LEDrate3 = millis() - btnHoldtime;
					btnPressed = false;
					enableLED = true;
					btnPresses = 1;
					resetMillis();
				}
				// Implement in next version
				/*else if ( btnPresses == 4 ) {
					PORTB ^= (1<<PB0);
					LEDrate4 = millis() - btnHoldtime;
					btnPressed = false;
					enableLED = true;
					btnPresses = 1;
					resetMillis();
				}*/
			}
		}
		else if ( bit_is_set(PINB,PB1) ) {
			PORTB |= (1<<PB0);
			btnHoldtime = millis();
			btnPressed = true;
			enableLED = false;
		}
		
		if ( enableLED == true ) {
			if ( millis() == LEDrate1 && rate1used == false ) {
				PORTB ^= (1<<PB0);
				if ( rateUsage == 1 ) {
					rate1used = true;
					rate2used = false;
					rateUsage = 0;
				}
				else { rateUsage = 1; }
				resetMillis();
			}
			else if ( millis() == LEDrate2 && rate2used == false ) {
				PORTB ^= (1<<PB0);
				if ( rateUsage == 1 ) {
					rate2used = true;
					rate3used = false;
					rateUsage = 0;
				}
				else { rateUsage = 1; }
				resetMillis();
			}
			else if ( millis() == LEDrate3 && rate3used == false ) {
				PORTB ^= (1<<PB0);
				if ( rateUsage == 1 ) {
					rate3used = true;
					rate1used = false;
					rateUsage = 0;
				}
				else { rateUsage = 1; }
				resetMillis();
			}
			// Implement in next version
			/*else if ( millis() == LEDrate4 && rate4used == false ) {
				PORTB ^= (1<<PB0);
				if ( rateUsage == 1 ) {
					rate4used = true;
					rate1used = false;
					rateUsage = 0;
				}
				else { rateUsage = 1; }
				resetMillis();
			}*/
		}
	}
}

void Prgm_Init() {				// Setup Program IO and Timer1
	
    DDRB |= 0b00000001;		        // PB1 - INPUT	| PB0 - OUTPUT
	
    TCCR1B |= (1 << WGM12); 	// Configure timer 1 for CTC mode
    TIMSK1 |= (1 << OCIE1A); 	// Enable CTC interrupt
    sei(); 				      // Enable global interrupts
    OCR1A = Rate;			  // Set CTC compare value to 1000Hz(1MHzclock), prescaler of 8
    TCCR1B |= (1 << CS10); 	// Start timer at Fcpu/8
}

unsigned long millis(void) {	// Returns milliseconds that have passed since micro turned on
	return milliseconds;
}

void resetMillis() {			// Resets milliseconds counter
	milliseconds = 0;
}

ISR(TIMER1_COMPA_vect) {		// Timer1 Interrupt
	
	milliseconds++;			// Increment millisecond counter every 1/1000th of a second
	
   //PORTB ^= (1 << 0); // Toggle the LED
} 

 

So there you have it, the One button Timer! Enjoy! Hopefully I’ll be updating a lot in the next few weeks, especially since I mentioned the “Rock Band Cheater” project (hint, hint…)

EasternFireTail, signing out!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s