Nextion Display - Teil 5 - Direkt am Raspberry Pi nutzen

Mit ** gekennzeichne Links auf dieser Seite sind Affiliatelinks.

In den vorigen Teilen wurde immer nur mit einem Arduino gesprochen - das ist auch denkbar einfach. Immerhin gibt es dafür fertige Libraries und man kann direkt drauf los programmieren. Aber warum sollte man das Display nicht auch direkt für die Kommunikation mit einem Raspberry Pi verwenden können? Immerhin hat dieser auch eine serielle Schnittstelle über GPIO im Angebot, welche man dafür super nutzen kann. Mein Ziel war es dann, die Kommandos direkt aus Node-Red abzusetzen und entsprechende Touch-Events auch dort auszuwerten. Wie genau das geht, und was ich mir dabei gedacht habe, erfährst Du in diesem Video.

Was wird benötigt?

  • Eine Nextion-Display
  • Eine Micro-SD-Karte
  • Ein Raspberry Pi (3)
  • Eine Node-Red-Installation auf dem Raspberry Pi
  • Ein Windows PC oder eine virtuelle Maschine mit Windows (um die Oberfläche zu bauen)

Video

Arduino-Kurs

Serielle Schnittstelle

Wie schon im Video angesprochen, müssen wir erstmal die serielle Schnittstelle auf dem Raspberry Pi von der Konsole lösen. Im Standard ist es so vorgesehen, dass man darüber ebenfalls den Raspberry Pi direkt konfigurieren kann (wie man es z.B. auch von Managed Switches usw. kennt).

Um diesen "Ballast" loszuwerden, müssen ein paar Dateien bearbeitet werden. Als erstes muss die boot-config bearbeitet werden. Da wird ganz an das Ende einfach enable_uart=1 in eine neue Zeile geschrieben.

sudo vi /boot/config.txt

enable_uart=1

Ist dies erledigt, muss die cmdline-Konfiguration ebenfalls angepasst werden. Dazu wird der Teil mit console und serial0 komplett entfernt! serial0 ist eigentlich nur ein Symlink, welcher bei dem Raspberry Pi 3 aber auf genau die Schnittstelle zeigt, welche wir brauchen.

sudo vi /boot/cmdline.txt

console=serial0,115200

Danach den Raspberry Pi einmal neustarten.

sudo reboot

Dann musste ich noch ein paar weitere Befehle ausführen, um den Dienst für die Konsole von der seriellen Schnittstelle zu lösen. Wir nutzen auf dem Raspberry Pi 3 ttyS0. Warum? Weil die "Hardware-Serial" bereits von Bluetooth belegt wird. Auf einem Raspberry Pi 2 oder älter (also ohne Bluetooth) müssen die Befehle auf ACM0 abgeändert werden.

sudo systemctl mask serial-getty@ttyS0.service
sudo systemctl stop serial-getty@ttyS0.service
sudo systemctl disable serial-getty@ttyS0.service
sudo reboot

Fertig. Danach kann die Schnittstelle auch schon genutzt werden. Natürlich beim Anschließen der Kabel auch wieder darauf achten, dass RX und TX immer verdreht sind. Also ein Gerät sendet auf TX und das andere hört diesem auf RX zu.

Für die Stromversorgung des Displays kann einfach einer der 5V-Pins am Raspberry Pi verwendet werden. Dann noch Ground mit einem GND-Pin verbinden und schon kann es direkt in NodeRed weiter gehen!

Beispiel-Flow

Damit Du nicht auch verzweifelst um eine Kommunikation mit dem Display hinzubekommen, habe ich hier einmal einen Basis-Flow für Dich. Einfach importieren und als Grundlage nutzen. Dieser enthält (wie im Video gezeigt) schon eine fertige Node um z.B. den Buffer für die Kommunikation mit dem Display zusammen zu bauen.

