lab project 3: adaptive traffic light control systems
TRANSCRIPT
Lab Project 3:
Adaptive Traffic Light Control Systems
NOTE: You will need a flash-drive to save your work, as you will need it the next
time you are in lab. Data will be cleared from the computers at the end of each lab section, so
save your work to your own disk.
Objective
In this experiment, you will be using the computer program MATLAB to interact with a Data
Acquisition (DAQ) Device. The DAQ device is connected to 12 light emitting diodes (LEDs),
which represent traffic lights at a 4-way intersection. The DAQ device is also connected to
magnetic reed switches mounted under each lane. The model cars are equipped with powerful
neodymium magnets that will cause the magnetic reed switches to close; this can be detected by
the DAQ device and will be used as inputs for detecting the presence of cars at the intersection.
In the first part of the experiment, you will write three functions: a function to initialize the DAQ
device, a function to send data to the traffic lights, and a function to receive data from the road
sensors.
In the second part of the experiment, you will write a program that controls the traffic lights,
incorporating the functions written in Part 1.
Materials
Computer
MATLAB
Traffic Light Assembly with DAQ device
USB cable
Toy cars with magnets
Storage Device from home to save work.
DAQ and the Traffic Light Module
The control unit of the traffic light module is a 24 bit DAQ device from Measurement
Computing. Each data bit is referred to as a port and is connected to a physical pin on the DAQ
device. The bits are grouped into 3 banks: A, B, and C. Hardware limitations of the DAQ Device
require that all ports on bank A are configured to be either input or output; the same goes for
bank B. Bank C, however, can be broken into 2 sets,: Ports C0-C3 must all have the same
direction, and ports C4-C7 must all have the same direction.
The LED lights are connected to ports A0-B3 (See Table 1), and the vehicle sensors are connected to
ports C0-C3. This means our program needs to configure ports A0-B3 as outputs, and C0-C3 as inputs.
Table 1: DAQ Device Connection
Pin Signal Name Bit Connected To Pin Signal Name Bit Connected To
1 Port C0 16 North Sensor 21 Port A0 0 North Red
2 Port C1 17 East Sensor 22 Port A1 1 North Yellow
3 Port C2 18 South Sensor 23 Port A2 2 North Green
4 Port C3 19 West Sensor 24 Port A3 3 East Red
5 Port C4 25 Port A4 4 East Yellow
6 Port C5 26 Port A5 5 East Green
7 Port C6 27 Port A6 6 South Red
8 Port C7 28 Port A7 7 South Yellow
9 GND 29 GND
10 n/c 30 PC +5V
11 n/c 31 GND
12 GND 32 Port B0 8 South Green
13 n/c 33 Port B1 9 West Red
14 n/c 34 Port B2 10 West Yellow
15 GND 35 Port B3 11 West Green
16 n/c 36 Port B4
17 GND 37 Port B5
18 n/c 38 Port B6
19 GND 39 Port B7
20 CTR 40 GND (n/c: Not connected, GND: Ground, PC +5V: 5 volt power from PC, CTR: Counter function of DAQ device)
When using MATLAB, you will refer to the various ports as their designated bit. All you need to
know is what bit is connected to what light or sensor. For more information on the other pins and
signal names, view the USB-1024LS manual on Moodle.
How to Use This Document Syntax, as found in the MATLAB Help documentation:
Code for you to use directly in your program:
Note: Anytime you see code in a box, you may use it in your program. If you choose to use
different variable names, keep in mind that this document will be referring to variable and
function names based on the sample code provided.
Terminology addline():
A function in the DAQ Toolbox that assigns a hardware line to a DAQ device.
Bit:
The numerical equivalent of a digital port.
Board/Board #:
The number assigned to a DAQ device by Instacal.
DAQ Device:
A device used for inputting and outputting data from a computer. The traffic light module has a
DAQdevice in its center that detects signals from the sensors and outputs signals to the traffic lights.
digitalio():
Short for “digital input and output;” a function in the DAQ Toolbox that creates an object for
communicating with a DAQ device.
Function:
An M-file that accepts input arguments and returns output arguments.
Globalize:
Declare a variable as a global variable.
Global Variable:
A global variable is a variable that is accessible to any function that declares it. If you want more than one
function to share a single copy of a variable, simply declare the variable as global in all the functions. Do
the same thing at the command line if you want the base workspace to access the variable. The global
declaration must occur before the variable is actually used in a function.
Hardware Line:
A port on a DAQ device. For example A2 and A6 are two different hardware lines.
Infinite loop:
A program loop that runs infinitely. Press Ctrl+C to break the program.
Interrupt:
A signal sent to the computer that ‘interrupts’ the computers current processes to temporarily process
another routine.
Instacal
The configuration utility for Measurement Computing DAQ devices such as the USB-1024LS.
Object:
An object is a type of variable that contains function information. An example of an object could be a
line on a plot, or an input or output range on a DAQ device.
Port:
An input or output on a DAQ device.
putvalue()/getvalue():
Functions for sending/receiving data to/from a DAQ device.
Script
A simple program that contains no inputs.
Note: Refer to the DAQ Toolbox MATLAB Help documentation on Moodle for more information
about the DAQ Toolbox functions used in this Lab.
Setup Note: If the following steps are performed out of order MATLAB will not recognize the Traffic
Light Module.
1. Plug in the traffic light module using the USB cable provided if it is not already plugged in.
One end of the USB cable connects to the USB port on the DAQ device in the base of the
traffic light module, the other connects to a USB port on the back of the computer. Please do
not connect the traffic light module to the USB ports on the front of the computer.
2. Open InstaCal from the icon located on the desktop.
(InstaCal is the configuration utility for the DAQ device.)
2a. If you get a PnP Board Detection message saying that a device is not connected, press
OK to continue and remove this board. If your traffic light module is properly connected a
Plug and Play Board Detection window will appear. Click OK to add the board to the
configuration file. You will not see this box if the computer is already configured to
communicate with the device.
3. If the device is seen by InstaCal, you will see a similar window. Take note of the Board #.
The Board# will probably be zero (0) because only one board is connected to the computer.
You can change the board number by right clicking on the device if necessary. The board
number does not need to be zero, however you do need to know what it is so that you can tell
MATLAB what device you are trying to communicate with.
4. Close InstaCal and start MATLAB
Part 1
Before you leave lab, you must write 3 functions
M-File 1 – Initializing the DAQ Device 1. Open a new M-file and save it as initiateLights.m. Be sure to include comments in your
code. Declare two global variables:
Recall that the lights and sensors are wired as follows, noting that a bit is the same as a
hardware line:
2. The following will add a digitalio object called trafficLights, configure it for output on
bits 0-11, and clear the data on the device at those ports. Add this to your M-file:
%Create a digital I/O object trafficLights for a %MCC board with hardware ID 0.
trafficLights = digitalio('mcc',0);
%Add twelve hardware lines (0-11) to trafficLights, %configuring them for output.
addline(trafficLights,0:11,'out');
%Turn off all lights by sending a zero to each bit putvalue(trafficLights,[0,0,0,0,0,0,0,0,0,0,0,0]);
%An alternate way to turn off all lights:
%putvalue(trafficLights,zeros(1,12));
3. Add the code necessary to add a digitalio object to sensorStatus, and configure it for input
on bits 16-19. You do not need to clear data on an input digitalio object.
4. Save the M-file. (See the Appendix for more information on these functions and how
they work).
M-File 2 – Changing the Lights This function must accept 2 values as input arguments: the color of the north and south bound
lights and the color of the east and west bound lights. The values for the input arguments for
each set of lights should operate as follows: an input of 0 should make the lights red, an input of
1 should make the lights yellow, and an input of 2 should make the lights green. This function
will change the lights illuminated on the traffic light module according to its inputs. Note: This
function is very similar to the “Your Turn” you completed in lecture 16.
1. Create a new M-file and save it as changeLights.m. Be sure to include comments in your
code.
2. You will need to globalize the object (declared in the first M-File) that interfaces with the
lights. This allows the function to access the same object declared in the first function. Do
not globalize the sensor object in this function.
3. Write the lines of code necessary to change the lights according to the function’s input
arguments:
Examples:
1. To change all of the lights to red the following line of code would be used:
putvalue(trafficLights,[1,0,0,1,0,0,1,0,0,1,0,0]);
2. To make the north and south bound lanes have a green light, and the east and west
bound lanes have a red light, the following line of code could be used:
putvalue(trafficLights,[0,0,1,1,0,0,0,0,1,1,0,0]);
Refer to table 2 to reference which light is connected to which port.
Hint: Modify your function from the lecture 16 “Your Turn” to use the putvalue()
function to send the output to the traffic lights, rather than returning a vector as the
output of the function.
4. Test your function from the command window: changeLights(1,2) should turn the N-S
lights to yellow and the E-W lights to green. Test each light color for each direction, and
debug if necessary.
M-File 3 – Polling the Sensors This function has 1 input argument: direction. Direction will be indicated as a 0 for N-S travel or
a 1 for E-W travel. If a car is present at either of the north or south bound sensors while the input
direction is 0 (for N-S travel), the function returns a 1 (indicating a car is present). If no car is
present, the function returns a 0. If the input direction is 1, the function will return the status for
the E-W sensors (0 if no car present at either sensor, 1 if a car is present at either or both
sensors).
1. Open a new M-file and save it as vehicleCheck.m. Be sure to include comments in your
code.
2. This will be a function. There is one output argument, and one input argument. The input
argument will either be a 0 or a 1. If the input argument is 0, then the function will be
looking at the North-South lanes of traffic, otherwise the function will look at the East-
West lanes of traffic.
3. Declare a global variable for sensor status with the same name as in initiateLights.m. Do
not globalize the traffic light object in this function.
4. Add the following code to get data from the sensor object sensorStatus (recall that
sensorStatus was a global variable declared in the initialization program):
A 1x4 vector of binary data will be read from the DAQ device and stored into variable
carLocations. Due to the nature of this DAQ device, if a bit value is a 1, then no car is
present at the corresponding location. The format of this vector is as follows: [north
bound lane, east bound lane, south bound lane, west bound lane].
Example:
If the If the value of carLocations = [1,1,0,1], then there is a car present in the south
bound lane, and no cars present in any other lane.
5. Write an algorithm that converts the inputs and outputs shown in Table 3 into MATLAB
code. This could be done with selection structures (if-elseif-else). Note that there are
essentially 5 inputs to the function, one from the function declaration, and 4 from the
DAQ device (in a 1x4 vector: [North, East, South, West] ).
carLocations = getvalue(sensorStatus);
%Note: a car is present only when a value of 0 is returned %from the DAQ device
6. Using the toy cars or bar magnets, test the function from the command window, and
debug if necessary. Note that in testing this function, you may find it useful to use call the
function inside of an infinite loop.
7. Save your work
8. If there is time remaining, and you wish to do so start working on Part 2 of the lab.
Check out
1. Show your instructor or ta the functionality of all three codes
2. Email all group members the three codes
3. Return magnets to instructor
4. Sign Out
Part II
The scenario: (Note, light durations have been sped up from real scenario times to allow
easier debugging of the program)
The East-West bound lanes have regular traffic and need priority. The North-South
bound lanes have very little traffic and only need to be green when a car arrives at
the light.
The E-S lanes should be green for a minimum of 5 seconds and a maximum of 15
seconds
If a car arrives at the N-S intersection the light will change within 5 seconds, except when
the minimum and maximum green time says otherwise
The N-S green light should be green for 5 seconds
Between cycles all directions should have a red light for 1 second
Yellow lights are 2 seconds
1. If you are returning to the lab, follow the steps under the Setup section of this document.
If your board number has changed, you may right click on the device and select Change
Board#..., or you may edit your initialization script (initiateLights.m) accordingly.
2. Create a new M-file called trafficLight.m. Be sure to include comments in your code.
3. Call your initialization function, initiateLights, at the start of trafficLight.m.
4. Declare and assign values to all variables (including the ones listed in the above
scenario.)
All parameters must be declared in this section of your code: points may be deducted for
values hardcoded elsewhere. This allows you to easily change certain program
parameters in one easy to find location. This can be useful when you want to change
values to speed up testing.
5. Use a “while 1” loop to run the traffic light scenario infinitely. Even though it is often
considered bad practice to use infinite loops in programming, you may use an infinite
loop to keep this program simple. An ideal traffic control system would include an
interrupt allowing an administrator to take control of the lights if necessary. Remember,
to break execution of your traffic light program, press Ctrl+C.
6. Inside the main program loop, use your changeLights function to change the lights to all
red, as shown in the following code:
Refer to Figure 1 for a flowchart representation of this code.
7. The lights can now be set to green for E-W direction of travel.
8. Insert another loop to time the green light. You will need to insert some code into the
loop to determine if a car is present and if the duration of the green light should be
extended. You will need to use your vehicleCheck function and an if-statement. Refer to
Figure 2 for a flowchart representation of this code.
%% All Red changeLights(0,0); tic while toc < allRedTime end
9. Add the remaining light changes and timing loops to finish the project. Test and debug
your program. When you are satisfied with your program, demonstrate your program to
your lab Instructor or UTA.
The flowcharts may help you design your program; however you are not restricted to
writing your program exactly as they are laid out, as there are numerous ways of
programming each subroutine. Figures 3 and 4 show flowcharts for one possible
implementation of the scenario. You will not be penalized for creativity, provided the
program works.
Figure 2: N-S Green Time
Figure 3: Main Program I: All Red Time and E-W Green Time
Figure 4: Main Program II: Transition to and from N-S Green Time
Check out
1. Show your instructor or ta the functionality of all three codes
2. Email all group members all codes
3. Return magnets to instructor
4. Sign Out
Appendix Some background information on how these functions work.
The first function is a script that does not have any inputs. It must be executed each time MATLAB starts
before you attempt to communicate with the DAQ device
In order to communicate with the DAQ device, you need to declare a few objects. An object is like a
variable, but instead of storing data, it also stores a function. In this case the data will be the status of the
ports on the DAQ device with which you are communicating and the function stores information for the
device and the ports that the data is representing. A full understanding of the object concept is not
required to complete the lab. Just follow the examples provided below and you will be interfacing with
your device in no time.
You will need a minimum of two objects, one for outputting to the traffic light, one for inputting from the
sensors. Because you will be accessing the device from multiple functions, you need to declare the objects
globally. A global variable or object is accessible outside of the function it was declared in. If you recall
from lecture 9, variables used in a function were not available to other functions or the workspace.
Declaring a variable globally allows the variable to be accessible to all functions. If the objects are not
declared globally, you will need to reinitialize the DAQ device in the other functions. It is critical that
your other functions operate as quickly as possible. Because it can take a few seconds to initialize the
DAQ device, it is not practical to re-initialize the program every time the functions are called. By
declaring the objects globally, you will be able to access them from other functions.
This demonstration will setup 2 objects, one called trafficLights, and one called sensorStatus.
Once the object names have been declared globally, they must be assigned an object type. The object type
that is used for communicating with digital DAQ devices is digitalio (for Digital I/O).
Once the object has been configured to a particular DAQ device you must tell it what ports on
the device to communicate with. You must also specify whether the object is an input or an
output.
DIO = digitalio('adaptor',ID);
Where:
DIO is the name of the object that will be used to communicate with the device 'adaptor' is the name or
brand of the DAQ device. (use 'mcc', for Measurement Computing devices).
ID is the Board number (Found in InstaCal, Default: 0).
addline(DIO,[hwline], 'direction');
Where:
DIO is the name of the object digitalio object,
[hwline] is the numeric IDs of the hardware lines being added to the device object. (Any MATLAB
vector syntax can be used), and 'direction' is the either 'in' for input or 'out' for output.ID is the Board
number (Found in InstaCal, Default: 0).
If the object is an input, you should clear any values the device might be outputting. The putvalue
function is used to send data to the DAQ for output.
putvalue(DIO,[data]);
Where:
DIO is the name of the digitalio object, and [data] is a vector of binary data of the same size as [hwline]