Thursday, March 17, 2022

[SOLVED] Problem with recoloring adressable LED strip

Issue

I am controlling a WS2811 LED strip from a raspberry pi in Java, using a library called Diozero.

When I set a color to the LEDs for the first time, there is no problem, but when i try to do it again the LEDs just turn white instead of the color I set to them. When I restart the application, I am able to recolor the LEDs, even if I didn't power cycle them, but again, only once.

Please help!

package venus;

import com.diozero.api.DigitalOutputDevice;
import com.diozero.ws281xj.LedDriverInterface;
import com.diozero.ws281xj.PixelColour;
import com.diozero.ws281xj.StripType;
import com.diozero.ws281xj.rpiws281x.WS281x;
import java.awt.Color;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author RETEC error
 */
public class Venus {

    private static Venus instance;

    private LedDriverInterface driver;
    private DigitalOutputDevice power;

    public Venus() {
        int dataPin = 10; //bcm 10
        int brightness = 127;
        int numPixels = 50;

        int powerPin = 26; //bcm 26 (inside, second from bottom)

        //power = new DigitalOutputDevice(powerPin); //create a toggleable power supply
        //powerOn(); //add power
        driver = new WS281x(0, 0, dataPin, brightness, numPixels, StripType.WS2811_RGB); //create the driver for the leds

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        instance = new Venus();
        instance.paintGradient(Color.red, Color.blue);
    }

    //power control methods
    /**
     * sudo Gives power to the designated power pin.
     */
    private void powerOn() {
        power.on();
    }

    /**
     * Cuts power from the designated power pin.
     */
    private void powerOff() {
        power.off();
    }

    /**
     * Cuts the power from the designated power pin and gives back power after 5
     * secs.
     */
    private void powerCycle() {
        powerOff();
        try {
            Thread.sleep(5000);

        } catch (InterruptedException ex) {
            Logger.getLogger(Venus.class.getName()).log(Level.SEVERE, null, ex);
        }

        powerOn();
    }

    //color control methods
    /**
     * Paints a gradient on the full length of the LED driver, fading from c1 to
     * c2.
     *
     * @param c1 Starting color
     * @param c2 Ending color
     */
    public void paintGradient(Color c1, Color c2) {
        int[] colorValues = new int[driver.getNumPixels()]; //the 24 bit color values to be sent to the LEDs

        for (int i = 0; i < colorValues.length; i++) {
            float t = (float) i / (float) colorValues.length - 1;
            Vector3 v1 = new Vector3(c1.getRed(), c1.getGreen(), c1.getBlue());
            Vector3 v2 = new Vector3(c2.getRed(), c2.getGreen(), c2.getBlue());

            Vector3 color = Vector3.Lerp(v1, v2, t);
            colorValues[i] = PixelColour.createColourRGB((int) color.x, (int) color.y, (int) color.z);
        }

        //paint the pixels
        for (int i = 0; i < driver.getNumPixels(); i++) {
            driver.setPixelColour(i, colorValues[i]);
        }
        driver.render();
    }

}

Solution

On the newer raspberrypi 4-s there is a problem with giving out signals with highly precise timing. This originates from the cpu adjusting its speed on the fly and causing the timings needed for the SPI communication to drift too. To fix this add the following lines to the boot/congig.txt "core_freq=500" "Core_freq_min=500"



Answered By - error13660
Answer Checked By - Marie Seifert (WPSolving Admin)