Introduction: Bike Hand Signal Light

The goal of this project is to create a light that fits on a bike glove and points in the direction of the intended turn, to increase visibility at night.  It should be lightweight, easy to use, and integrated with the existing motions for signaling (minimal tweaking of signal method (you don't have to press a button, it just goes when you signal)).  This would make a great holiday gift.

Note:  This requires previous knowledge of how to solder and an idea of how to program AVR's is a big plus.  With that in mind, have fun, be patient and post pictures of your product below!

Here's a video:


And here's a picture of mine:

Step 1: Parts

x1 ATmega 32L 8PU (www.digikey.com)
x1 40-pin DIP socket (www.digikey.com)
x1 8x8 LED Array (www.sparkfun.com)
x1 74138 De-multiplexer (www.digikey.com)
x2 Flex Sensors (www.sparkfun.com)
x(Many) Resistors  180 ohm and 10k ohm
x2 PC Board (www.sparkfun.com)
x6 Standoffs (www.sparkfun.com) and screws to fit (Local Hardware Store)
x1 Accelerometer on breakout board (www.sparkfun.com)
x2 Headers - Male (www.sparkfun.com), Female (www.sparkfun.com), and Right Angle (www.sparkfun.com)
x1 LM7805 (www.digikey.com)
x2 8 pin sockets (I got mine at Radio Shack)
x1 9v battery
x1 foot stick-on velcro
x1 Full-fingered bike glove
x1 spool polyester thread
x1 Programmer (I have this one)
x1 Wire stripper and clip
x1 Multimeter

Some of the parts:

Step 2: Prepare the Boards

First, add the standoffs.  You will have to screw two together to get the proper height.  Make sure that the standoffs are descending from the side with the SQUARE pads.  This way you can bridge pads with solder on the bottom and bridge with the common pad on the top to connect to ground.  Next add the LED array and solder it in.  It should be as far to the edge of the board with the the two stanoffs as it can be with the YS facing the opposite side.  The pin on the bottom left is pin 1. (It's also marked on the picture.)  Next add the two 8 pin sockets one on top of another so as to form one 16 pin socket.  Make sure to have one space to the left and then solder that in.  Next split the male and female headers into 10 and 11 pin sections.  You will need twice as many female headers.  Solder those in as seen in the photo.  As for the male headers you need to shift the pin so their is an equal amount on each side of the plastic  It's easiest to look at a picture to see what I mean so take a look at #6.  I used some pliers and it worked quite well.  Now if you take the male headers and place them in between the 2 female headers you will see that they are now the right size to connect the top and bottom board together.

Step 3: Add the Resistors

These resistors go between the LED array and the 74138 (Ground) to protect the array.  Fold one of the leads from the resistor over the top so the two leads are parallel.  Fit them in on pins 7,  9, 10, 11, 12, 13, 14, and 15 and solder.  I found that it works best if you alternate the direction of the resistor as you can see in the second and third pictures.

Step 4: Wire the Top

This is by far the longest step of the project so I sure hope you like soldering!  Just follow the schematic below and make sure to test continuity with you multimeter.  In case you want to know how I came us with the schematic look at the datasheet for the array and the 74138.

Step 5: Populate the Bottom

Now it's time to place our basic components on the bottom board.  First we'll do the 40 pin DIP socket which goes as close to the top left as it can while leaving one row of space on the left side.  (See picture #1.)  Solder that in and then place the headers.  The easiest way to do this is to connect the ones on the top to the ones that will go on the bottom using your modified male headers.  If you did everything right you should end up with the three top three pins on the left header next to the bottom right pins on the socket.  This is OK.  We only use the bottommost pin on the right and as you can see we have a clear shot at it from another direction.  Now add the voltage regulator as shown in the picture.  I secured mine through the hole in the metal heat sink with a screw and nut.  The heat sink is another way to ground the chip and bolting it to the board provides a solid contact with the common connection.  This is connected to the bottom as well as the top because the two are connected with metal standoffs.  However, if you are not using the common connection for ground DO NOT bolt the heat sink to the board as the heat sink serves as ground and you will probably short circuit something.  Next wire in the battery clip.  Red goes to the pin on the left (With the heat sink up and the pins down) black to the middle and the right pin produces +5v.  Now you can wire power to the top (see picture #2).  Now for the programmer connecter.  I have an adapter that I made for  my programmer but you will probably want to incorporate a 6 pin (3x2) header into you design.  However if you do have an adapter like I do, here is what I did.  I took a right angle header and a female header and soldered them together (Picture #3).  Then I attached it to the board with the first pin connected to pin 6.  Now you need to power and ground the chip as well as wiring in a resistor to pull reset high.  I ran a 10k resistor from pin 9 to pin 10 and then connected pin 10 to +5v.  The next pin (11) goes to the common connection (Ground).  Finally look at picture #4 to finish this step (It's pretty self explanatory).

Step 6: Wire the Bottom

Remember that really fun step where you got to run over 30 wires to get a LED array working?  Now you get to do it again!  On the bottom!.  This one is a little faster but not my much.  Once again, look at the schematic and check all of your connections with your multimeter.  Don't worry, this is the last big soldering piece of the project and you're almost done.

Step 7: Flex Sensors and the Accelerometer

We'll tackle the flex sensors first but you are on the home stretch as far as hardware goes.  I think that the pictures below pretty much explain what to do.  Connect one pin to +5v the other to the third or fourth pin from the top on the right side of the AVR (The microcontroler at the heart of this project).  When I first put this together I thought that was all I needed to do but it turns out that for the AVR to read the flex sensors you need to put a resistor from the pin on the sensor going to the AVR to ground (See pictures #10 and 11).  I used a 10k.  This divides the voltage going to the AVR which practically doubles the sensitivity of the sensor.  Now for the accelerometer.  Because the accelerometer is just a hair taller than the space between the two boards and because we might want to replace it some day I have decided to use headers to bump it out from the board and to connect it.  Use a right angle header to connect to the 6 pins on the breakout board.  Now take another right angle header and solder a female header to the short pins then solder this into the bottom left of your board.  Plug in the accelerometer to make sure it fits, unplug it and then connect the proper pins to Vcc (+5v) and Gnd.  Then connect the pin outputting X to pin 40 and Y to pin 39. Now you should be set to add the IC's (Integrated circuits) and power it on.

Dec 26, 2009:  I have found that the way I mounted the index finger flex sensor caused the material  connecting the sensor with the pins to degrade.  I have since bought a replacement sensor and hot glued a piece of thin plastic to the sensor to prevent this area being the part doing most of the bending.  I have tagged the location in the below photo.

Step 8: Adding IC's and the First Program

This is probability the easiest step of the whole process.  Once again the picture help.  Make sure that you have the chips in the correct way as explained in picture #3.  I would first connect power with nothing connected and touch the heat sink on the voltage regulator.  If it is hot then something is shorting out and you need to go back and check you connections.  Proceed this way, adding one chip at a time, feeling for heat and once everything is in it's place tighten the nuts on the bottom board so the two boards are securely fastened together.  Next you will program the AVR.  If you have never done this before, a quick google search yields a plethora of results.  If I were you I would put my AVR on a breadboard and program on there before you attempt it on your piece of hard work.  I wrote a simple program to output the information being received from the flex sensors to the LED array.  This should give you a basic idea of what is and isn't working in your circuit.

Here is a video of the code in action...




...and here's the code:


#define F_CPU 800000UL

#include
#include
#include

void ADCINIT()
{
  ADMUX = 0b01100000;
  ADCSRA = 0b10000000;
}

int main()
{
  int a;
  a = 0;
  int b;
  b = 0;
  DDRD = 0xFF;
  DDRB = 0xFF;
  DDRA = 0b11100000;
  ADCINIT();
  while(1)
    {
      ADMUX = 0b01100011;
      ADCSRA |= 0b01000000;
      while(bit_is_clear(ADCSRA, ADIF));
      PORTA = 0b00000000;
      PORTD = ADCH;
      _delay_ms(1);
      PORTD = 0x00;
      ADMUX = 0b01100010;
      ADCSRA |= 0b01000000;
      while(bit_is_clear(ADCSRA, ADIF));
      PORTA = 0b11100000;
      PORTB = ADCH;
      _delay_ms(1);
      PORTB = 0x00;
    }
}


Step 9: Attaching Your Circut to a Glove

I think that there are many ways to attach your circuit to you hand and for a while thought I would leave it up to the reader but then decided that the instructable wouldn't be complete without this closure.

I went to my local bike store and got the cheapest full-finger glove I could find.  Full finger is necessary because otherwise you cannot attach the flex sensors very well.  I then went by a fabric store and got some polyester thread and stick-on velcro.  I put the glove on and placed the circuit on my hand.  Part of positioning is comfort but another part is the flex sensors.  They should be going down the middle of two fingers.  I sewed loops around the three standoffs to hold the main board on (See picture #2) and then did loose loops 3/4 of the way down each flex sensor finger (#3 and 4).  Make sure you don't sew your glove closed.  Next I stuck a piece of velcro onto the side of my thumb to hold the battery.  I have found after testing that it really pays off to sew this on too as the stick doesn't last for too long.  Next I put a loop of velcro around the 9v (Picture 5).  This setup seems to work pretty well.  As you see in the pictures on the first and last slides, I have now added sleeves for the flex sensors but if you don't have the time, loops should do fine.

When you finish with your project please post photos of your finished product below.  I'd love to see what you came up with to attach the circuit!

Step 10: The Real Code

Thanks for bearing with me so far.  Please keep in mind that my code is not perfect.  I have found that it takes a little bit of learning to get the signal working just right.  I will continue trying to perfect my system and will keep this page updated with new code once I write it.

Dec 26, 2009:  NEW CODE!  It's posted where the old code was.  Many thanks to Jacob for the simplification.  It really works well.


Here it is.  Thanks for reading and don't forget to vote!
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
// Sets or Clears bits in registers
#define setBit(sfr, bit) (sfr |=  (1 << bit))
#define clearBit(sfr, bit) (sfr &= ~(1 << bit))
#define flipBit(sfr, bit) (sfr ^=  (1 << bit))
#define FALSE 0
#define TRUE 1
#define matrixX(x) (PORTA = (x - 1) << 5)
#define matrixGY(y) (PORTD = y)
#define matrixRY(y) (PORTB = y)
void delay(unsigned int delay)
{
    unsigned int x = 0;
    while(x < delay)
    {
        x++;
    }
}
void initMatrix()
{
    DDRD = 0xFF; // Green control
    DDRB = 0xFF; // Red control
    DDRA = 0xE0; // Ground control
}
void matrixRowDraw(char greenmask, char redmask, char column)
{
    matrixX(column);
    int i = 0;
    for(i = 0; i < 8; i++)
    {
        matrixGY(greenmask & (1 << i));
        matrixRY(redmask & (1 << i));
        _delay_us(150);
    }
    matrixGY(0x00);
    matrixRY(0x00);
}
void matrixLeft()
{
    matrixRowDraw(0x10, 0, 1);
    matrixRowDraw(0x20, 0, 2);
    matrixRowDraw(0x40, 0, 3);
    matrixRowDraw(0xFF, 0, 4);
    matrixRowDraw(0xFF, 0, 5);
    matrixRowDraw(0x40, 0, 6);
    matrixRowDraw(0x20, 0, 7);
    matrixRowDraw(0x10, 0, 8);
}
void matrixRight()
{
    matrixRowDraw(0x18, 0, 1);
    matrixRowDraw(0x18, 0, 2);
    matrixRowDraw(0x18, 0, 3);
    matrixRowDraw(0x18, 0, 4);
    matrixRowDraw(0x99, 0, 5);
    matrixRowDraw(0x5A, 0, 6);
    matrixRowDraw(0x3C, 0, 7);
    matrixRowDraw(0x18, 0, 8);
}
void adcInit()
{
    ADMUX = 0x60;
    ADCSRA = 0x80;
}
char adcGet(char chan)
{
    ADMUX = 0x60 | chan;
    ADCSRA |= 0x40;
    while(bit_is_clear(ADCSRA, ADIF));
    return ADCH;
}
char adcAvg(char chan, char avgnum) // Only average up to 256 samples
{
    int i = 0;
    unsigned int total = 0;
    for(i = 0; i < avgnum; i++)
    {
        total += adcGet(chan);
    }
    return total/avgnum;
}
int main()
{
    initMatrix();
    adcInit();
    while(1)
    {
      while(adcAvg(3, 50) > 0x45 & adcAvg(2,50) > 0x70) // The hex values here should be changed depending on the users setup to determine the sensitivity of the flex sensors.
        {
            if(adcAvg(1, 50) > 0x4F)
            {
                matrixRight();
            }
            if(adcAvg(1, 100) < 0x4F)
            {
                matrixLeft(50);
            }
        }
    }   
    return 0;
}

Special thanks to the Chamberlains, my parents and friends who helped.

Homemade Holidays Contest

Finalist in the
Homemade Holidays Contest