Raspberry Pi Knight Rider LEDs Part 2

Now we’ve got one LED up and running, it’s pretty easy to expand this to make a light bar like K.I.T.T.’s.

Step 1 – Wire up the breadboard

The next thing we need to do is switch everything off, and then wire up the breadboard as per the circuit diagram below. Leave the female ends of the jumper wires dangling for now – we’ll plug them into the Pi in step 2.

knightrider_bb

Step 2 – Connect the GPIO pins

Remember that Revision 1 boards and Revision 2 boards have different pin layouts.

You can use these reference diagrams to help you connect to the right pins on your Pi.

What you will do in this step is connect the wires above, in order from left to right (brown to grey), to the GPIO pins that correspond with the wiringPi library definitions of pins 0 to 7.

This sounds more complex than it is. It’s a two step process and I’ll talk you through it now (cause I’m nice like that).

OK, the wiringPi pin numbers correspond to the GPIO pins in this order:

0 – GPIO 17
1 – GPIO 18
2 – GPIO 21
3 – GPIO 22
4 – GPIO 23
5 – GPIO 24
6 – GPIO 25
7 – GPIO 4

So, the black wire will be the first connection, and it will go to GPIO 17. The grey wire will be the next connection, and it will go to GPIO 18. And so on, through each of the wires on your breadboard, until you get to the last wire (the blue one), which will go to GPIO 4.

Remember to refer to the pin diagram (here’s that link again) for your board revision so that you connect to the right pins!

Here’s my breadboard, wired up and ready to go:

raspberrypi_gpio_breadboard

Step 3 – Back to the code

All with me so far?

Great.

Last thing we need to do is modify our code to toggle all of the LEDs on and off in the correct order. Here’s the code:

#include <wiringPi.h>

enum {
    PIN0,
    PIN1,
    PIN2,
    PIN3,
    PIN4,
    PIN5,
    PIN6,
    PIN7
};

int main (void)
{
    const int WAIT = 105;
    const int LONG_WAIT = 250;
    int i = 0;
    wiringPiSetup();

    for (i = 0 ; i < 8 ; ++i)
    {
        pinMode (i, OUTPUT);
    }

    while(1)
    {
        digitalWrite(PIN0, HIGH);
        delay(LONG_WAIT);        
        digitalWrite(PIN1, HIGH);
        delay(WAIT);

        for (int i = PIN0, j = PIN2; i <= PIN5; ++i, ++j)
        {
            digitalWrite(i, LOW);
            digitalWrite(j, HIGH);
            delay(WAIT);
        }

        digitalWrite(PIN6, LOW);
        delay(WAIT);
        digitalWrite(PIN6, HIGH);
        delay(WAIT);

        for (int i = PIN7, j = PIN5; i >= PIN2; --i, --j)
        {
            digitalWrite(i, LOW);
            digitalWrite(j, HIGH);
            delay(WAIT);
        }

        digitalWrite(PIN1, LOW);
    }
}

You’ll notice that there are two constants, LONG_WAIT and WAIT defined at the beginning. Feel free to play around with the timings to get the most realistic effect (or speed it up or down).

To compile the code type:

g++ knightrider.c -o kr -lwiringPi

And to run, type

sudo ./kr

And that’s all there is to it!

Wanna see that video one more time?

 


2 Comments

  1. alberto
    Posted 3 February 2015 at 08:13 | Permalink

    Hi! I love your Technical Tuesday posts. But please, can you explain a little bit the logic of this super simple piece of code? Is a delay a blocking function like in arduino enviroment? why the last digitalWrite(PIN1, LOW)? Sorry but I’m new to programming!

  2. Posted 3 February 2015 at 14:04 | Permalink

    Yes – I should have written an explanation of the code!
    The delay function is part of the wiringPi library and pauses program execution. I suppose the equivalent is sleep on a linux system. The digitalWrite commands are set in a while loop, to flash each LED on and then off again. To get the drifting effect of light traveling right to left, I have turned on two LEDs each time, in a stair-step fashion. So, starting with the first LED lit, I turn on the second, then the third, then I turn off the first. Then repeat, but moving up by one. Then I reverse the pattern coming back.
    To be honest, when I first wrote the code, I wrote the entire lot out in long form with no for loops. I only added the loops to condense the code once I got the lights flashing how I wanted them.
    The last digitalWrite turns off the second LED, leaving everything back to how it started. i.e. the first LED lit and the others off.