Tutorials/Arduino Projects/Mobile Robotics/BoeBot/What is an LED

From ROBOTC API Guide
Jump to: navigation, search

What is an LED?

An LED is a “Light-Emitting Diode”, which is an electronics component that emits light when it is powered. Since it is a diode, and diodes only let the current flow in one direction, for an LED to work it must be wired correctly. When connecting an LED it is important to be able to distinguish which lead is the anode (positive) and which is the cathode (negative). To make it easy to identify the leads, all LEDs are manufactured with two physical properties. The first is that LEDs have one lead that is longer that the other. This longer lead is the anode, and the shorter one is the cathode. The second feature is a small flat notch on the side of the led. The lead that is closer to the notch is always the cathode. This is important to remember since the leads may have been clipped.

Insert image of LED and how it relates to the schematic symbol.

When referencing a schematic (drawing of the electrical pathways and components using symbols), the symbol for the LED shows which way the current flows and allows you to connect the LED the correct way. The cathode on the symbol is the side with the line across the point of the triangle and the anode is the other side.

How to Wire up an LED

To wire up an LED you need an LED, a breadboard, some wires, and a 470Ω resistor (color code: yellow-violet-brown) Wiring up an LED is very simple. For this circuit, all you need to do is connect one lead of the resistor to digital pin 5 on the Arduino. Connect the other lead of the resistor to the anode lead of one of the LEDs, and then connect the cathode to ground.

LED Circuit Schematic

To make this easier, we will use the breadboard.

File:BoeBot Breadboard 1 LED.png
Breadboard setup for one LED

Understanding the circuit

The Arduino digital pin in this circuit will be configured as an output, which for this setup can be thought of as connecting the circuit to the power when set to high, or disconnecting it when set to low. When it is connected the current will flow from the pin, through the resistor and through the LED, then into the ground connection. For electronics, the ground connection refers to the voltage supply connection that has 0 volts. For the Arduino circuits, the voltage supply has 5 volts. However the LED requires about 2 volts across the leads not the 5 volts output from the pin. This is where the resistor comes in to play. For a series circuit (the components are connected one after the other), the sum of the voltage drop across each component must be equal to the source voltage, which in this case is 5 volts. Since the LED needs 2 volts the resistor must have a voltage drop of 3 volts. Additionally, for series circuits, the current (amperes) going through each component is the same. Based on these properties it is possible to calculate the required resistance of the resistor using (Vs-V¬LED)/I¬LED=R, where Vs is the supply voltage, VLED is the voltage across the LED, ILED is the desired current flowing through the LED, and R is the resistance of the resistor. We already selected the 470Ω resistor because it provides a nice safety range for variances of the components.

Programing One LED

To demonstrate how you can use an LED with the Arduino, we are going to have the Arduino make the LED flash.

Configuring ROBOTC

First thing you need to do is make a new source file in ROBOTC. Once you have done that you need to tell ROBOTC what type of Arduino you are using. Since you are using the Parallax Boe Bot Shield, you will be using the Arduino UNO. To specify the board go to Robot > Platform Type > Arduino Types > Standard Arduino then click on Arduino UNO.

Arduino board type menu

Now that ROBOTC knows what board you are using, it is time to configure the pins on the Arduino. To do this we open the Motors and Sensors Setup window by opening the Robot drop-down menu and clicking on Motors and Sensors Setup.

Opening the Motors and Sensors Setup window

Now we want to let ROBOTC know that we have the Parallax Boe Bot Shield attached, so we navigate to the Controller Board tab and under Optional Plugin Shields, we want to select the parallax Boe Bot Shield from the selection box next to the 0.

Parallax Boe Bot Sheild configured

Now we want to tell ROBOTC to configure digital pin 5 as a Digital Output and name it led1. To do this we navigate to the Digital 0-13 tab. in the text field next to "dgtl5" type in led1, then next the text field select Digital Out from the drop-down list.

Digital pins configured

Now that everything is configured we click OK. The Motors and Sensors Setup window will close and your source code file should contain the following code.

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(PluginCircuitBoard, typeShieldParallaxBoeBot)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Sensor, dgtl5,  led1,           sensorDigitalOut)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//


Programming task main()

Now that the configuration is done, it is time to add the code to make the LED flash. To do this we want the Arduino to set the output to high, pause for a moment, set the output to low, pause again then repeat. The first step to doing this is to crate a task main() to run everything.

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(PluginCircuitBoard, typeShieldParallaxBoeBot)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Sensor, dgtl5,  led1,           sensorDigitalOut)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//
 
task main()
{
 
}

Now we want the pin to be set High and pause for a second. To do this we use the following code.

//turn the LED on
SensorValue[led1] = true;
 
//wait 1 second
wait1Msec(1000);

We now need to turn the LED off then pause again. By setting the value to false instead of true in the above code, the LED will turn off. Using that information, the following code will turn the LED on for one second, then turn it off and wait another second before continuing.

