pi4j 2.0 Neuerungen

matze86

Bekanntes Mitglied
Hallo, vor einiger zeit hatte ich das Thema Java mit dem pi4j aufgemacht wie das mit einer Matrix funktioniert.
Das hatte alles funktioniert. Allerdings war das alles in Version 1.x. Jetzt mache ich es über Maven und pi4j 2.0.

wenn ich den alten Code nehme, kann man schon gar nicht "com.pi4j.io.spi.SpiDevice;" importen.
Das scheint es in 2.0 nicht zu geben.
Die Seite zeigt ja alles, aber jetzt kann ich nicht "spi.SpiDevice" oder "spi.SpiFactory" setzen.
Wie sieht das jetzt bei 2.0 aus? Was muss in den Parameter bei dem Konstruktor 'spi' übergeben werden?
 

matze86

Bekanntes Mitglied
Ich habe vor, das ganze erst mal in einer Klasse zu machen.
Laut der Klasse "MAX7219" muss der Konstruktor
Java:
 public MAX7219(Spi spi) {
        this.spi = spi;

mit Werten für Spi gefüttert werden. In dem verlinkten Beispiel von @mihe7 lautet der Konstruktor
Java:
public LedMatrixComponent(Context pi4j) {
        this(pi4j, DEFAULT_CHANNEL, DEFAULT_BAUD_RATE);

Wie muss ich vorgehen, damit ich das in einer Klasse verwirklichen kann?

Bei dem Thread im #35 mussten nur die importierten Klassen wie "SpiDevice device" nur angepasst werden.
 

mihe7

Top Contributor
Wenn Du den Code mal verfolgst, kommst Du irgendwann zu
Java:
       return Pi4J.newContextBuilder()
            .noAutoDetect()
            .add(new CrowPiPlatform())
            .add(
                PiGpioDigitalInputProvider.newInstance(piGpio),
                PiGpioDigitalOutputProvider.newInstance(piGpio),
                PiGpioPwmProvider.newInstance(piGpio),
                PiGpioI2CProvider.newInstance(piGpio),
                PiGpioSerialProvider.newInstance(piGpio),
                PiGpioSpiProvider.newInstance(piGpio)
            )
            .build();
Frag mich nicht, was CrowPiPlatform ist. Da musst Du ein bisschen recherchieren.
 

matze86

Bekanntes Mitglied
OK, ist natürlich viel schwieriger als die Version von 1.4.
Andere Frage, kann man das auch weg lassen und default einstellen?
 

matze86

Bekanntes Mitglied
Ich habe nochmal das ganze angeschaut, das erscheint mir zu kompliziert mit Version 2.x. Bei der Version 1.4 war es viel einfacher. Da hat man mit normalen Raspbian x Zugriff auf das ganze bekommen. Jetzt muss man CrowPi nutzen, was auch immer das ist.
Mir geht es darum, das ich mit der Matrix mein Java Wissen zu erweitern und zu spielen neben mein Java Lehrgang.
Aber wenn ich noch 150 Stunden damit verbringe um zu wissen wie man das ohne dieses CrowPi macht bringt es mir nix.

Spricht was dagegen, wenn ich es mit der Version 1.4 weiter mache?
 

mihe7

Top Contributor
Naja, es ist halt eine alte Version. Abgesehen davon: die Doku bezieht sich doch auf v2, d. h. das sollte doch eigentlich das kleinere Übel darstellen :) Lt. Doku scheint CrowPi irgendein elektronisches Pi-Kit zu sein, brauchst Du also nicht.

Lt. Doku sollte ebenfalls ein Pi4J.newAutoContext() reichen:
https://pi4j.com/getting-started/minimal-example-application/ hat gesagt.:
The ‘newAutoContext()’ method will automatically load all available Pi4J extensions found in the application’s classpath which may include ‘Platforms’ and ‘I/O Providers’.

Wenn du willst, kann ich mal versuchen, ein Projekt mit einer IDE zu bauen, nur testen kann ich es nicht.
 

matze86

Bekanntes Mitglied
Ich habe mir auf die schnelle was zusammengebaut, aber das funktioniert (noch) nicht. Fehler gibt es keine aber es tut nicht was es soll. Hier der Code:
Java:
import com.pi4j.Pi4J;
import com.pi4j.io.spi.Spi;
import com.pi4j.io.spi.SpiConfig;
import java.io.IOException;
import com.pi4j.context.Context;

public class Matrix {


    public static void main(String[] args) throws InterruptedException, IOException{
        var pi4j = Pi4J.newAutoContext();
        Max7219 neu = new Max7219(pi4j.create(buildSpiConfig(pi4j, 0, 8000000)));
        System.out.println("hello");

        neu.initial();
        neu.aus();
        
        neu.execute((byte)0, (byte)129);
//        neu.execute((byte)0x0c, (byte)0x00);
        
        
    }
    private static SpiConfig buildSpiConfig(Context pi4j, int channel, int baud) {
        return Spi.newConfigBuilder(pi4j)
            .id("SPI" + channel)
            .name("LED Matrix")
            .address(channel)
 //           .baud(baud)
            .build();}
}

class Max7219{
    protected final Spi spi;
    public Max7219(Spi spi) {
        this.spi = spi;}
    
    
     void initial() throws IOException, InterruptedException{ // hier wird alles initialisiert
        execute((byte) 0x09, (byte) 0x00); // decode mode
        execute((byte)0x0a, (byte)15); // intensität 1-15
        execute((byte)0x0b, (byte)0x07); // scan limit, 07 ist stehet fuer 8 Reihen
        execute((byte)0x0c, (byte)0x01); // steht fuer shutdown, 01 ist normal mod
        execute((byte)0x0f, (byte)0x00); //display test, 00 ist aus
    }
    
    
     void aus()  throws IOException, InterruptedException{  //schaltet erst einmal alles aus
        int end = 8;
        for (int i = 1; i <=end; i++) {
            spi.write((byte)i, (byte)0);
        System.out.println(i);}
        }
     public void execute(byte command, byte data) {
            spi.write(command, data);
    
    
    
    
}
}
 

matze86

Bekanntes Mitglied
Aber leider macht meine Matrix nix. Ist der Code deiner Meinung her grundlegend richtig?
Hier mal ein funktionierender Code von Version 1.4 zum Vergleich.
Java:
import com.pi4j.io.spi.SpiChannel;
import com.pi4j.io.spi.SpiDevice;
import com.pi4j.io.spi.SpiFactory;
import com.pi4j.util.Console;

import java.io.IOException;

public class MatrixOne {

    static void initial(SpiDevice spi) throws IOException, InterruptedException{ // hier wird alles initialisiert
        spi.write((byte) 0x09, (byte) 0x00); // decode mode
        spi.write((byte)0x0a, (byte)15); // intensität 1-15
        spi.write((byte)0x0b, (byte)0x07); // scan limit, 07 stehet fuer 8 Reihen
        spi.write((byte)0x0c, (byte)0x01); // steht fuer shutdown, 01 ist normal mod
        spi.write((byte)0x0f, (byte)0x00); //display test, 00 ist aus
    }
       
    static void aus(SpiDevice spi) throws IOException, InterruptedException{  //schaltet erst einmal alles aus
        int end = 8;
        for (int i = 1; i <=end; i++) {
            spi.write((byte)i, (byte)0);
        System.out.println(i);}
        }
   
    public static void main(String[] args) throws InterruptedException, IOException{
        SpiDevice spi = SpiFactory.getInstance(SpiChannel.CS0,
                SpiDevice.DEFAULT_SPI_SPEED, // default spi speed 1 MHz
                SpiDevice.DEFAULT_SPI_MODE); // default spi mode 0
        initial(spi);
        aus(spi);


        // LED anknipsen
        spi.write((byte)1, (byte)129); //1. Reihe 8. und 1. LED
        spi.write((byte)7, (byte)4); //7. Reihe 3. LED
        spi.write((byte)8, (byte)64);//8. Reihe 7. LED
        spi.write((byte)3, (byte)(1 << 5));
       
    }

}
 

mihe7

Top Contributor
Ich habe mir den Code zu Spi angesehen, da gibts Methoden open() und close() - kann aber durchaus sein, dass die vom Framework automatisch aufgerufen werden. Wenn im Beispielcode nichts drin ist, wird man es nicht brauchen.
 

matze86

Bekanntes Mitglied
Ja genau, die Methoden habe ich auch gesehen.
Das ganze habe ich nochmal unter 1.4 ausgeführt, da funktioniert es.
Ich denke mal es liegt an der Methode "buildSpiConfig" in meinen Code. Das da irgendwelche Fehler bzw. andere Werte eingetragen werden müssen.
 

matze86

Bekanntes Mitglied
Ich habe mal bei dem Entwickler gefragt, er meint ich soll "newAutoContext() " durch den PiGpio-Provider ersetzen siehe unten im code ,er verwies darauf.

Java:
return Pi4J.newContextBuilder()
            .noAutoDetect()
            .add(new CrowPiPlatform())
            .add(
                PiGpioDigitalInputProvider.newInstance(piGpio),
                PiGpioDigitalOutputProvider.newInstance(piGpio),
                PiGpioPwmProvider.newInstance(piGpio),
                PiGpioI2CProvider.newInstance(piGpio),
                PiGpioSerialProvider.newInstance(piGpio),
                PiGpioSpiProvider.newInstance(piGpio)
            )
            .build();
    }
