Programmable NAZA LED Neopixels for Y6 - RC Groups
Shop our Airplanes Products Drone Products Sales
Thread Tools
This thread is privately moderated by ElGuano, who may elect to delete unwanted replies.
Apr 11, 2014, 04:42 PM
Registered User
Mini-HowTo

Programmable NAZA LED Neopixels for Y6


This mod details the parts/setup/programming for an Arduino-based orientation LED system that incorporates the NAZA's (and presumably, WKM/A2) LED signals. My lights are set to display a static orientation front/back, but change to mimic the Naza's red/green/yellow flashes in real time as well. You can also add animations, responses to other RC input (change color when throttling, etc.) and whatever else you can think of.

Details:
  • 3 rings of 16 LEDs each (48 total)
  • Fully programmable color and brightness for each LED, including complex animations
  • Total weight installed: 35g
  • Does NOT interfere with USB/NAZA-M Assistant function

Here's what it looks like on the Y6:


And a test and flight video here:
F450 Neopixel + Arduino install completed (1 min 7 sec)


First off, huge props to Yves Gohy's original mod posted here. I used similar parts, and adapted his Neopixels code.

PARTS

Here's the parts list:
  1. Adafruit Trinket 5V (Arduino-lite controller): http://www.adafruit.com/products/1501
  2. Adafruit Neopixel 16-LED ring (one for each arm). The 16-LED version fits perfectly around the E300 2212/920kv motor housing, but you can get light strips, light bars, individual LED+driver modules, etc. http://www.adafruit.com/products/1463.
  3. 5V output UBEC (just use whichever one you want)
  4. 300 ohm resistor for Neopixel data line: http://www.mouser.com/ProductDetail/...i5Pn2foA%3d%3d
  5. 1000uF 10V electrolytic capacitor (x3, one for each power branch): http://www.mouser.com/ProductDetail/...%2fTZdLTc4RXtG
  6. Misc electronics parts - several meters of 30awg wire, servo/futaba 0.1" terminals and connecters, crimping tool, hot glue, nylon spacers for mounting, solder, flux, heat shrink, etc.
  7. PC with USB port and cable, Arduino IDE (I used the prebaked Adafruit Trinket distro), Adafruit Neopixel library

Adafruit has a GREAT section on their website with details on how to setup and use the Trinket and Neopixels. I highly recommend perusing this to get the hang of how these work: Trinket Tutorial and Neopixel Uber-Guide.

PHYSICAL SETUP

A picture is worth a thousand words, so let's start with that:


A few things to note:
  1. The Trinket doesn't have as many pins as a standard Arduino controller. You need a digital output pin (#1 is tied to the Trinket's on-board LED so that's a good one to use), and you need two analog-readable pins. Digital pins #2, 3 and 4 work, but pins 3-4 are also USB data pins, so you can't upload sketches to the Trinket unless those are disconnected. I tried to get around it by moving one of these leads to #2, but I still have to disconnect the LED to upload new patterns. In the end, it's just a minor limitation you have to deal with.
  2. Adafruit recommends a large capacitor be added to the power leads going to the first Neopixel, to act as a de-bouncer. I actually use three since I have separate power leads from the UBEC to each Neopixel ring, but you can save weight/cost by daisy-chaining.
  3. Same story with the 300ohm resistor on the data line. It's also subject to a smaller current rush, so protect that first pixel on the ring with the extra resistor.
  4. Yves' original documentation was very confusing as he refers to the Naza's "A/E/T/R" pins, but what he actually means are the LED pins above the rx labels. A = LED pin 1 (+5VCC), E = LED pin 2 (red light, or LED2 on LED-V2), T = LED pin 3 (green light, or LED1 on LED-V2), and R = LED pin 4 (GND).
  5. If you use long strips are lengths of power wire between arms, the voltage drop may cause the LEDs further along the chain to be dimmer or color-shifted. While the data line has to be daisy chained from ring 1 to ring n, you can provide direct power to any ring separately.
  6. I power the Trinket from the same 5V UBEC, but if you're powering Neopixels directly from the board, you want closer to 5.5v input. The trinket has its own BEC and supports input voltage to 14V. So a 3S is no problem, a fully charged 4S at 16.8V? Ehh....I'd probably take a risk since the Trinket itself is <$8, and they're optionally sold in six-packs for goodness' sake, but it may fry.

