Showing posts with label ATtiny13. Show all posts
Showing posts with label ATtiny13. Show all posts

Sunday, February 7, 2010

RGB Night-lights


My kids love lights; flashlights, LEDs, house lights, pen-lights, light-up teddy bears, the northern lights... you name it, they love it. I've been playing around with RGB LEDs for another project along with ping-pong ball diffusers and baby jar containers. It occurred to me that I could make a simple night-light with most of the same components & the girls were bound love 'em.

I put it all together on Saturday evening after the girls were in bed. I think I'm getting better at all this as I had the code working and 2 lights put together by midnight. The girls found them in the morning (unfortunately, very early...) and came into our bedroom to play with them. First off, they played some kind of colour matching game where they were shouting (yes, shouting, early, in bed...) "RED! I'm wearing red!", "Blue! My socks are blue!". After a bit of this they moved into their bedroom to make a 'tent' out of a couple of chairs and a duvet (comforter). They played with the lights in there for a while; I'm not sure what they were doing as I was drifting in and out of consciousness.

It's Sunday and I've just put the kids to bed. They wanted to go to bed with their lights right next to them. I declare them a success!


I apologise for the quality of this video. It was taken on an iPhone and I've not been able to get hold of them again to take a proper vid. I'm sure you get the idea though.



Ingredients:



  • ATtiny13
  • RGB LED (common anode)
  • 8 pin DIP socket
  • switch (the ones I used were SPDT)
  • coin cell battery holder
  • coin cell battery
  • baby jar
  • hookup wire (I used stranded 24 AWG).
  • ping pong ball
  • neodymium magnet
I used the magnet to attach everything to the lid of the baby jar. I've not had much luck with hot-glue and lids (metal ones), so I figured this should work better. I decided to put this together free-form (i.e. no perfboard), mainly for space reasons - but also as I like the aesthetics of the free-form projects (like this advent wreath or this programmable led).

First off I realised that the DIP socket would fit nicely onto the side of my coin cell holders:



Then I added the neodymium magnet to the center of the holder:



This was actually a bad idea... these things are very strong and everything you're playing with at this point has some kind of ferrous metal involved. This thing attracted the soldering iron, the solder, cut off leads, pliers, the helping hand... If I do this again, I'd definitely wait until the end to attach the magnets.

Next step was to solder on the RGB LED:



You may notice that the socket has changed orientation. I was planning on attaching wire to the leads of the LED so that it'd be easily positionable. Then I realised that, since I only had a tiny amount of room in the jar, I could leave the LEDs leads in place and bend them to put the LED into the correct position. That meant re-orientating the DIP socket (as seen above).

The LEDs common anode has not been attached at this point. I added some heat-shrink tubing to this lead to insulate it from the others. It has to be bent forward and could easily touch one of the adjacent leads.

Also, I sanded the LED casing to diffuse the light. Without this step there are obvious areas of red/green/blue that shine on the ping pong ball from the LED.

Now all that's left is the final bit of wiring:





I attached the switch to Vcc and added a ground wire from the battery holder to the DIP socket. The wire is bent around the magnet and was, er... "fun" to solder in place. The soldering iron kept 'pinging' onto the magnet just as I was getting into position... like I said before, put the magnet on last!

I decided to house the lights in baby food jars. The only modification was to cut some holes for my switches (I used a Proxxon rotary tool for this).

Here's a few shots of them in working order:


Code:

