Digitales Prototyping: Raspberry Pi: Motion, Webserver, P5-Datenvisualisierung / 2019-06-06 / Matthias Edler-Golla, CC BY-SA 4.0


|



 



Themen heute

Raspberry Pi

  • Raspi als Webserver
  • Automatische Bildergalerie mit PHP
  • Motion: Livestream der Kamera
  • Livestream innerhalb einer Website
  • Arduino-Helligkeiswerte in CSV-Datei einlesen
  • CSV-Dateien: Werte abfragen
  • p5.js zur Darstellung von CSV-Werten
  • p5.js zur Darstellung der aktuellen Helligkeitswerte

Raspberry Pi als Webserver

Webadresse im „raspi_net“

Um im Browser die Sachen aus dem Ordner /var/www/html angezeigt zu bekommen, müsst Ihr die IP-Adresse eingeben, mit der Ihr Euch auch via SSH verbindet, also z.B. http://192.168.0.100/

http://192.168.0.100/

Kein direkter Zugriff via SFTP (Cyberduck)

Weil Ihr Euch via Cyberduck als User „pi“ mit dem Raspi verbindet, könnt Ihr Eure Sachen nicht direkt in den Ordner /var/www/html kopieren. Stattdessen müsst Ihr diese zuerst in den Ordner /home/pi/ via Cyberduck kopieren und von dort an die richtige Stelle verschieben:

cd /home/pi/
sudo mv -r EureSachenOrdner /var/www/html

Website editieren

Ihr könnt die Startseite index.html direkt auf dem Raspi editieren – probiert es doch mal aus:

cd /var/www/html
sudo nano index.html

tragt doch dort mal Euren Namen zwischen den Tags <body> und </body> ein, sichert das Dokument und schaut, ob Euer Name im Browser sichtbar wird!


Automatische Bildergalerie mit PHP

PHP ist eine Skriptsprache mit einer an C und Perl angelehnten Syntax, die hauptsächlich zur Erstellung dynamischer Webseiten oder Webanwendungen verwendet wird.

ImageMagick

Die Bilder habe ich davor mit ImageMagick und den Bash-Script thumbnails.sh heruntergerechnet – siehe dazu mein Script!

PHP hilft einem, z.B. die Darstellung von vielen Bildern innerhalb einer Galerie zu automatisieren: Das hier verwendete Script untersucht automatisch den gewünschten Ordner und stellt alle dort gefundenen Bilder auf einer Website dar. Es generiert darüber auch automatisch alle Links zu den (größeren) Bildern, die dann in einem Popup gezeigt werden können.

PHP7 habe ich auf den Raspis installiert. Es kann direkt in den HTML-Code eingefügt werden – die Datei muss dann jedoch die Endung *.php haben und auf einem Server (wie z.B. dem Raspi) ausgeführt werden.

HTML mit PHP

<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bildergalerie mit aufspringenden Großbildern</title>
    <link rel="stylesheet" href="assets/c/style.css">
    <!-- das spezielle Stylesheet fürs Popup -->
    <link rel="stylesheet" href="assets/c/magnific-popup.css">
</head>

<body>

    <h1>Bildergalerie mit aufspringenden Großbildern</h1>

    <main>

    <?php
        // Aufruf des PHP-Scripts zum autom. Darstellen aller Bilder

        $thumbs = 'p/Thumbs'; // rel. Pfadangabe zum Ordner mit den Thumbnails
        $gross = 'p/Gross'; // rel. Pfadangabe zum Ordner mit den großen Bildern

        // externes php-script zum autom. Einfüegen von Bilder aus de oben genannten Ordnern
        include 'assets/phpScripts/galerie.php';  
    ?>

    </main>

    <script src="assets/js/jquery-3.2.1.min.js"></script>
    <script src="assets/js/jquery.magnific-popup.min.js"></script>
    <script src="assets/js/script.js"></script>

</body>
</html>

Schaut Euch den Code von assets/phpScripts/galerie.php an, dort sind einige Kommentare enthalten, was das Script macht…

Online ausprobieren

Gerne könnt Ihr das komplette Paket herunterladen und auf dem Raspi installieren!

Dazu die gezippte Datei erst via Cyberduck auf den Raspi in „/home/pi“ kopieren und von dort im Terminal an die richtige Stelle verschieben:

sudo mv /home/pi/Bildergalerie.zip /var/www/html/

Die gezippte Dateien noch entpacken:

sudo unzip -a Bildergalerie.zip

Zip-Datei noch löschen

sudo rm Bildergalerie.zip

Testen im Browser

Damit das funktioniert, müsst Ihr wieder die richtige IP Eures Raspis wissen und damit folgende URL zusammenbauen:

 z.B. http://192.168.0.100/ + Bildergalerie

Motion: Livestream der Kamera

Anschließen der Kamera

Bitte beachtet beim Anschliessen der Kamera, dass der Raspi ausgeschaltet ist! Ein detaillierte Anweisung zum Anschließen findet Ihr im letzten Script.

Motion

Mit Motion könnt Ihr die Kamera des Raspis nutzen, um live Videos zu streamen!

Starten von Motion

sudo motion

Anhalten von Motion

sudo killall motion

Ansehen des Livestreams

Ihr könnt Euch den Livestream direkt im Browser ansehen, auch dazu braucht Ihr wieder die IP-Adresse Eures Raspis und zusätzlich den richtigen Port von Motion. Also zum Beispiel: http://192.168.0.100:8085

andere Livestreams

Wenn die anderen auch Motion gestartet haben, könnt Ihr Euch deren Livestream ebenfalls im Browser ansehen, dazu einfach die IP-Adresse ändern:


Livestream innerhalb einer Website

Achtung: Motion muss dafür natürlich gestartet werden!

sudo motion

Einbinden des Livestreams innerhalb eines HTML-Dokumentes

Den Motion-Livestream könnte Ihr – wie ein „normales“ Bild – direkt im HTML-Code einbinden:

<!-- hier die richtige IP-Adresse angeben! -->
<img src="http://192.168.0.100:8085" alt="Livestream Kamera">

Das komplette HTML-Dokument könnte dann so aussehen:

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Livestream Kamera</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8" />
    <style>
        body {font-family:Verdana,sans-serif;}
        main {width:90%;max-width:960px;margin:3% auto;border:1px solid #ccc;}
    </style>
  </head>
  <body>
    <main>
        <h1>Livestream Kamera</h1>
        <!-- hier die richtige IP-Adresse angeben! -->
        <img src="http://192.168.0.100:8085" alt="Livestream Kamera">
    </main>
  </body>
</html>

Hier die Demo dazu

Übung

Probiert es doch selber mal aus! Erzeugt direkt auf dem Raspi im Ordner /var/www/html/ eine Datei demo.html und fügt das oben gezeigte HTML dort ein – richtige IP-Adresse Eures Raspis nicht vergessen…

cd /var/www/html/
sudo nano demo.html

Anschliessend könnt Ihr im Browser schauen, ob es geklappt hat – auch hier die richtige IP-Adresse angeben:


Arduino-Helligkeitswerte in CSV-Datei einlesen, Schritt 1

Verwendet hierfür wieder einen 10kΩ Widerstand

Details zum bisherigen Arduino-Code findet Ihr im 1. Script zu Arduino

Neu an dem unten aufgeführten Script ist, dass dieses nicht ständig ausgeführt wird, sondern wartet, bis vom Raspi die Aufforderung dazu geschickt wird – dies geschieht durch das Verschicken des Buchstaben A.

Arduino

// der Arduino übergibt die Werte erst an den Raspberry, wenn dieser (via sudo crontab e)
// ihn dazu auffordert! Dies geschieht durch das Schicken des Buchstaben "A" an den Arduino via Python/Raspberry Pi
// verwendete Python-Scripte (bei /home/pi/bin): serial_arduino_to_pi.py, serial_arduino_auffordern.py
// "serial_arduino_to_pi.py" wird bei jedem Neustart des Raspis unter "sudo crontab -e" aktiviert
// "serial_arduino_auffordern.py" wird im gewollten Abstand (z.B. alle 15min) ebenfalls unter "sudo crontab -e" aktiviert

int fotozelle = A0; // Pin Zuweisung bei A0; Widerstand 10 kOhm

// für Abfrage, ob vom Raspi etwas via Serial geschickt wurde
int incomingByte = 0;   // for incoming serial data

void setup() {
  pinMode(fotozelle, INPUT);
  Serial.begin(9600);
}

void loop() {
  // send data only when you receive data:
  if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();

    // Erst wenn der Buchstabe "A" geschickt wurde, soll Arduino was an Raspi schicken
    if (incomingByte == 65) {
      int hell = analogRead(fotozelle); // Wert, den Fotozelle ausgibt, wird gelesen
      Serial.print("Helligkeit,");
      Serial.println(hell); // Ausgabe des Helligkeitswertes der Foto-Zelle
    }
  }
}

