UniPi and pi4j



  • Hi all,

    I would like to build an extension to the pi4j library, and am doing some tests:

    UniPi + Rasp 2 + raspbian

    I cannot seem to get relay 1, GP07 to work. There is somethig I missing here, but whar is it?

    I have confirmed that I have address 20 for the MCP23008:

    pi@raspberrypi ~ $ i2cdetect -y 1
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
    10: -- -- -- -- -- -- -- -- 18 -- -- -- -- -- -- -- 
    20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    50: 50 51 52 53 54 55 56 57 -- -- -- -- -- -- -- -- 
    60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- 6f 
    70: -- -- -- -- -- -- -- --  
    

    I can use:

    i2cset -y 1  0x20 0x09 0x80
    ```to control, with no issues.
    
    .. I get the following error when executing the program:
    
    

    Number of relays to test: 8
    Milliseconds to wait: 50
    A serious error has occurred:
    java.lang.ArrayIndexOutOfBoundsException: 128
    at com.pi4j.io.gpio.GpioProviderBase.getPinCache(GpioProviderBase.java:69)
    at com.pi4j.io.gpio.GpioProviderBase.export(GpioProviderBase.java:98)
    at com.pi4j.gpio.extension.mcp.MCP23008GpioProvider.export(MCP23008GpioProvider.java:127)
    at com.pi4j.io.gpio.GpioProviderBase.export(GpioProviderBase.java:79)
    at com.pi4j.io.gpio.impl.GpioPinImpl.export(GpioPinImpl.java:158)
    at com.pi4j.io.gpio.impl.GpioControllerImpl.provisionPin(GpioControllerImpl.java:517)
    at com.pi4j.io.gpio.impl.GpioControllerImpl.provisionDigitalOutputPin(GpioControllerImpl.java:669)
    at sfcountertester.SFCounterTester.<init>(SFCounterTester.java:93)
    at sftestsuite.SFTester.main(SFTester.java:71)
    Expect: 17 counts for relay: Relay2
    Expect: 16 counts for relay: Relay3
    Expect: 15 counts for relay: Relay4
    Expect: 14 counts for relay: Relay5
    Expect: 13 counts for relay: Relay6
    Expect: 12 counts for relay: Relay7
    Expect: 11 counts for relay: Relay8
    Exception in thread "Thread-1"
    java.lang.RuntimeException: java.io.IOException: Error writing to /dev/i2c-1 at address 0x20 to address 0x9. Got -10001.
    at com.pi4j.gpio.extension.mcp.MCP23008GpioProvider.setState(MCP23008GpioProvider.java:203)
    at com.pi4j.io.gpio.impl.GpioPinImpl.setState(GpioPinImpl.java:325)
    at com.pi4j.io.gpio.impl.GpioControllerImpl.shutdown(GpioControllerImpl.java:939)
    at com.pi4j.io.gpio.impl.GpioControllerImpl$ShutdownHook.run(GpioControllerImpl.java:888)
    Caused by: java.io.IOException: Error writing to /dev/i2c-1 at address 0x20 to address 0x9. Got -10001.
    at com.pi4j.io.i2c.impl.I2CDeviceImpl.write(I2CDeviceImpl.java:124)
    at com.pi4j.gpio.extension.mcp.MCP23008GpioProvider.setState(MCP23008GpioProvider.java:201)
    ... 3 more
    run-remote:
    BUILD SUCCESSFUL (total time: 29 seconds)

    in addition I attach code:
    
    

    package sfcountertester;

    import com.pi4j.gpio.extension.mcp.MCP23008GpioProvider;
    import com.pi4j.gpio.extension.mcp.MCP23008Pin;
    import com.pi4j.io.gpio.GpioController;
    import com.pi4j.io.gpio.GpioFactory;
    import com.pi4j.io.gpio.GpioPinDigitalOutput;
    import com.pi4j.io.gpio.PinState;
    import com.pi4j.io.i2c.I2CBus;
    import java.io.IOException;

    /**

    • @author gproost
      */
      public class SFCounterTester implements Runnable {

      private int numRelays;
      private int minimumClicks = 10;
      private int delay = 100;

      // create gpio controller
      final GpioController gpio = GpioFactory.getInstance();

      // create custom MCP23008 GPIO provider
      final MCP23008GpioProvider gpioProvider;

      // relays
      static GpioPinDigitalOutput relay1;
      static GpioPinDigitalOutput relay2;
      static GpioPinDigitalOutput relay3;
      static GpioPinDigitalOutput relay4;
      static GpioPinDigitalOutput relay5;
      static GpioPinDigitalOutput relay6;
      static GpioPinDigitalOutput relay7;
      static GpioPinDigitalOutput relay8;

      /**


      • @param numRelays

      • @param delay

      • @throws InterruptedException

      • @throws java.io.IOException
        */
        public SFCounterTester(int numRelays, int delay) throws InterruptedException, IOException {

        gpioProvider = new MCP23008GpioProvider(I2CBus.BUS_1, 0x20);

        try {

         this.numRelays = numRelays;
         this.delay = delay;
        
         if (numRelays >= 1) {
             relay1 = gpio.provisionDigitalOutputPin(gpioProvider, MCP23008Pin.GPIO_00, "Relay8", PinState.LOW);
             relay1.setShutdownOptions(true, PinState.LOW);
         }
        
         if (numRelays >= 2) {
             relay2 = gpio.provisionDigitalOutputPin(gpioProvider, MCP23008Pin.GPIO_01, "Relay7", PinState.LOW);
             relay2.setShutdownOptions(true, PinState.LOW);
         }
        
         if (numRelays >= 3) {
             relay3 = gpio.provisionDigitalOutputPin(gpioProvider, MCP23008Pin.GPIO_02, "Relay6", PinState.LOW);
             relay3.setShutdownOptions(true, PinState.LOW);
        
         }
        
         if (numRelays >= 4) {
             relay4 = gpio.provisionDigitalOutputPin(gpioProvider, MCP23008Pin.GPIO_03, "Relay5", PinState.LOW);
             relay4.setShutdownOptions(true, PinState.LOW);
         }
        
         if (numRelays >= 5) {
             relay5 = gpio.provisionDigitalOutputPin(gpioProvider, MCP23008Pin.GPIO_04, "Relay4", PinState.LOW);
             relay5.setShutdownOptions(true, PinState.LOW);
        
         }
        
         if (numRelays >= 6) {
             relay6 = gpio.provisionDigitalOutputPin(gpioProvider, MCP23008Pin.GPIO_05, "Relay3", PinState.LOW);
             relay6.setShutdownOptions(true, PinState.LOW);
         }
        
         if (numRelays >= 7) {
             relay7 = gpio.provisionDigitalOutputPin(gpioProvider, MCP23008Pin.GPIO_06, "Relay2", PinState.LOW);
             relay7.setShutdownOptions(true, PinState.LOW);
         }
        
         if (numRelays == 8) {
             relay8 = gpio.provisionDigitalOutputPin(gpioProvider, MCP23008Pin.GPIO_07, "Relay1", PinState.LOW);
             relay8.setShutdownOptions(true, PinState.LOW);
         }
        

        } catch (Exception ex) {
        System.out.println("A serious error has occured:");
        ex.printStackTrace();
        }
        }

      @Override
      public void run() {

       switch (numRelays) {
      
           case 8:
               runTest(relay8, minimumClicks + 8, this.delay);
      
           case 7:
               runTest(relay7, minimumClicks + 7, this.delay);
      
           case 6:
               runTest(relay6, minimumClicks + 6, this.delay);
      
           case 5:
               runTest(relay5, minimumClicks + 5, this.delay);
      
           case 4:
               runTest(relay4, minimumClicks + 4, this.delay);
      
           case 3:
               runTest(relay3, minimumClicks + 3, this.delay);
      
           case 2:
               runTest(relay2, minimumClicks + 2, this.delay);
      
           case 1:
               runTest(relay1, minimumClicks + 1, this.delay);
      
       }
      
       // get out gracefully
       gpioProvider.shutdown();
       //       gpio.shutdown();
      

      }

      /**

      • @param pin

      • @param number

      • @throws InterruptedException
        */
        private void runTest(GpioPinDigitalOutput pin, int number, int delay) {

        try {

         System.out.println("Expect: " + number + " counts for relay: " + pin.getName());
        
         for (int i = 0; i <= number - 1; i++) {
        
             gpio.setState(PinState.HIGH, pin);
             Thread.sleep(delay);
        
             gpio.setState(PinState.LOW, pin);
             Thread.sleep(delay);
         }
        

        } catch (Exception e) {

        }
        }
        }

    
    If anyone can help, I would appreciate it immensely.
    
    Regards,
    
    George.


  • Hi all,

    I would like to build an extension to the pi4j library, and am doing some tests:

    UniPi + Rasp 2 + raspbian

    I cannot seem to get relay 1, GP07 to work. There is somethig I missing here, but whar is it?

    I have confirmed that I have address 20 for the MCP23008:

    pi@raspberrypi ~ $ i2cdetect -y 1
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
    10: -- -- -- -- -- -- -- -- 18 -- -- -- -- -- -- -- 
    20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    50: 50 51 52 53 54 55 56 57 -- -- -- -- -- -- -- -- 
    60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- 6f 
    70: -- -- -- -- -- -- -- --  
    

    I can use:

    i2cset -y 1  0x20 0x09 0x80
    ```to control, with no issues.
    
    .. I get the following error when executing the program:
    
    

    Number of relays to test: 8
    Milliseconds to wait: 50
    A serious error has occurred:
    java.lang.ArrayIndexOutOfBoundsException: 128
    at com.pi4j.io.gpio.GpioProviderBase.getPinCache(GpioProviderBase.java:69)
    at com.pi4j.io.gpio.GpioProviderBase.export(GpioProviderBase.java:98)
    at com.pi4j.gpio.extension.mcp.MCP23008GpioProvider.export(MCP23008GpioProvider.java:127)
    at com.pi4j.io.gpio.GpioProviderBase.export(GpioProviderBase.java:79)
    at com.pi4j.io.gpio.impl.GpioPinImpl.export(GpioPinImpl.java:158)
    at com.pi4j.io.gpio.impl.GpioControllerImpl.provisionPin(GpioControllerImpl.java:517)
    at com.pi4j.io.gpio.impl.GpioControllerImpl.provisionDigitalOutputPin(GpioControllerImpl.java:669)
    at sfcountertester.SFCounterTester.<init>(SFCounterTester.java:93)
    at sftestsuite.SFTester.main(SFTester.java:71)
    Expect: 17 counts for relay: Relay2
    Expect: 16 counts for relay: Relay3
    Expect: 15 counts for relay: Relay4
    Expect: 14 counts for relay: Relay5
    Expect: 13 counts for relay: Relay6
    Expect: 12 counts for relay: Relay7
    Expect: 11 counts for relay: Relay8
    Exception in thread "Thread-1"
    java.lang.RuntimeException: java.io.IOException: Error writing to /dev/i2c-1 at address 0x20 to address 0x9. Got -10001.
    at com.pi4j.gpio.extension.mcp.MCP23008GpioProvider.setState(MCP23008GpioProvider.java:203)
    at com.pi4j.io.gpio.impl.GpioPinImpl.setState(GpioPinImpl.java:325)
    at com.pi4j.io.gpio.impl.GpioControllerImpl.shutdown(GpioControllerImpl.java:939)
    at com.pi4j.io.gpio.impl.GpioControllerImpl$ShutdownHook.run(GpioControllerImpl.java:888)
    Caused by: java.io.IOException: Error writing to /dev/i2c-1 at address 0x20 to address 0x9. Got -10001.
    at com.pi4j.io.i2c.impl.I2CDeviceImpl.write(I2CDeviceImpl.java:124)
    at com.pi4j.gpio.extension.mcp.MCP23008GpioProvider.setState(MCP23008GpioProvider.java:201)
    ... 3 more
    run-remote:
    BUILD SUCCESSFUL (total time: 29 seconds)

    in addition I attach code:
    
    

    package sfcountertester;

    import com.pi4j.gpio.extension.mcp.MCP23008GpioProvider;
    import com.pi4j.gpio.extension.mcp.MCP23008Pin;
    import com.pi4j.io.gpio.GpioController;
    import com.pi4j.io.gpio.GpioFactory;
    import com.pi4j.io.gpio.GpioPinDigitalOutput;
    import com.pi4j.io.gpio.PinState;
    import com.pi4j.io.i2c.I2CBus;
    import java.io.IOException;

    /**

    • @author gproost
      */
      public class SFCounterTester implements Runnable {

      private int numRelays;
      private int minimumClicks = 10;
      private int delay = 100;

      // create gpio controller
      final GpioController gpio = GpioFactory.getInstance();

      // create custom MCP23008 GPIO provider
      final MCP23008GpioProvider gpioProvider;

      // relays
      static GpioPinDigitalOutput relay1;
      static GpioPinDigitalOutput relay2;
      static GpioPinDigitalOutput relay3;
      static GpioPinDigitalOutput relay4;
      static GpioPinDigitalOutput relay5;
      static GpioPinDigitalOutput relay6;
      static GpioPinDigitalOutput relay7;
      static GpioPinDigitalOutput relay8;

      /**


      • @param numRelays

      • @param delay

      • @throws InterruptedException

      • @throws java.io.IOException
        */
        public SFCounterTester(int numRelays, int delay) throws InterruptedException, IOException {

        gpioProvider = new MCP23008GpioProvider(I2CBus.BUS_1, 0x20);

        try {

         this.numRelays = numRelays;
         this.delay = delay;
        
         if (numRelays >= 1) {
             relay1 = gpio.provisionDigitalOutputPin(gpioProvider, MCP23008Pin.GPIO_00, "Relay8", PinState.LOW);
             relay1.setShutdownOptions(true, PinState.LOW);
         }
        
         if (numRelays >= 2) {
             relay2 = gpio.provisionDigitalOutputPin(gpioProvider, MCP23008Pin.GPIO_01, "Relay7", PinState.LOW);
             relay2.setShutdownOptions(true, PinState.LOW);
         }
        
         if (numRelays >= 3) {
             relay3 = gpio.provisionDigitalOutputPin(gpioProvider, MCP23008Pin.GPIO_02, "Relay6", PinState.LOW);
             relay3.setShutdownOptions(true, PinState.LOW);
        
         }
        
         if (numRelays >= 4) {
             relay4 = gpio.provisionDigitalOutputPin(gpioProvider, MCP23008Pin.GPIO_03, "Relay5", PinState.LOW);
             relay4.setShutdownOptions(true, PinState.LOW);
         }
        
         if (numRelays >= 5) {
             relay5 = gpio.provisionDigitalOutputPin(gpioProvider, MCP23008Pin.GPIO_04, "Relay4", PinState.LOW);
             relay5.setShutdownOptions(true, PinState.LOW);
        
         }
        
         if (numRelays >= 6) {
             relay6 = gpio.provisionDigitalOutputPin(gpioProvider, MCP23008Pin.GPIO_05, "Relay3", PinState.LOW);
             relay6.setShutdownOptions(true, PinState.LOW);
         }
        
         if (numRelays >= 7) {
             relay7 = gpio.provisionDigitalOutputPin(gpioProvider, MCP23008Pin.GPIO_06, "Relay2", PinState.LOW);
             relay7.setShutdownOptions(true, PinState.LOW);
         }
        
         if (numRelays == 8) {
             relay8 = gpio.provisionDigitalOutputPin(gpioProvider, MCP23008Pin.GPIO_07, "Relay1", PinState.LOW);
             relay8.setShutdownOptions(true, PinState.LOW);
         }
        

        } catch (Exception ex) {
        System.out.println("A serious error has occured:");
        ex.printStackTrace();
        }
        }

      @Override
      public void run() {

       switch (numRelays) {
      
           case 8:
               runTest(relay8, minimumClicks + 8, this.delay);
      
           case 7:
               runTest(relay7, minimumClicks + 7, this.delay);
      
           case 6:
               runTest(relay6, minimumClicks + 6, this.delay);
      
           case 5:
               runTest(relay5, minimumClicks + 5, this.delay);
      
           case 4:
               runTest(relay4, minimumClicks + 4, this.delay);
      
           case 3:
               runTest(relay3, minimumClicks + 3, this.delay);
      
           case 2:
               runTest(relay2, minimumClicks + 2, this.delay);
      
           case 1:
               runTest(relay1, minimumClicks + 1, this.delay);
      
       }
      
       // get out gracefully
       gpioProvider.shutdown();
       //       gpio.shutdown();
      

      }

      /**

      • @param pin

      • @param number

      • @throws InterruptedException
        */
        private void runTest(GpioPinDigitalOutput pin, int number, int delay) {

        try {

         System.out.println("Expect: " + number + " counts for relay: " + pin.getName());
        
         for (int i = 0; i <= number - 1; i++) {
        
             gpio.setState(PinState.HIGH, pin);
             Thread.sleep(delay);
        
             gpio.setState(PinState.LOW, pin);
             Thread.sleep(delay);
         }
        

        } catch (Exception e) {

        }
        }
        }

    
    If anyone can help, I would appreciate it immensely.
    
    Regards,
    
    George.


  • This looks like maybe a bug in the Pi4J Java code and not in the application.

    As far as i known the Pi4J library caches the pinmodes at the moment they are being initialized just in case you re-initialize a pin it throws an exception.

    The error is an error showing that a certain entry in an Java Array does not exist at position 128, and hence throws an index out of bounds exception. I would discuss this one with the Pi4J developer as it is the Pi4J lib throwing the exception.



  • Hi John,

    Yes issue is pi4j .. pin caching..

    Currently under snapshot-1.0.1 fails … under version 1.0 works.
    I need snapshot however due to improved serial behaviour.

    I have contacted the developers.

    Regards

    George



  • Hi George,

    Have you tried jssc for serial connections? It controls both serial pins (using /dev/) and serial over usb. You would be able to use the 1.0 then.

    Cheers,
    John



  • Thanks John,

    I'll look into that.

    George.