Most people don't have a Y6 (or tricopter), so you can add or subtract rings, or use a Neopixel light strip or light bar or matrix panel, by adding them to the data line and providing power. Adafruit has a ton of Neopixel options, you can find them here: https://www.adafruit.com/categories/87

Here's how I tapped the GND, LED1 and LED2 wires (pins 2-4) from the NAZA LED (the red 5V VCC wire is unused):


The "male" servo connector goes into the NAZA, the "female" goes to pins GND, 2 and 4 on the Trinket. It was useful to have these wires on a servo because you have to unplug pin 3 to access the USB and upload sketches.

My LED rings are temp-mounted. They're just hotglued straight to the frame, with 3mm nlyon spacers to elevate them evenly over the motor wires:






PROGRAMMING

I'm not sure if I should post the code to github or request a fork from Yves, but for now, here's the sketch as should compile for the above setup on the Trinket. I'll leave the details about working with the Arduino IDE to the much better documentation out there on the web:
Code:
/*

 Original DJI LED project
 Author(s): Yves Gohy (diogeneyves@gmail.com)
 Thanks to: Leandre Gohy (leandre.gohy@hexeo.be)
 
 Current fork: Basic Adafruit Trinket NAZA LED Adaptation
 Version: V1.0 April 9, 2014
 Author: ElGuano on RCGroups.com
 Description: This version is modified to the Adafruit Trinket, particularly
 the implementation posted at ___. It is simplified from the original to save 
 RAM and flash space; I also didn't need RX-based controls or switchable 
 animation modes, just basic orientation and NAZA mimicry. 
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:
 
 The above copyright notice and this permission notice shall be
 included in all copies or substantial portions of the Software.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 For more detail on the MIT license, see <http://opensource.org/licenses/MIT>
 
 */

#include <Adafruit_NeoPixel.h>
//#include <math.h>

#define PIN 1 // LED output Pin (Pin 1 output is tied to the red LED on the Trinket)

#define BRIGHTNESS 30 // brightness 0-255  
#define STATICSPEED 30 // Placeholder for spin animation (not used here)

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(48, PIN);

void setup() {
  pixels.begin();
  pixels.setBrightness(BRIGHTNESS);
  pinMode(2, INPUT);  // GPIO pins 2 and 4 for analogRead
  pinMode(4, INPUT);
}

unsigned long int getAnimationColor(word animationSpeed) {
  static const unsigned long int animationColors[] = { 
    0x000000, 0x00FF00, 0xFF0000, 0xFFFF00       }; // colors of animation OFF, GREEN, RED, YELLOW
  static unsigned long int animationColor = 0x000000;
  // read Naza green led
  int sensorValue0 = analogRead(2);  //Digital pin 4 is Analog 2 on Trinket
  // read Naza red led
  int sensorValue1 = analogRead(1);   //Digital pin 2 is Analog 1 on Trinket
  
  byte animationColorIndex = (sensorValue0 > 500) + ((sensorValue1 > 500) << 1); // e.g., 1 + 2 = 3 (yellow), 0 + 2 = 2 (red)

  animationColor = animationColors[animationColorIndex];

  return animationColor;
}

void playAnimation(word animationSpeed, unsigned long int animationColor) {
    playNoAnimation(animationColor);
}

