3

I have a Raspberry Pi 2 and I am trying to create an led display for it from scratch. It works.. but the refresh is far to slow.

My project is running very very slow averaging around 21 ms per refresh on only a 5x10 led display. I am using the development branch of pi4j which is supposed to be much faster. What is it im doing incorrectly, as my project stands the display in not usable.

private static  void displayBitmap(int[][] bmp){

for (int rws = 0; rws < 5; rws++){      
//even
    for (int cls = 0; cls<10;cls=cls+2){
        if (bmp[rws][cls]==1){
            if (states[cls/2] != 1){
                Gpio.digitalWrite(fCols[cls],1);
                states[cls/2] =1;
            }
        }else{
            if (states[cls/2] != -1){
                Gpio.digitalWrite(fCols[cls],0);            
            states[cls/2] =-1;
            }
        }
    }
    turnPinOn(rows[rws], 0);
//odd       
    rows[rws].high();
    for (int cls = 1; cls<10;cls=cls+2){
        if (bmp[rws][cls]==1){
            if (states[cls/2]!=-1){
                Gpio.digitalWrite(fCols[cls],0);                
                states[cls/2] = -1;
            }
        }else{
            if (states[cls/2]!= 1){
                Gpio.digitalWrite(fCols[cls],1);                
                states[cls/2] = 1;
            }
        }
    }

    turnPinOff(rows[rws]);
}
}



public static void main(String[] args) throws InterruptedException {
    final FastRaspiGpioProvider provider = new FastRaspiGpioProvider();

    GpioFactory.setDefaultProvider(provider);
    final GpioController gpio = GpioFactory.getInstance();
    Thread.currentThread().setPriority(Thread.MAX_PRIORITY);    

     bmp[0] = new int[] {0,1,0,1,0,1,1,1,0,1};
     bmp[1] = new int[] {0,1,0,1,0,0,1,0,0,1};
     bmp[2] = new int[] {0,1,1,1,0,0,1,0,0,1};
     bmp[3] = new int[] {0,1,0,1,0,0,1,0,0,0};
     bmp[4] = new int[] {0,1,0,1,0,1,1,1,0,1};



    rows[0]= gpio.provisionDigitalOutputPin(RaspiPin.GPIO_15, "15", PinState.LOW);fRows[0]=15;
    rows[1]= gpio.provisionDigitalOutputPin(RaspiPin.GPIO_16, "16", PinState.LOW);fRows[1]=16;
    rows[2]= gpio.provisionDigitalOutputPin(RaspiPin.GPIO_01, "1", PinState.LOW) ;fRows[2]=1;
    rows[3]= gpio.provisionDigitalOutputPin(RaspiPin.GPIO_04, "4", PinState.LOW) ;fRows[3]=4;
    rows[4]= gpio.provisionDigitalOutputPin(RaspiPin.GPIO_05, "5", PinState.LOW) ;fRows[4]=5;


    cols[9]= gpio.provisionDigitalOutputPin(RaspiPin.GPIO_06, "6", PinState.LOW) ;fCols[9]=6;
    cols[8]= cols[9]                                                             ;fCols[8]=6;
    cols[7]= gpio.provisionDigitalOutputPin(RaspiPin.GPIO_10, "10", PinState.LOW);fCols[7]=10;
    cols[6]= cols[7]                                                             ;fCols[6]=10;
    cols[5]= gpio.provisionDigitalOutputPin(RaspiPin.GPIO_11, "11", PinState.LOW);fCols[5]=11;
    cols[4]= cols[5]                                                             ;fCols[4]=11;
    cols[3]= gpio.provisionDigitalOutputPin(RaspiPin.GPIO_26, "26", PinState.LOW);fCols[3]=26;
    cols[2]= cols[3]                                                             ;fCols[2]=26;
    cols[1]= gpio.provisionDigitalOutputPin(RaspiPin.GPIO_27, "27", PinState.LOW);fCols[1]=27;
    cols[0]= cols[1]                                                             ;fCols[0]=27;


    System.out.println("<--Pi4J--> GPIO Control Example ... started.");
    long t,tt,ta = 0;
    for (int ii =1;ii<100;ii++){
        for (int i =0;i<20;i++){
            t = System.currentTimeMillis();
            displayBitmap(bmp);
            t= (System.currentTimeMillis()-t);
            System.out.println("<--Pi4J--> time =" + t);
            ta =ta +t;
        }
        System.out.println("<--Pi4J--> time avg =" + ta/(ii*20));      

        //bmp = scrollBmp(bmp);
    }

    gpio.shutdown();
}
  • The code formatting didn't come out too well in the post. Since you are running Java, I wonder if there isn't some profiling capabilities in the JVM that could be used? By running a profiler, you could then see where time is being spent. I am also thinking that 21ms / refresh is 50 refreshes/second which doesn't sound bad at all? What is your target refresh rate? – Kolban Dec 15 '15 at 3:00
  • Without the io calls the java code runs in less then a ms refresh. I'm aiming for 60hZ refresh on a display 5 times this size. – Hailey Upchurch Dec 15 '15 at 4:59
  • If I am hearing you correctly, when you commented out the IO calls, you went from 21ms to 1ms. A reduction of 20ms. By commenting out the IO calls, I think you removed 50 IO calls. That would tend to say that the cost of a single IO call is 20ms/50 = 400 microseconds. The question now becomes ... is that too expensive? You might find that if you write your app in C and bypass the cost of a virtual machine interpretation, it might run a lot faster. – Kolban Dec 15 '15 at 5:11
  • Are IO calls faster in C? Pi4j/ wiring pi are jni/native apps as far as I understand. I mean I could write this in C if I have to I guess. – Hailey Upchurch Dec 15 '15 at 6:33
  • I believe that Pi4J uses WiringPi but the overhead of Java may be too much for your task. We also need to remember that Raspian is not a realtime OS. When your application is running, what else is going on in the system as that will have an effect on your application. Your code doesn't look to complex ... and if you know or are willing to learn enough C, it shouldn't take too long to write a C version ... if nothing else ... just to compare. – Kolban Dec 15 '15 at 9:29
-2

The java implementation is slow, it could be one of a variety of reasons. Re code this in C.

  • This isn't a good answer. Java is not as fast as C; that is undeniable. It should easily be fast enough for this task though. Simply telling someone to switch languages is not constructive. – Jacobm001 Dec 17 '15 at 19:20
  • I agree, but it's the answer I have to go with because I have no idea how to find out what exactly is wrong with the java implementation. No one was coming up with any ideas on how to figure it out either. I can't spend a month on it. – Hailey Upchurch Dec 19 '15 at 7:04
  • Although the essence of rewriting in C is a very good suggestion, I agree that expanding on your answer may earn you the reputation you deserve. – Piotr Kula Jan 8 '16 at 19:14
  • Lol if there community wants to bash me for whatever crazy reason. I'll just delete my question. I'm not here to be told I'm not good enough. – Hailey Upchurch Jan 9 '16 at 20:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.