⇐ Back to Mantis X8 Airframe

Gemma/Neopixel Navigation Lights

Bright green and red lights are highly recommended to assist with line-of-sight flying. For my aircraft, I decided to add a RGB LED on the end of each spoke so I can place the red and green navigation lights on the fore and aft and show system status on the mid spokes. The PX4 platform presently supports status indicators to a BlinkM LED. I decided to use Neopixels for my LEDs for more flexibility and the smaller form-factors available. Unfortunately, neopixels do not understand the BlinkM commands natively so we implement a simple sketch on a Gemma Neopixel controller to emulate a BlinkM.

The Gemma is wired as shown below:

The 5V LED supply from the ESC is not connected to the Gemma. The Gemma is powered from the BEC on the PX4 through the I2C port. This is to avoid contention between the two BECs and to prevent accidentally powering the eight LEDs from the PX4 supply which isn't designed to provide for such a load.

All eight Neopixels wired:

Testing before installation (video):

Fishing each through each spoke (note the bare wire “fish” in the center ready to attach to and pull the sixth of eight connectors through the spoke):

Installed:

Final installation demonstration with diffusers (video):

Here's a look at the connectors at the fourth LED where the additional power connector is brought out to connect to that motor's 5V BEC supply:

Each neopixel will be mounted in a custom LED diffuser I designed and printed on Shapeways to fit on the end of each spoke.

Here is the script I used to emulate a BlinkM. You will need to download and install the TinyWire and the Adafruit_Neopixel libraries.

/*
NeoPixel driver to receive BlinkM commands on I2C and drive eight neopixels
Only supporting a limited set of BlinkM commands (those used by the PX4
flight management unit)
 
IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
and minimize distance between Arduino and first pixel.  Avoid connecting
on a live circuit...if you must, connect GND first.
*/
 
#include "TinyWireS.h"                 // wrapper class for I2C slave routines
 
#define I2C_SLAVE_ADDR  0x09            // Default BilnkM i2c slave address
 
#include <Adafruit_NeoPixel.h>
#include <avr/power.h>
 
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(32, 1, NEO_GRB + NEO_KHZ800);
 
// Gamma correction improves appearance of midrange colors
const uint8_t PROGMEM gamma8[] = {
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
      0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,
      1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,  2,  3,  3,  3,  3,
      3,  3,  4,  4,  4,  4,  5,  5,  5,  5,  5,  6,  6,  6,  6,  7,
      7,  7,  8,  8,  8,  9,  9,  9, 10, 10, 10, 11, 11, 11, 12, 12,
     13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20,
     20, 21, 21, 22, 22, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29,
     30, 31, 31, 32, 33, 34, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42,
     42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
     58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70, 71, 72, 73, 75,
     76, 77, 78, 80, 81, 82, 84, 85, 86, 88, 89, 90, 92, 93, 94, 96,
     97, 99,100,102,103,105,106,108,109,111,112,114,115,117,119,120,
    122,124,125,127,129,130,132,134,136,137,139,141,143,145,146,148,
    150,152,154,156,158,160,162,164,166,168,170,172,174,176,178,180,
    182,184,186,188,191,193,195,197,199,202,204,206,209,211,213,215,
    218,220,223,225,227,230,232,235,237,240,242,245,247,250,252,255
};
 
 
void setup() {
  pixels.begin();
  TinyWireS.begin(I2C_SLAVE_ADDR);    // init I2C Slave mode
  pixels.setPixelColor(0, 100, 0, 0); // Red bow light
  pixels.setPixelColor(1, 0, 0, 10);
  pixels.setPixelColor(2, 0, 0, 10);
  pixels.setPixelColor(3, 0, 100, 0);  // Green aft light
  pixels.setPixelColor(4, 0, 100, 0);  // Green aft light
  pixels.setPixelColor(5, 0, 0, 10);
  pixels.setPixelColor(6, 0, 0, 10);
  pixels.setPixelColor(7, 100, 0, 0); // Red bow light
  pixels.show();
}
 
void loop() {
    byte byteRcvd = 0;
    byte r,g,b;
    byte rot = 1;
 
  if (TinyWireS.available()){           // got I2C input!
    byteRcvd = TinyWireS.receive();     // get the byte from master
    if(byteRcvd == 'n' || byteRcvd == 'c'){
      while (!TinyWireS.available()) { /* nop */ }  // wait for next byte
      r = pgm_read_byte(&gamma8[TinyWireS.receive()]);
      while (!TinyWireS.available()) { /* nop */ }  // wait for next byte
      g = pgm_read_byte(&gamma8[TinyWireS.receive()]);
      while (!TinyWireS.available()) { /* nop */ }  // wait for next byte
      b = pgm_read_byte(&gamma8[TinyWireS.receive()]);
      pixels.setPixelColor(((rot+0)&7), 100, 0, 0); // Red bow light
      pixels.setPixelColor(((rot+1)&7), r, g, b);
      pixels.setPixelColor(((rot+2)&7), r, g, b);
      pixels.setPixelColor(((rot+3)&7), 0, 100, 0); // Green aft light
      pixels.setPixelColor(((rot+4)&7), 0, 100, 0); // Green aft light
      pixels.setPixelColor(((rot+5)&7), r, g, b);
      pixels.setPixelColor(((rot+6)&7), r, g, b);
      pixels.setPixelColor(((rot+7)&7), 100, 0, 0); // Red bow light
      pixels.show();
    }
  }
  delay(10);
}

After uploading this to the Gemma using the Arduino software, the mid lights should reflect the system state as defined by the BlinkM code onthe PX4 platform and the fore and aft lights should be steady on Red & Green.

⇐ Back to Mantis X8 Airframe

Translations of this page:


Quick Links

QR Code: URL of current page