I'm running the ATtiny at 8MHz. This requires setting the fuse bits because the default setting is to divide the clock by 8. This code uses the same software PWM as the firefly-jar-II I wrote about previously. No other tricks here, other than a hack (in the main method) to increase the duration of the RedToYellow transition. That's just personal taste though & (since I'm fickle) I may remove that section in the future.

Current code is available on github. Here's the code that's running in my kids bedroom at the time of posting:

/*
 * rgb_strobe.c
 *
 * Distributed under Creative Commons 3.0 -- Attib & Share Alike
 *
 *  Created on: Feb 6, 2010
 *      Author: PaulBo
 */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#ifndef F_CPU
    #define F_CPU 8000000UL
#endif

//Hardware definitions
#define RED_LED      PB2
#define GREEN_LED    PB1
#define BLUE_LED     PB0
#define ALL_LEDS    ((1 << RED_LED) | (1 << GREEN_LED) | (1 << BLUE_LED))

//Maximum value for led brightness
#define R_MAX 255
#define G_MAX 255
#define B_MAX 255

#define RED_INDEX   0
#define GREEN_INDEX 1
#define BLUE_INDEX  2

//Cycle States
#define RedToYellow     0
#define YellowToGreen   1
#define GreenToCyan     2
#define CyanToBlue      3
#define BlueToMagenta    4
#define MagentaToRed     5

//set red to max (we start in the RedToYellow state)
volatile unsigned char mRgbBuffer[] = {0,0,0};
unsigned char mRgbValues[] = {255,0,0};
unsigned char mState;

void init_timers()
{
    TIMSK0 = (1 << TOIE0);         // enable overflow interrupt
    TCCR0B = (1 << CS00);          // start timer, no prescale

    //enable interrupts
    sei();
}

void rgbCycle(){
    switch (mState) {
    case RedToYellow:
        mRgbValues[GREEN_INDEX]++;
        if (mRgbValues[GREEN_INDEX] == G_MAX)
            mState++;
        break;
    case YellowToGreen:
        mRgbValues[RED_INDEX]--;
        if (mRgbValues[RED_INDEX] == 0)
            mState++;
        break;
    case GreenToCyan:
        mRgbValues[BLUE_INDEX]++;
        if (mRgbValues[BLUE_INDEX] == B_MAX)
            mState++;
        break;
    case CyanToBlue:
        mRgbValues[GREEN_INDEX]--;
        if (mRgbValues[GREEN_INDEX] == 0)
            mState++;
        break;
    case BlueToMagenta:
        mRgbValues[RED_INDEX]++;
        if (mRgbValues[RED_INDEX] == R_MAX)
            mState++;
        break;
    case MagentaToRed:
        mRgbValues[BLUE_INDEX]--;
        if (mRgbValues[BLUE_INDEX] == 0)
            mState++;
        break;
    }

    //state should never advance beyond 5.
    //It wraps back to 0 when we reach 6
    mState %= 6;
}

int main(void){
    //Set LED pins to output
    DDRB |= ALL_LEDS;

    init_timers();

    while (1) {
        rgbCycle();
        _delay_ms(250);

        //I like the orange state and it only lasts for a second
        //so lets extend it a little bit more
        if(mState == RedToYellow)
        {
            _delay_ms(250);
            _delay_ms(250);
        }
    }
    return 0;
}

/*
 * Timer/Counter overflow interrupt. This is called each time
 * the counter overflows (255 counts/cycles).
 */
ISR(TIM0_OVF_vect)
{
    //static variables maintain state from one call to the next
    static unsigned char sPortBmask = ALL_LEDS;
    static unsigned char sCounter = 255;

    //set port pins straight away (no waiting for processing)
    PORTB = sPortBmask;

    //this counter will overflow back to 0 after reaching 255.
    //So we end up adjusting the LED states for every 256 interrupts/overflows.
    if(++sCounter == 0)
    {
        mRgbBuffer[RED_INDEX] = mRgbValues[RED_INDEX];
        mRgbBuffer[GREEN_INDEX] = mRgbValues[GREEN_INDEX];
        mRgbBuffer[BLUE_INDEX] = mRgbValues[BLUE_INDEX];

        //set all pins to low (remember this is a common anode LED)
        sPortBmask &=~ ALL_LEDS;
    }
    //this loop is considered for every overflow interrupt.
    //this is the software PWM.
    if(mRgbBuffer[RED_INDEX]   == sCounter) sPortBmask |= (1 << RED_LED);
    if(mRgbBuffer[GREEN_INDEX] == sCounter) sPortBmask |= (1 << GREEN_LED);
    if(mRgbBuffer[BLUE_INDEX]  == sCounter) sPortBmask |= (1 << BLUE_LED);
}

Tuesday, February 2, 2010

Jar-O-Fireflies (Mark II)


I really enjoyed the process of making my first 'Jar-O-Fireflies' but I was a little disappointed with the performance (i.e. the software), especially the obvious flicker when the lights were pulsing on and off. I've learned a lot more about how to program the AVR uCs over the last few months (but still just the basics really). So, I decided to re-write the software and make a smaller, battery powered, version. I'm going to make another and put it in an empty Nuttela jar for the girls to use as a night light (I'm sure the girls will help me empty the jar).

The software took a little while to sort out but the hardware, on the other hand, only took about 2 hours to put together. Most of that was due to the fiddlyness of using magnet wire for the LED leads.

Below is a little video of it working. Yes, we have 'pet' ants at the moment - at least it was interested in what was going on...



The parts:
  • some magnet wire
  • coin cell holder (and coin cell to go with it)
  • perf board - I used a board with a semi breadboard layout (see picture below), but it wasn't much more help than a standard one other than having a common power and ground rail to connect everything to.
  • switch (one that fits onto a PCB/perf board)
  • 8-pin dip
  • 5 green LEDs (3mm)
  • ATtiny13

This is the layout I used (for the battery holder, DIP socket and switch):



The trickiest part was soldering the magnet wire onto the LEDs. I used a third-hand to hold all the pieces together. It helps that the magnet wire is quite stiff and bendable even though it's thin.


As you can see from the photo. After soldering on the wire I twisted the two strands together. After doing the 5 LEDs I realised that it'd be really nice to have 2 different colours of wire so that the positive and negative leads were obvious... oops. I ended up testing each pair of wires with my LED tester to determine which lead was positive and which was negative.

Then it's was just a matter of soldering on the LED leads to the board:


Then I glued everything onto the jar lid (using a hot glue gun):



Et voila!



Code
:

I've just started using code.google.com as a code repository. The google site supports subversion source control (and there's a good plug-in for eclipse called subversive). I'd been going back and forth between computers and it was turning into quite a headache trying to get the code in sync. Now I can just push and pull from the code repository.

Here's the location of the firefly code:
http://code.google.com/p/pboardman-avr/source/browse/firefly_jar/firefly_jar.c

Google code is no-more.  I've moved all the code to github.

https://github.com/paulboardman/avr/blob/master/firefly_jar/firefly_jar.c

This may change in the future as I tinker a bit more, so I'm including below the version of the code that was running when I wrote this post. This version required setting the fuse bits for the ATtiny13 to make it run at 8MHz. I also wrote a better software PWM routine (see the Atmel technote: "Low-Jitter Multi Channel Software PWM". Warning: PDF link).

There are a few enhancements that I have in mind like actually using a random number generator for generating random numbers... The reason I didn't was that I had trouble coming up with a method for generating a seed (without a differing seed, the pseudo random number generator would give the same sequence each time the AVR was switched on). My latest project (post forthcoming) saves the seed in EEPROM and increments it each time the AVR is booted up - this way the random number generator produces a different sequence each time. Anyway, here's the code:

/*
 * firefly_jar.c
 *
 * Distributed under Creative Commons 3.0 -- Attib & Share Alike
 *
 *  Created on: Feb 2, 2010
 *      Author: PaulBo
 */
#import <util/delay.h>
#import <avr/io.h>
#import <avr/interrupt.h>

#ifndef F_CPU
    #define F_CPU 8000000UL
#endif

//LED pin definitions
#define LED1    PB0
#define LED2    PB1
#define LED3    PB2
#define LED4    PB3
#define LED5    PB4
#define N_LEDS  5
#define ALL_LEDS (1 << LED1) | (1 << LED2) | (1 << LED3) | (1 << LED4) | (1 << LED5)

//Max value for LED brightness
#define MAX     100

#define PULSE_UP   1
#define PULSE_DOWN 0

volatile unsigned char buffer[N_LEDS];

//counter for use in updateLedState() and pulseLeds()
unsigned char i;

//structure for storing data on each LED
struct ledData {
    unsigned char mBrightness;
    unsigned int  mTime;
    unsigned char mPin;
    unsigned char mPulseDirection;
};

//set up some initial values
struct ledData led_data[] = {
        {0, 1000,  LED1, PULSE_DOWN},
        {0, 10, LED2, PULSE_DOWN},
        {0, 500, LED3, PULSE_DOWN},
        {0, 50, LED4, PULSE_DOWN},
        {0, 150,  LED5, PULSE_DOWN}
};

//return a random time interval from 0 to 255
int getTime()
{
    return TCNT0;//just read the current timer/counter value
}

void updateLedState()
{
    for(i = 0; i < N_LEDS; i++)
    {
        switch(led_data[i].mBrightness)
        {
            case MAX://led is on
                if(--led_data[i].mTime == 0)
                {
                    //decrement the brightness, this puts the LED in a
                    //pulse state
                    led_data[i].mBrightness--;

                    //specify the "down" direction for pulsing
                    led_data[i].mPulseDirection = PULSE_DOWN;
                }
                break;
            case 0://led is off
                if(--led_data[i].mTime == 0)
                {
                    //increment the brightness,this puts the LED in
                    //a pulse state
                    led_data[i].mBrightness++;

                    //specify the "up" direction for pulsing
                    led_data[i].mPulseDirection = PULSE_UP;

                    //set the ON time
                    led_data[i].mTime = getTime() + 1;
                }
                break;
            default: //pulse state
                if(led_data[i].mPulseDirection == PULSE_UP)
                {
                    led_data[i].mBrightness++;
                }
                else
                {
                    if(--led_data[i].mBrightness == 0)
                    {
                        //set the OFF time - make this longer than the on time
                        led_data[i].mTime = (getTime() + 1) * 5;
                    }
                }
                break;
        }
    }
}

void init_timers()
{
    TIMSK0 = (1 << TOIE0);         // enable overflow interrupt
    TCCR0B = (1 << CS00);          // start timer, no prescale

    //enable interrupts
    sei();
}

void init_io()
{
    //set all LED pins as outputs
    DDRB |= ALL_LEDS;
    PORTB &= ~(ALL_LEDS); //off to start
}

void setup()
 {
    init_io();
    init_timers();
}

int main(void)
{
    setup();

    //infinite loop
    while(1)
    {
        updateLedState();
        _delay_ms(10);
    }
}

/*
 * Timer/Counter overflow interrupt. This is called each time
 * the counter overflows (255 counts/cycles).
 */
ISR(TIM0_OVF_vect)
{
    //static variables maintain state from one call to the next
    static unsigned char sPortBmask = ALL_LEDS;
    static unsigned char sCounter = 255;

    //set port pins straight away (no waiting for processing)
    PORTB = sPortBmask;

    //this counter will overflow back to 0 after reaching 255.
    //So we end up adjusting the LED states for every 256 overflows.
    if(++sCounter == 0)
    {
        for(i = 0; i < N_LEDS; i++)
        {
            buffer[i] = led_data[i].mBrightness;
        }
        //set all pins to high
        sPortBmask = ALL_LEDS;
    }
    //this loop is considered for every overflow interrupt.
    //this is the software PWM.
    if(buffer[0] == sCounter) sPortBmask &= ~(1 << led_data[0].mPin);
    if(buffer[1] == sCounter) sPortBmask &= ~(1 << led_data[1].mPin);
    if(buffer[2] == sCounter) sPortBmask &= ~(1 << led_data[2].mPin);
    if(buffer[3] == sCounter) sPortBmask &= ~(1 << led_data[3].mPin);
    if(buffer[4] == sCounter) sPortBmask &= ~(1 << led_data[4].mPin);
}

Thursday, December 17, 2009

Duplo Traffic Lights




We've been playing with LEGO and DUPLO quite a lot at home recently (Lin's been doing some great work on expanding our LEGO possibilities - see these posts over on filthwizardry: "Lego and hole punching cards", "Festive card punching with more LEGO", "LEGO and DUPLO" and "LEGO car and DUPLO truck cardboard printables").

