Loading...
 

Teensy Telemetry LED Configurator

The LED Configurator is used to customize the LED programming and create almost any pattern that you can visualize.  These patterns can be controlled by MAVLINK data.  For example, you could have a navigation pattern displayed, but if the battery voltage or consumed mah hits a certain point have the navigation pattern flash, or even display an entirely different pattern.  You can make the back two arms form a bar that displays the battery voltage.  You can even layer patterns.

The configuration is defined in a single text file. This file is compiled and uploaded to the Teensy using the configurator utility. The configuration utility only runs on Windows at this time, but you can still compile and upload configurations to the Teensy on other operating systems.

Using the Configurator Application

This is a Windows application that is used to compile and upload LED configurations.  It's also a diagnostic console for the firmware running on the Teensy.

 
Image  

Steps to upload an LED configuration

  1. Connect the Teensy to the USB port
  2. Start the Configurator application
  3. Select the Com port for the Teensy
  4. Click the Connect button.  You should see the Teensy diagnostic console help screen in the Configurator window.  You are now ready to upload an LED configuration
  5. Click LEDs->Compile and Upload from the menu
  6. Navigate to the pattern file that you want to upload and click OK
  7. The diagnostic console will display a message if the upload was successful

 

Creating a Configuration File

The LED configuration file is used to describe the patterns and how they are triggered.  Here's an example of a simple configuration file that will set strip 1 red.

initialize begin
  append group 1 as strip 1 led 1 to 8
end

loop begin
  color group 1 [ 255 0 0 ]
end
 

The first line "initialize begin" is used to start off the initialzation section.  Groups are setup in the initialization section

The second line "append group" is used to add some LEDs to a group.  We're configuring group 1 to be the first 8 LEDs on strip 1.  

The "end" is used to complete the initialize section

The next section starts with the "loop begin".  The loop defines configuration that is checked over and over, at 100 times per second.  You configuration can use this to check for mav data that is changing and set lights based on these changes.  In the example above, the loop is just using color action to set the LEDs in group 1 red ( the [ 255 0 0 ] is our way of specifing red).  There's really no reason why we need to set the LEDs red 100 times per second, but later, when we use mav data to set LED colors, the concept of a loop will make more sense.

Specifying Colors 

RGB LED strips contain three colored LEDs in each cell.  A red, a green and a blue.  By setting the brightness on each one of these individual colors, we can make the LED cell appear to be virtually any color a jhuman can see.  If you look closely at an LCD computer monitor, you'll see that each cell is actually made up of a red, green and a blue cell.  The three levels used in the configuration file inside the square brackets, simply specify the level for red, green and blue.  The values must be between 0 and 255.  So,  [ 255 0 0 ] is red, [ 0 255 0 ] is green, [ 0 0 255 ] is blue.

Then, we can mix colors so [ 255 255 0 ] appears yellow, [ 0 255 255 ] appears cyan, [ 255 0 255] appears magenta and [ 255 255 255 ] appears white.

In the examples above, the colors were all set full on (255) or off (0).  You can specify various levels of each LED and create any color.  There are many color pickers on the web, here's one to give you an idea http://www.w3schools.com/colors/colors_rgb.asp

There is another syntax you can use to specify the colors here.  It's the hexidecimal web syntax, where red is #FF0000, green is #00FF00 and blue is #0000FF.  

Anyone interested in knowing why red, green and blue are used may find this interesting.  The human eye contains cones which detect colors.  We have three types of cones; red, green and blue.  So, when we tell an LED cell to be equal levels of red and green with no blue, we are really stimulating the cones in our eyes exactly the same way a pure yellow light does.  Our eyes can't tell the difference from this simulated yellow color and a pure yellow color (which is actually a single frequency about 1/2 way between red and green on the color spectrum).

 

Layers

In the previous example, we setup a single group and make it solid red.  In the following example, we are going to make a flashing red pattern

initialize begin
  append group 1 as strip 1 led 1 to 8
end

loop begin
  color group 1 [ 0 0 0 ]
  flash group 1 [ 255 0 0 ] 100 900 0
end
 
The initialization section is the same as the previous example, setting group 1 to the first LEDs on strip 1.

We've change the color command to set group 1 to [ 0 0 0 ]. This action is configuring group 1 to be all off.

Next, we've introduced the flash command which is telling group 1 to flash red ([ 100 0 0 ]) for 100 milliseconds, then go dormant for 900 milliseconds.  Time parameters are always specified in milliseconds, so 1000 is actually 1 second.  By flashing on for 100 milliseconds and dormant for 900 milliseconds, we've create a light that will basically blink on every second.  

The last paramter is 0, which is an offset parameter.  We'll talk more about that later.

The important thing here is to understand how the two actions work together.  The first color command is turning the group off, then the flash is applied over top as a second layer which will turn the LED on for 100 milliseconds.  

When applying layers to groups, the last always wins, so 

initialize begin
  append group 1 as strip 1 led 1 to 8
end

loop begin
  color group 1 [ 0 0 0 ]
  color group 1 [ 255 0 0 ]
end 

really just sets the color of the group to red.  

The first color command doesn't need to be off.  You could set it to green so that the group flashes between green and red

initialize begin
  append group 1 as strip 1 led 1 to 8
end

loop begin
  color group 1 [ 0 255 0 ]
  flash group 1 [ 255 0 0 ] 100 900 0
end

 

The concept of layering becomes more interesting when we do something more complicated.  Say we want to flash the lights for three short pulses every second.  We can set a background color, then use three flash commands offset from  one another using the offset parameter.

 

initialize begin
  append group 1 as strip 1 led 1 to 8
end

loop begin
  color group 1 [ 0 0 0 ]
  flash group 1 [ 255 0 0 ] 20 980 0
  flash group 1 [ 0 255 0 ] 20 980 50
  flash group 1 [ 0 0 255 ] 20 980 100
end

The lights flash so fast in this example that it's difficult to tell that a red, green, then blue are flashing but it is an interesting effect.  You can easily try it yourself by pasting the above configuration into a text file and using Compile and Upload in the configurator.  

 

Conditionals (if statements)

We probably don't always want the LEDs to be displaying the same pattern.  We can use if statements to specify LED actions which should only occur under specific conditions. Building on the previous configuration, we can make a pattern that only flashes if a switch (rc value) is set

initialize begin
  append group 1 as strip 1 led 1 to 8
end

loop begin
  color group 1 [ 0 0 0 ]
  if ( 1500 > rc.ch8 ) then
    flash group 1 [ 255 0 0 ] 100 900 0
  end
end

We've added the if statement around the flash action from the previous example.  This if statement is telling the LEDs to only do the flash action if rc.ch8 (the is greater than 1500).  There are several things you can use in the if statement, but since we want to control the flashing from a switch, we've decided to use rc.ch8 (the receivers channel 8) value.  These values are the same as what is displayed in mission planner logs or on the transmitter calibration page of Mission Planner.  The rc channel values typically range from 1000 to 2000 depending on your transmitter and receiver.  I've picked the value in the middle of the range (1500).  Anything higher than this will cause the flash action.

Here are some of the values that you can use in conditional statements

Value NameDescription
rc.ch7RC Channel 7 
rc.ch8RC Channel 8 
rc.rssiMavlink rssi value - make sure you can see your rssi in mission planner (new to version 2.1.17.6.3)
bat.currentInstantaneous Current (100 = 1 Amp)
bat.voltageInstantaneous Battery Voltage (100 = 1 Volt)
bat.remainingPercent Batter Remaining
bat.consumedTotal mAh Consumed
gps.hdopHDOP (100 = 1 Meter)
gps.satsNumber of Satellites
fc.baraltBarometric Altitude in Meters
fc.cogCourse Over Ground in degrees
fc.distanceDistance from where the craft was armed in meters (new to version 2.1.17.6.3)
fc.headingHeading in Degrees
fc.speedSpeed in Meter per Second
fc.armedArmed = 1, Disarmed = 0
fc.flightmodeFlight mode number
 0 Stabilize
 1 Acro
 2 Altitude Hold
 3 Auto
 4 Guided
 5 Loiter
 6 Return to launch
 7 Circle
 9 Land
 10 Optical Loiter
 11 Drift
 13 Sport
 14 Flip Mode
 15 Auto Tune
 16 Position Hold
imu.brakeDeceleration value (use > 10 or more to detect braking)
time.bootTotal time in seconds since the Teensy has been powered on
time.armTotal time in seconds since the craft has been armed
time.throttleTotal time in seconds that the Teensy has sensed a throttle > 25%

 

Actions

We've described using some of the actions above.  Here's a complete list of actions and what they do.

 

