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.

Files at this revision

API Documentation at this revision

Comitter:
Ned Konz
Date:
Fri Jun 12 18:23:46 2015 -0700
Parent:
35:f177e1bf5ef7
Child:
37:e25d212ee3fe
Commit message:
Refactored self-test; getting wait_for_dma_done() to work

Changed in this revision

.vimrc Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/.vimrc	Fri Jun 12 11:44:46 2015 -0700
+++ b/.vimrc	Fri Jun 12 18:23:46 2015 -0700
@@ -1,1 +1,2 @@
 set path=,.,TSI,MMA8451Q,mbed,mbed/TARGET_KL25Z,mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM,mbed/TARGET_KL25Z/TARGET_Freescale,mbed/TARGET_KL25Z/TARGET_Freescale/TARGET_KLXX,mbed/TARGET_KL25Z/TARGET_Freescale/TARGET_KLXX/TARGET_KL25Z,Multi_WS2811
+set makeprg=remake\ $*\ \&\&cp\ Nevermores_Revenge.bin\ /Volumes/MBED
--- a/main.cpp	Fri Jun 12 11:44:46 2015 -0700
+++ b/main.cpp	Fri Jun 12 18:23:46 2015 -0700
@@ -13,16 +13,16 @@
 // PTD2 (D11) data output for strip# 1
 // PTD3 (D12) data output for strip# 2
 // PTA2 (D3) blinking eyes output (HI = ON)
+// PTA5 (D5) servomotor (20 msec period; 1.0-2.0msec ON)
 
-unsigned const DATA_OUT_PIN1 = 2; // PTD2
-unsigned const DATA_OUT_PIN2 = 3; // PTD3
-
+const unsigned DATA_OUT_PIN1 = 2; // PTD2
+const unsigned 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;
+const unsigned nLEDs = MAX_LEDS_PER_STRIP;
 
 template class WS2811<MAX_LEDS_PER_STRIP>;
 
@@ -34,16 +34,20 @@
 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
+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
+PwmOut eyes(D3);            // also redLED1; max = 1.0
+PwmOut servo(D5);
+DigitalOut greenLED2(D4);   // max = 1.0
+DigitalIn button1(D6);      // low=ON, debounced
+DigitalIn button2(D7);      // low=ON, debounced
 
-float touchPercentage;
+// Limits
+const float maxBrite = 0.5;
 
-float const minBrite = 0.2;
-float const maxBrite = 0.5;
-float brite;
+const float minServo = -0.7; // -1.0 = -60°
+const float maxServo = 0.6; // 1.0 = +60°
 
 // @brief sets different colors in each of the LEDs of a strip
 // @param strip the light strip
@@ -71,10 +75,30 @@
     strip.show();
 }
 
-static void selfTest()
+// range is -1.0 (full CCW) to +1.0 (full CW)
+static void positionServo(float pos)
+{
+    if (pos < minServo) pos = minServo;
+    else if (pos > maxServo) pos = maxServo;
+
+    servo.pulsewidth_us((1.5 + (pos / 2.0)) * 1000.0);
+}
+
+static void selfTestServo()
 {
-    pc.printf("self test: ");
+    pc.printf("Servo:\r\n");
+    pc.printf("CCW, ");
+    positionServo(-1.0);
+    wait(1.0);
+    pc.printf("CW, ");
+    positionServo(+1.0);
+    wait(1.0);
+    pc.printf("center.\r\n");
+    positionServo(0.0);
+}
 
+static void selfTestLEDs()
+{
     pc.printf("LEDs .");
     rled = 0.0; // red LED on
     wait(1.0);
@@ -88,10 +112,13 @@
     wait(1.0);
     pc.printf(".");
     eyes = 0.0;
-    pc.printf(", ");
+    pc.printf("\r\n");
+}
 
+static void selfTestLightStrips()
+{
     pc.printf("light strips");
-    float rgb[4] = { 1.0, 0.0, 0.0, 0.0 };
+    uint8_t rgb[4] = { 255 * maxBrite, 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]);
@@ -108,10 +135,19 @@
     pc.printf("\r\n");
 }
 
+static void selfTest()
+{
+    pc.printf("self test: ");
+
+    selfTestServo();
+    selfTestLEDs();
+    selfTestLightStrips();
+}
+
 int main(void)
 {
     pc.baud(115200);
-    pc.printf("\r\nNevermore's Revenge!\r\ncompiled " __DATE__ ", " __TIME__ "\r\n");
+    pc.printf("\r\n\r\nNevermore's Revenge!\r\ncompiled " __DATE__ ", " __TIME__ "\r\n");
 
     lightStrip1.begin();
     lightStrip2.begin();
@@ -119,6 +155,8 @@
     rled = 1.0;
     gled = 1.0;
     eyes = 0.0;
+    greenLED2 = 0.0;
+    servo.period_ms(20);
 
     selfTest();
 
@@ -133,6 +171,8 @@
         showRainbow(lightStrip1, 1.0, maxBrite, fabs(xyz[0]));
         showRainbow(lightStrip2, 1.0, maxBrite, fabs(xyz[1]));
         MyWS2811::startDMA();
+        MyWS2811::wait_for_dma_done();
+        wait(0.000055);
     }
 }