I thought it'd be really nice to be able to add some traffic lights (like these ones I made a while back) to the creative fun. Lin suggested I house some in a DUPLO block, so I set to work trying to figure out how to do it.



Ingredients: 3 LEDs (red, yellow, green), 3 resistors (I used 330 ohm), ATtiny13, 8 pin DIP socket, perf board, magnet wire (thin), switch, stranded wire (black and red), coin cell battery, DUPLO blocks (the 8 knobble variety, 1 standard and 2 thin).

Tools: soldering iron, dremel, hot glue gun, various dremel attachments and drill bits (depending on your LEDs and switch).

The three holes/cylinders on the underside of a standard DUPLO block are perfect for traffic light mimicry. I ended up using 3 blocks, one large and two thin. The large block houses the electronics and the switch, one thin piece has 3 holes drilled in it for the LEDs and the last piece is used on the back as a battery cover.

Here's a couple of pictures showing the carved out bricks. You have to leave some of the 'tubing' in the large brick in order for the other brick to still connect normally. I used a dremel to cut off the 4 middle bobbles from the thinner piece - leaving a hollow center, between the two pieces, for the electronics.



I haven't taken a picture of the remaining thin block, I hollowed that out in the same manner as the larger block, to make room for the coin cell battery. Again leaving enough of the innards so it'd still fit tightly on the back of the main block.

