WS2812Serial, BasicTest not working

Status
Not open for further replies.

PaulS

Well-known member
Read about the new WS2812Serial library so gave it try on a Teensy LC using a 24-LED NeoPixel Ring.
But I can't get it to work.

Here's a photo how it physically connects:
Teensy_LC_Neopixel_Ring24.jpg
Mounted a wire to connect pin 24 to pin 17 as suggested by Paul here.

And this is the code:
Code:
// WS2812Serial BasicTest Example
// Test LEDs by turning then 7 different colors.

#include <WS2812Serial.h>

const int numled = 24;
const int pin = 24;

// Usable pins:
//   Teensy LC:   1, 4, 5, 24
//   Teensy 3.2:  1, 5, 8, 10, 20, 31
//   Teensy 3.5:  1, 5, 8, 10, 20, 26, 32, 33, 48
//   Teensy 3.6:  1, 5, 8, 10, 20, 26, 32, 33

byte drawingMemory[numled * 3];       //  3 bytes per LED
DMAMEM byte displayMemory[numled * 12]; // 12 bytes per LED

WS2812Serial leds(numled, displayMemory, drawingMemory, pin, WS2812_GRB);

#define RED    0xFF0000
#define GREEN  0x00FF00
#define BLUE   0x0000FF
#define YELLOW 0xFFFF00
#define PINK   0xFF1088
#define ORANGE 0xE05800
#define WHITE  0xFFFFFF

void setup() {
  leds.begin();
}

void loop() {
  // change all the LEDs in 1.5 seconds
  int microsec = 1500000 / leds.numPixels();

  colorWipe(RED, microsec);
  colorWipe(GREEN, microsec);
  colorWipe(BLUE, microsec);
  colorWipe(YELLOW, microsec);
  colorWipe(PINK, microsec);
  colorWipe(ORANGE, microsec);
  colorWipe(WHITE, microsec);
}

void colorWipe(int color, int wait) {
  for (int i = 0; i < leds.numPixels(); i++) {
    leds.setPixel(i, color);
    leds.show();
    delayMicroseconds(wait);
  }
}

Just to be sure that the hardware was OK, I loaded the following sketch on the same hardware:
Code:
#include <FastLED.h>
#define DATA_PIN    24
#define NUM_LEDS    24

CRGB ring[NUM_LEDS];

void setup() {
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(ring, NUM_LEDS);
  FastLED.setBrightness(128);
}

void loop() {
  for  ( int i = 0; i < 255; i++) {
    fill_rainbow( ring, NUM_LEDS, i, 255/24);
    FastLED.show();
    FastLED.delay(10);
    }
  }
This does show a rotating rainbow on the NeoPixel ring as expected, so the hardware and wiring seems OK.

I'm using Arduino V1.8.2 & Teensyduino V1.36. Compiling of both .ino's returned no errors.


So I'm stuck now... Am I overlooking the obvious?

Thanks,
Paul
 
Problem solved!

Updated to Arduino V1.8.5 & Teensyduino V1.40.

Regards,
Paul
 
Additional question about WS2812serial lib

Hi Paul,
While looking more in depth into the WS2812serial lib, I noticed the following in ws2812serial.cpp:
Code:
// wait 300us WS2812 reset time
uint32_t min_elapsed = (numled * 30) + 300;
if (min_elapsed < 2500) min_elapsed = 2500;
Looking into the datasheet of the WS2812(B), it is stated for RESET time: "Above 50µs".
So I changed the code to:
Code:
// wait 300us WS2812 reset time
uint32_t min_elapsed = (numled * 30) + 55;      << changed 300 to 55
//if (min_elapsed < 2500) min_elapsed = 2500;   << commented this line out
That seems to work fine as and is potentially faster.

Was there a specific reason to set the reset time to 300us and make it minimally 2500us?

Thanks,
Paul
 