[
    {
        "id": "d4e4079c.9dd598",
        "type": "tab",
        "label": "Flow 1",
        "disabled": false,
        "info": ""
    },
    {
        "id": "4be20f1a.b1e9d",
        "type": "serial in",
        "z": "d4e4079c.9dd598",
        "name": "Nextion",
        "serial": "f527860f.a985e8",
        "x": 330,
        "y": 400,
        "wires": [
            [
                "f1638733.61b278",
                "c28671c7.1c0be"
            ]
        ]
    },
    {
        "id": "fbe17560.e436c8",
        "type": "serial out",
        "z": "d4e4079c.9dd598",
        "name": "Nextion",
        "serial": "f527860f.a985e8",
        "x": 640,
        "y": 200,
        "wires": []
    },
    {
        "id": "778cdd99.1d8f24",
        "type": "function",
        "z": "d4e4079c.9dd598",
        "name": "Create Progress Message",
        "func": "msg.payload = 'jProgressBar.val=' + msg.payload;\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 170,
        "y": 160,
        "wires": [
            [
                "fb3a7104.93817"
            ]
        ]
    },
    {
        "id": "fb3a7104.93817",
        "type": "function",
        "z": "d4e4079c.9dd598",
        "name": "Create Buffer",
        "func": "var textBuf = Buffer.from(msg.payload, 'ascii');\nvar postFixBuf = new Buffer(\"FFFFFF\", \"hex\");\n\nmsg.payload = Buffer.concat([textBuf, postFixBuf]);\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 490,
        "y": 200,
        "wires": [
            [
                "fbe17560.e436c8"
            ]
        ]
    },
    {
        "id": "f1638733.61b278",
        "type": "function",
        "z": "d4e4079c.9dd598",
        "name": "Extract Button ID",
        "func": "msg.payload = Number(msg.payload[2]);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 510,
        "y": 400,
        "wires": [
            [
                "47c6ef91.5cfc3"
            ]
        ]
    },
    {
        "id": "47c6ef91.5cfc3",
        "type": "switch",
        "z": "d4e4079c.9dd598",
        "name": "Which Button",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "1",
                "vt": "num"
            },
            {
                "t": "eq",
                "v": "2",
                "vt": "num"
            },
            {
                "t": "eq",
                "v": "3",
                "vt": "num"
            },
            {
                "t": "eq",
                "v": "4",
                "vt": "num"
            },
            {
                "t": "eq",
                "v": "6",
                "vt": "num"
            }
        ],
        "checkall": "false",
        "repair": false,
        "outputs": 5,
        "x": 720,
        "y": 400,
        "wires": [
            [
                "5e98107f.1710f"
            ],
            [
                "f08a77ac.10a9c8"
            ],
            [
                "d9b647de.c34dd8"
            ],
            [
                "955a95d9.7f8928"
            ],
            [
                "3ec5fc47.28afd4"
            ]
        ],
        "outputLabels": [
            "Licht Links",
            "Licht Rechts",
            "Drucker Links",
            "Drucker Rechts",
            "Stop"
        ]
    },
    {
        "id": "f08a77ac.10a9c8",
        "type": "function",
        "z": "d4e4079c.9dd598",
        "name": "Payload tauschen",
        "func": "if (flow.get(\"ro\") == 1) {\n    msg.payload = 0;\n} else {\n    msg.payload = 1;\n}\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 990,
        "y": 360,
        "wires": [
            []
        ]
    },
    {
        "id": "5e98107f.1710f",
        "type": "function",
        "z": "d4e4079c.9dd598",
        "name": "Payload tauschen",
        "func": "if (flow.get(\"lo\") == 1) {\n    msg.payload = 0;\n} else {\n    msg.payload = 1;\n}\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 990,
        "y": 320,
        "wires": [
            []
        ]
    },
    {
        "id": "d9b647de.c34dd8",
        "type": "function",
        "z": "d4e4079c.9dd598",
        "name": "Payload tauschen",
        "func": "if (flow.get(\"lu\") == 1) {\n    msg.payload = 0;\n} else {\n    msg.payload = 1;\n}\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 990,
        "y": 400,
        "wires": [
            []
        ]
    },
    {
        "id": "955a95d9.7f8928",
        "type": "function",
        "z": "d4e4079c.9dd598",
        "name": "Payload tauschen",
        "func": "if (flow.get(\"ru\") == 1) {\n    msg.payload = 0;\n} else {\n    msg.payload = 1;\n}\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 990,
        "y": 440,
        "wires": [
            []
        ]
    },
    {
        "id": "3ec5fc47.28afd4",
        "type": "function",
        "z": "d4e4079c.9dd598",
        "name": "Payload tauschen",
        "func": "msg.payload = 1;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 990,
        "y": 480,
        "wires": [
            []
        ]
    },
    {
        "id": "c28671c7.1c0be",
        "type": "debug",
        "z": "d4e4079c.9dd598",
        "name": "Nextion-Event",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "x": 500,
        "y": 360,
        "wires": []
    },
    {
        "id": "c5e71d37.1ab5e",
        "type": "comment",
        "z": "d4e4079c.9dd598",
        "name": "Button 1 (Oben Links)",
        "info": "",
        "x": 1200,
        "y": 320,
        "wires": []
    },
    {
        "id": "fd55da06.8885a8",
        "type": "comment",
        "z": "d4e4079c.9dd598",
        "name": "Button 2 (Oben Rechts)",
        "info": "",
        "x": 1200,
        "y": 360,
        "wires": []
    },
    {
        "id": "99240dba.2103a",
        "type": "comment",
        "z": "d4e4079c.9dd598",
        "name": "Button 3 (Unten Links)",
        "info": "",
        "x": 1200,
        "y": 400,
        "wires": []
    },
    {
        "id": "fa1921b3.bca5e",
        "type": "comment",
        "z": "d4e4079c.9dd598",
        "name": "Button 4 (Unten Rechts)",
        "info": "",
        "x": 1200,
        "y": 440,
        "wires": []
    },
    {
        "id": "2dda2f9a.1b09",
        "type": "comment",
        "z": "d4e4079c.9dd598",
        "name": "Button 5 (Stop unten)",
        "info": "",
        "x": 1200,
        "y": 480,
        "wires": []
    },
    {
        "id": "2c26e4b2.6fe67c",
        "type": "inject",
        "z": "d4e4079c.9dd598",
        "name": "Display dunkler",
        "topic": "",
        "payload": "dim=0",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 140,
        "y": 200,
        "wires": [
            [
                "fb3a7104.93817"
            ]
        ]
    },
    {
        "id": "a045253d.0fa958",
        "type": "inject",
        "z": "d4e4079c.9dd598",
        "name": "Display hell",
        "topic": "",
        "payload": "dim=100",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 130,
        "y": 240,
        "wires": [
            [
                "fb3a7104.93817"
            ]
        ]
    },
    {
        "id": "f527860f.a985e8",
        "type": "serial-port",
        "z": "",
        "serialport": "/dev/ttyS0",
        "serialbaud": "9600",
        "databits": "8",
        "parity": "none",
        "stopbits": "1",
        "newline": "100",
        "bin": "bin",
        "out": "interbyte",
        "addchar": false,
        "responsetimeout": ""
    }
]

Newsletter

Trage Dich jetzt in den Newsletter ein und genieße dadurch viele Vorteile:

  • 5€-Gutschein als Dankeschön
  • Zugang zu exklusiven Inhalten
  • Rabattaktionen für Kurse
  • Angebote für Produkte

* Durch Angabe meiner E-Mail-Adresse erkläre ich mich damit einverstanden, dass mir regelmäßig Informationen und Produktempfehlungen aus dem Fachgebiet Smart Home zugesendet werden. Mit dem Eintrag akzeptieren Sie unsere Datenschutzbestimmungen. Meine Einwilligung kann ich jederzeit widerrufen.

Matthias Kleine

Matthias Kleine

Großer Fan und Anhänger von OpenSource-Projekten und erweiterbaren Haus-Automatisierungskomponenten. Je offener und flexibler das System, desto besser. Ich lege mich ungern auf einzelne Protokolle oder Standards fest, sondern probiere aus allen Welten das Beste zu verheiraten. Unterwegs als Softwareentwickler, Trainer und Blogger im Bereich Smart Home.

Auf YouTube und hier im Blog gibt es bereits unzählige kostenlose Videos, Informationen und Tutorials. Wenn Dir das noch nicht reicht, ist ein Training genau das richtige für Dich! Die folgenden Trainings haben den Vorteil, dass immer von Anfang an gestartet wird und Du ohne Vorwissen teilnehmen kannst.