Wie muss ich das in meinen Code verstehen?
 

mihe7

Top Contributor
Keine Ahnung, wenn ich es richtig sehe, müsste man eigentlich etwas schreiben wie:
Java:
var pi4J = Pi4J.newContextBuilder()
        .noAutoDetect()
        .add(new RaspberryPiPlatform())
        .add(
            RpiSpiProvier.newInstance()
        )
        .build();

Aber hast du mal das Minimalbeispiel laufen lassen?
 

matze86

Bekanntes Mitglied
Ja mit den GPIO output hat funktioniert.
Da ist der Funktionierende Code:
Java:
import com.pi4j.Pi4J;

import com.pi4j.io.gpio.digital.DigitalOutput;
import com.pi4j.io.gpio.digital.DigitalState;
import com.pi4j.io.gpio.digital.PullResistance;
import com.pi4j.util.Console;
import com.pi4j.Pi4J;
import com.pi4j.io.IOType;
import com.pi4j.io.gpio.digital.DigitalOutput;
import com.pi4j.io.gpio.digital.DigitalOutputConfig;
import com.pi4j.io.gpio.digital.DigitalOutputProvider;
import com.pi4j.io.gpio.digital.DigitalStateChangeListener;
import com.pi4j.platform.Platform;

import java.util.concurrent.TimeUnit;


