Light Bar Add-On

Learn how to assemble the Light Bar add-on for Stackr and use addressable RGB LEDs as turn signals while driving with an RC transmitter and receiver required for this project.

How to assemble the Light Bar

The easiest way to assemble the Light Bar is by following the instructions in the video below.

RC drive with turn signals

An RC controller is required. This sketch drives Stackr with channels 1 and 2 and lights amber turn signals on the NeoPixel bar when you steer, left LEDs for a left turn, right LEDs for a right turn, all off when driving straight.

Stackr_LightBar.ino
#include <SparkFun_TB6612.h>
#include <Adafruit_NeoPixel.h>

#define AIN1 D5
#define BIN1 D6
#define AIN2 D4
#define BIN2 D7
#define PWMA D3
#define PWMB D8
#define STBY D9

#define CH1_LR A0
#define CH2_FWD A1

const int fwdDirectionA = 1;
const int fwdDirectionB = 1;

Motor motor1 = Motor(AIN1, AIN2, PWMA, fwdDirectionA, STBY);
Motor motor2 = Motor(BIN1, BIN2, PWMB, fwdDirectionB, STBY);

#define PIN 21
#define NUMPIXELS 5

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

unsigned long hori_pulse = 0;
unsigned long vert_pulse = 0;

void setup()
{
  pinMode(CH1_LR, INPUT_PULLUP);
  pinMode(CH2_FWD, INPUT_PULLUP);
  motor1.brake();
  motor2.brake();

  pixels.begin();
}

void loop()
{
  hori_pulse = pulseIn(CH1_LR, HIGH);
  vert_pulse = pulseIn(CH2_FWD, HIGH);

  if (hori_pulse >= 999 && hori_pulse <= 2000 && vert_pulse >= 999 && vert_pulse <= 2000) {
    int speed = map(vert_pulse, 999, 2000, -255, 255);
    int direction = map(hori_pulse, 999, 2000, -255, 255);

    int left_speed  = constrain(speed + direction, -255, 255);
    int right_speed = constrain(speed - direction, -255, 255);
    motor1.drive(right_speed);
    motor2.drive(left_speed);

    if (50 <= right_speed - left_speed) {
      pixels.setPixelColor(3, pixels.Color(255, 100, 0));
      pixels.setPixelColor(4, pixels.Color(255, 100, 0));
      pixels.setPixelColor(0, pixels.Color(0, 0, 0));
      pixels.setPixelColor(1, pixels.Color(0, 0, 0));
      pixels.show();
    } else if (50 <= left_speed - right_speed) {
      pixels.setPixelColor(0, pixels.Color(255, 100, 0));
      pixels.setPixelColor(1, pixels.Color(255, 100, 0));
      pixels.setPixelColor(3, pixels.Color(0, 0, 0));
      pixels.setPixelColor(4, pixels.Color(0, 0, 0));
      pixels.show();
    } else {
      pixels.setPixelColor(0, pixels.Color(0, 0, 0));
      pixels.setPixelColor(1, pixels.Color(0, 0, 0));
      pixels.setPixelColor(3, pixels.Color(0, 0, 0));
      pixels.setPixelColor(4, pixels.Color(0, 0, 0));
      pixels.show();
    }
  }
}

Code Breakdown

RC required: Valid pulses on channels 1 and 2 (999–2000 µs) are needed before motors and LEDs update.

NeoPixel strip: Five LEDs on pin 21. Pixels 0–1 are the left side; pixels 3–4 are the right side (pixel 2 is unused in this layout).

#define PIN 21
#define NUMPIXELS 5

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

Differential drive: Channel 2 sets forward/back speed; channel 1 adds steering. Motor speeds are combined and clamped to ±255.

Turn signals: When the right wheel command is at least 50 higher than the left, the right LEDs turn amber. When the left is 50 higher, the left LEDs turn amber. Otherwise all signal LEDs are off.

if (50 <= right_speed - left_speed) {
  pixels.setPixelColor(3, pixels.Color(255, 100, 0));
  pixels.setPixelColor(4, pixels.Color(255, 100, 0));
} else if (50 <= left_speed - right_speed) {
  pixels.setPixelColor(0, pixels.Color(255, 100, 0));
  pixels.setPixelColor(1, pixels.Color(255, 100, 0));
}

Libraries

Install Adafruit NeoPixel and SparkFun TB6612 from the Arduino Library Manager. You also need an RC transmitter and receiver for drive and turn-signal control.

External Resources