Elastic Sheep

Because elasticdog was already taken

Elastic Sheep header image 2

Blinking the leds

September 29th, 2009 · No Comments · Project Wiggum

My prototyping of the Wiggum project will begin with the usual blinking leds demo. This will help to establish a simple basis for hardware and software by slowly adding features layer after layer.

Building a basic circuit

My target is an ATMEGA168. Here is the datasheet. I will use an USB port as the 5V power supply. With this voltage, the oscillator frequency can be up to 20MHz. So a 16MHz crystal will be ok.

The most basic circuit to start an ATMEGA168: 1 crystal, 2 capacitors to connect the capacitor to ground (12-22pF recommended) and a resistor to pull-up the RESET pin.

Basic ATMEGA168 circuit with crystal

The resistor on the RESET pin is required to allow the ISP programmer to drive it when programming the device. To connect the AVRISPMKII programmer I use a small ISP breakout board from Sparkfun, very useful to avoid a cable mess on the breadboard.

Basic ATMEGA168 circuit with ISP connector

Blinking a led

To blink a led we will program an infinite loop that toggle all the pins of PORTB (PB0-PB5) each second. By connecting a led on any pin of PORTB we will immediately know if our first program is working or not.

Connectind a led on PB1 output of an ATMEGA168

I connect a led on PB1 through a 220 ohms resistor. It should limit the current in the led to about 15mA (Explanation).

The full circuit connected to USB and to the programmer:

Basic ATMEGA168 with a led, USB power and an AVRISPMKII programmer

Here is the main function of my test program:

// Full source: test_leds_blinking.zip
int main(void)
{
  /* Setup the PORTB pins as outputs */
  DDRB = 0xFF;
 
  /* Infinite loop */
  for(;;)
  {
    /* Toggle the PORTB pins */
    if (PORTB == 0xFF)
      PORTB = 0x00;
    else
      PORTB = 0xFF;
 
    /* Wait for 1s */
    delay_ms(1000);
  }
 
  return(0);
}

The full source code is available at the end of the post.

To compile and program the device (I assume a compiler toolchain like WinAVR or AVR MacPack is installed):

make
make program

The Makefile is configured for the ATMEGA168 target at 16MHz and to use the AVRISPMKII programmer on the usb port.

The default clock source with a factory-fresh ATMEGA168 is the internal 8MHz RC oscillator. To use the external crystal you have to fiddle with the CKSEL0-3 fuse bits with avrdude.

The result:

It’s working: the led is being switched on and off every second.

Blinking six leds

Blinking 6 leds should be as easy as one. We only have to connect one led/resistor couple on each remaining pin of PORTB:

basic-circuit-6-leds

The result:

It does not work. The leds are constantly on.

The problem is that with 6 leds we draw more power from the power supply thus decreasing the input voltage because of the load. This result in the ATMEGA168 being repeatedly reset.

The solution is to use a decoupling capacitor on the Vcc input of the microcontroller to protect against voltage fluctuations.

In the next video, I just add a 100nF capacitor and now the circuit is working:

Let’s begin the light show

More complex patterns can be implemented by changing the value of PORTB in the main loop of the program.

For example:

// Full source: test_leds_snake.zip
int main(void)
{
  uint8_t index = 0;
 
  /* Setup PB0 to PB5 as outputs */
  DDRB = _BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3) |  _BV(PB4) | _BV(PB5);
 
  /* Setup PD7 as an output */
  DDRD = _BV(PD7);
 
  for(;;)
  {     
    /* Toggle one of the PORTB pin */     
    PORTB ^= _BV(index);
 
    /* Loop index from 0 to 5 */
    index += 1;
    if (index == 6)
      index = 0;
 
    /* Toggle the PD7 pin */
    PORTD ^= _BV(PD7);
 
    /* Wait for 0.25s */
    delay_ms(250);
  }
 
  return(0);
}

Next time, we will add some buttons to interact with the leds.

Full source code

test_leds_blinking.zip
test_leds_snake.zip

Tags: ··

No Comments so far ↓

There are no comments yet...Kick things off by filling out the form below.

Leave a Comment