//turn the LED on
SensorValue[led1] = true;
 
//wait 1 second
wait1Msec(1000);
 
//turn the LED off
SensorValue[led1] = false;
 
//wait 1 second
wait1Msec(1000);

We want this to happen indefinitely so we surround the previous code with a while(true) loop, and insert the code into the task main() and end up with the program

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(PluginCircuitBoard, typeShieldParallaxBoeBot)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Sensor, dgtl5,  led1,           sensorDigitalOut)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//
 
task main()
{
  while(true) //repeat indefinitely
  {
    //turn the LED on
    SensorValue[led1] = true;
 
    //wait 1 second
    wait1Msec(1000);
 
    //turn the LED off
    SensorValue[led1] = false;
 
    //wait 1 second
    wait1Msec(1000);
  }
}


Adding Another LED

Wiring the Second LED

The wiring for the second LED is almost identical to the first. The only difference is that instead of connecting to digital pin 5 line the first LED, the second will be connected to digital pin 6. The circuit for the two LEDs will be constructed as depicted below.

Schematic for two LEDs
File:BoeBot Breadboard 2 LEDs.png
Breadboard setup for two LEDs

Programing Two Flashing LEDs

First create a new source code file and tell ROBOTC what type of Arduino you are using. Now we need to configure the pins. Open up the Motors and Sensors Setup window and tell ROBOTC that you have a Parallax Boe Bot Shield connected to the Arduino.

Opening the Motors and Sensors Setup window
Parallax Boe Bot Sheild configured

Now tell ROBOTC to configure digital pins 5 and 6 both as a Digital Out. Give pin 5 the name "led1" and give pin 6 the name "led2".

Digital pins 5 and 6 configured

Now submit by clicking OK. The Motors and Sensors Setup window will close and your source code file should contain the following code.

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(PluginCircuitBoard, typeShieldParallaxBoeBot)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Sensor, dgtl5,  led1,           sensorDigitalOut)
#pragma config(Sensor, dgtl6,  led2,           sensorDigitalOut)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//


Programming task main()

Now that everything is configured, it is time to add the code to make the LEDs flash. In this case we want to have led1 on and led2 off for a second then have led1 off and led2 on for a second, and have this repeat. Since we already have code that turn led1 on for one second then turns it off for a second and repeats, lets use that as a starting point. Since the code already handles led1, we need to add some code to turn led2 on and off. Based on the work for one LED, we know that

SensorValue[led2] = true;

will turn led2 on and that

SensorValue[led2] = false;

will turn it off. Since we want both LEDs to change at the same time, we want those commands as close, instruction-wise, as possible. Since the existing code is just controlling the one LED, it is very simple. We just insert the led2 control command after the led1 command but before the pause, and we end up with

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(PluginCircuitBoard, typeShieldParallaxBoeBot)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Sensor, dgtl5,  led1,           sensorDigitalOut)
#pragma config(Sensor, dgtl6,  led2,           sensorDigitalOut)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//
 
task main()
{
  while(true) //repeat indefinitely
  {
    //turn led1 on
    SensorValue[led1] = true;
 
    //turn led2 off
    SensorValue[led2] = false;
 
    //wait 1 second
    wait1Msec(1000);
 
    //turn the led1 off
    SensorValue[led1] = false;
 
    //turn led2 on
    SensorValue[led2] = true;
 
    //wait 1 second
    wait1Msec(1000);
  }
}


Extension - Dimming LEDs

How to Adjust the Brightness

While being able to turn LEDs on and off is great, there are times when it might be desirable to have various levels of brightness. This could be achieved using multiple pins and resistors with various resistances and thus adjust the current and voltage flowing through the LED. However, this method requires additional components and thus would cost more money. This method would also make the circuit more complex and would limit you to preset levels. Since these are problems that we want to avoid, you may be asking if there is another way to dim LEDs. Fortunately there is. The method is called Pulse-Width Modulation, or PWM for short. PWM works by turning the circuit on and off very rapidly. By adjusting the ratio of the time on and the time off, it is possible to adjust the brightness of the LED. This ratio is called the Duty-Cycle and is the percentage of time the output is high with respect to the time of one cycle (when the output goes high then low then back to high). If the Duty-Cycle is 100% then the output is high all the time and thus the LED would be a full brightness. If the Duty-Cycle is 0%, the output is off all the time, so the LED would just be off. Now if the Duty-Cycle is set to 50%, the output is on 50% of the time and off the other 50%. In this setup, the LED would appear be at 50% of its full brightness, an thus appears to be dimmed. This works by basically averaging the time on with the time off. The cool thing about PWM is that the same dimming properties can be applied to things like incandescent lights, and even to electric motors to control their speed. Additionally, by measuring the time on, you can even use the PWM signal to transmit data. This concept will be explored more in-depth in the next project.

Programming

Due to the high frequency that PWM operates at, to get an accurate signal using code would basically prevent you from doing anything else with the chip. To eliminate this problem, chip manufacturers included hardware to generate the PWM signal. However not every I/O pin supports PWM output. For the Arduino UNO, only digital pins 3, 5, 6, 9, 10, and 11, support it. luckily, ROBOTC has a tab in the Motors and Sensors Setup window that lists the pins that can me used.

In this code, we want the LEDs to dim in and out over 10 seconds. Again we need to start with a new source code file, and to tell ROBOTC which Arduino board we are using. Now we need to configure the pins by going into the Motors and Sensors Setup. First we will tell ROBOTC that we have the Parallax Boe Bot Shield attached. Up to this point everything is the same as for the flashing LED configurations. In order to be able to set PWM output we need to configure pins 5 and 6 each as a Variable Intensity LED. To do this we go into the Motors tab, not the Digital 0-13 tab. We want to configure motor_5 and motor_6, which map to digital pins 5 and 6 respectively. Give motor_5 the name "led1" and motor_6 the name "led2". Now set the type of both to Variable Intensity LED and click OK.

Pins 5 and 6 configured for LED PWM

The file should have the following code at the top.

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(PluginCircuitBoard, typeShieldParallaxBoeBot)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Motor,  motor_5,         led1,          tmotorVariableIntensityLED, openLoop, reversed, IOPins, dgtl5, None)
#pragma config(Motor,  motor_6,         led2,          tmotorVariableIntensityLED, openLoop, reversed, IOPins, dgtl6, None)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

Now we add the task main() and we are ready to code the behavior.

To tell the Arduino what Duty-Cycle to output to led1 for example,

motor[led1] = level;

is used with level being the Duty-Cycle from 0 to 127, with 0 mapping to 0% and 127 mapping to 100%. To make the dim in and out, we will have the code slowly step the values up and down over time. For demonstration purposes we will increase or decrease the Duty-Cycle by 10% (level value: 12.7) every 500ms. Doing the math, we get the following values.

Time (ms) led1 value led2 value
0 127 0
500 114 13
1000 102 25
1500 89 38
2000 76 51
2500 64 64
3000 51 76
3500 38 89
4000 25 102
4500 13 114
5000 0 127
5500 13 114
6000 25 102
6500 38 89
7000 51 76
7500 64 64
8000 76 51
8500 89 38
9000 102 25
9500 114 13

Combining the times and values, with the commands to set the outputs and the pauses and you get

#pragma config(CircuitBoardType, typeCktBoardUNO)
#pragma config(PluginCircuitBoard, typeShieldParallaxBoeBot)
#pragma config(UART_Usage, UART0, uartSystemCommPort, baudRate200000, IOPins, dgtl1, dgtl0)
#pragma config(Motor,  motor_5,         led1,          tmotorVariableIntensityLED, openLoop, reversed, IOPins, dgtl5, None)
#pragma config(Motor,  motor_6,         led2,          tmotorVariableIntensityLED, openLoop, reversed, IOPins, dgtl6, None)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//
 
task main()
{
  while(true) //repeat indefinitely
  {
    motor[led1] = 127;
    motor[led2] = 0;
    wait1Msec(500);
 
    motor[led1] = 114;
    motor[led2] = 13;
    wait1Msec(500);
 
    motor[led1] = 102;
    motor[led2] = 25;
    wait1Msec(500);
 
    motor[led1] = 89;
    motor[led2] = 38;
    wait1Msec(500);
 
    motor[led1] = 76;
    motor[led2] = 51;
    wait1Msec(500);
 
    motor[led1] = 64;
    motor[led2] = 64;
    wait1Msec(500);
 
    motor[led1] = 51;
    motor[led2] = 76;
    wait1Msec(500);
 
    motor[led1] = 38;
    motor[led2] = 89;
    wait1Msec(500);
 
    motor[led1] = 25;
    motor[led2] = 102;
 
    motor[led1] = 13;
    motor[led2] = 114;
    wait1Msec(500);
 
    motor[led1] = 0;
    motor[led2] = 127;
    wait1Msec(500);
 
    motor[led1] = 13;
    motor[led2] = 114;
    wait1Msec(500);
 
    motor[led1] = 25;
    motor[led2] = 102;
    wait1Msec(500);
 
    motor[led1] = 38;
    motor[led2] = 89;
    wait1Msec(500);
 
    motor[led1] = 51;
    motor[led2] = 76;
    wait1Msec(500);
 
    motor[led1] = 64;
    motor[led2] = 64;
    wait1Msec(500);
 
    motor[led1] = 76;
    motor[led2] = 51;
    wait1Msec(500);
 
    motor[led1] = 89;
    motor[led2] = 38;
    wait1Msec(500);
 
    motor[led1] = 102;
    motor[led2] = 25;
    wait1Msec(500);
 
    motor[led1] = 114;
    motor[led2] = 13;
    wait1Msec(500);
  }
}