Tip

Ihr könnt testen, ob das Arduino-Script funktioniert, indem ihr im Serial Monitor den Buchstaben A eingebt und auf Send klickt…


Arduino-Helligkeitswerte in CSV-Datei einlesen, Schritt 2

Schliesst nach dem Hochladen des Sketch (vorheriger Slide) den Arduino an den Raspberry Pi an!

Zuerst die benötigten Ordner anlegen – da sich dieser nicht mehr im eigenen Home-Bereich befindet, muss man „sudo“ verwenden!

sudo mkdir /var/www/html/fotoresistor
sudo mkdir /var/www/html/fotoresistor/daten

Damit der Raspi die Werte des Arduino einlesen kann, werden zwei Python-Scripte benötigt:

Das Script serial_arduino_to_pi.py liest die Werte, die vom Arduino kommen, alle 60sek ein und speichert diese als CSV im Ordner /var/www/html/fotoresistor/daten

serial_arduino_to_pi.py

#!/user/bin/env python
# -*- coding: UTF-8 -*-

# https://classes.engineering.wustl.edu/ese205/core/index.php?title=Serial_Communication_between_Raspberry_Pi_%26_Arduino

# wird via sudo crontab -e direkt bei jedem Neustart aktiviert
# @reboot /usr/bin/python /home/pi/bin/serial_arduino_to_pi.py

import os
import time
from time import sleep
from datetime import datetime
import serial

# hier richtigen Serial-Port des Arduinos angeben!
# Arduino Uno
port = "/dev/ttyACM0"

# Achtung, hier die richtige Bautrate fuer den Arduino eintragen
ser = serial.Serial(port, 9600)
ser.flushInput()

# pfad zum HTML-Ordner
pfadDatei = "/var/www/html/fotoresistor/daten/data_log.csv"

# Geschwindigkeit muss identisch wie bei Arduino-Script sein!
s1 = serial.Serial(port,9600)
s1.flushInput()

file = open(pfadDatei, "a")

while True:
    if s1.inWaiting()>0:

        # formatierte Datum- und Zeit-Kombination
        now = datetime.now().strftime('%Y-%m-%d,%H:%M:%S')

        # gibt den Helligkeiswert jeweil in einer Zeile aus
        inputValue =s1.readline()

        # "\r" geht, macht aber eigenartiges Sonderzeichen auf naechster Zeile!
        # "\n" macht jeweils eine Leerzeile
        file.write(str(now)+","+inputValue+"\n")
        file.flush()

        # Script wartet 1 Minute (60), bis es sich wiederholt
        time.sleep(60)

file.close()

serial_arduino_auffordern.py

#!/user/bin/env python
# -*- coding: UTF-8 -*-

# https://classes.engineering.wustl.edu/ese205/core/index.php?title=Serial_Communication_between_Raspberry_Pi_%26_Arduino

# wird via sudo crontab -e aktiviert
# fordert den Arduino z.B. jede 15 Minute auf, Werte zu schicken
# einfach hier die gewuenschten Zeitabstaende einstellen (kuerzestes Interval 1min),
# es muss NICHTS in den Python- oder Arduino-Scripts geaendert werden
# */15 * * * * /usr/bin/python /home/pi/bin/Serial_arduino_auffordern.py

import serial
import sys

# Achtung, hier den richtigen Port fuer den Arduino eintragen
ser = serial.Serial('/dev/ttyACM0', 9600)
ser.flushInput()

# das Python-Script verschickt via SerialPort nur den Buchstaben "A"
# auf dem Arduino wird dieses ausgelesen und nur dann eine Messung von Temp und Feuchtigkeit
# an den Raspi geschickt

