0

I must create a java videogame that runs on a Raspberry Pi 3b and controls external devices. The game is ready. It communicates successfully with a joystick, coin acceptor and 7-segments LED-display. But I can not control a LED-strip. It is the last problem. It uses ws2811 chips that needs the input signal frequency 800 kH. The shortest single signal duration time on my Raspberry Pi 4B, that I can got from Java using functions like:

digitalWrite(pinNumber, HIGH);

is 6500 nanoseconds. But for the LED strip control I need 250 nanoseconds. I have tried the example from Pi4J library. It uses SPI but it doesn't work properly with my LED strip : it switched on random LEDs and doesn't switch off all the LEDs every time I run the allOff() function. I call the allOff() function twice to switch off all the flashing LEDs.

I have only one idea: I know that the same function called from a C program hat the duration time 100 nanoseconds. I want to write a simple program on C and either compile it and call the compiled code from my java code using for example JNI or run this program parallel direct from my Java game. I don't know C, I only know Java but have no experience with JNI. I have wrote the code that I would like to port in C. The program must be pretty simple: I have 10 LEDs in the strip. I need to switch on the LEDs with numbers 1-2, 3-5, 6-10 and have an ability to switch off all the LEDs. The color is only white. My dream abstract code:

public class AbstractLedStripController {   //super abstract LED strip controller. I want port this code on C and launch from java

    private final static long BIT_0_SIGNAL_START_DURATION = 250;   // every bit starts with high level. A single bit transfer durations is 1250 nanoseconds
    private final static long BIT_0_SIGNAL_END_DURATION = 1000;   // every bit ends with low level. A single bit transfer durations is 1250 nanoseconds
    private final static long BIT_1_SIGNAL_START_DURATION = 600;   // every bit starts with high level. A single bit transfer durations is 1250 nanoseconds
    private final static long BIT_1_SIGNAL_END_DURATION = 650;   // every bit ends with low level. A single bit transfer durations is 1250 nanoseconds
    private final int LEDs = 10;    //Chain contains 10 LEDs. I think it is important that pin supports

    private final int signalPin = 10;       // Pin number for control the LED. GPIO10 - MOSI pin for SPI. I think it is faster as the anothers
    private static long start, end;         // Variables for saving time

    public void flash1_2(){  //Switch on LEDs from 1 to 2;
        changeStatement(0,1);
    }

    public void flash3_5(){  //Switch on LEDs from 3 to 5;
        changeStatement(2,4);
    }

    public void flash6_10(){  //Switch on LEDs from 6 to 10;
        changeStatement(5,9);
    }

    public void allOff(){   // Color for a single LED is encrypted in 24 bits. To switch off the LED I send 24 logical false
        for (int i = 0; i < LEDs; i++){
            for (int j = 0; j < 24; j++){
                write0();
            }
        }
    }

    private void changeStatement(int startPin, int lastPin){
        for (int i = 0; i < LEDs; i++){
            if (i>= startPin && i <= lastPin){
                for (int j = 0; j < 24; j++){   // Color for a single LED is encrypted in 24 bits. For white color I send 24 logical TRUE
                    write1();
                }
            }
            else {
                for (int j = 0; j < 24; j++){   // Color for a single LED is encrypted in 24 bits. To switch off the LED I send 24 logical FALSE
                    write0();
                }
            }
        }
    }

    private void write0(){
        start = System.nanoTime();
        end = start+BIT_0_SIGNAL_START_DURATION;
        digitalWrite(true);
        while(System.nanoTime()<end){
            //wait
        }
        start = System.nanoTime();
        end = start+BIT_0_SIGNAL_END_DURATION;
        digitalWrite(false);
        while(System.nanoTime()<end){
            //wait
        }
    }

    private void write1(){
        start = System.nanoTime();
        end = start+BIT_1_SIGNAL_START_DURATION;
        digitalWrite(true);
        while(System.nanoTime()<end){
            //wait
        }
        start = System.nanoTime();
        end = start+BIT_1_SIGNAL_END_DURATION;
        digitalWrite(false);
        while(System.nanoTime()<end){
            //wait
        }
    }

    private void digitalWrite(boolean level){
        //Something that changes the pin statement very fast
    }
}

Give me please an idea what I need to do port this code in C and make it launchable from Java.

  • What is wrong with the proposed solution using the SPI? Note that I've written a response to https://stackoverflow.com/questions/75917421/addressable-led-strip-control-using-raspberry-pi-3b-and-pi4j-library where I show you why your current code (using the SPI) doesn't work: simple put you turn on all LEDs and then try to turn on some of them again. – Thomas Kläger Apr 06 '23 at 07:53
  • It doesn't work again. I think already that the customer has problems with electromagnetic compatibility - sometimes LED becomes red color on some LEDs, sometimes not every LED is switched off when the right command comes. https://youtu.be/qL6ph2J-_BM – Alexander Gorodilov Apr 06 '23 at 08:09
  • The Pi4j library you mention already has a JNI component (which allows calling C code). I think you should look into extending that with your "dream api" – Botje Apr 06 '23 at 09:49
  • I think I can create better from 0 than I will try to use SPI for this purpose. I have no success with the ready example. That is why I want to start from the null point – Alexander Gorodilov Apr 06 '23 at 11:00

0 Answers0