I drilled 3 holes in the front piece (the thin black one above) directly in the center of the three tubes; the holes need to be just the right size for the LEDs to fit snuggly (I messed this up with my first prototype). I also drilled a small hole in the center of the big block for the power wires to feed through later on. This way you can have all the electronics hidden in the main block and have the battery accessible on the back.

The main board is just a small bit of perf-board with the 8-pin DIP socket soldered on. I'm using the same code as last time, so the LEDs and resistors are attached to pins 5, 6 and 7 (PB0, PB1 and PB2 respectively). I used magnet wire to attach the LEDs as it's flexible and takes up very little room. I tried just soldering the LEDs directly onto the perf-board but that made it difficult to get a good fit later on. If you give this a go, remember to sand the insulation off the ends of the magnet wire before soldering.



Add a switch:


Then place it all inside the main block (feeding the power wires out of the hole in the back).



Then glue the LEDs into the holes of the front piece and close it all up. I'm probably going to have to glue it shut in the future to keep out fiddling fingers.



I didn't have a coin cell holder, so I scavenged some metal tabs from the innards of a happy meal toy and soldered these onto the ends of the power leads. Then I taped them tightly onto the coin-cell. Clip on the battery cover (3rd block) and it's all done. This would all be a bit cleaner if there was a coin cell holder attached to the back in some way (I'll give that a go next time).

Here's the lights in operation (with my first attempt on the right which has directly soldered LEDs and an ugly switch):



The kids really do seem to like them! The original lights have had to be repaired a few times from er... 'overly keen' play. Well, that and Ffion ripping them apart.

Next ideas are to make them easier to include with normal duplo play by attaching blocks to the top and bottom (may require some cutting and gluing). Another good addition would be to have lights on both sides of the block to control traffic in both directions (so when one side is green the other is red). If only I had more black duplo...

Sunday, August 30, 2009

Toy Traffic Lights



This is something I've been meaning to make for ages. My kids love toy cars (ok, lets face it, all kids love toy cars!). There's been lots of car related fun in our household (some of which has been documented on filthwizardry: "Toy cars and trucks from recycling", "shower curtain village playmat" and "home made toy carwash") and one of the kids favourite pastimes in the car is to shout "RED means STOP!" and "GREEN: GO!" (as loudly as humanly possible). I figured it was about time I used this as an excuse to spend some time in the garage making something with flashing LEDs :)