public class Gpio{

 
    public static final int PIN_LED = 18;

    public static void main(String[] args) throws InterruptedException {
        var pi4j = Pi4J.newAutoContext();
        var ledConfig = DigitalOutput.newConfigBuilder(pi4j)
                  .id("led")
                  .name("LED Flasher")
                  .address(PIN_LED)
                  .shutdown(DigitalState.LOW)
                  .initial(DigitalState.LOW)
                  .provider("pigpio-digital-output");
        var led = pi4j.create(ledConfig);   
        
        System.out.println("ein");
        led.high();
            
        Thread.sleep(5000);
        led.low();
        System.out.println("ein");
        pi4j.shutdown();
    
}}
 

mihe7

Top Contributor
Mich hätten mehr die Zeilen interessiert, die Du rausgelöscht/nicht übernommen hast :) Die Bildschirmausgabe der Provider etc. :)
 

matze86

Bekanntes Mitglied
Nach vielen testen habe ich es hinbekommen.

Hier ist der Code. Falls noch Verbesserungsvorschläge gibt, dann immer zu.

Java:
import com.pi4j.Pi4J;
import com.pi4j.io.spi.Spi;
import com.pi4j.io.spi.SpiConfig;
import java.io.IOException;
import com.pi4j.context.Context;
import com.pi4j.library.pigpio.PiGpio;
import com.pi4j.plugin.pigpio.provider.gpio.digital.PiGpioDigitalInputProvider;
import com.pi4j.plugin.pigpio.provider.gpio.digital.PiGpioDigitalOutputProvider;
import com.pi4j.plugin.pigpio.provider.i2c.PiGpioI2CProvider;
import com.pi4j.plugin.pigpio.provider.pwm.PiGpioPwmProvider;
import com.pi4j.plugin.pigpio.provider.serial.PiGpioSerialProvider;
import com.pi4j.plugin.pigpio.provider.spi.PiGpioSpiProvider;


public class Matrix {


    public static void main(String[] args) throws InterruptedException, IOException{
        final var piGpio = PiGpio.newNativeInstance();
        var pi4j = Pi4J.newContextBuilder()
                .noAutoDetect()
                .add(
                    PiGpioDigitalInputProvider.newInstance(piGpio),
                    PiGpioDigitalOutputProvider.newInstance(piGpio),
                    PiGpioPwmProvider.newInstance(piGpio),
                    PiGpioI2CProvider.newInstance(piGpio),
                    PiGpioSerialProvider.newInstance(piGpio),
                    PiGpioSpiProvider.newInstance(piGpio)
                )
                .build();
      
        Max7219 neu = new Max7219(pi4j.create(buildSpiConfig(pi4j, 0, 8000000)));//(buildSpiConfig(pi4j, 0, 8000000)));
        System.out.println("hhello");
        neu.initial();
        neu.aus();
        neu.execute((byte)1, (byte)129); 
    }
  
  
    private static SpiConfig  buildSpiConfig(Context pi4j, int channel, int baud) {
        return Spi.newConfigBuilder(pi4j)
            .id("SPI" + channel)
            .name("Matrix")
            .address(channel)
            .baud(baud)
            .build();}
}

