Using a Servo Dev Board for NeoPixel LED Control

The Kitronik Simply Servos Board (Figure 1) solves the problem of providing an adequate 3 V – 12 V power rail when using multiple servos in a project. The built-in 3 V power regulation and pin headers provide a quick way to add a Raspberry Pi Pico to operate the servos. But what about a different device that has a three-wire lead, needs 5 V power, and can have significant current draw? Like Adafruit’s NeoPixel LED strips!

Figure 1: The Kitronik Simply servos board. (Image source: Kitronik)

Recently, I had the idea of creating a night flyer out of one of my R/C combat planes. I could throw in just about any microcontroller and find a way to connect the NeoPixel strips to a power supply but, what if it could be done quickly using servo leads and be easily serviceable? The Simply Servos Board is not just for servos. Choosing this platform streamlined this project and minimized the need for custom wiring and a host of connectors.

The details of the flying platform and a fun video of how the combat plane is converted are presented in blog and video links provided at the end of this article. The Arduino IDE was used to program the Pico to run the NeoPixels based on input from the R/C transmitter. The plan is to use a marquee function on the sides of the plane body that chases faster with increased throttle. As the evening gets darker, the Neopixels can be hard on the eyes due to excessive brightness. An auxiliary channel is used to dim the LEDs. Lastly, when landing the aircraft in the dark, landing lights would be handy. Rather than add another channel, the bottom NeoPixels turn bright white when the throttle is at or below landing speed. I used basic programming but there is room for improvement or additional features to explore.

CopyArduino IDE Code:

//Rx throttle as LED speed control. Rx Aux 2 as dimmer. Channels 1 and 2 as inputs on Simply Servos.
//Remaining servo ports on board (channels 3-8, pins 4-9) used as NeoPixel outputs.
#include <neopixelconnect.h>

//Number of NeoPixels in each string
#define FIN_LEN 34  //Number of NeoPixels on each fin
#define BOT_LEN 28  //Number of NeoPixels on each bottom skid
#define AUX_LEN 61  //Number of NeoPixels on each auxiliary location
#define THRESH 60   //Landing versus flight throttle threshold

//Rx channel Pico GPIO inputs
#define THROT 2
#define AUX2 3

// Create an instance of NeoPixelConnect and initialize it for each strand of NeoPixels
// (pin, number of pixels in string, programmable IO location (0 or 1), programmable IO state machine usage (0-3))
NeoPixelConnect R_Aux(4, AUX_LEN, pio0, 0);
NeoPixelConnect L_Aux(5, AUX_LEN, pio1, 0);
NeoPixelConnect R_Bot(6, BOT_LEN, pio0, 1);
NeoPixelConnect L_Bot(7, BOT_LEN, pio1, 1);
NeoPixelConnect R_Fin(8, FIN_LEN, pio0, 2);
NeoPixelConnect L_Fin(9, FIN_LEN, pio1, 2);

uint8_t AuxSingLED;  //Single LED variable on auxiliary string

//Function - Get intensity level from Rx Aux2 output
uint8_t get_pixel_intensity() {
  return map(pulseIn(AUX2, HIGH), 900, 2200, 0, 255);
}

//Function - Get speed level from Rx Throttle output
uint8_t get_pixel_speed() {
  return map(pulseIn(THROT, HIGH), 990, 1902, 100, 0);
}

void setup() {
  pinMode(THROT, INPUT);  //Set Pico GPIO pin 2 as input
  pinMode(AUX2, INPUT);   //Set Pico GPIO pin 3 as input
}

void loop() {
  uint8_t LEDInten = get_pixel_intensity();  //Get NeoPixel intensity value
  uint8_t LEDSpeed = get_pixel_speed();      //Get NeoPixel speed value
  if (LEDSpeed < 10) LEDSpeed = 0;           //Dampen lower speed limit

  if (LEDSpeed < THRESH) {                                   //Throttle high color
    R_Bot.neoPixelFill(LEDInten, 0, 0, true);                //Fill string with red
    L_Bot.neoPixelFill(LEDInten, 0, 0, true);                //Fill string with red
  } else {                                                   //Throttle low color
    R_Bot.neoPixelFill(LEDInten, LEDInten, LEDInten, true);  //Fill string with white
    L_Bot.neoPixelFill(LEDInten, LEDInten, LEDInten, true);  //Fill string with white
  }

  R_Fin.neoPixelFill(0, LEDInten, 0, true);  //Fill string with green
  L_Fin.neoPixelFill(0, LEDInten, 0, true);  //Fill string with green

  R_Aux.neoPixelFill(0, 0, LEDInten, false);                           //Fill string with blue
  R_Aux.neoPixelSetValue(AuxSingLED, LEDInten, 0, 0, false);           //Set a NeoPixel to red
  R_Aux.neoPixelSetValue(AuxSingLED - 1, LEDInten / 10, 0, 0, false);  //Set trailing NeoPixel to dimmed red
  R_Aux.neoPixelSetValue(AuxSingLED + 1, LEDInten / 10, 0, 0, true);   //Set leading NeoPixel to dimmed red
  L_Aux.neoPixelFill(0, 0, LEDInten, false);                           //Fill string with blue
  L_Aux.neoPixelSetValue(AuxSingLED, LEDInten, 0, 0, false);           //Set a NeoPixel to red
  L_Aux.neoPixelSetValue(AuxSingLED - 1, LEDInten / 10, 0, 0, false);  //Set trailing NeoPixel to dimmed red
  L_Aux.neoPixelSetValue(AuxSingLED + 1, LEDInten / 10, 0, 0, true);   //Set leading NeoPixel to dimmed red

  AuxSingLED = AuxSingLED + 3;                //Marquis - move R_Aux and L_Aux red LEDs along NeoPixel string 3 pixels at a time.
  if (AuxSingLED >= AUX_LEN) AuxSingLED = 0;  //If at end of string, return to start.

  delay(LEDSpeed);  //Set how long to delay code execution cycle depending upon throttle level.
}

Arduino IDE Code END:
</neopixelconnect.h>

Listing 1: Arduino IDE code for controlling the NeoPixel strips.

The entire program will benefit from elimination of any delay functions and LEDs can run faster by manipulating the input value from the throttle or the input value mapping. The rest of the strips are open for whatever pattern or color is desired. Keep in mind that the pilot relies on a recognizable pattern of lights to determine aircraft orientation and heading. Night flying is fun and challenging at the same time. Practice night flying in the early evening when you can still see the plane and its LEDs at the same time.

Additional Resources:

Video: Explore R/C Night Flying with NeoPixel LEDs

Blog: How to Build a Low-Cost RC Combat UAV

关于此作者

Image of Don Johanneck

Don Johanneck 是 DigiKey 的技术内容开发人员,自 2014 年以来一直在该公司工作。他最近刚转岗到现在的职位,负责撰写视频说明和产品内容。Don 通过 DigiKey 奖学金计划获得了北国社区技术学院电子技术和自动化系的应用科学副学士学位。他喜欢无线电控制建模,老式机器修复和修补。

More posts by Don Johanneck
 TechForum

Have questions or comments? Continue the conversation on TechForum, Digi-Key's online community and technical resource.

Visit TechForum