Why LED-strip on chip ws2811 never switch on the first LED?

75 Views Asked by At

I use Pi4J library to control a LED-strip. The LED-strip contains 10 LEDs with chips ws2811. They are connected serially. I have found a simple example on github that I use on a Raspberry Pi 3B (Raspberry Pi OS 32 bit). My code set some LEDs on white color and switches them off. It works but has two troubles:

  1. Sometimes one LED can be switched on and flashes weakly red. I have no place in the code where I set the LEDs on red - only white or complete switched off.
  2. First LED doesn't flash (it can only flash red when the previous error appears). When I try to switch on LEDs from 0 to 3 the LEDs with numbers from 1 to 4 are switched on. When I try to switch on LEDs from 1 to 4 the LEDs with numbers from 2 to 5 are switched on.

I think the first error can be low electromagnetic compatibility. For the second error I have founded some strange things in the source code. It has some reset bytes at the start and at the end of the data transmission matrices. The function render, that must be called to see the result, starts the counter from 1.

public void render() {
    //beginning at 1, because the first byte is a reset
    int counter = 1;
    for (int i = 0; i < numLeds; i++) {

      //Scaling the color to the max brightness
      leds[i] = PixelColor.setRedComponent(leds[i], (int) (PixelColor.getRedComponent(leds[i]) * brightness));
      leds[i] = PixelColor.setGreenComponent(leds[i], (int) (PixelColor.getGreenComponent(leds[i]) * brightness));
      leds[i] = PixelColor.setBlueComponent(leds[i], (int) (PixelColor.getBlueComponent(leds[i]) * brightness));

      // Calculating GRB from RGB
      for (int j = 15; j >= 8; j--) {
        if (((leds[i] >> j) & 1) == 1) {
          pixelRaw[counter++] = Bit_1;
        } else {
          pixelRaw[counter++] = Bit_0;
        }
      }
      for (int j = 23; j >= 16; j--) {
        if (((leds[i] >> j) & 1) == 1) {
          pixelRaw[counter++] = Bit_1;
        } else {
          pixelRaw[counter++] = Bit_0;
        }
      }
      for (int j = 7; j >= 0; j--) {
        if (((leds[i] >> j) & 1) == 1) {
          pixelRaw[counter++] = Bit_1;
        } else {
          pixelRaw[counter++] = Bit_0;
        }
      }
    }

    // While bitbanging, the first and last byte have to be a reset
    pixelRaw[0] = Bit_Reset;
    pixelRaw[pixelRaw.length - 1] = Bit_Reset;

    // waiting since last render time
    long diff = Math.abs(System.nanoTime()) - lastRenderTime;
    if (renderWaitTime - diff > 0) {
      long wait = renderWaitTime - diff;
      long millis = wait / 1_000_000L;
      int nanos = (int) (wait % 1_000_000);
      System.out.println("Waiting " + (millis) + "ms and " + nanos + "ns");
      sleep(millis, nanos);
    }

    //writing on the PIN
    spi.write(pixelRaw);

    System.out.println("finished rendering");
    lastRenderTime = Math.abs(System.nanoTime());
}

Can you please explain me what means this Bit_Reset, why the LED place it at the start and at the end and why they are so important? And why flashes some LEDs red?

0

There are 0 best solutions below