RPi Starwars Uhr mit Internetradio

43176914545393888441054441454726041099

Eine kleine RPi-Zero (5€ Minicomputer) Uhr die die aktuelle Uhrzeit in der Mitte anzeigt und bei Wechsel wie im StarWars Vorspann raus und wieder einfliesst.

Wenn man Internetzeit als Sync benutzen möchte kann man auch gleich ein Internetradio daraus bauen, ansonsten bieten sich Diverse RealTimeClocks an.

Das ganze basiert auf einem Headless-Linux (ohne HDMI Bildschirm und Grafik) Debian Wheezy mit installiertem Java8 und einer JavaFX Animation. Das Elektronik SPI-Interface Display ist über die IOs mit dem FBTFT Framebuffer Treiber eingebunden.

Als Internetradio App habe ich MPD ohne Grafikoberfläche gewählt, dafür gibt es viele Apps in den Android und IPhone Stores.

  • Basiert auf Rapbian Wheezy ohne DesktopManager, deinstalliertem LightDM, Java8FX Engine schreibt JavaFX direkt in den Framebuffer.

    Gute Anleitung als Grundlage, im Endeffekt einfach zu lang http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/RaspberryPiFX/raspberryfx.html

    EDIT /boot/config.txt ähnlich:

    # uncomment to force a specific HDMI mode (this will force VGA)
    hdmi_group=2
    hdmi_mode=87
    hdmi_cvt=320 240 60 1 0 0 0
    # uncomment to force a HDMI mode rather than DVI. This can make audio work in
    # DMT (computer monitor) modes
    #hdmi_drive=2
    
    # uncomment to increase signal to HDMI, if you have interference, blanking, or
    # no display
    #config_hdmi_boost=4
    
    # uncomment for composite PAL
    #sdtv_mode=2
    
    
    # Uncomment some or all of these to enable the optional hardware interfaces
    #dtparam=i2c_arm=on
    #dtparam=i2s=on
    dtparam=spi=on

     

  • 2

    Installiere fbcp um den Main Framebuffer zum LCD-Framebuffer zu kopieren.

         sudo apt-get install cmake git
         git clone https://www.github.com/tasanakorn/rpi-fbcp
         cd rpi-fbcp/
         mkdir build
         cd build
         cmake ..
         make
         install fbcp /usr/local/bin/fbcp
  • 3

    Erstelle start.sh zum Beispiel:

    #!/bin/sh
    #On Staging kernel not needed
    #sudo modprobe fbtft dma
    
    #Example for hy28B
    sudo modprobe fbtft_device name=hy28b fbtft_device.speed=3000000 rotate=90 fbtft_device.fps=20
    sleep 10
    fbcp&
    JAVAFX_DEBUG=1 java -Dcom.sun.javafx.experimental.embedded.3d=true -Dprism.glDepthSize=16 -jar /home/pi/StarWars.jar
    

     

    Update Kernel mit rpi-update:

    rpi-update
    reboot
    REPO_URI=https://github.com/notro/rpi-firmware rpi-update
    reboot
  • 5

    Downloade Java8 JDKu71 für ARM und extrahiere die Dateien. Exportiere gegebenfalls Deinen Javapath  EXPORT PATH zu opt/jdkXXX/bin

    sudo tar zxvf jdk-8u71-linux-arm32-vfp-hflt.tar.gz -C /opt/
    mv /opt/jdk1.8.0_71/ /opt/jdk1.8.0
  • 6 Kompiliere das StarWars JavaFX Script und kopiere das Hintergrundbild StarWars.jpg in den gleichen Ordner /Projektpfad :
    import java.io.File;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javafx.animation.Animation;
    import javafx.animation.Animation.Status;
    import javafx.animation.Interpolator;
    import javafx.animation.KeyFrame;
    import javafx.animation.KeyValue;
    import javafx.animation.PauseTransition;
    import javafx.animation.SequentialTransition;
    import javafx.animation.Timeline;
    import javafx.animation.TranslateTransition;
    import javafx.application.Application;
    import static javafx.application.Application.launch;
    import javafx.concurrent.Service;
    import javafx.concurrent.Task;
    import javafx.concurrent.WorkerStateEvent;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.geometry.Point3D;
    import javafx.scene.Group;
    import javafx.scene.PerspectiveCamera;
    import javafx.scene.Scene;
    import javafx.scene.image.Image;
    import javafx.scene.image.ImageView;
    import javafx.scene.paint.Color;
    import javafx.scene.text.Font;
    import javafx.scene.text.FontPosture;
    import javafx.scene.text.Text;
    import javafx.scene.text.TextAlignment;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
    import javafx.util.Duration;
    
    public class TextCrawler extends Application {
    
        private static final String crawl = "22:24";
    
        @Override
        @SuppressWarnings("empty-statement")
        public void start(Stage stage) throws Exception {
            
            Group root = new Group();
            root.setTranslateX(160);
            root.setTranslateY(120);
          
    ImageView background = new ImageView(new Image("StarWars.jpg", 320, 240, false, true));
    background.relocate(-160, -120);
    root.getChildren().add(background);
    File file = new File("starfield.css"); 
      root.getStylesheets().add(file.toURI().toURL().toExternalForm());  
    
             //   root.setStyle("-fx-background-image: url('StarWars.jpg')");  
            Scene scene = new Scene(root);
            scene.setCamera(new PerspectiveCamera());
            //scene.setFill(Color.BLACK);
         
            stage.setScene(scene);
            stage.setWidth(320);
            stage.setHeight(240);
            stage.initStyle(StageStyle.UNDECORATED);
     
          
            Text text = new Text(getCurrentTimeStamp());
            text.setTextAlignment(TextAlignment.CENTER);
            text.setFill(Color.YELLOW);
            text.setFont(Font.font("Arial", FontPosture.REGULAR, 100));
            text.setRotationAxis(new Point3D(1.0, 0.0, 0.0));
            text.setRotate(-50.0);
            text.setTranslateX(-text.getLayoutBounds().getWidth() / 2);
            root.getChildren().add(text);
            stage.show();
    
            TranslateTransition trans = new TranslateTransition(Duration.millis(20_000), text);
            trans.setFromY(500);//500
            trans.setFromZ(-1_000);
            trans.setToY(-500);
            trans.setToZ(1000);//1000
            trans.setInterpolator(Interpolator.LINEAR);
    //        trans.setCycleCount(Animation.INDEFINITE);
            trans.setCycleCount(0);
    
          
            trans.setOnFinished(new EventHandler<ActionEvent>() {
    
                @Override
                public void handle(ActionEvent event) {
                                 text.setText(getCurrentTimeStamp());
                      Task<Void> sleeper = new Task<Void>() {
                @Override
                protected Void call() throws Exception {
                    try {
                        Thread.sleep(9500);
    
                    } catch (InterruptedException e) {
                    }
                    return null;
                }
            };
                   sleeper.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
                @Override
                public void handle(WorkerStateEvent event) {
                    
                    trans.pause();
                    try {
                        Thread.sleep(50000);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(TextCrawler.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    trans.play();
                }
            });
                    new Thread(sleeper).start();
                    trans.play();
                }
            });
     
    
            trans.play();
    
        }
    
        public static void main(String... args) {
            launch(args);
        }
    
        public String getCurrentTimeStamp() {
            return new SimpleDateFormat("HH:mm").format(new Date());
        }
    
        private void Runnable() {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
    }
    
    
    
  • 7

    Die Uhr mit dem Raspi starten:

     sudo nano /etc/rc.local
    
    EDIT:
    
    sudo -u pi sh /home/pi/start.sh
    
    BEFORE:
    
    exit 0

     

 

 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.

Denkhilfe *

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.