Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 10 of 10

Thread: Teensy 3.2 + WS2812b project

  1. #1
    Junior Member
    Join Date
    Jan 2018
    Posts
    12

    Teensy 3.2 + WS2812b project

    Hi, I'm starting my first Teensy project and need some guidance. I need to send a 16x60 "video signal" from Processing to a set of WS2812b LED strips. Looking around I found the OctoWS2811 library, with seems ideal for the project. But what I'm controlling is not a traditional LED screen, but a series of (very spaced) short LED strips, so the wiring is my main concern here. The idea is to have 16 vertical structures with 1m (60 LEDs) WS2812b LED strip each (let's call them "sticks"). The sticks are part of a little scenography for a show, so I need them to work at an ideal 60fps.

    So, my first idea was to work with two sets of 8 sticks each, wired as one long strip of 60x8 LEDs. Why? Because I found attractive the idea of a single chain of data between all the sticks, I thought it was the best way to maintain the signal quality based on the fact that the last LED of a stick regenerates the signal for the first one on the next stick. BUT, controlling long strips seems to be a problem for reaching high frame rates and on the other hand, two strips are a waste of process for the OctoWS2811 library (that works with multiples of 8).

    Click image for larger version. 

Name:	method01.jpg 
Views:	47 
Size:	81.1 KB 
ID:	12558

    So, mi second idea was to work with 8 groups of 2 sticks, optimizing the processing power of the OctoWS2811 library, but having a new problem: because of the nature of the installation, the wiring needs to go in and out of each stick (each stick has an in and an out RJ45 female connector), so for when the signal reaches the last strip of each of the two outputs of the OctoWS2811 adaptor, it had to go through 6 jump wires (one inside each stick before the last) and long cat6 wire lengths (up to 20feet), so I'm not quite sure of the signal quality here.

    (The drawing doesn't show it at all, but imagine that the two main lines that come out of the adapter go in and out of each stick until the 7th. In "real life" wiring the signal for the 4th pair of each of the two CAT6 cables that go out of the adapter has to go in an RJ45 connection and out of another RJ45 connection 6 times)

    Click image for larger version. 

Name:	method02.jpg 
Views:	41 
Size:	73.5 KB 
ID:	12559

    A 3rd option could be making a sort of a HUB at the exit of the OctoWS2811 adapter and throwing a CAT6 line to each of the sticks, but I don't like the idea of filling the place with cables.

    A 4th option could be changing to another library, maybe FastLED, and mantaining the wiring of the first option (two long strips of 480 LEDs each), but I don't think I can reach the speed I want with this method (this is slowly turning into my favorite option, could I control two WS2812b 480LED strips at 60fps with FastLED and Teensy 3.2?).

    Sorry if it's hard to understand and thank you for any advice you can give me.
    Last edited by maurobarreca; 01-09-2018 at 03:29 AM.

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,194
    I would say first, using 2 of the 8 outputs is perfectly fine. The "waste" of 6 output is 75% of a $10 board (or perhaps less if you just use a chip and your own wiring, if your time to build is free). $7.50 is probably the cheapest part of this project! Of the options you've mentioned, that first one looks pretty reasonable.

    Achieving 60 Hz with FastLED using the normal WS2812 driver would be almost impossible. While 480 LEDs can update in ~14.7 ms, during that time you'd be severely limited to do anything else, leaving you just under 2 ms to do everything needed to get the next data ready. You really need OctoWS2811 or WS2812Serial (both of which can be used through drivers from FastLED), so your code can run and get the next frame ready during the entire 16.6 ms. That's the key to achieving a smooth & reliable 60 Hz refresh.

    Running these types of signals down a long 20 foot wire sometimes works well, other times runs into all sorts of interference problems. I recently made these transmitter and receiver boards for a project that worked great with 25 feet of wire during testing, but was unable to communicate after a battery charger was also connected. These little boards solve that problem, giving a very good signal even with terrible noise. You might need to do something similar.

    As you can see in the photos, that project turned out pretty well in the end. It used 3 of the 8 output with the other 5 "wasted". There so many things to build in large LED art projects, almost all costing far more than $10, so I'd say the last thing you should worry about it whether all 8 pins are used.
    Last edited by PaulStoffregen; 01-09-2018 at 08:54 AM.

  3. #3
    Junior Member
    Join Date
    Jan 2018
    Posts
    12
    Oh, great! If OctoWS2811 is the way, then perfect, I can benefit easily from VideoDisplay. For the long wires, that problem was present only on the second option, with the first one the maximum cable length between LEDs will be 10ft max. I will check out those transmitters and receivers, they seem handy for another project that I have running. Thank you very much, I will update with my doubts for a couple months and with some pictures when finished.

  4. #4
    Member crees's Avatar
    Join Date
    Dec 2016
    Location
    Utah
    Posts
    71
    Here is a project I am working on that is for the teensy and uses OctoWs2811 hardware.

    The Controller



    The Receiver (two per controller)




    Its looking more like this February-March that I will have the boards and kits ready.

  5. #5
    Junior Member
    Join Date
    Jan 2018
    Posts
    12
    Thank you, I'll check it out. For now my concerns are about processing speed and signal quality, I think I can handle the software side (made a similar project some months ago, but using Arduino).

    I have a question about signal quality. As I described my idea now is to control the installation as if it is made by two long LED strips. The idea is to send the data signal through a ~10ft CAT6 wire to the first LED of the first 1 meter long WS2812b strip, and going out of the last LED of that strip to the first LED of the next through another ~10ft long CAT6 cable, and so on. Paul linked me to some DMX boards that could work for what I'm about to ask, but meanwhile I'll try to solve it just with wiring. There's two questions really:

    1. I saw in the OctoWS2811 documentation that it is recommended to use impedance matching resistors at the output of the Teensy, should I use one also at the output of the last LED of every 1 meter strip?

    2. For structure design reasons I'll prefer to use a thinner wire than UTP at the output of every last LED of the 1 meter strips. I know that it's not ideal, but if I make those ~10ft long CAT6 wires, ~3ft single wire and ~7ft CAT6 (UTP), should it work? What cable type should I use for those ~3ft (for them to be thinner than UTP)?

    (Sorry for mixing units, I live in a country that uses the metric system and my project is designed in meters)

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,194
    Quote Originally Posted by maurobarreca View Post
    1. I saw in the OctoWS2811 documentation that it is recommended to use impedance matching resistors at the output of the Teensy, should I use one also at the output of the last LED of every 1 meter strip?
    The really depends on the LED controller chip and the type of cable you're using, and of course how long it is. The sad reality is you're not going to get a really good answer anywhere, other than using an oscilloscope to actually look at the signal quality.

    The datasheets those Chinese LED companies publish have barely any tech info, and what little they do have is often wrong or just copied from a competitor. Even if the data is good, a least a couple times in the last 5 years very different controller chips have appeared on the market, all called "WS2812B" (and/or any other name they think will get you to buy it).

    For some cable length, you'd need to use RS485 or similar drivers (like those 2 little boards I used for Martin's "3 Wishes" project).


    2. For structure design reasons I'll prefer to use a thinner wire than UTP at the output of every last LED of the 1 meter strips. I know that it's not ideal, but if I make those ~10ft long CAT6 wires, ~3ft single wire and ~7ft CAT6 (UTP), should it work? What cable type should I use for those ~3ft (for them to be thinner than UTP)?
    CAT6 is pretty tough to beat for signal quality, but it is bulky. Maybe if you find thin cable meant for USB, use either the white or green for signal and the other 3 wires for ground?

    Before we made the OctoWS2811 adaptor board (yeah, foolishly I published the code without a solid product to make projects easier on the physical wiring side) we had 1 or 2 questions here every week from people who built large LED projects using questionable wiring. Coax and speaker wires are confirmed to not work well. Even coax meant for very high frequency does not work well, probably due to too much capacitance per foot and relatively low characteristic impedance (eg, 50 ohms).

    Sorry, I just don't have a great answer for you, other than advising to stay on the well worn path of CAT5 & CAT6.

  7. #7
    Junior Member
    Join Date
    Jan 2018
    Posts
    12
    Thank you Paul.

    I already made the first tests. Sending the data for 60 LEDs from Processing worked great, I'm having some troubles when trying to write from Processing to all the LEDs, so I have some questions about the OctoWS2811 library and the Teensy in general.

    (NOTE: I'm not using VideoDisplay or movie2serial libraries, I just have them as a reference.)

    - I'm using the leds.setPixel() function to write to all the LEDs (I'm trying 960 now). I did this because I thought I could save time reading the array of LEDs ignoring the 6 outputs I'm not using but, checking the VideoDisplay code I noticed that theres no mention of setPixel(), instead it seems that the Teensy's buffer is filled with data and then leds.show() transfers that data to the WS2812b, am I right? Is that the way to optimize the code?

    - My setup, as I explained earlier is made with just 2 strips of 480 LEDs each, so I'm using 2 of the outputs of the 8 offered by the library (I'm using first pair of cables in one RJ45 and first pair of the other RJ45 to control the two strips), should I send to the Teensy an array with 0's for the unused outputs? What's the optimal array structure for this case?

    - This question is maybe for another forum, but when I was writing to the serial to 60 LEDs from Processing all worked well. But when I try to write the entire array of colors (for 960 pixels) to the serial port, Processing slows drastically down (from 60fps to about 10). Why does this happen? The movie2serial library seems to write the data in the same way (by using this line ledSerial[i].write(ledData); ).

  8. #8
    Junior Member
    Join Date
    Jan 2018
    Posts
    12
    I'll share wit you my code. I'm having problems sending long arrays from Processing. I narrowed it down to the line that determines the array size to send on the Processing side. With values higher than ~300 pixels (300 * 24bit color values in HEX) the Teensy starts updating the LEDs erratically (at a very low frame rate). I have both sides configured at 8000000 baud rate, but somehow it seems that the system is working much slower (don't know how to test that).

    Arduino testing code:

    Code:
    #include <OctoWS2811.h>
    
    const int ledsPerStrip = 60;
    
    DMAMEM int displayMemory[ledsPerStrip*6];
    int drawingMemory[ledsPerStrip*6];
    
    const int config = WS2811_GRB | WS2811_800kHz;
    
    OctoWS2811 leds(ledsPerStrip, displayMemory, drawingMemory, config);
    
    char val;
    char receivedChars[6722];
    boolean started = false;
    boolean ended = false;
    int serialIn = 0;
    
    void setup() {
      Serial.begin(8000000);
      leds.begin();
      leds.show();
    }
    
    void loop() {
    
      while(Serial.available() > 0) {
        int incomingByte = Serial.read();
        if(incomingByte == '<'){
          started=true;
          ended=false;  
        } else if (incomingByte == '>'){
          ended=true;
          break;  
        } else {
          receivedChars[serialIn] = incomingByte;
          serialIn++;  
        }
      }
    //TODO: enviar y recibir directamente en HEX
      if(started && ended) {
        int arrIndex = 0;
        char * token = strtok(receivedChars," ");
        while(token!=NULL){
          int aNum = strtoul(token,NULL,16);
          if(arrIndex<=60){
            for(int i=0;i<60;i++){
              leds.setPixel(arrIndex+i,aNum);
            }
            arrIndex++;
          }
          token = strtok (NULL," ");
        }
      }
      leds.show();
      serialIn = 0;
      receivedChars[serialIn] = '\0';
      started = false;
      ended = false;
      
    }
    Processing serial writing code ("matrixSizeY*X", the X is what I change to increase the String size, matrixSizeY is a constant 60, the problem starts showing when X>5, I need it to be 16):

    Code:
      String serialString = "<";  
      for (int i=0;i<matrixSizeY*X;i++) {
          if(i>0){ serialString += " "; }
          serialString += serialOut[i];
      }  
      serialString += ">";
      //println(serialString);
      myPort.write(serialString);
      serialString = "";
      myPort.clear();

  9. #9
    Junior Member
    Join Date
    Jan 2018
    Posts
    12
    Sorry for the multiple posts, I have many things to test before asking the questions I asked but, it would save me so much work if someone can give me some advice on which of these two options is better fitted for the project:

    Keeping in mind that I have 2 long strips of 480 LEDs each should I:

    - Send through serial the pixel data for the 2 strips (ignoring the remaining 6 that are unused) and update the pixels of just those 2 strips with setPixel() (again, leaving the 6 remaining outputs untouched). I've read that setPixel() can update between 2000 and 3000 LEDs at 60fps, I need to update just 960.

    -or-

    - Send through serial the entire array of colors (the data for the 2 strips and 0's -or whatever- for the remaining 6) and using VideoDisplay and movie2serial to make it work at the highest speed possible (I tested the example files and it seems to work well, but I need to adapt the Processing sketch for my project). The OctoWS2811 Adaptor info page says that I can drive up to 4416 LEDs at 60Hz, that's 552 LEDs per output, I have 480.

    Thank you.

  10. #10
    Junior Member
    Join Date
    Jan 2018
    Posts
    12
    Well, ignore my questions, I made it work.

    I stored into a PImage array the pixel info of the portion of the screen I wanted the LEDs to show and then copied and adapted the image2data function of the movie2data sketch.

    I'll leave the portion of the code I used to store into the PImage as it can be useful for someone else:

    Code:
    //matrixSizeX and matrixSizeY are the dimensions of the LED matrix
    ledImage = createImage(matrixSizeX,matrixSizeY,RGB);
      for(int i=0; i<matrixSizeY; i++){
        for(int j=0; j<matrixSizeX; j++){
          //the next line stores the data of every relevant pixel into ledImage
          ledImage.pixels[(i*matrixSizeX)+j] = pixels[(i*width)+j];   
        }
      }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •