*arg max *arg min
CSCE 236 Embedded Systems, Spring 2015
Lab 5

Thursday, April 9, 2015
Names of Group Members:

1  Instructions

This is a group assignment to work on during class. You only need to hand in one copy of this, but make sure that the names of all of your group members are on this sheet to receive credit. Complete all of the sections below and make sure to get the instructor or TA to sign off where required. You should keep your own notes on what you complete since parts of future homework will build on this lab.

2  Button Interrupt

In this section you will implement an interrupt handler for button presses. There are two pins, labeled INT0 and INT1 on the Arduino Schematic, that can be configured to trigger an interrupt on a transition, rising edge, or falling edge1. Start by identifying the pin on the Arduino that corresponds to INT1. Connect your button to this pin (if it isn't already). In the code, make sure you enable the internal pullup for this pin (if you don't have an external pullup) and that it is set as an input. Make sure that your button is working by using the standard non-interrupt based code to turn on an LED when the button is pressed.
Now look at section 13 (External Interrupts) of the datasheet to determine how to enable interrupts on INT1. Pay particular attention to the descriptions of registers EICRA and EIMSK. Configure these registers to:
In your code, insert the following function:
  //INT1 interrupt handling code goes here

This is a special macro function that tells the compiler to properly configure the interrupt vector to point to this function whenever the interrupt INT1 occurs. Now write code to do the following: In this configuration, the interrupt handler turns on the LED and the main loop turns off the LED.
Checkoff: (You can get checked off for this question along with the other questions at the end of this section.) The LED does not always turn on and off as expected sometimes. Why?
It is possible to disable interrupts by using the function cli() and to enable interrupts using the function sei(). Use these to fix part of the above problem.
It is also possible to fix this problem without disabling/enabling interrupts by having the interrupt trigger whenever any logic change occurs on the pin (by changing register EICRA). Use this approach as well to fix this problem.
Checkoff: Describe the advantages and disadvantages of both solutions used to correct the above problem. Make sure to save the solutions as two different sketches so you can show the instructor both approaches.

3  Real-Time Events

Sometimes it is important to run a particular event at a specific frequency. One way to do it is to periodically check the millis() command to see if the desired number of milliseconds has elapsed and if so, you can run the event. This is fine if this is the only task you are performing, but you can run into trouble if other tasks are occurring. You may have noticed during the project competition that if you printed a lot of debug information the rate at which you could read the sensors decreased. In this section, you will blink the LED at a fixed rate using the timers and interrupts, but first you will implement blinking the "old fashion" way of using millis().
Download the lab5 sample code from the course website. For the moment, ignore the timer interrupt setup code and interrupt handler. You will see that normally the LED toggles every 500ms. When the button is pressed (you may need to change the pin your button and LED are connected to in the defines at the top of the code) the values of the analog input pins and digital input pins are printed.
Checkoff: What happens to the blinking rate when you press the button? Is it consistent? (You can get checked off for this question with the next checkoff.)
Now configure the timer to do the blinking in an interrupt. You should comment out the blinking code from the main loop and uncomment the toggleLED() function call in the interrupt handler. In the function setupTimerInterrupt() you need to determine the proper value of the register OCR1A to cause an interrupt to be generated every 500ms (this is the only thing you need to change). You can remind yourself how the timers work by looking at the register descriptions in section 16.
Checkoff: What value did you use for OCR1A and how did you figure this out? What happens now when you press the button? Does the blinking rate change?
Using interrupts generated by the timers is a good way to make sure events happen at the desired frequency. For instance, the millis() function uses an interrupt based on Timer0 to count the number of elapsed milliseconds. However, you must be careful not to put too much code in the interrupt handler since that may prevent the main loop from executing or interrupts may be missed.

4  Final Project Preview

For the final project your team will compete against other teams in a modified capture the flag-type environment. Each robot will start guarding an exit of a "room" and the goal will be to get out of the opposite exit before your opponent2. There will be a black line on the ground connecting the two exits that you can follow to the exit. There will also be walls at least 3 inches high surrounding the environment. You are free to modify your robots, but please make sure all of the components I gave you are returned in working condition. You must also fall within the following constraints: Note that these are preliminary requirements and there may be minor modifications in the final project description.
There will also be a number of checkpoints associated with the competition. The first will be wall following using the range finder (see below) to follow a wall for at least 50cm. This checkpoint will be due in class on Thursday, April 16th (next week). Get started on this once you complete the above lab.

5  Range Finder

In this section you will start using a VCNL 4000 range sensor (it also has an ambient light sensor), which is an I2C device. The stated range for this sensor is 20cm, although it typically works best for measuring distances under 10-15cm. The datasheet and example code are linked to on the course website.

5.1  I2C Communication Library

Download the code, datasheet, and application note for this sensor from the course website. Briefly read through these documents before trying the code. With the power disconnected, hook up your sensor to the Arduino. You will first need to determine which pins on the Arduino are the SDA and SCL pins. Make sure you connect the yellow 3.3V line ONLY to the 3.3V supply on the Arduino and NOT to the 5V line.
Test the sample code and perform some basic characterization of the sensor. For the first project checkpoint you will have to follow a short wall with this sensor. So work on implementing code to do so. Note that the relationship between distance and the returned value is not linear.


1 A c t u a l l y a l l p i n s c a n b e c o n f i g u r e d t o t r i g g e r a n i n t e r r u p t o n a c h a n g i n g s t a t e , b u t t h e r e i s o n l y a s i n g l e i n t e r r u p t h a n d l e r f o r a l l o f t h e o t h e r p i n s , s o w e w i l l u s e o n e o f t h e p i n s t h a t h a s a d e d i c a t e d i n t e r r u p t h a n d l e r .
2 I f n e i t h e r r o b o t e x i t s w i t h i n t h e t i m e l i m i t , t h e n t h e r o b o t c l o s e s t t o i t s e x i t w i n s .

File translated from TEX by TTH, version 4.03.
On 8 Apr 2015, 14:54.