Yes, there's a reason. Many WS2812 LEDs actually use approx 425 Hz PWM. Some of then behave badly if updated faster than their PWM frequency.
 
Allright. So I guess I'm just lucky with the Neopixel ring that I have.
The PWM frequency is not even mentioned in the datasheets I found...thanks for the info!

Paul
 
Glad you got it working. I only ever tested this on the latest 1.40, since it was just written last weekend. ;)

I'm afraid I'm running into the same problem as the OP, except running a 3.2, Arduino v1.8.5 and Teensy 1.41.

Has the 1.41 update broken this library in anyway? Strip works fine with other code, using the same pins, just getting no response so far from the LED strip with the BasicTest code.
 
Hi propa,

What is your hardware setup? A Teensy 3.2 does not have a 5V output at pin 17 like a Teensy LC. Most Neopixels need a 5V driving signal to work reliably.

Paul
 
Hi propa,

What is your hardware setup? A Teensy 3.2 does not have a 5V output at pin 17 like a Teensy LC. Most Neopixels need a 5V driving signal to work reliably.

Paul

Hi Paul, thanks for the reply. I understand, what is confusing is using the exact same pins (5V, GND, Pin 6) I can run standard neopixel code and get colours coming out, regardless of if the data pin on the strip is going to a buffered data pin on the MCU. When using the WS2812serial library I get nothing.

If I go to Manage libraries in Arduino and search the WS Serial library it says "Already installed" version unknown, I've looked at the github and seems it was updated 2 months ago, but I can't find where Teensy installs it's own libraries on a mac, they don't seem to appear in the conventional Arduino libraries folder so I cannot over write by dumping a new download on it, and when tried to update the WS2812Serial library through the library manager I get no option to download and also version unknown.

I'd have a gamble and say that library update (or lack thereof) could be the culprit, although I've run out of ideas of how to go about fixing it.

I actually have a LC, I'll see if the library works with that particular board and if it works, we can rule out the possibility of the library being the culprit.
 
Teensyduino installs its own libraries on a Mac in /Applications/Arduino/Java/hardware/teensy/avr/libraries ...

Thank you! I was able to reinstall the WS2812Serial library, I managed to get everything working now, I think it was a pin conflict between the Audio Sheild using pin 5, so I moved to Pin 1 for the Data pin and now works perfectly. :eek:

Now to figure out how to port the Frequency Analyser example over to using the WS2812Serial library, here's what I've got so far, works ok-ish:

Code:
/* WS2812Serial & Frequency Analyser Example

   This example code is in the public domain. */

#include <WS2812Serial.h>
#include <Audio.h>
#include <Wire.h>
#include <SD.h>
#include <SPI.h>

// The display size and color to use
const unsigned int matrix_width = 60;
const unsigned int matrix_height = 12;
const unsigned int myColor = 0x400020;

// These parameters adjust the vertical thresholds
const float maxLevel = 0.5;      // 1.0 = max, lower is more "sensitive"
const float dynamicRange = 40.0; // total range to display, in decibels
const float linearBlend = 0.3;   // useful range is 0 to 0.7

const int numled =  matrix_width * matrix_height;
const int pin = 1;

// Usable pins:
//   Teensy LC:   1, 4, 5, 24
//   Teensy 3.2:  1, 5, 8, 10, 20, 31
//   Teensy 3.5:  1, 5, 8, 10, 20, 26, 32, 33, 48
//   Teensy 3.6:  1, 5, 8, 10, 20, 26, 32, 33

byte drawingMemory[numled*3];         //  3 bytes per LED
DMAMEM byte displayMemory[numled*12]; // 12 bytes per LED

WS2812Serial leds(numled, displayMemory, drawingMemory, pin, WS2812_GRB);

//AudioInputAnalog         adc1(A0);       //xy=99,55
AudioInputI2S            i2s2;           //xy=145,131
AudioAnalyzeRMS          rms1;           //xy=298,42
AudioAnalyzePeak         peak1;          //xy=323,193
AudioAnalyzePeak         peak2;          //xy=327,274
AudioAnalyzeFFT256       fft256_1;       //xy=422,80
AudioAnalyzeFFT1024      fft;            //xy=265,75
AudioOutputI2S           i2s1;           //xy=515,173
AudioConnection          patchCord1(i2s2, 0, i2s1, 0);
AudioConnection          patchCord2(i2s2, fft);
AudioControlSGTL5000     sgtl5000_1;     //xy=144,324



// This array holds the volume level (0 to 1.0) for each
// vertical pixel to turn on.  Computed in setup() using
// the 3 parameters above.
float thresholdVertical[matrix_height];

// This array specifies how many of the FFT frequency bin
// to use for each horizontal pixel.  Because humans hear
// in octaves and FFT bins are linear, the low frequencies
// use a small number of bins, higher frequencies use more.
int frequencyBinsHorizontal[matrix_width] = {
   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
   2,  2,  2,  2,  2,  2,  2,  2,  2,  3,
   3,  3,  3,  3,  4,  4,  4,  4,  4,  5,
   5,  5,  6,  6,  6,  7,  7,  7,  8,  8,
   9,  9, 10, 10, 11, 12, 12, 13, 14, 15,
  15, 16, 17, 18, 19, 20, 22, 23, 24, 25
};

void setup() {
  // the audio library needs to be given memory to start working
  AudioMemory(12);
    Serial.begin(115200);
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.5);
  sgtl5000_1.inputSelect(AUDIO_INPUT_MIC);
  sgtl5000_1.micGain(40);

  // compute the vertical thresholds before starting
  computeVerticalLevels();

  // turn on the display
  leds.begin();
  leds.show();
}

// A simple xy() function to turn display matrix coordinates
// into the index numbers OctoWS2811 requires.  If your LEDs
// are arranged differently, edit this code...
unsigned int xy(unsigned int x, unsigned int y) {
  if ((y & 1) == 0) {
    // even numbered rows (0, 2, 4...) are left to right
    return y * matrix_width + x;
  } else {
    // odd numbered rows (1, 3, 5...) are right to left
    return y * matrix_width + matrix_width - 1 - x;
  }
}

// Run repetitively
void loop() {
  unsigned int x, y, freqBin;
  float level;

  if (fft.available()) {
    // freqBin counts which FFT frequency data has been used,
    // starting at low frequency
    freqBin = 0;

    for (x=0; x < matrix_width; x++) {
      // get the volume for each horizontal pixel position
      level = fft.read(freqBin, freqBin + frequencyBinsHorizontal[x] - 1);

      // uncomment to see the spectrum in Arduino's Serial Monitor
      // Serial.print(level);
      // Serial.print("  ");

      for (y=0; y < matrix_height; y++) {
        // for each vertical pixel, check if above the threshold
        // and turn the LED on or off
        if (level >= thresholdVertical[y]) {
          leds.setPixel(xy(x, y), myColor);
        } else {
          leds.setPixel(xy(x, y), 0x000000);
        }
      }
      // increment the frequency bin count, so we display
      // low to higher frequency from left to right
      freqBin = freqBin + frequencyBinsHorizontal[x];
    }
    // after all pixels set, show them all at the same instant
    leds.show();
    // Serial.println();
  }
}


// Run once from setup, the compute the vertical levels
void computeVerticalLevels() {
  unsigned int y;
  float n, logLevel, linearLevel;

  for (y=0; y < matrix_height; y++) {
    n = (float)y / (float)(matrix_height - 1);
    logLevel = pow10f(n * -1.0 * (dynamicRange / 20.0));
    linearLevel = 1.0 - n;
    linearLevel = linearLevel * linearBlend;
    logLevel = logLevel * (1.0 - linearBlend);
    thresholdVertical[y] = (logLevel + linearLevel) * maxLevel;
  }
}
 
Status
Not open for further replies.
Back
Top