Jump to content
43oh

Launchpad + AS1106 + 8x8 LED Matrix = fun!


Recommended Posts

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();
}

Link to post
Share on other sites

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! :)

Link to post
Share on other sites
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
}

Link to post
Share on other sites
  • 1 month later...

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

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...