string1 = "A"
string1_encode = string1.encode()
ser.write(string1_encode)

sys.exit()

Wenn das Interval für das Script „serial_arduino_auffordern.py“ länger (z.B. 15min) ist, spielt das keine Rolle.

Aufgabe

Erstellt die beiden oben gezeigten Python-Scripte auf dem Raspi unter home/pi/bin und macht diese ausführbar

sudo chmod 755 serial_arduino_to_pi.py && sudo chmod 755 serial_arduino_auffordern.py

Arduino wird nicht gefunden

In den Python-Scripten muss ja angegeben werden, an welchem Port der Arduino angesprochen werden soll. Falls Ihr keine Werte übertragen bekommt, müsst Ihr testen, ob der richtige Port verwendet wird:

Abfragen, ob Arduino erkannt wird:

Da sollte in einer Zeile etwas mit „Arduino“ vorkommen, dann wird er schon mal erkannt!

lsusb

Abfragen, an welchem Port der Arduino angeschlossen ist:

Dazu folgenden Befehl einmal mit angeschlossenem Arduino ausführen und einmal ohne – in der Ausgabe sollte dadurch ein Eintrag wegfallen – dieser ist dann der Port des Arduinos! Hier also der Port /dev/ttyACM0

ls /dev/tty*

Arduino-Helligkeitswerte in CSV-Datei einlesen, Schritt 3

Um die Python-Scripte (vorheriges Slide) automatisch auszuführen, müssen diese in einem crontab angegeben werden

sudo crontab -e

sudo crontab -e

# Script beim Starten des Raspi
# liest die Werte, die vom Arduino kommen, alle 60sek ein und speichert diese als CSV
# im Ordner "/var/www/html/fotoresistor/daten"
# wenn das Interval für das Script "serial_arduino_auffordern.py" länger (z.B. 15min) ist, spielt das keine Rolle
@reboot /usr/bin/python /home/pi/bin/serial_arduino_to_pi.py

# fordert den Arduino jede 15 Minute auf, Werte zu schicken
# einfach hier die gewünschten Zeitabstände einstellen,
# es muss NICHTS in den Python- oder Arduino-Scripts geändert werden
# das kürzeste Intervall, das man einstellen kann, ist 1 min!
*/15 * * * * /usr/bin/python /home/pi/bin/serial_arduino_auffordern.py

Neustart erforderlich

…sonst würde das Script bei „@reboot“ nicht ausgeführt…

sudo reboot

Damit erhält man eine CSV-Datei, die alle 15min mit einem weiteren Helligkeitswert befüllt wird:

2019-05-27,09:45:01,Helligkeit,371
2019-05-27,10:00:01,Helligkeit,329
2019-05-27,10:15:01,Helligkeit,131
2019-05-27,10:30:01,Helligkeit,144
2019-05-27,10:45:01,Helligkeit,138
2019-05-27,11:00:01,Helligkeit,209
2019-05-27,11:15:01,Helligkeit,157
2019-05-27,11:30:02,Helligkeit,168
2019-05-27,11:45:01,Helligkeit,131
2019-05-27,12:00:01,Helligkeit,134

Das Python-Script serial_arduino_to_pi.py fügt dabei automatisch Datum und Uhrzeit ein, so dass man gleich einen Timestamp hat, wann die Messung durchgeführt wurde…


CSV-Dateien: Einzelwerte abfragen

CSV: Comma Separated Values

Eine CSV-Datei lässt sich gut mit Programmen wie z.B. Excel oder Numbers öffnen und zeigt dort eine tabellarische Darstellung

Um dort einzelne Zellen auszuwählen, muss man nur das Raster verstanden haben:

Code-Beispiele

// 1: Zeile 0, Eintrag 0
Eintrag =  data_log.get(0, 0);  // Ergebnis: 2019-05-27

// 2: Zeile 13, Eintrag 1
Eintrag =  data_log.get(13, 1); // Ergebnis: 11-45-01

// 3: Zeile 13, Eintrag 1
Eintrag =  data_log.get(19, 3); // Ergebnis: 104

CSV-Dateien: Spaltenwerte abfragen

Alle Werte der rot umrandeten Spalte sollen abgefragt werden

Code-Beispiele

