savageautomate / pi4j-plugin-microchip

1 stars 0 forks source link

Pi4J provider [xxx-i2c] could not be found #1

Open tatery opened 2 years ago

tatery commented 2 years ago

I have created separate maven project to test this plugin with real hardware however there is some issue with i2c provider/s. I tested with both linuxfs-i2c and pidpio-i2c providers but ended up in the same result:

[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running TestSuite
----------------------------------------------------------
PI4J PROVIDERS
----------------------------------------------------------
PROVIDERS: [2] "I/O Providers" <com.pi4j.provider.impl.DefaultProviders>
├─SPI: [0] <com.pi4j.io.spi.SpiProvider>
├─ANALOG_OUTPUT: [0] <com.pi4j.io.gpio.analog.AnalogOutputProvider>
├─DIGITAL_OUTPUT: [1] <com.pi4j.io.gpio.digital.DigitalOutputProvider>
│ └─PROVIDER: "MCP23017 Digital Output (GPIO) Provider" {mcp23017-digital-output} <com.pi4j.plugin.microchip.mcp23017.provider.gpio.digital.impl.MCP23017DigitalOutputProviderImpl> {com.pi4j.plugin.microchip.mcp23017.provider.gpio.digital.impl.MCP23017DigitalOutputProviderImpl}
├─ANALOG_INPUT: [0] <com.pi4j.io.gpio.analog.AnalogInputProvider>
├─DIGITAL_INPUT: [1] <com.pi4j.io.gpio.digital.DigitalInputProvider>
│ └─PROVIDER: "MCP23017DigitalInputProviderImpl" {com.pi4j.plugin.microchip.mcp23017.provider.gpio.digital.impl.MCP23017DigitalInputProviderImpl} <com.pi4j.plugin.microchip.mcp23017.provider.gpio.digital.impl.MCP23017DigitalInputProviderImpl> {com.pi4j.plugin.microchip.mcp23017.provider.gpio.digital.impl.MCP23017DigitalInputProviderImpl}
├─SERIAL: [0] <com.pi4j.io.serial.SerialProvider>
├─PWM: [0] <com.pi4j.io.pwm.PwmProvider>
└─I2C: [0] <com.pi4j.io.i2c.I2CProvider>
----------------------------------------------------------
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 2.97 s <<< FAILURE! - in TestSuite
[ERROR] test1(gpio.MCP23017Test)  Time elapsed: 1.876 s  <<< FAILURE!
com.pi4j.provider.exception.ProviderNotFoundException: Pi4J provider [pigpio-i2c] could not be found.  Please include this 'provider' JAR in the classpath.
        at gpio.MCP23017Test.test1(MCP23017Test.java:40)

[INFO]
[INFO] Results:
[INFO]
[ERROR] Failures:
[ERROR]   MCP23017Test.test1:40 » ProviderNotFound Pi4J provider [pigpio-i2c] could not ...
[INFO]
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------

Pi4j dependencies from my project:

        <pi4j.version>2.0</pi4j.version>

        <dependency>
            <groupId>com.pi4j</groupId>
            <artifactId>pi4j-core</artifactId>
            <version>${pi4j.version}</version>
        </dependency>
        <dependency>
            <groupId>com.pi4j</groupId>
            <artifactId>pi4j-plugin-raspberrypi</artifactId>
            <version>${pi4j.version}</version>
        </dependency>
        <dependency>
            <groupId>com.pi4j</groupId>
            <artifactId>pi4j-plugin-pigpio</artifactId>
            <version>${pi4j.version}</version>
        </dependency>
        <dependency>
            <groupId>com.pi4j</groupId>
            <artifactId>pi4j-plugin-linuxfs</artifactId>
            <version>${pi4j.version}</version>
        </dependency>
        <dependency>
            <groupId>com.pi4j</groupId>
            <artifactId>pi4j-plugin-mock</artifactId>
            <version>${pi4j.version}</version>
        </dependency>

        <dependency>
            <groupId>com.pi4j.plugin.microchip</groupId>
            <artifactId>pi4j-plugin-microchip</artifactId>
            <version>0.0.1</version>
        </dependency>

Any idea what can be wrong?

tatery commented 2 years ago

Issue with the "missing" i2c provider was solved by running the test from the root account but then the following error appears:

test1(gpio.MCP23017Test)  Time elapsed: 2.558 s  <<< FAILURE!
com.pi4j.provider.exception.ProviderNotFoundException: Pi4J provider [mcp23017-digital-output] could not be found.  Please include this 'provider' JAR in the classpath.
        at gpio.MCP23017Test.test1(MCP23017Test.java:46)
tatery commented 2 years ago

Unfortunately initial issue is still there even when test is running on root account. When the MCP23017 provider is removed from the code then i2c provider is visible. When the MCP23017 provider is added to the test:

Context pi4j = Pi4J.newContextBuilder().add(
 MCP23017DigitalOutputProvider.newInstance(),
 MCP23017DigitalInputProvider.newInstance()).build();

I2C mcp23017_i2c = pi4j.i2c().create(MCP23017_I2C_BUS, MCP23017_I2C_ADDRESS); <--- this is line 40 reported as place where error occurs
MCP23017DigitalOutputProvider provider = pi4j.provider(MCP23017DigitalOutputProvider.ID);

provider.setup(mcp23017_i2c);

then:

[ERROR] test1(gpio.MCP23017Test)  Time elapsed: 1.877 s  <<< FAILURE!
com.pi4j.provider.exception.ProviderNotFoundException: Pi4J provider IO type [I2C] could not be found.  Please include this 'provider' JAR in the classpath for this provider type.
        at gpio.MCP23017Test.test1(MCP23017Test.java:40)
tatery commented 2 years ago

When

        var pi4j = Pi4J.newContextBuilder().add( 
                MCP23017DigitalOutputProvider.newInstance(), 
                MCP23017DigitalInputProvider.newInstance(),
                LinuxFsI2CProvider.newInstance()).build();   <----- this is new compared to the previous settings

then

[INFO] Running TestSuite
----------------------------------------------------------
PI4J PROVIDERS
----------------------------------------------------------
PROVIDERS: [3] "I/O Providers" <com.pi4j.provider.impl.DefaultProviders>
├─SERIAL: [0] <com.pi4j.io.serial.SerialProvider>
├─I2C: [1] <com.pi4j.io.i2c.I2CProvider>
│ └─PROVIDER: "LinuxFS I2C Provider" {linuxfs-i2c} <com.pi4j.plugin.linuxfs.provider.i2c.LinuxFsI2CProviderImpl> {com.pi4j.plugin.linuxfs.provider.i2c.LinuxFsI2CProviderImpl}
├─ANALOG_OUTPUT: [0] <com.pi4j.io.gpio.analog.AnalogOutputProvider>
├─DIGITAL_INPUT: [1] <com.pi4j.io.gpio.digital.DigitalInputProvider>
│ └─PROVIDER: "MCP23017DigitalInputProviderImpl" {com.pi4j.plugin.microchip.mcp23017.provider.gpio.digital.impl.MCP23017DigitalInputProviderImpl} <com.pi4j.plugin.microchip.mcp23017.provider.gpio.digital.impl.MCP23017DigitalInputProviderImpl> {com.pi4j.plugin.microchip.mcp23017.provider.gpio.digital.impl.MCP23017DigitalInputProviderImpl}
├─PWM: [0] <com.pi4j.io.pwm.PwmProvider>
├─SPI: [0] <com.pi4j.io.spi.SpiProvider>
├─DIGITAL_OUTPUT: [1] <com.pi4j.io.gpio.digital.DigitalOutputProvider>
│ └─PROVIDER: "MCP23017 Digital Output (GPIO) Provider" {mcp23017-digital-output} <com.pi4j.plugin.microchip.mcp23017.provider.gpio.digital.impl.MCP23017DigitalOutputProviderImpl> {com.pi4j.plugin.microchip.mcp23017.provider.gpio.digital.impl.MCP23017DigitalOutputProviderImpl}
└─ANALOG_INPUT: [0] <com.pi4j.io.gpio.analog.AnalogInputProvider>
----------------------------------------------------------
----------------------------------------------------------
CREATE GPIO OUTPUT PIN
----------------------------------------------------------
----> GPIO CURRENT STATE: LOW
----------------------------------------------------------
PI4J I/O REGISTRY
----------------------------------------------------------
REGISTRY: [2] "I/O Registered Instances" <com.pi4j.registry.impl.DefaultRegistry>
├─IO: "I2C-1.32" {I2C-1.32} <com.pi4j.plugin.linuxfs.provider.i2c.LinuxFsI2C> {I2C-1.32}
└─IO: "LED Flasher" {led} <com.pi4j.plugin.microchip.provider.gpio.digital.MicrochipDigitalOutput> {DOUT-11}
----------------------------------------------------------
SET GPIO PIN
----------------------------------------------------------
----> GPIO CURRENT STATE: HIGH
----------------------------------------------------------
SLEEPING FOR 1 SECONDS
----------------------------------------------------------
----------------------------------------------------------
SET GPIO PIN
----------------------------------------------------------
----> GPIO CURRENT STATE: LOW
---------------------------------------------------------- 

This seems to work, but at the moment I don't have access to the hardware to measure the actual states on the I/O (I will verify it tomorrow).

Could this be a bug on the pi4j side?

taartspi commented 2 years ago

the question of whether the code functioned. It does, the code assumes iocon.bank = 0; Also, I strapped my 23017 chip address lines to ACK 0x22 Using i2cdump will probe file /dev/i2c-1, address 0x22, mode byte Continue? [Y/n] y 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 40:
After the code executes I will probe file /dev/i2c-1, address 0x22, mode byte Continue? [Y/n] y 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 10: 00 00 02 00 02 00 00 00 00 00 00 00 00 00 00 00 ..?.?........... Offset 0x12 GPIOA was updated to 02

taartspi commented 2 years ago

PS Had I reset the 23017 prior to running the example you would see the IODIR register was also modified.

tatery commented 2 years ago

@taartspi you are right, some settings in this provider are wrong, I've noticed that too. However, it works correctly after fixing the wrong settings (and context as mentioned https://github.com/savageautomate/pi4j-plugin-microchip/issues/1#issuecomment-954102491), of course.

savageautomate commented 2 years ago

@tatery

REF:

var pi4j = Pi4J.newContextBuilder().add( 
                MCP23017DigitalOutputProvider.newInstance(), 
                MCP23017DigitalInputProvider.newInstance(),
                LinuxFsI2CProvider.newInstance()).build();   <----- this is new compared to the previous settings

Yes, using this context builder example, there are no providers "automatically" detected but rather they are explicitly configured by the user code.

So in this case pi4j.i2c() was not able to return any valid providers because no I2C providers were loaded into the context.

savageautomate commented 2 years ago

@taartspi , @tatery

PS Had I reset the 23017 prior to running the example you would see the IODIR register was also modified.

This is not a surprise as I was coding it up without connecting to a real chip and just copying and pasting some code from the Pi4J v1 codebase. So its no surprise that some of its not right :-)

