Intermediate Series Lesson 5: Digital Write and Controller LEDs
In this lesson we will learn how to control the LEDs on our controller using the Arduino function digitalWrite()



The CoDrone controller has 8 built-in blue LEDs that can be programmed.  These LEDs each share pins with the bottom digital IR sensors, which makes using them a bit confusing. Here we will learn about switching between pin modes and how to use the on-board LEDs in your programs.


Sharing Pins

The most confusing part of using the controller’s LEDs is the pin sharing.  If you look at the SmartInventor Board’s pin-out diagram, you’ll notice that the LED pins are 11-18.


These are the same pins as your digital IR sensors.  This is because both the digital IR sensors and LEDs are connected to the same digital pins.   To switch between using IR Sensors and LEDs, we use different pin modes:

Digital IR Sensors – INPUT

pinMode( 11, INPUT)


pinMode( 11, OUTPUT)

A pin can only be either INPUT or OUTPUT, so you will have to choose which pins you want to be IR Sensors or LEDs.

By default, the CoDrone library sets the following pinModes



You might have noticed that there are 8 LEDs, but only 7 IR sensors.  Both of the middle IR sensor pins 14 and 15 are connected to the same sensor, so digitalRead(14)  and digitalRead(15)  will always give the same answer.

On the LED side, pins 14 and 15 are connected to two separate LEDs so  digitalWrite(14, HIGH)  and digitalWrite(15, HIGH)  will control different LEDs.



To turn on our LEDs, we use the function digitalWrite() .


digitalWrite(pin number, output);

pin number – The pin number of the LED/IR Sensor

output – This can be either HIGH  or LOW (1 or 0)


To turn an LED on and off, we use the terms HIGH  and LOW .  This refers to the voltage of the pin.

HIGH  will set the pin to high voltage, turning the LED on.  You can also use 1.

LOW  will set the pin to low voltage, turning it off.  You can also use 0.

An LED will stay it’s current state unless told otherwise.


Example 1: Turning an LED On and Off

This will initialize pin 11, turn it on, then turn it off.

Arduino also recognizes HIGH  as 1 and LOW  as 0, just like how true  is 1 and false  is 0


Example 2: Using LED 11 with CoDrone

This will change pin 11 from inputting data from the IR sensor to output the LED light.  Remember, you cannot use pin 11 as an IR sensor after switching it to OUTPUT.


Example 3: Using LEDs to Indicate Modes

This code uses the LEDs 13 and 16, which are set to OUTPUT  by default.

The integer Mode  is incremented by sensor 18 bt8 .  Each mode is represented by a different combination of LEDs.

Mode 1 (Mode = 0)

Mode 2 (Mode = 1)

Mode 3 (Mode = 2)

Mode 4 (Mode = 3)

This will help you keep track of your different controller modes.

Notice we put the LED commands within the if (bt8) {  if-statement.  This will only send the LED commands once when the sensor is triggered.


Switching Pin Modes

For some programs, you might want to use a pin as both an LED and an IR sensor.  This can be done by rapidly switching between INPUT and OUTPUT.

It’s best to switch to INPUT  right before your sensor read and switch back to OUTPUT  right after.


Example 4: Using Pin 18 as Input and Output

Unlike example 3, in this example we put our LED commands outside of the if (bt8) {  if-statement.  When switching between input and output, our LEDs will turn off.  In this case, it is necessary for us to repeatedly send the HIGH  or LOW  commands.


Changing Intensities with Pulse Width Modulation

The intensity or brightness of an LED can be altered by quickly turning the LED on and off.  Since the SmartInventor Board can switch the LED on and off faster than our eyes can notice, all we see is a decrease in brightness.

For example, if I wanted my LED to be full brightness, I would leave it on the whole time.


If I wanted half the brightness, I would want my LED to be off for about half of the amount of time.  To do this, we use what is called Pulse Width Modulation (PWM).


Pulse Width Modulation

A pulse is just a quick switch from OFF to ON then back to OFF.  Imagine a single wave


Applying this to an LED, this would flick the LED on and off once.  This would happen much faster than our eyes can notice, so we probably wouldn’t see anything.

Here’s an example of what half intensity might look like in pulses


You can see that about half the time the LED is on and the other half the LED is off.


To Reduce the intensity of the LED, we create more “OFF” time in between pulses.  If our “OFF” times are too long, though, then our eyes have enough time to notice that the LED is off.  This leads to the LED appearing to blink rapidly, rather than just appear dim.


To reduce the appearance of blinking, we have to make sure we don’t have too much “OFF” time.  Too little “OFF” time will result in the LED appearing at full intensity. We need to find that perfect balance.


Luckily, we have some established guidelines to help us along.  First, we need to understand some signal terminology.


Period – The time between the start of one pulse and the start of another.

Pulse Width – The width of the pulse, from On to Off.

Duty Cycle – The relative length of the Pulse Width to the Period in percentage.  For example, if the Pulse with is 10ms and the Period is 20ms, then the duty cycle is 50%.


Example 5: Half Intensity

For common LEDs, the period should be around 20ms.  This means that for half brightness (50% duty cycle), we should have a pulse width of 10ms.


Translating this into code would look something like this

We use micros()  instead of millis()  for more accuracy.  The LED on pin 13 will be half intensity. Compare it to the LED on pin 16, which is full intensity.

For the first 10000 microseconds (10 milliseconds), the LED will be HIGH (ON).  The next 10000 microseconds will be LOW (OFF).

Half intensity might not be as noticeable as you think you would want.


Example 6: Very Low Intensity


This example sends very small pulses of 100 microseconds ( .1 millisecond).  This will result in a very low brightness.


Example 7: Brightness and Joystick Correlation

If we set our pulse width to variable

We can do some cool things with it.

Here, we will use our left joystick to control the size of our PulseWidth  variable.

The code line  CoDrone.AnalogScaleChange(analogRead(A4))  is used in our controller code.  We know that this reads our joystick’s analog inputs and gives a re-scaled number from -100 to 100.

In our pulse width equation

we add 100 to LeftJoystick  to ensure we don’t get a negative number.  Our range is now 0 to 200.

We then multiply it by 50, so that our new range is 0 to 10,000.  This means that with the joystick all the way up, our intensity will be 50%, and all the way down will be 0%.



Activity:  Shiny Objects



Create an interactive menu using your controller’s LEDs and IR sensors.

  1. Each menu option should illuminate it’s own LED
  2. Each menu option should have it’s own unique function (Change the CoDrone’s LED color, perform a specific maneuver, different controller flight controls.. ect)
  3. The left IR sensor should change your menu option by -1, or move your menu to the left
  4. The right IR sensor should change your menu option by +1, or move your menu to the right

Be creative and try to use buzzers too!


Mode 1


Mode 2


Mode 3

Include a kill switch and make sure that you can Stop your CoDrone at any time.