Sunday 22 May 2011

A standalone MSP430 project! Basic POV example.

The first thing I wanted to do with my Launchpad was to create a standalone project.  I'd seen how the elite mocked people for leaving a complete Arduino dev. board in their final project - I wanted to be sure I could avoid such mockery should I ever complete a project.  Happily, the MSP430 chips which come with the Lauchpad require only one component to allow them to run on their own.  Happier still, that component is a lowly, cheaper than chips resistor.

Using only* the MSP430G2211 that was supplied with the Launchpad, 8 x 3mm LEDs, 1 x 10k Ohm resistor and a battery power source, the persistence of vision (POV) in the video below was created.


*I also used a breadboard and some jumper wires, but counter to what others may say, they don't count in the component count.






Read on for more information on how the magic happens.




Put simply, persistence of vision (POV) enables us to create several images in rapid succession which appear to the human eye to be one continuous image.  This phenomenon is used to great effect in cartoons, films and snazzy LED displays.  YouTube has some awe-inspiring examples of POV LED displays, all of which put the low resolution green face to shame.  In defence of my little green friend (and me!), the more impressive displays use more than LEDs and resistors, so I hold my head high with my minimalist circuit.


On to the circuit itself.  I don't think it justifies it's own schematic  A rather shoddy schematic is below, along with a photograph of the breadboard.  If you're in any doubt, it consists of the annodes of the 8 LEDs connected to P1.0 - P1.7 of the MSP430G2211 chip.  A 10k Ohm resistor connects the reset pin (pin 10) to the +V supply, and Vcc (pin 1) and Gnd (pin 14) are connected to +V and Gnd respectively.  With the circuit built, it's on to design. 





We have a column of 8 LEDs, so our image is limited to 8 pixels tall.  The next step is to put our desired image down and work out which outputs need to be switched for each column.  I prefer to do this with a pencil and paper, but I can't upload the sketch I drew, so I fired up MS Paint and came up with the masterpiece below.


As has been said, we have an 8 LED high column, but how do we decide the width?  The width is set by how far you physically move the circuit, so to keep it simple our image is 7 pixels wide.  Each separate column is a position in space, as we move the column of LEDs through the air, the MSP430 illuminates the LEDs in the pattern, column by column.  If we had accelerometers or some other method of letting the MSP430 know where the LEDs are in space, it could be coded to change the outputs as it moved.  However, we don't have accelerometers, so it's going to be done with crude time delays.  But first we need to translate our image into something which is easier for the MSP430 to work with.  Step forward Mr GreenFace MkII.


Above you can see our image being converted into numbers.  The bottom LED represents the most significant bit, as that is connected to P1.7 on our chip.  As can be seen from our diagram, the first column, starting from the bottom, is ON, ON, ON, ON, ON, ON, OFF, OFF, or 11111100 in binary.  Putting out binary value into any binary to hexadecimal converter tells us that the binary equivalent is 7C.  We now know the first column of Mr GreenFace's face is 7C.  To make it clear that 7C is a hexadecimal number, it must be preceded by 0x for the microcontroller to understand, so from now on, we'll do just that.  The next column in Mr GreenFace's Face is ON, OFF, OFF, OFF, OFF, OFF, ON, OFF, or 10000010 in binary, or 0x82.  Feel free to work the rest out if you want to, though it would probably be more constructive to create your own 8x? image to try.  Now, on to the code...

The code is very simple.  As we have connected the output pins to the LEDs in order (from output P1.0 at the top to P1.7 at the bottom), all we have to do is send out hexadecimal number to P1.  In C, we can do this with a simple line of code - P1OUT = 0x7C for example will illuminate the LEDs for the first column of our image.  Follow this up with a delay before it moves on the the next column of the image and our code is nearly complete.  Obviously there's a few more bits to add, so to save you the bother, I've pasted the full code below.

#include <msp430g2211.h> //This is the header file for your chip.
void delay(unsigned int delayTime);
void main(void) {
   WDTCTL = WDTPW + WDTHOLD;    //Hold the WDT (WatchDog Timer)
   
   P1DIR = 0xff; //Set Port 1 (P1) to output.
   
   unsigned int i=250; //This is the delay value between each column (found by trial and error)
   
   while(1){
   
    P1OUT = 0x00;
    delay(i);  
    P1OUT = 0x7C; //Mr GreenFace's first column.
    delay(i); //The delay
    P1OUT = 0x82;
    delay(i);
    P1OUT = 0xA9;
    delay(i);
    P1OUT = 0xA1;
    delay(i);
    P1OUT = 0xA9;
    delay(i);
    P1OUT = 0x82;
    delay(i);
    P1OUT = 0x7C; //Mr GreenFace's last column.
    delay(i);
    P1OUT = 0x00;
    delay(i);
   
   }
   
}

void delay(unsigned int delayTime){
int x;
for (x=0;x<delayTime;x++){
x=x*1;
}
}  


That's it - just put the code on the chip, build the circuit, have fun!  Please comment - if it's helped anyone I'd love to know, if it contains glaring errors, I'd like to correct them before I misinform anyone else!  Next time I'll do something using shift registers, or if anyone has any suggestions I'd be happy to look into them.

Thank you for looking at my little corner of the internet :)

Guy.

EDIT:  I decided to solder the circuit to some stripboard to make it easier to handle and "swish" around.  I've added a couple of pictures below to show you some of my results.

Circuit on stripboard.

Just showing where the two wires lead.


First attempt at text - "Mike"

Inverse and regular text - not working too well!
About the best picture I managed to get.


6 comments:

  1. Awesome man! It did help, it's nice to have have a short and sweet example to get started. Thanks!

    ReplyDelete
  2. This is really great, thank you for posting. There are a lot of guides for using microcontrollers with dev boards, but not much help for those of us who want to start integrating these things with our projects.

    Here is a question: (for either a blog post, or possibly via email?) Could you explain the pinouts of this chip? Or, how exactly it is you knew how to wire it?

    And, as I read the datasheets of other microcontrollers (AVR, PIC), what kind of information do I need to be able to put together a bare-bones circuit without a dev board? Why do some use capacitors and crystals and this one does not?

    At any rate, all of this is really great. Thanks so much!

    ReplyDelete
  3. Hi Jay, thanks for the comments and suggestions - I'll definitely do a post about the pinouts etc. I'm not clued up enough about other microcontrollers to be able to explain which MCU needs what components to run, but

    http://www.marengo-ltd.com/blog/?p=105

    is a very good write up about creating a standalone ATMega circuit.

    Hope that helps you!

    ReplyDelete
  4. Thanks for thins post. I didn't know that I need to put a resistor between VSS and RST pin so the unit can work stand alone... Can You explaine, why it must be done? Thanks again!

    ReplyDelete
    Replies
    1. On page 32 of the family user guide (http://www.ti.com/lit/ug/slau144i/slau144i.pdf), it tells you that a Power On Reset (POR) occurs when a low signal is seen on the reset pin. So by tying RST high, a low condition on the RST pin is avoided.

      Delete
  5. This comment has been removed by the author.

    ReplyDelete