I would hope that we can work out all the correct registers to configure for each pin instance that is created and initialized. I hope a chip reset is not needed in the final version as that could be problematic. If a reset is somehow needed, then perhaps this can be performed once when the provider is first initialized (or after the call to setup is performed) and not for each pin provisioned.

Thanks, Robert

taartspi commented 2 years ago

Reset should not be needed. Normally the POR of turning on the Pi should do the trick. Or at least a single reset before starting any apps. In my case i had been running some other tests and the chip configured very different than POR

On Thu, Nov 4, 2021 at 11:49 PM Robert Savage @.***> wrote:

@taartspi https://github.com/taartspi , @tatery https://github.com/tatery

PS Had I reset the 23017 prior to running the example you would see the IODIR register was also modified.

This is not a surprise as I was coding it up without connecting to a real chip and just copying and pasting some code from the Pi4J v1 codebase. So its no surprise that some of its not right :-)

I would hope that we can work out all the correct registers to configure for each pin instance that is created and initialized. I hope a chip reset is not needed in the final version as that could be problematic. If a reset is somehow needed, then perhaps this can be performed once when the provider is first initialized (or after the call to setup is performed) and not for each pin provisioned.

Thanks, Robert

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/savageautomate/pi4j-plugin-microchip/issues/1#issuecomment-961625475, or unsubscribe https://github.com/notifications/unsubscribe-auth/AK5A32ZNRMJ5INR64WYVK7LUKNV47ANCNFSM5G42YXYQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

savageautomate commented 2 years ago

Reset should not be needed. Normally the POR of turning on the Pi should do the trick. Or at least a single reset before starting any apps. In my case i had been running some other tests and the chip configured very different than POR

Well in any case, it seems like we should be applying the necessary register settings to get the chip in the expected configuration for Pi4J to use it even if some other previous app configured it differently. Otherwise we will definitely hear about it from future users :-)