// Zeile 0, Eintrag 3
Eintrag =  data_log.get(0, 3);  // Ergebnis: 354

// Zeile 1, Eintrag 3
Eintrag =  data_log.get(1, 3);  // Ergebnis: 371

// wenn man alle Einträge der Spalte angezeigt haben möchte
// geht das mit einer for-Schleife…
var anzahl = data_log.getRowCount(); // wieviele Spalten?
for (var i = 0; i < anzahl; i++) {
    // geht die Spalte 3 von oben bis unten durch
    Eintrag = data_log.get(i, 3);
    console.log("Wert: " + Eintrag); // gibt die Werte in der Konsole des Browsers aus
}

p5-Scripte

Bitte schaut Euch zur Auffrischung Eurer p5-Kenntnisse noch mal meine p5-Scripte an!


p5 zur Darstellung von CSV-Werten (tabellarisch)

HTML

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8" />
    <title>P5 Tabelle</title>
    <meta charset="utf-8" />
    <link rel="stylesheet" href="assets/c/style.css" />
    <script src="assets/js/p5.min.js"></script>
    <script src="tabelle.js"></script>
  </head>
  <body></body>
</html>

*Die HTML-Datei ist hier nur der Rahmen für p5 – die Darstellung der CSV-Werte findet in der Datei tabelle.js statt – siehe unten!

Javascript

var data_log, datum, zeit, helligkeit;

function preload() {
  // einlesen der Werte in die Variable "data_log"
  data_log = loadTable("data_log.csv");
}

function setup() {
  createCanvas(960, 520);
  background(240);
  textSize(16);

  // Überschrift
  text("komplette Tabelle", 18, 30);

  textAlign(RIGHT);

  // hier werden alle Werte, die bei "data_log.csv" gespeichert sind
  // ausgelesen und als eine Art von Tabelle dargestellt
  for (var i = 0; i < data_log.getRowCount(); i++) {
    datum = data_log.get(i, 0); // 1. Eintrag pro Zeile
    zeit = data_log.get(i, 1); // 2. Eintrag pro Zeile
    helligkeit = data_log.get(i, 3); // 4. Eintrag pro Zeile

    fill(0);

     // durch "60 + i * 20" werden die Texte untereinander mit dem Zeilenabstand 20px dargestellt
    text(datum, 100, 60 + i * 20);
    text(zeit, 170, 60 + i * 20);
    text(data_log.get(i, 2), 250, 60 + i * 20); // hier ohne Variable, direkt ausgelesen

    fill(255, 0, 0);
    text(helligkeit, 300, 60 + i * 20);
  }

  // wieviele Zeilen enthält die Datei "data_log.csv"
  var anzahl = data_log.getRowCount();

  textAlign(LEFT);
  fill(0);
  text("Die Datei 'data_log.csv' enthält " + anzahl + " Zeilen", 450, 30);

  // Ausgabe des 1. und des letzes Helligkeitswertes
  var ersterHelligkeitswert = data_log.get(0, 3);
  var letzterHelligkeitswert = data_log.get(anzahl - 1, 3);

  text("Erster Helligkeitswert: " + ersterHelligkeitswert, 450, 60);
  text("Letzte Helligkeitswert: " + letzterHelligkeitswert, 450, 80);
}

Demo

Bitte schaut Euch die Demo an – oder ladet Euch das Paket komplett herunter


p5 zur Darstellung von CSV-Werten 2 (Graph)

Javascript

var data_log;
var hPunkte = []; // ein Array der Helligkeitspunkte

function preload() {
  // einlesen der Werte in die Variable "data_log"
  data_log = loadTable("data_log.csv");
}

function setup() {
  createCanvas(960, 520);
  background(240);
  textSize(16);
  noStroke();

  // Überschrift
  fill(0);
  text("Tabellenwerte als Graph", 18, 30);

  // wieviele Zeilen enthält die Datei "data_log.csv"
  var anzahl = data_log.getRowCount();
  // console.log("Anzahl:" + anzahl);

  // liest alle Helligkeitswerte in das Array ein
  for (var i = 0; i < anzahl; i++) {
    hPunkte[i] = data_log.getNum(i, 3);
  }

  var b = 220; // Breite des Rechtecks
  var a = b + 10; // Abstand der Rechtecke

  // ==== Rechtecke, bei dem die Höhe dem Wert des jeweiligen Eintrags bei hPunkte entspricht ===

  // Rechteck mit Wert des Eintrags 0
  fill(255, 0, 0);
  rect(18, 50, b, hPunkte[0]);

  // Rechteck mit Wert des Eintrags 1
  fill(0, 255, 0);
  rect(18 + a, 50, b, hPunkte[1]);

  // Rechteck mit Wert des Eintrags 4
  fill(0, 0, 255);
  rect(18 + a * 2, 50, b, hPunkte[4]);

  // Rechteck mit Wert des LETZTEN Eintrag
  fill(0, 0, 0);
  rect(18 + a * 3, 50, b, hPunkte[anzahl - 1]);
}

Demo

Bitte schaut Euch die Demo an – oder ladet Euch das Paket komplett herunter


p5 zur Darstellung von CSV-Werten 3 (Graph, alle Werte)

Javascript

var data_log;
var hPunkte = []; // ein Array der Helligkeitspunkte

// wo fängt Beschriftung und Graph an?
var StartpunktX = 40;
var StartpunktY = 70;

function preload() {
  // einlesen der Werte in die Variable "data_log"
  data_log = loadTable("data_log.csv");
}

function setup() {
  createCanvas(960, 520);
  background(240);
  textSize(16);
  noStroke();

  // Überschrift
  fill(0);
  text("Tabellenwerte als Graph, alle Werte", StartpunktX, StartpunktY - 30);

  // wieviele Zeilen enthält die Datei "data_log.csv"
  var anzahl = data_log.getRowCount();
  // console.log("Anzahl:" + anzahl);

  // liest alle Helligkeitswerte in das Array ein
  for (var i = 0; i < anzahl; i++) {
    hPunkte[i] = data_log.getNum(i, 3);
  }

  var b = 30; // Breite des Rechtecks
  var a = b + 8; // Abstand der Rechtecke

  for (var i = 0; i < anzahl; i++) {
    // je nach Helligkeitswert werden die Rechtecke unterschiedlich eingefärbt
    if (hPunkte[i] <= 100) {
      fill(182, 8, 0);
    } else if (hPunkte[i] > 100 && hPunkte[i] <= 200) {
      fill(232, 44, 0);
    } else if (hPunkte[i] > 200 && hPunkte[i] <= 300) {
      fill(226, 117, 0);
    } else {
      fill(227, 206, 0);
    }

    // die Rechtecke werden gezeichnet
    rect(StartpunktX + a * i, StartpunktY, b, hPunkte[i]);
  }

  // waagrechte Maßlinien
  stroke(150);
  line(StartpunktX - 5, StartpunktY, width - 20, StartpunktY); // 0-Linie
  line(StartpunktX - 5, StartpunktY + 100, width - 20, StartpunktY + 100); // 100-linie
  line(StartpunktX - 5, StartpunktY + 200, width - 20, StartpunktY + 200); // 200-linie
  line(StartpunktX - 5, StartpunktY + 300, width - 20, StartpunktY + 300); // 300-linie

  // Beschriftung der Skala, vertikal
  noStroke();
  fill(120);
  textAlign(RIGHT);
  textSize(12);
  text("0", StartpunktX - 7, StartpunktY + 5);
  text("100", StartpunktX - 7, StartpunktY + 5 + 100);
  text("200", StartpunktX - 7, StartpunktY + 5 + 200);
  text("300", StartpunktX - 7, StartpunktY + 5 + 300);

  // Beschriftung der Skala, horizontal
  textAlign(CENTER);
  for (var i = 0; i < anzahl; i++) {
    text(i, StartpunktX + b / 2 + i * a, StartpunktY - 5);
  }
}

Demo

Bitte schaut Euch die Demo an – oder ladet Euch das Paket komplett herunter


p5: Darstellung von aktuellen Helligkeitswerten

Der Graph skaliert sich automatisch, je nachdem wieviele Werte bei „data_log.csv“ gespeichert sind

Javascript

var data_log;
var hPunkte = []; // ein Array der Helligkeitspunkte

// wo fängt Beschriftung und Graph an?
var StartpunktX = 40;
var StartpunktY = 70;