void playNoAnimation(unsigned long int animationColor) {
  for (byte i = 0; i < 16; i++) {
 /*   // This shows 12 front/back LEDs, with four - equally spaced NAZA lights per ring

    if ( i == 3 || i == 7 || i == 11 || i == 15) {   // Assign pixels to Naza Blink
      pixels.setPixelColor(i, animationColor);       // Back ring
      pixels.setPixelColor(i+16, animationColor);    // Front right ring
      pixels.setPixelColor(i+32, animationColor);    // Front left ring
    }
    
    else {                                         // Assign all remaining pixels
      pixels.setPixelColor(i, 0, 180, 180);        // Back ring  
      pixels.setPixelColor(i+16, 180, 0, 180);     // Front right ring
      pixels.setPixelColor(i+32, 180, 0, 180);     //Front left ring
    }
 */

// This shows all 16 front/back directional colors, which all flash NAZA lights when lit up

    if (animationColor != 0x000000) {   // Assign rings to Naza Blink if not-black
      pixels.setPixelColor(i, animationColor);       // Back ring
      pixels.setPixelColor(i+16, animationColor);    // Front right ring
      pixels.setPixelColor(i+32, animationColor);    // Front left ring
    }
    
    else {                                         // otherwise assigns rings to directional color
      pixels.setPixelColor(i, 0x0099CC);        // Back ring  
      pixels.setPixelColor(i+16, 0xCC00CC);     // Front right ring
      pixels.setPixelColor(i+32, 0xCC00CC);     //Front left ring
    }
 }

  pixels.setBrightness(180);
  pixels.show();
}

void loop() {
  unsigned long int animationColor = getAnimationColor(STATICSPEED);
  playAnimation(STATICSPEED, animationColor);
}
A few notes on the code:
  • Follow the directions on the Adafruit learning site. You need to make sure your IDE version supports the Trinket and TinyUSB programmer. You also need to add the Adafruit_Neopixel library.
  • The Trinket's digital pin labels are DIFFERENT from their analogRead designations. So you call pinMode to pins 2 and 4, but in getAnimationColor you'll be reading from 1 and 2 (which are calling the same pins 2 and 4). Why is it this way? Because.
  • I don't have the LEDs set to full brightness, they're 180 out of 255. They're bright enough for now, but not as bright as the NAZA LED.
  • The commented out pattern in playNoAnimation would show 12 orientation LEDs and 4 cross-pattern NAZA LEDs. Give it a shot, maybe you'll like it better (but I found you couldn't see the flashes at distance).
  • Neopixels support awesome animations, PWM effects, you name it. Don't just stay with my static lights! Mess around with them and light up the sky.
  • The Trinket has enough RAM to support ~120 pixels, depending on the complexity of the code. My three rings are 48 pixels, a quad layout would be 64, and hex would be 96.
  • There's room in RAM for more complex logic, as well as a gamma correction table. The color-elitists around can use that to correct the look.

You can also grab Yves' original (and more complex) code here: https://github.com/diogeneyves/dji-naza-led

He also has some setup pics with an Arduino micro, in case mine are incomplete/confusing.
Last edited by ElGuano; Apr 20, 2014 at 09:01 PM.
Sign up now
to remove ads between posts
Apr 11, 2014, 07:17 PM
Registered User
Mowee's Avatar
"A/E/T/R" refers to the labels of the four ports underneath the LED port and not for the pins of the LED port it's self.
Apr 11, 2014, 07:37 PM
Registered User
Quote:
Originally Posted by Mowee
"A/E/T/R" refers to the labels of the four ports underneath the LED port and not for the pins of the LED port it's self.
Precisely. The original instructions confused the hell out of me because the setup included RX connections for throttle/elevator control too, so it seemed like the Arduino was tapped into the rx pins instead of the LED. That's why I refer generally to "NAZA LED pins 1-4" instead.
Apr 12, 2014, 12:10 AM
Scott
n-2-stuff's Avatar
Great work. Is that the full code you have posted? I have a 8 strip,12 ring , 8x8 matrix. I also have the trinket and a uno. I was thinking strips but after seeing the rings (16) I like that much better.
Apr 12, 2014, 07:33 AM
I'd Rather Be Flying
mikenmel08's Avatar
Just when i thought i was done spending money on my toys.......There goes another $200......It would be unfair to only put these on one of my multirotors......Great job by the way
Apr 12, 2014, 11:53 AM
Registered User
Quote:
Originally Posted by n-2-stuff
Great work. Is that the full code you have posted? I have a 8 strip,12 ring , 8x8 matrix. I also have the trinket and a uno. I was thinking strips but after seeing the rings (16) I like that much better.
That's nuts to soup right there. It's very lightweight; gotta be <5kbin flash and < 400b in RAM!