ActionDescription 
color GROUP_NUMBER COLOR_VALUESets a group to a specific color
flash GROUP_NUMBER ON_COLOR_VALUE ON_TIME OFF TIME OFFSET_TIMEWhen the flash isn't on, the action is dormant so any underlying layers are visible.  This means that you have to set a background for when the flash is dormant even if just to off (#000000)
 ON_TIME - the time the flash stays on
 OFF_TIME -the time the flash stays off
 OFFSET_TIME - how long the flash waits to go on.  This is useful when you want flashes to occur time shifted from one another.
wave GROUP_NUMBER ON_COLOR_VALUE STATE_TIME ON_WIDTH REVERSEMakes a wave of lights
 STATE_TIME - how long it stays in each state
 ON_WIDTH - how many LEDs are on in any state
 REVERSE - set to 1 if the wave should start at the highest LED in the group and move towards the lowest
random  GROUP_NUMBER CHANGE_TIME INTENSITYChange time specifies how often the random value changes
 INTENSITY - value from 0 to 255 specifying how bright each random color is
bar GROUP_NUMBER ON_COLOR VALUE LOW_VALUE HIGH_VALUE REVERSEThis makes a bar graph.  It's useful to display battery remaining, etc.
 VALUE - the variable value used to determine the size of the bar
 LOW_VALUE - the value that should represent the lowest bar
 HIGH_VALUE = the value that should represent the highest bar
 REVERSE - set to 1 if the bar should start at the highest LED in the group
bounce GROUP_NUMBER ON_COLOR STATE_TIME WIDTHLike wave, but bounces back and forth

 

Definitions

Constants such as colors, groups and times can be defined using a UPPERCASE text identifier to make the configuration easier to read.  For example, the following

define RED [255 0 0 ] 

will define a constant RED so that anytime the text RED is used in the config file, the value [255 0 0 ] is substituted.  

Instead of

    color group 1 [255 0 0]

you can specify

    color group 1 RED

You can even use defines for groups, so instead of using group 1 to reference the front LEDs you could do the following

    define RED [255 0 0 ] 
    define FRONT 1

    append group FRONT as strip 1 led 1 to 8
    append group FRONT as strip 2 led 1 to 8

Then, later when applying actions to the groups, you can use the following which is much more readable

    color group FRONT RED

      • Please remember that the define must be in upper case characters.


Please see the default configuration Default Configuration Script file for more examples of definitions

Example Configuration Snippets

 

Brake Lights

The following sample sets up two groups, one for the front, and one for the rear.  After that, white is applied to the front, and a low brighness red to the rear.  The if statement checks if there is deceleration and sets the back to full bright. 


initialize begin
  append group 1 as strip 1 led 1 to 8       // Front
  append group 1 as strip 2 led 1 to 8
  append group 2 as strip 7 led 1 to 8       // Rear
  append group 2 as strip 8 led 1 to 8
end

loop begin
  color group 1 [ 85 85 85 ]                            // Front mid brightness white
  color group 2 [ 85 0 0 ]                                // Back mid brightness red

  if ( imu.brake > 20 ) then                            // Braking
    color group 2 [ 255 0 0 ]                            // Back bright red
  end
end

 

HDOP and Battery Warning

The following sample sets up two groups, one for the front, and one for the rear.  After that, white is applied to the front, and a low brighness red to the rear.  The if statement checks various ba


initialize begin
  append group 1 as strip 1 led 1 to 8       // Front
  append group 1 as strip 2 led 1 to 8
  append group 2 as strip 7 led 1 to 8       // Rear
  append group 2 as strip 8 led 1 to 8
end

loop begin
  color group 1 [ 85 85 85 ]                            // Front mid brightness white
  color group 2 [ 85 0 0 ]                                // Back mid brightness red

  if ( gps.hdop > 500 ) then                            // HDOP > 5
    color group 2 [ 0 0 0]
    flash group 2 [ 0 255 0 ] 500 500 0
  end

  if ( bat.voltage < 1100 ) then                        // Battery < 11.0 Volts flash yellow
    color group 2 [ 0 0 0 ]
    flash group 2 [ 255 255 0 ] 500 500 0
  end

  if ( bat.voltage < 1070 ) then                         // Battery < 10.7 Volts flash red
    color group 2 [ 0 0 0 ]
    flash group 2 [ 255 0 0 ] 100 100 0
  end
end
 

Default Configuration Script

/////////////////////////////////////////////////////////////
//
// default_led_pattern.txt
//
// This is the test pattern used to generate the factory default firmware pattern
//
//
/////////////////////////////////////////////////////////////
// compiler_version:v2 PLEASE DO NOT REMOVE OR ALTER THIS LINE
/////////////////////////////////////////////////////////////

define MAX_LEDS_PER_STRIP 8

// Define group numbers

define ALL_LEDS         1
define STRIP_NUMBER_ID  2

define FRONT            3
define BACK             4
define MIDDLE_FOUR      5
define CORNERS          6

define LEFT             7
define RIGHT            8

define FRONT_LEFT       9
define FRONT_RIGHT     10
define BACK_LEFT       11
define BACK_RIGHT      12

// Define flight modes

define MODE_STABILIZE   0
define MODE_ACRO        1
define MODE_ALT_HOLD    2
define MODE_AUTO        3
define MODE_RTL         6
define MODE_LAND        9
define MODE_TUNE       15
define MODE_POSHOLD    16

// Define standard colors

define RED            [255 0 0]
define GREEN          [0 255 0]
define BLUE           [0 0 255]
define YELLOW         [255 255 0]
define CYAN           [0 255 255]
define MAJENTA        [255 0 255]

define OFF            [0 0 0]             
       
define WHITE_20       [50 50 50]                  // ~20% White    
define WHITE_80       [200 200 200]                // ~80% White    
define RED_20         [50 0 0]                  // ~20% Red

initialize begin

    // group ALL_LEDS is used for all leds - usually this group is used for background
    append group ALL_LEDS as strip 1 led 1 to MAX_LEDS_PER_STRIP
    append group ALL_LEDS as strip 2 led 1 to MAX_LEDS_PER_STRIP
    append group ALL_LEDS as strip 3 led 1 to MAX_LEDS_PER_STRIP
    append group ALL_LEDS as strip 4 led 1 to MAX_LEDS_PER_STRIP
    append group ALL_LEDS as strip 5 led 1 to MAX_LEDS_PER_STRIP
    append group ALL_LEDS as strip 6 led 1 to MAX_LEDS_PER_STRIP
    append group ALL_LEDS as strip 7 led 1 to MAX_LEDS_PER_STRIP
    append group ALL_LEDS as strip 8 led 1 to MAX_LEDS_PER_STRIP

    // group for strip number identification
    append group STRIP_NUMBER_ID as strip 1 led 1 to 1
    append group STRIP_NUMBER_ID as strip 2 led 1 to 2
    append group STRIP_NUMBER_ID as strip 3 led 1 to 3
    append group STRIP_NUMBER_ID as strip 4 led 1 to 4
    append group STRIP_NUMBER_ID as strip 5 led 1 to 5
    append group STRIP_NUMBER_ID as strip 6 led 1 to 6
    append group STRIP_NUMBER_ID as strip 7 led 1 to 7
    append group STRIP_NUMBER_ID as strip 8 led 1 to 8

    // groups for front, back, middle and corners
    append group FRONT as strip 1 led 1 to MAX_LEDS_PER_STRIP
    append group FRONT as strip 2 led 1 to MAX_LEDS_PER_STRIP
    append group BACK as strip 7 led 1 to MAX_LEDS_PER_STRIP
    append group BACK as strip 8 led 1 to MAX_LEDS_PER_STRIP
    append group MIDDLE_FOUR as strip 3 led 1 to MAX_LEDS_PER_STRIP
    append group MIDDLE_FOUR as strip 4 led 1 to MAX_LEDS_PER_STRIP
    append group MIDDLE_FOUR as strip 5 led 1 to MAX_LEDS_PER_STRIP
    append group MIDDLE_FOUR as strip 6 led 1 to MAX_LEDS_PER_STRIP  
    append group CORNERS as strip 1 led 1 to MAX_LEDS_PER_STRIP
    append group CORNERS as strip 2 led 1 to MAX_LEDS_PER_STRIP
    append group CORNERS as strip 7 led 1 to MAX_LEDS_PER_STRIP
    append group CORNERS as strip 8 led 1 to MAX_LEDS_PER_STRIP
 
 
  // groups for left and right
    append group LEFT as strip 1 led 1 to MAX_LEDS_PER_STRIP        
    append group LEFT as strip 3 led 1 to MAX_LEDS_PER_STRIP        
    append group LEFT as strip 5 led 1 to MAX_LEDS_PER_STRIP         
    append group LEFT as strip 7 led 1 to MAX_LEDS_PER_STRIP         
    append group RIGHT as strip 2 led 1 to MAX_LEDS_PER_STRIP        
    append group RIGHT as strip 4 led 1 to MAX_LEDS_PER_STRIP        
    append group RIGHT as strip 6 led 1 to MAX_LEDS_PER_STRIP        
    append group RIGHT as strip 8 led 1 to MAX_LEDS_PER_STRIP        
       
  // groups for corner arms
    append group FRONT_LEFT as strip 1 led 1 to MAX_LEDS_PER_STRIP
    append group FRONT_RIGHT as strip 2 led 1 to MAX_LEDS_PER_STRIP
    append group BACK_LEFT as strip 7 led 1 to MAX_LEDS_PER_STRIP
    append group BACK_RIGHT as strip 8 led 1 to MAX_LEDS_PER_STRIP

end

loop begin
  //
  // One of the following if conditions will match depending on the value of channel 8.  When channel 8 is max, an auto mode is enabled and that uses flight modes to set LEDs
  //
  if ( rc.ch8 <= 1100 ) then 
    //
    // LED test - identify strip numbers (see documentation for which strip should be on which arm)
    //
    color group ALL_LEDS WHITE_20                                     
    color group STRIP_NUMBER_ID RED_20                             
  elsif ( rc.ch8 <= 1200  ) then 
    color group ALL_LEDS OFF                                     
    flash group ALL_LEDS YELLOW 30 970   0                             
    flash group ALL_LEDS YELLOW 20 980 200                         
  elsif ( rc.ch8 <= 1300  ) then 
    random group 1 200 10                     
    bar group FRONT_LEFT RED    25 0 100 1   
    bar group FRONT_RIGHT GREEN 25 0 100 1     
    bar group BACK_LEFT RED     25 0 100 1     
    bar group BACK_RIGHT GREEN  25 0 100 1           
  elsif ( rc.ch8 <= 1400 ) then       // scotts nav pattern
    color group 1 #000000                         
    fill group FRONT_LEFT RED    150 1000 1
    fill group FRONT_RIGHT GREEN 150 1000 1
    fill group BACK_LEFT RED     150 1000 0
    fill group BACK_RIGHT GREEN  150 1000 0
  elsif ( rc.ch8 <= 1500 ) then
    random group 1 200 10                     
    wave group FRONT_LEFT RED    50 2    1
    wave group FRONT_RIGHT GREEN 50 2 1
    wave group BACK_LEFT RED     50 2 0
    wave group BACK_RIGHT GREEN  50 2 0              
  elsif ( rc.ch8 <= 1600 ) then 
    color group ALL_LEDS #050505        
    bounce group FRONT_LEFT RED    100 1                 
    bounce group FRONT_RIGHT GREEN 100 1               
    bounce group BACK_LEFT RED     100 1              
    bounce group BACK_RIGHT GREEN  100 1                           
  elsif ( rc.ch8 <= 1700 ) then
    //
    // Double flash left (red) to right (green)
    //
    color group  ALL_LEDS OFF                         
    flash group LEFT RED    20 950   0     
    flash group LEFT RED    20 950 100       
    flash group RIGHT GREEN 20 950 200        
    flash group RIGHT GREEN 20 950 300                               
  elsif ( rc.ch8 <= 1800 ) then     
    color group ALL_LEDS WHITE_80                    
    bar group FRONT_LEFT RED    25 0 100  1   
    bar group FRONT_RIGHT GREEN 25 0 100  1     
    bar group BACK_LEFT RED     25 0 100  1     
    bar group BACK_RIGHT GREEN  25 0 100  1  
  elsif ( rc.ch8 <= 1900 ) then 
    //
    // Stealth mode
    //
    color group 1 OFF                    
  else
    //
    // Auto mode
    // When ch8 is maxed, the LED mode is specified by flight mode (and braking)
    //
    color group ALL_LEDS OFF                         
    if ( fc.flightmode == MODE_STABILIZE ) then 
      color group ALL_LEDS CYAN                         
    elsif ( fc.flightmode == MODE_ALT_HOLD ) then
      color group CORNERS RED                                                
    elsif ( fc.flightmode == MODE_POSHOLD ) then
      color group CORNERS GREEN                         
    elsif ( fc.flightmode == MODE_RTL ) then
      color group CORNERS BLUE                         
    elsif ( fc.flightmode == MODE_AUTO ) then
      color group CORNERS MAJENTA
    elsif ( fc.flightmode == MODE_LAND ) then
      color group CORNERS YELLOW                         
    else
      color group MIDDLE_FOUR WHITE_20                            
    end
    if ( imu.brake > 20 ) then                       // Braking
      color group BACK RED                           // Back bright red                               
    end  
  end
  
end