1

I'm trying to use a digital anemometer to work with my raspberry PI with pi4j.

My idea was to add GpioPinListenerDigital to monitor when a pin goes high (means 1 complete anemometer rotation), but I cannot have it works... I would like to set an interval to watch for interrupts, with no success...

This is my main class

public class Main {

public static void main(String[] args) throws InterruptedException {

    Anemometer anemometer;

    int rotations = 0;
    System.out.println("Start");
    while(true){
        rotations = Anemometer.countPulse();

        System.out.println("Rotations "+ rotations);

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }


}

}

It simply call Anemometer, which is

public class Anemometer {

final static int short_interval = 3;
static int final_counter = 0;

public static int countPulse() {
    GpioController gpio = GpioFactory.getInstance();
    GpioPinDigitalInput input = gpio.provisionDigitalInputPin(RaspiPin.GPIO_01, PinPullResistance.PULL_DOWN);
    input.addListener(new GpioPinListenerDigital() {

        @Override
        public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
            long start = System.currentTimeMillis();
            long end = 0L;
            int counter = 0;
            while (end < short_interval * 1000) {
                System.out.println("Inizio while");
                if (event.getState().isHigh()) {
                    System.out.println("Pin state: " + event.getState());
                    counter++;

                }
                end = (new Date()).getTime() - start;
            }
            final_counter = counter;
            System.out.println("final counter: "+final_counter);
        }

    });

    gpio.unprovisionPin(input);
    try {
        Thread.sleep(200);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return final_counter;
}

}

It looks like it never goes inside the while loop... Any idea?

yglodt
  • 13,807
  • 14
  • 91
  • 127
MarioC
  • 2,934
  • 15
  • 59
  • 111
  • I'm not 100% sure what exactly the problem is, but i assume that the intervall is set up wrong. Set the ´start´ variable just immediately before you go into your loop. Are you facing the same problems then? – kaetzacoatl Jun 07 '16 at 11:01
  • yes, i changed it, but nothing happens... i'll edit the questions, thanks – MarioC Jun 07 '16 at 11:25

1 Answers1

1

I'm not familiar with this API, but it is evident that you are not giving the listener enough time to be fired. Here's the code for GpioControllerImpl.unprovisionPin:

public void unprovisionPin(GpioPin... pin) {
    if (pin == null || pin.length == 0) {
        throw new IllegalArgumentException("Missing pin argument.");
    }
    for (int index = (pin.length-1); index >= 0; index--) {
        GpioPin p  = pin[index];

        // ensure the requested pin has been provisioned
        if (!pins.contains(p)) {
            throw new GpioPinNotProvisionedException(p.getPin());
        }
        // remove all listeners and triggers
        if (p instanceof GpioPinInput) {
            ((GpioPinInput)p).removeAllListeners();
            ((GpioPinInput)p).removeAllTriggers();
        }

        // remove this pin instance from the managed collection
        pins.remove(p);
    }        
}

Note the removeAllListeners call. So essentially, you add the listener and then immediately remove it in your code. Try calling gpio.unprovisionPin(input); after waiting 200ms.

try {
    Thread.sleep(200);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
gpio.unprovisionPin(input);
predi
  • 5,528
  • 32
  • 60