Quote:
Originally Posted by mikenmel08
Just when i thought i was done spending money on my toys.......There goes another $200......It would be unfair to only put these on one of my multirotors......Great job by the way
Wow, how many pixels are you going to be powering? $200 buys a lot of lumens.
Apr 12, 2014, 01:49 PM
I'd Rather Be Flying
mikenmel08's Avatar
Wow, how many pixels are you going to be powering? $200 buys a lot of lumens.[/QUOTE]

2 Hex's and 2 Quads with a ring on every motor....
Apr 13, 2014, 12:13 AM
Registered User
Very cool! Pretty techie for me. Have you thought about building them to sell? I've got a F450.
Just a thought! Lol
You might just start something.......
Apr 13, 2014, 12:46 AM
Registered User
Quote:
Originally Posted by mikenmel08

2 Hex's and 2 Quads with a ring on every motor....
The quads will be fine. The hexes will be 96 pixels (more if you have pancake motors and want to use larger rings to match), which is getting really close to the Trinket's ram limit. I'd go with an Arduino micro or or some other ATmega implementation.
Apr 13, 2014, 12:51 AM
Registered User
Quote:
Originally Posted by Starber
Very cool! Pretty techie for me. Have you thought about building them to sell? I've got a F450.
Just a thought! Lol
You might just start something.......
Well, it looks nice in pics and videos, but it's really way too DIY to be productized. The most I'd be able to do is flash the Arduinos so people don't have to deal with the coding, but you'd still need to solder everything together and wire it up.

What if I told you that with the full source code for the sketch I posted here, you don't have to touch a single line of code? If you can plug in a USB cable , install software and hit a button labeled "upload," you can get the microcontroller part working with zero programming required! Literally 99% of the effort is in soldering/wiring.
Apr 13, 2014, 12:58 AM
I'd Rather Be Flying
mikenmel08's Avatar
Quote:
Originally Posted by ElGuano
The quads will be fine. The hexes will be 96 pixels (more if you have pancake motors and want to use larger rings to match), which is getting really close to the Trinket's ram limit. I'd go with an Arduino micro or or some other ATmega implementation.
Using stock dji motors , I've already placed my order so hopefully the trinket will handle it...
Last edited by mikenmel08; Apr 13, 2014 at 11:02 AM.
Apr 13, 2014, 10:22 AM
Registered User
Quote:
Originally Posted by mikenmel08
Using stock dji motors , I've worst placed my order so hopefully the trinket will handle it...
Great, eager to see how it works. The sketch I provided is super-lightweight so you may be good on RAM. Too bad there's no easy way to see accurate malloc.
Apr 13, 2014, 11:31 AM
I'd Rather Be Flying
mikenmel08's Avatar
I ordered one extra Trinket and Ring just to mess around with and see if i can figure anything out...lol.....I will be using your code first though....
Apr 14, 2014, 11:23 AM
Registered User
Quote:
Originally Posted by mikenmel08
I ordered one extra Trinket and Ring just to mess around with and see if i can figure anything out...lol.....I will be using your code first though....
As I was soldering, I also thought "I should have ordered extras just in case." They'll definitely won't go unused even if everything works perfectly the first time

Now that I think about it, I should have gone with the 3.3v Trinket, just to save a tiny bit of power. I wouldn't power the pixels through the Trinket anyways.
Apr 16, 2014, 08:16 PM
I'd Rather Be Flying
mikenmel08's Avatar
Got my stuff today but i wont get a chance to even attempt installing it for a few days....


Quick Reply
Message:
Thread Tools