Arduino Traffic Lights: Programming the Arduino controller

In the previous blog article I describe my plan for building a set of traffic lights which can be controlled using an arduino micro controller. This second blog article will explain how to program the arduino to accept incoming commands and act accordingly.

About Arduino

Arduino is an open-source physical computing platform based on a simple microcontroller board, and a development environment for writing software for the board. The boards can be assembled by hand or purchased pre-assembled; the open-source IDE can be downloaded for free. For this project an Arduino Duemilanove is used in combination with an Arduino Ethernet Shield add-on. Visit the official Arduino website for more information.

An Arduino board contains a set of digital and analog pins which can be used for input or output. In our case we will be needing 3-4 digital output pins for switching the three lights (the 4th output pin is optional and is connected to a led displaying web server activity).

Initial project

The first step is to install the Arduino IDE and to verify your arduino is working correctly.  A minimalistic arduino program exists of a set of variable declarations, a set-up routine and a main loop. The code below defines the initial variables and set-up routine. In the set-up routine the Serial driver is initialised for debugging purposes.

int current = 4;

void setup() {
    // Initialize output pins
    pinMode(4, OUTPUT);      // Green light
    pinMode(5, OUTPUT);      // Yellow light
    pinMode(6, OUTPUT);      // Red light
    pinMode(7, OUTPUT);      // Optional Power/Progress light

    // Setup serial debugging support
    Serial.begin(9600);
    Serial.println("Initializing device");
}

The main routine will loop through the four LED's. The 'current' variable is used for storing the current active led. A separate routine is defined for switching to the next led, which will be re-used later on. After uploading the compiled code onto the Arduino board, the Arduino will automatically boot and execute the code. The example below loops through all four LED's and switch it on for a single second. The corresponding code can be found on GitHub project tag 0.1.

void loop() {
next();
}

void next() {
    int prev = current;
    current = (current>=7) ? 4 : current+1;

    Serial.println("Switching leds");
    Serial.print("- Prev: ");
    Serial.println(prev);
    Serial.print("- Next: ");
    Serial.println(current);

    digitalWrite(prev, LOW);
    digitalWrite(current, HIGH);
    delay(1000);
}

Accepting web server requests

The next step is to load the Ethernet library and start a basic server listening on port 80. The code below initialises an Ethernet connection using IP 192.168.1.99 and starts a  server listening on port 80. The mac address to define can be found on the back of the Ethernet module. The corresponding code can be found on the GitHub project tag 0.2.

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1,99 };
Server server(80);

void setup() {

    // Initalize the Ethernet connection
    Serial.println("Initializing ethernet connection");
    Ethernet.begin(mac, ip);

    // Start the webserver
    Serial.println("Starting webserver");
    server.begin();
}

Next the main loop is replaced with the following code in order to handle new requests. The incoming data is read one character at a time (the device has limited amount of memory, so use it wisely!). After receiving an empty line, which defines the end of a HTTP request, the device sends back a response. In the example below the next routine is invoked once per request and the response is an empty document.

void loop() {
// Listen for incoming clients
Client client = server.available();
String requestFirstLine = "";

if (client) {
    // Print debug
    Serial.println("Accepted client");
    // An http request ends with a blank line
    boolean currentLineIsBlank = true;
    // Only the first line of the request is needed
    boolean firstLine = true;
    while (client.connected()) {
        if (client.available()) {
            // Append the character to get the uri string
            char c = client.read();
            if (firstLine) {
                requestFirstLine += c;
            }
            // If you've gotten to the end of the line (received a newline
            // character) and the line is blank, the http request has ended,
            // so the reply can be sent
            if (c == '\n' && currentLineIsBlank) {
                // Switch next led
                next();

                // Send a standard http response header
                client.println("HTTP/1.1 200 OK");
                client.println("Content-Type: text/html");
                client.println();
                break;
            }

            if (c == '\n') {
                // New line found
                currentLineIsBlank = true;
                firstLine = false;
            } else if (c != '\r') {
                // Next line contains a character
                currentLineIsBlank = false;
            }
        }
    }
    // Give the web browser time to receive the data
    delay(10);

    // close the connection:
    client.stop();
    }
}

Switching lights according HTTP parameters

The device will accept some HTTP parameters in order to switch a specific light on or off. All four parameters (green, yellow, red, all) supported by the device use the values (on, off) to specify an action. For each LED a variable is defined to storing its state.

int stateGreen = 0;
int stateYellow = 0;
int stateRed = 0;
int stateProgress = 0;

In the main loop invoking the next() routine is replaced with a new method, defined below. This methods requires the requestFirstLine variable, which contains the first line of the request, containing the requested URL. In the example code below only handles the green LED. The code for handling all LED's can be found on the GitHub project tag 0.3.

void params(String requestFirstLine) {
    // Print request params
    Serial.print("- Request Info:");
    Serial.print(requestFirstLine);

    // Check get parameters: Green light
    if(requestFirstLine.indexOf("green=on") >0) {
        digitalWrite(4, HIGH);
        stateGreen = 1;
        Serial.println("- Switching green light to ON!");
    }
    if(requestFirstLine.indexOf("green=off") >0) {
        digitalWrite(4, LOW);
        stateGreen = 0;
        Serial.println("- Switching green light to OFF!");
    }
}

The code above should help you getting started to build your own traffic lights. It explained the basic concepts with simple implementation.

Rendered Content in 0.001 seconds

Rendered UI Widgets in 0.001 seconds

Want to see the cheezy internals?
twig layout template | twig page template | json data