class Max7219{
    protected final Spi spi;
    public Max7219(Spi spi) {
        this.spi = spi;}
  
  
  
     void initial() throws IOException, InterruptedException{ // hier wird alles initialisiert
        execute((byte) 0x09, (byte) 0x00); // decode mode
        execute((byte)0x0a, (byte)15); // intensität 1-15
        execute((byte)0x0b, (byte)0x07); // scan limit, 07 ist stehet fuer 8 Reihen
        execute((byte)0x0c, (byte)0x01); // steht fuer shutdown, 01 ist normal mod
        execute((byte)0x0f, (byte)0x00); //display test, 00 ist aus
    }
  
  
     void aus()  throws IOException, InterruptedException{  //schaltet erst einmal alles aus
        int end = 8;
        for (int i = 1; i <=end; i++) {
            execute((byte)i, (byte)0);
            System.out.println("nuna" + i);}
        }
     public void execute(byte command, byte data){
         spi.write(command, data);
        
}
}

Anbei noch eine Frage, man liest im Beispielcoden immer von Bufferungen, was hat das auf sich?
 

mihe7

Top Contributor
Anbei noch eine Frage, man liest im Beispielcoden immer von Bufferungen, was hat das auf sich?
Dazu müsste man den genauen Kontext kennen. Ein Buffer ist ein Zwischenspeicher. Wenn Du an Deine Matrix denkst, dann hatten wir das damals (wenn ich mich recht entsinne) so gemacht, dass die Werte der LEDs gepuffert (buffered) waren. Damit konnte man einzelne LEDs ansprechen, obwohl an das Bauteil die komplette Zeile übertragen wurde.
 

matze86

Bekanntes Mitglied
Ich habe den Code nochmal angepasst und das unnötige raus geschmissen. Hier jetzt der minimal-Code.
Vielleicht braucht es ja jemand.
Java:
import com.pi4j.Pi4J;
import com.pi4j.io.spi.Spi;
import com.pi4j.io.spi.SpiConfig;
import java.io.IOException;
import com.pi4j.context.Context;
import com.pi4j.library.pigpio.PiGpio;
import com.pi4j.plugin.pigpio.provider.spi.PiGpioSpiProvider;


public class Matrix {


    public static void main(String[] args) throws InterruptedException, IOException{
        final var piGpio = PiGpio.newNativeInstance();
        var pi4j = Pi4J.newContextBuilder()
                .noAutoDetect()
                .add(
                    PiGpioSpiProvider.newInstance(piGpio)
                )
                .build();
       
        Max7219 neu = new Max7219(pi4j.create(buildSpiConfig(pi4j, 0, 8000000))); //Baudrate eventuell anpassen
        System.out.println("hello");
        neu.initial();
        neu.aus();
        neu.execute((byte)1, (byte)129); //Reihe 1 LED 
        neu.execute((byte)4, (byte)68); // Reihe 4 LED  2 und 6
        neu.execute((byte)7, (byte)68); // Reihe 7 LED 2 und 6
    }
   
   
    private static SpiConfig  buildSpiConfig(Context pi4j, int channel, int baud) {
        return Spi.newConfigBuilder(pi4j)
            .id("SPI" + channel)
            .name("Matrix")
            .address(channel)
            .baud(baud)
            .build();}
}

class Max7219{
    protected final Spi spi;
    public Max7219(Spi spi) {
        this.spi = spi;}
   
   
   
     void initial() throws IOException, InterruptedException{ // hier wird alles initialisiert
        execute((byte) 0x09, (byte) 0x00); // decode mode
        execute((byte)0x0a, (byte)1); // intensität 1-15
        execute((byte)0x0b, (byte)0x07); // scan limit, 07 ist stehet fuer 8 Reihen
        execute((byte)0x0c, (byte)0x01); // steht fuer shutdown, 01 ist normal mod
        execute((byte)0x0f, (byte)0x00); //display test, 00 ist aus
    }
   
   
     void aus()  throws IOException, InterruptedException{  //schaltet erst einmal alles aus
        int end = 8;
        for (int i = 1; i <=end; i++) {
            execute((byte)i, (byte)0);
            System.out.println("Reihe" + i);}
        }
     public void execute(byte command, byte data){
         spi.write(command, data);
     }
}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A Neuerungen in Java 8 StreamAPI- Paar fragen Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben