Test program for my Multi_WS2811 library that started out as a fork of heroic/WS2811. My library uses hardware DMA on the FRDM-KL25Z to drive up to 16 strings of WS2811 or WS2812 LEDs in parallel.

Dependencies:   Multi_WS2811 mbed MMA8451Q

Fork of WS2811 by Heroic Robotics

NOTE: I have accidentally pushed changes for another fork of this program that I used in the recent Georgetown Carnival Power Tool Races. When I get some time, I will restore the test program to its original glory.

You can see my power tool racer (Nevermore's Revenge) here

/media/uploads/bikeNomad/img_0482.jpg

This tests my FRDM-KL25Z multi-string WS2811/WS2812 library. It uses the accelerometer to change the rainbow phase on two strings of LEDs as well as the touch sense to change brightness.

A video of this program in operation is here.

Here is the library that I developed to run the LEDs:

Import libraryMulti_WS2811

Library allowing up to 16 strings of 60 WS2811 or WS2812 LEDs to be driven from a single FRDM-KL25Z board. Uses hardware DMA to do a full 800 KHz rate without much CPU burden.

main.cpp

Committer:
Ned Konz
Date:
2015-06-12
Revision:
34:cd56c00ed910
Parent:
33:43b504e417e3
Child:
36:9ee1ec2135d5

File content as of revision 34:cd56c00ed910:

#include "mbed.h"
#include "Colors.h"
#include "MMA8451Q.h"

#define MMA8451_I2C_ADDRESS (0x1d<<1)

#define INSTANTIATE_TEMPLATES 1
#include "WS2811.h"

// I/O pin usage
// PTD0 TPM0 CH0 monitor
// PTD1 TPM0 CH1 monitor
// PTD2 (D11) data output for strip# 1
// PTD3 (D12) data output for strip# 2
// PTA2 (D3) blinking eyes output (HI = ON)

unsigned const DATA_OUT_PIN1 = 2; // PTD2
unsigned const DATA_OUT_PIN2 = 3; // PTD3

const unsigned MAX_LEDS_PER_STRIP = 32;

// per LED: 3 * 20 mA = 60mA max
// 60 LEDs: 60 * 60mA = 3600 mA max
// 120 LEDs: 7200 mA max
unsigned const nLEDs = MAX_LEDS_PER_STRIP;

template class WS2811<MAX_LEDS_PER_STRIP>;

typedef WS2811<MAX_LEDS_PER_STRIP> MyWS2811;

MyWS2811 lightStrip1(nLEDs, DATA_OUT_PIN1);
MyWS2811 lightStrip2(nLEDs, DATA_OUT_PIN2);

Serial pc(USBTX, USBRX);

MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS);
PwmOut rled(LED_RED);   // max = 0.0
PwmOut gled(LED_GREEN); // max = 0.0
// LED_BLUE is on PTD1
PwmOut eyes(D3);        // max = 1.0

float touchPercentage;

float const minBrite = 0.2;
float const maxBrite = 0.5;
float brite;

// @brief sets different colors in each of the LEDs of a strip
// @param strip the light strip
// @param sat saturation, 0.0 - 1.0
// @param brite brightness, 0.0 - 1.0
// @param hueShift shift, 0.0 - 1.0 is equivalent to 0 - 360 degrees
static void showRainbow(MyWS2811 &strip, float sat, float brite, float hueShift)
{
    unsigned nLEDs = strip.numPixels();
    for (unsigned i = 0; i < nLEDs; i++) {
        uint8_t r, g, b;
        float hue = ((float)i / (float)nLEDs) + hueShift;
        HSBtoRGB(hue, sat, brite, &r, &g, &b);
        strip.setPixelColor(i, r, g, b);
    }
    strip.show();
}

static void showSolidColor(MyWS2811 &strip, uint8_t r, uint8_t g, uint8_t b)
{
    unsigned nLEDs = strip.numPixels();
    for (unsigned i = 0; i < nLEDs; i++) {
        strip.setPixelColor(i, r, g, b);
    }
    strip.show();
}

static void selfTest()
{
    pc.printf("self test: ");

    pc.printf("LEDs .");
    rled = 0.0; // red LED on
    wait(1.0);
    pc.printf(".");
    rled = 1.0; // red LED off, green LED on
    gled = 0.0;
    wait(1.0);
    pc.printf(".");
    gled = 1.0; // green LED off, eyes on
    eyes = 1.0;
    wait(1.0);
    pc.printf(".");
    eyes = 0.0;
    pc.printf(", ");

    pc.printf("light strips");
    float rgb[4] = { 1.0, 0.0, 0.0, 0.0 };
    for (int i = 0; i < 3; i++) {
        showSolidColor(lightStrip1, rgb[0], rgb[1], rgb[2]);
        showSolidColor(lightStrip2, rgb[1], rgb[2], rgb[0]);
        MyWS2811::startDMA();
        if (i == 2) break;
        wait(1.0);
        rgb[3] = rgb[2];
        rgb[2] = rgb[1];
        rgb[1] = rgb[0];
        rgb[0] = rgb[3];
        pc.printf(".");
    }

    pc.printf("\r\n");
}

int main(void)
{
    pc.baud(115200);
    pc.printf("\r\nNevermore's Revenge!\r\ncompiled " __DATE__ ", " __TIME__ "\r\n");

    lightStrip1.begin();
    lightStrip2.begin();

    rled = 1.0;
    gled = 1.0;
    eyes = 0.0;

    selfTest();

    float xyz[3];

    for (;;) {
        acc.getAccAllAxis(xyz);
        pc.printf("x: %f y: %f z: %f\r\n", xyz[0], xyz[1], xyz[2]);
        rled = 1.0 - fabs(xyz[0]);
        gled = 1.0 - fabs(xyz[1]);
        eyes = fabs(xyz[2]);
        showRainbow(lightStrip1, 1.0, maxBrite, fabs(xyz[0]));
        showRainbow(lightStrip2, 1.0, maxBrite, fabs(xyz[1]));
        MyWS2811::startDMA();
    }
}