// wie wird der Graph in der Höhe skaliert
var factor = 2.3;

function preload() {
  // einlesen der Werte in die Variable "data_log"
  // hier korrekten, relativen Pfad eingeben!
  data_log = loadTable("daten/data_log.csv");
}

function setup() {
  createCanvas(960, 520);
  background(240);
  textSize(16);
  noStroke();

  // Überschrift
  fill(0);
  text("Tabellenwerte als Graph, live-Werte", StartpunktX, StartpunktY - 30);

  // wieviele Zeilen enthält die Datei "data_log.csv"
  var anzahl = data_log.getRowCount();
  // console.log("Anzahl:" + anzahl);

  textAlign(RIGHT);
  var Datensaetze = "Datensätze: " + anzahl;
  text(Datensaetze, width - 20, StartpunktY - 30);

  // liest alle Helligkeitswerte in das Array ein
  for (var i = 0; i < anzahl; i++) {
    hPunkte[i] = data_log.getNum(i, 3);
  }

  // Breite der Rechtecke abhängig von Anzahl der Einträge bei "data_log.csv"
  // "130" durch Ausprobieren ermittelt!
  var b = (width - 130) / anzahl;
  var a = b + b / 10; // Abstand der Rechtecke ebenfalls proportional

  for (var i = 0; i < anzahl; i++) {
    // je nach Helligkeitswert werden die Rechtecke unterschiedlich eingefärbt
    if (hPunkte[i] <= 200) {
      fill(182, 8, 0);
    } else if (hPunkte[i] > 200 && hPunkte[i] <= 400) {
      fill(232, 44, 0);
    } else if (hPunkte[i] > 400 && hPunkte[i] <= 600) {
      fill(226, 117, 0);
    } else if (hPunkte[i] > 600 && hPunkte[i] <= 800) {
      fill(227, 206, 00);
    } else {
      fill(236, 233, 0);
    }

    // die Rechtecke werden gezeichnet, Höhe wird durch den "factor", damit der Graph nicht zu hoch wird
    rect(StartpunktX + a * i, StartpunktY, b, hPunkte[i] / factor);
  }

  textSize(12);

  // waagrechte Maßlinien und vertikale Beschriftung
  for (var i = 0; i < 11; i++) {
    // die yPos der Linien bzw. der Texte
    var yPos = StartpunktY + (100 / factor) * i;
    // die Linien
    stroke(150);
    line(StartpunktX - 5, yPos, width - 20, yPos);
    // die Beschriftung vertikal
    noStroke();
    fill(120);
    textAlign(RIGHT);
    var Ausgabe = 100 * i; // z.B. "0", "100" usw.
    text(Ausgabe, StartpunktX - 7, yPos + 4);
  }

  // Beschriftung der Skala, horizontal
  textAlign(CENTER);

  // die horizontale Beschriftung passt sich an:
  // wenn wenige Einträge vorhanden sind, wird jeder Balken einzeln beschriftet
  // sonst nur jeder 10. Eintrag
  if (anzahl <= 45) {
    var i_Sprung = 1;
  } else {
    i_Sprung = 10;
  }

  for (var i = 0; i < anzahl; i = i + i_Sprung) {
    text(i, StartpunktX + b / 2 + i * a, StartpunktY - 5);
  }
}

Demo

Bitte schaut Euch die Demo an – oder ladet Euch das Paket komplett herunter

Auf dem Raspi testen

  1. Ladet das Paket p5-auf-raspi.zip herunter
  2. Kopiert p5-auf-raspi.zip auf Euren Raspi (bei /home/pi/)
  3. Verschiebt das Paket von dort in den Ordner /var/www/html/fotoresistor (sudo mv…)
  4. Entpackt dort die Zip-Datei (sudo unzip -a p5-auf-raspi.zip)
  5. Verschiebt den kompletten Inhalt des Ordners p5-auf-raspi.zip in den Ordner /var/www/html/fotoresistor (sudo mv *…)

Im Browser ansehen:

Damit das funktioniert, müsst Ihr wieder die richtige IP Eures Raspis wissen und damit folgende URL zusammenbauen:

 z.B. http://192.168.0.100/ + fotoresistor/p5-graph-live.html

Danke

Weitere Vorträge: