fj604 34 Posted March 15, 2012 Share Posted March 15, 2012 The 2211 chip that came with the Launchpad is not useless! Here is what can be done with it: I decided to drive a LED matrix with the AS1106 chip from Austria Microsystems. It is a an equivalent of MAX7219 but can work with 3.3V that Launchpad supplies. Two buttons on a breadboard move the "catcher", and a single button on the Launchpad changes the game speed. Launchpad LEDs are used to indicate a catch (green) or a miss (red). A piezo buzzer can be added for (very annoying) sound effects beeps. I thought the whole thing has a certain 1970's touch to it #include #include #define DATA_PIN BIT4 // data for AS1106 #define LOAD_PIN BIT5 // load for AS1106 #define CLOCK_PIN BIT7 // clock for AS1106 #define BL_PIN BIT1 // Left button #define BR_PIN BIT2 // Right button #define SPEED_PIN BIT3 // Speed increase button #define GREEN_PIN BIT6 // Green LED on Launchpad (LED2) #define RED_PIN BIT0 // Red LED on Launchpad (LED1) #define BUZZER_PIN BIT7 // Piezo BUZZER = XOUT = P2.7 #define MAX_DELAY 2500 // Slowest speed #define MIN_DELAY 1000 // Fastest speed #define STEP_DELAY 300 // Speed step #define TONE_CATCH 5 // Tone on catch #define TONE_MISS 10 // Tone on miss #define TONE_CHIRP 2 // Chirp tone #define CHIRP_DUR 10 // Chirp duration #define TONE_DUR 300 // Catch / miss tone duration unsigned char bitmap[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; volatile unsigned char t = 3, // catcher x position refresh = 0, // flag to refresh matrix refreshing = 0; // set during refresh volatile unsigned int clk = 0, // clock ticks, 1 tick = 1/10000 sec delay = MAX_DELAY, // step delay tone = 0, // tone frequency, 1 = 5000 Hz, 5 = 1000 Hz sound = 0; // sound duration in ticks void pixel_set(unsigned char x, unsigned char y) { bitmap[x] |= 1 << y; } void pixel_clear(unsigned char x, unsigned char y) { bitmap[x] &= ~ (1 << y); } // Shift out data, MSB first void shiftout(unsigned char data) { unsigned char n; for (n = 0; n < 8; n++) { if (data & BIT7) P1OUT |= DATA_PIN; else P1OUT &= ~DATA_PIN; P1OUT |= CLOCK_PIN; P1OUT &= ~CLOCK_PIN; data <<= 1; } } // Send command to AS1106 void as1106(unsigned char addr, unsigned char data) { P1OUT &= ~LOAD_PIN; shiftout(addr); shiftout(data); P1OUT |= LOAD_PIN; } // show bitmap on the matrix void display(void) { refreshing = 1; // Set flag so that we do not change bitmap during refresh unsigned char c; for (c = 0; c < 8; c++) as1106(c + 1, bitmap[c]); refreshing = 0; // Clear flag } void as1106_init(void) { P1DIR |= (DATA_PIN | LOAD_PIN | CLOCK_PIN); P1OUT |= LOAD_PIN; P1OUT &= ~CLOCK_PIN; as1106(0x0C, 0x00); // shutdown display(); as1106(0x0F, 0x01); // Test on _delay_cycles(400000); as1106(0x0F, 0x00); // Test off _delay_cycles(200000); as1106(0x0E, BIT1); // Reset all control registers _delay_cycles(100); as1106(0x0E, 0); // Normal operation as1106(0x09, 0x00); // No decode as1106(0x0A, 0x0F); // full brightness as1106(0x0B, 0x0F); // display all rows as1106(0x0C, 0x81); // No shutdown } void clock_init(void) { BCSCTL1 = CALBC1_1MHZ; // Set DCO DCOCTL = CALDCO_1MHZ; } void timer_init(void) { TACCR0 = 100; // Generate interrupt 10000 times per second TACTL = TASSEL_2 + MC_1; // SMCLK, upmode TACCTL0 = CCIE; // Capture/Compare Interrupt Enable } void sound_init(void) { P2SEL = 0; // Disable XIN/XOUT P2DIR = BUZZER_PIN; // XOUT pin = P2.7 } void intro_sound(void) { for (tone = 10; tone > 0; tone--) { sound = 500; while(sound) ; } } void button_init(void) { P1DIR &= ~(BL_PIN | BR_PIN | SPEED_PIN); P1OUT |= BL_PIN | BR_PIN ; // Pull up P1REN |= BL_PIN | BR_PIN ; // Enable pull up resistors P1IE |= BL_PIN | BR_PIN | SPEED_PIN; // Interrupt enable P1IES |= BL_PIN | BR_PIN | SPEED_PIN; // Interrupt Edge Select high-to-low P1IFG &= ~ (BL_PIN | BR_PIN | SPEED_PIN); // Clear interrupt flag } void main(void) { unsigned char n, p; // n = dot y, p = catcher x, WDTCTL = WDTPW + WDTHOLD; // Disable watchdog timer (WDT) as1106_init(); button_init(); timer_init(); sound_init(); P1DIR |= RED_PIN | GREEN_PIN; P1OUT &= ~(RED_PIN | GREEN_PIN); pixel_set(t, 7); pixel_set(t+1, 7); _enable_interrupts(); intro_sound(); for (; { p = rand() % 8; // random drop x position for (n = 0; n < 7; n++) // drop { pixel_set(p, n); display(); refresh = 0; clk = 0; tone = TONE_CHIRP; sound = CHIRP_DUR; while (clk < delay) { _low_power_mode_0(); if (refresh) { display(); refresh = 0; } } pixel_clear(p, n); } if ((p == t) || (p == t + 1)) // if caught { P1OUT |= GREEN_PIN; P1OUT &= ~RED_PIN; tone = TONE_CATCH; } else { P1OUT &= ~GREEN_PIN; P1OUT |= RED_PIN; tone = TONE_MISS; } sound = TONE_DUR; } } #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { if (P1IFG & SPEED_PIN) // speed switch { if ((delay-= STEP_DELAY) < MIN_DELAY) delay = MAX_DELAY; } else if ((P1IFG & BL_PIN) && (t > 0) && !refreshing) // left { pixel_clear(t + 1, 7); pixel_set(--t, 7); refresh = 1; } else if ((P1IFG & BR_PIN) && (t < 6) && !refreshing) // right { pixel_clear(t, 7); pixel_set(++t + 1, 7); refresh = 1; } P1IFG &= ~ (BL_PIN | BR_PIN | SPEED_PIN); // clear interrupt flags for all buttons _low_power_mode_off_on_exit(); } #pragma vector=TIMERA0_VECTOR __interrupt void Timer_A (void) { static unsigned int z; clk++; if (sound) { --sound; if ((z++ % tone) == 0) P2OUT ^= BUZZER_PIN; // vibrate buzzer } _low_power_mode_off_on_exit(); } oPossum, cubeberg, dacoffey and 3 others 6 Quote Link to post Share on other sites
timotet 44 Posted March 15, 2012 Share Posted March 15, 2012 Great job The sound effects make it that much cooler! Quote Link to post Share on other sites
dacoffey 5 Posted March 16, 2012 Share Posted March 16, 2012 This is very cool Quote Link to post Share on other sites
ozymandias 7 Posted March 16, 2012 Share Posted March 16, 2012 super sweet! is there a perf. board in a case version coming along? Quote Link to post Share on other sites
fj604 34 Posted March 16, 2012 Author Share Posted March 16, 2012 I've never encased any of my projects before, but tempted to make a case for this one - and the next which I hope to finish soon and post here. I am mortally terrified of a thought of having to find a suitable case and have no idea how to mount a LED matrix into it. This article/video http://blog.makezine.com/2010/04/27/circuit-skills-electronics-enlosure/ explains the basics, but does not tell how to mount things like LED matrices, 7-segment displays, speakers etc. Any ideas or pointers please? Also, would annotations in the video be helpful, or is it pretty much self-explanatory? This is my first video on YouTube! Quote Link to post Share on other sites
fj604 34 Posted March 16, 2012 Author Share Posted March 16, 2012 This project uses all GPIO pins on P1 and also P2.7. The only one left unused is P2.6 - any ideas on a function to add? Quote Link to post Share on other sites
DanAndDusty 62 Posted March 16, 2012 Share Posted March 16, 2012 Nice project. Loving the beeps. My son would love this. Personally Im very grateful to you for letting me know about the AS1106 IC. I have a few 8x8 displays (and a home made 16x8).. so im impressed with this little beauty. Thanks, Dan Quote Link to post Share on other sites
ozymandias 7 Posted March 16, 2012 Share Posted March 16, 2012 i don't have much mounting advice except: -cut a big enough hole. -use enough hot glue. This project uses all GPIO pins on P1 and also P2.7. The only one left unused is P2.6 - any ideas on a function to add? whaddya mean P2? i though this was a G2211? Quote Link to post Share on other sites
DanAndDusty 62 Posted March 17, 2012 Share Posted March 17, 2012 whaddya mean P2? i though this was a G2211? As long as you aren't using the crystal oscilator P2.6 and P2.7 are available as GPIO pins. (From memory I think you have to ensure BIT6 and BIT7 are cleared in P2SEL. Dan Quote Link to post Share on other sites
gordon 229 Posted March 18, 2012 Share Posted March 18, 2012 This is a nice one. The 2211 is not useless, oh by far it is not . Quote Link to post Share on other sites
fj604 34 Posted March 18, 2012 Author Share Posted March 18, 2012 whaddya mean P2? i though this was a G2211? As long as you aren't using the crystal oscilator P2.6 and P2.7 are available as GPIO pins. (From memory I think you have to ensure BIT6 and BIT7 are cleared in P2SEL. Dan void sound_init(void) { P2SEL = 0; // Disable XIN/XOUT P2DIR = BUZZER_PIN; // XOUT pin = P2.7 } Quote Link to post Share on other sites
Kman 3 Posted May 3, 2012 Share Posted May 3, 2012 This is a great project. I can help you with the enclosure. I have made many. BTW, I'm the one that you responded to on Youtube that is doing an electronics merit badge class for my boy scouts. You can mount the matrix any way you want, but the normal way would be to make a PCB with the matrix on it, and put mounting bolts on the PCB. Then obviously it's mounted such that the matrix centers itself in an opening in whatever enclosure you make. If you want to put this on a perfboard, the same thing applies. Just mount it on the perfboard and drill holes to mount the perfboard. I like to cheat and use smoked plastic as a cover on my projects. It serves two purposes: 1. It makes the matrix look great because the contrast between the dark smoked plastic and the LED is much better than the contrast between the white matrix (without the smoked plastic) and the LED. It doesn't have to be dark, just smoked a bit. 2. It also hides much of the sloppiness in the hole around the matrix. IN fact, you don't even have to have a hole, you could have the whole front be the smoked plastic. As far as mounting the speaker, you can mount it any way you want. Here are a few common ways. 1. Put it behind holes in the enclosure and hot glue/epoxy it down. 2. Attach it to the case rigidly to a wall so that the case vibrates with the speaker vibrations. 3. Put it anywhere on the inside and the sound will escape anywhere there are holes in the case. I hope that helps. Thanks again for posting your code. I would appreciate any feedback you might have on the differences between the AS1106 and the AS1116 if you know. Thanks! Kman Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.