Between Lin and myself we've managed to amass quite a bit of cheap 'junk' that can be hacked together for something like this. I was going to make something flimsy using a battery pack and a drinking straw, but I was persuaded to make something a bit more kid-proof using a dollar store wooden box, an Altoids tin and the tube from a black felt-tip pen. Here's a picture of all the bits (there are three 150 ohm resistors are missing):



The plastic domes are the discarded remnants of 25c kids toys purchased from a vending machine in our local Taqueria, they looked like they'd make good LED covers (and they were used as wheels in another crafty distraction: "Toy cars and trucks from recycling"). The chip is an ATtiny13.

First up was to drill some holes: two in the box, one on the side for the switch and one on the top for the pen tube; one in the base of the altoids tin (again, for the pen tube) and three in the back of the tin for the LEDs.

Then I painted it black.



The wiring for the base/box is pretty simple, just an AA battery pack wired to a switch with the main wires threaded out of the hole in the top of the box. I stuck the pen casing in at this point and threaded the wires through to the top.



Now it's time for the wiring.

First off, I hot glued the base to the Altoids tin. Then I glued the LEDs into their holes with the cathodes all facing in one direction so I could solder them together to form a ground rail.




I soldered on three, 150 ohm, resistors to an 8-pin dip socket (pins 5, 6 and 7), soldered the positive lead from the base to pin 8 on the socket. Then I connected the LEDs to the resistors and finally connected the ground pin (pin 4) to the ground rail. That's it!





When I was writing the code I didn't think ahead about which pins were going to be connected where in the final project and ended up with the red and green pins mixed up (in software), so the initial sequence was backwards; but then that's why I used a socket rather than directly soldering the uC ;). Easy to fix with a quick software update.

Here's the final working project (yes, the yellow works too, I just didn't take a picture of it):



I've included the code below. As always, it's pretty simple:

### code starts here ###
(I found a nice way of displaying code in blogger. I talk about setting it up here)

/*
* trafflic_lights.c
*
* Created on: Aug 29, 2009
* Author: Paul
*/
#include <avr/io.h>
#include <avr/delay.h>

#define RED_LED PB2
#define YELLOW_LED PB1
#define GREEN_LED PB0

#define RED_DELAY 10
#define YELLOW_DELAY 3
#define GREEN_DELAY 15

uint8_t i = 0;
uint8_t j = 0;
void delay_seconds(uint8_t pSecs)
{
for(i = 0; i < pSecs; i++)
{
for(j = 0; j < 4; j++)
_delay_ms(250);
}
}

int main(void)
{
DDRB = 0xFF;//set all to output

//start traffic light sequence
while(1)
{
PORTB = (1 << RED_LED);
delay_seconds(RED_DELAY);
PORTB = (1 << YELLOW_LED);
delay_seconds(YELLOW_DELAY);
PORTB = (1 << GREEN_LED);
delay_seconds(GREEN_DELAY);
}
}

Tuesday, August 25, 2009

Led camp fire



A few days ago I came home from work and was rather surprised to find a, full-sized, indoor camp-out taking up the living room... you have to see it to believe it (the original was bigger than the version above!):- filthwizardry.blogspot.com. Well, the kids loved it and my lovely lady inspired me to make a flame free campfire to add to the fun. I figured it'd be easy to do with a uC and a few red/orange LEDs -all of which I had lying around the place.

To get the basic set-up I cannibalized the innards of the glow in the dark balls project and jammed a few LEDs in the right places; this let me start messing with the code. In the second image you can see my test set-up. I ended up using my LED tester to provide power to the breadboard and my ATtiny header board for quickly cycling the code on the chip. I was happily surprised that both of these worked and were useful - I've been getting frustrated jamming frayed power leads into the breadboard and it'd only just occurred to me that I could use the LED tester.



All I wanted the code to do was randomly switch the LEDs on and off fast enough to mimic flickering flames. I messed around with the speed of flickering a bit until I was happy.

For those who are interested, I've included the code at the bottom of the page. It's a pretty simple affair. I take no credit for the random number generator, in the past I've just used library code for this, but I happened across that nice bit of code online and fancied using it (I think this is the original source but I found it here). The code is in a slightly incomplete state as I was also messing around with altering the delay between each set of LED updates. Shorter delays give the impression of an angry/quick burning fire and longer delays give rise to a soothing fire. I quite like the idea of having a random drift for the delay to make the fire more interesting, but got tired at around midnight and decided to simplify.

Lin suggested housing everything in the top section of a solar garden light case (which had been destroyed during a particularly energetic play-date). All that needed modifying was to add a small hole for the switch. I also cut down the LEDs so they took up less space and were more secure:



Then I added some protection to the top and a cardboard base to keep the innards in place (I used a hot-glue gun to secure both parts).



And that's it! Very simple.

Here's the contraption hidden in the kids camp fire waiting to be discovered:



and a little video of it in action:



p.s. anyone notice the freaky kiddie scarecrow in the first image? Have a look at the whole filthwizardry post, that thing freaks me out on a daily basis! I think it's the eyes... "she's got the cold dead eyes of a killer" ;)

### code starts here ###

/*
* candle.c
*
* Created on: Aug 21, 2009
* Author: Paul
*/
#include <avr/io.h>
#include <avr/delay.h>

/*
* pseudorandom
* return the next pseudo-random number (PRN) using a standard maximum
* length xor-feedback 16-bit shift register.
* This returns the number from 1 to 65535 in a fixed but apparently
* random sequence. No one number repeats.
*/
uint16_t randreg = 10;

static uint16_t pseudorandom16 (void)
{
uint16_t newbit = 0;

if (randreg == 0) {
randreg = 1;
}
if (randreg & 0x8000) newbit = 1;
if (randreg & 0x4000) newbit ^= 1;
if (randreg & 0x1000) newbit ^= 1;
if (randreg & 0x0008) newbit ^= 1;
randreg = (randreg << 1) + newbit;
return randreg;
}

int main(void)
{
uint8_t i = 0;
uint16_t j = 0;
uint8_t delay = 20;
DDRB = 0xFF;

while(1)
{
j = pseudorandom16();
for(i=0;i<5;i++)
{
if(pseudorandom16() > j)
{
PORTB ^= (1<<i);
}
}
_delay_ms(delay);
}
}

Monday, May 18, 2009

ATtiny header board


I've been programming my AVRs using the SparkFun set-up since I started. This is fine for the odd bit of tinkering, but it's a pain having all those wires poked into the programming cable and getting in the way on the breadboard. With an 8-pin dip, there's not a lot of room around the chip for my fat fingers to add wires.


I'd seen these breadboard headers over at Tinkerlog.com and fancied having a go at making my own using the components I'd got lying around (well, ok, I bough the male/female header pins from eBay).

First a rough idea of how I thought it should look:

Then I tried to figure out where the wires should go based on my original set-up (pic of wire mess above) and the ATtiny13 datashet.

Finally I gave a little thought as to where the physical wires were going to go on the perfboard. I decided to swap the position of the 6-pin programming header to make the wiring a little easier. I'm sure there's a better solution, but I was impatient and wanted to get on with it.


Then it was a matter of soldering everything together. I am not an accomplished solderer - this is only my 3rd real soldering project and I'm sure most people wouldn't even consider the ones I've done so far 'projects'.

First off I soldered the headers, push switch (cannibalized from a broken kids toy) and IC socket. This is pretty much how the finished project looks from the top.

Then I realise that I could bridge pins 1 and 8 using the 10K resisitor and have the resistor out of the way of the rest of the wires by having it on the front of the board.

After that it all got a little messy... I need to give myself more time to figure out wiring/routing! I guess this is all a learning experience :)




I kept the insulation on the long wires to prevent short circuits, unfortunately I also ended up melting a lot of the plastic which caused a few issues around pin 5 of the IC socket hence the blackened mess and excess solder around there... I think I managed to sort out my technique a bit better after than and the remaining solder bridges are ok (tips on creating these gratefully received!).

Here it is in action (note that I have to bring in power from the breadboard with my particular programmer).