Basics

Einfache HTML-Datei

<!doctype html>
<html>
<head>
<title>Hallo Welt!</title>
</head>
<body>
Hallo Welt!
</body>
</html>

Hier ist der passende Quellcode.

Strukturierte HTML-Datei

Nun bauen wir etwas Struktur in unsere Datei ein. Wir verwenden eine Überschrift (header - h1), einen Absatz (paragraph - p) und eine nicht nummerierte Liste (ul) mit Listeneinträgen (li). Wie in html üblich werden die entsprechenden Tags <geöffnet> und hinterher wieder </geschlossen>. Ein offensichtlicher Slash / macht hier den Unterschied.

<!doctype html>
<html>
<head>
<title>Strukturierte HTML-Datei</title>
</head>
<body>
<h1>Überschrift</h1>
<p>Das ist Text in einem Absatz. Es folgt eine Liste.</p>
<ul>
<li>Erster wichtiger Punkt.</li>
<li>Zweiter Punkt auf der Liste.</li>
</ul>
</body>
</html>

Dazu obiger Quelltext in einer Datei.

HTML mit Stil

Noch sieht die Datei nicht sehr schön aus. Standartmäßig wird eine schwarze Roman-Schriftart verwendet, der Hintergrund ist weiss. Das kann man mit Angaben zum Stil (style) ändern.

<!doctype html>
<html>
<head>
<title>Strukturierte HTML-Datei</title>
</head>
<body style="font-family:sans serif; background-color:lightgray;">
<h1>Überschrift</h1>
<p>Das ist Text in einem Absatz. Es folgt eine Liste.</p>
<ul>
<li>Erster wichtiger Punkt.</li>
<li>Zweiter Punkt auf der Liste.</li>
</ul>
</body>
</html>

Auch hier wieder der Quelltext in einer Datei.

HTML mit Javascript

<!doctype html>
<html>
<head>
<title>Hallo Welt!</title>
</head>
<body>
Hallo Welt!
</body>
</html>

Einfaches Formular in HTML

Für interaktive Eingaben wäre es doch schön, wenn man.

<!doctype html>
<html>
<head>
<title>Hallo Welt!</title>
</head>
<body>
Hallo Welt!
</body>
</html>

Javascript

Javascript in eigene Datei auslagern

Hier die HTML-Datei mit Hinweis auf die Javascript-Datei im Kopf (head).

<!doctype html>
<html>
<head>
<title>Hallo Welt!</title>
</head>
<body>
Hallo Welt!
</body>
</html>

Cascading Style Sheets - CSS

CSS in eigene Datei auslagern

Wie schon Javascript wird auch CSS in eine extra Datei ausgelagert, da die Formatierung der Darstellung vom eigentlichen Text getrennt werden soll. Außerdem kann man so eine einheitliche Darstellung erreichen, Angaben für viele Dateien verwenden und sehr leicht zentral ändern. Beginnen wir wieder mit der HTML-Datei und dem Link im Kopf (head):

<!doctype html>
<html>
<head>
<title>Hallo Welt!</title>
</head>
<body>
Hallo Welt!
</body>
</html>

Visual Basic for Applications - VBA

Einfaches Hallo-Welt Formular

Das erste "Hallo Welt" in VBA ist in 5 Schritten erreicht. Wir öffen ein leeres Excel-Dokument und drücken F11. Unter Start - Neu - Formular erstellen wir ein leeres Template. Dorthin fügen wir einen Button ein. Das war's für das Formular

Nun müssen wir noch eine Aktion für den Button progammieren. Einfach einen Doppelklick und es öffnet sich ein neuer Reiter mit "whatsoever".

Arduino

1. Basics - blinkende LED

Dieses einfache Progamm ist in den Beispielen (auf englisch) standardmäßig unter "Blink" enthalten. Dennoch beschreiben wir hier die ersten Schritte bis zum ersten ausgeführten Programm. Es funktioniert mit Arduino uno, nano oder einem selbstgebautem Computer aus ATmega328 auf einem Breadboard. Im NaWi-Kurs der 5. Klassen an der Eichenschule haben wir jenen am 12. Januar 2016 aufgebaut. So sah er dann aus:

Beispielhaft verwenden wir im weiteren den Arduino Uno. Jenen kann man auf ebay für 3,89 € aus Hongkong versandkostenfrei bestellen. Das passende USB-Kabel ist dabei. Auf unserem PC installieren wir die Software Arduino von www.arduino.cc. Danach verbinden wir den Arduino per USB. Die passenden Treiber werden automatisch installiert. Die Software öffnet mit einem leeren Gerüst für ein Programm:

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

2. Arduino auf dem Breadboard selbst bauen

Unter Punkt 1 haben wir bereits den selbstgebauten Arduino betrachtet. Die Idee dazu stammte von einem englischen Video auf Youtube. Kurz zusammengefasst benötigen wir die folgenden Bauteile:

Im Komplettset bei ebay kostet es etwa 6,50 €. Dazu kommt noch die serielle USB-Schnittstelle für weitere 4,32 € und ein Breadboard für etwa 1,- €. Die Motivation zu diesem Projekt ist also eher in der Erfahrung und im Experiment als in der möglichen Kostenersparnis zu finden.

3. 8x8 LED Matrix mit Maxim 7219 ansteuern

Beschreibung.

4. Steppermotor ansteuern

Beschreibung.

5. LCD-Display mit 20x4 Zeilen an I2C nutzen

Beschreibung.

6. Touch-TFT von banggood nutzen

Im Bundle mit einem Arduino Uno kostet das Set nur etwa 11,-€. Das TFT-Display hat eine Auflösung von 320x200 Punkten und wird von einem H4323 mit 48kByte RAM angesteuert. Damit hat das Display mehr Speicher als unser Arduino. Ganze Bilder passen nur zu einem Bruchteil in den Speicher des Arduino. Daher ist gleich ein SD-Kartenleser unter den Display angebracht. Hier können mehr als genug Dateien abgelegt werden.

7. Sensoren an den Arduino anschließen

Beschreibung.

8. Useless Box mit ArduinoSensoren an den Arduino anschließen

Als Bausatz erhält man eine nutzlose Box für 12 Euro. Doch mit einem Arduino kann man ihr sogar etwas wie ein Eigenleben schenken. Das sieht dann so aus:

Oder auch so (im Duell).

9. Sammlung von Bibliotheken

Für die obigen Projekte benötigt man einige Bibliotheken, die man vor dem Compilieren einbinden muss. Ich habe diese hier einmal zusammengefasst:

OpenWRT auf einem Router TP-Link WR703N

1. Benötigte Hardware

2. Software

Neuestes Build von OpenWrt auf den WR703N flashen.
(z.B. attitude adjustment r33212 mit kernel 3.3.8 von 2012-08-21)
Am LANport ist jetzt 192.168.1.1, dorthin mit telnet connecten.
passwd eingeben und damit das rootpasswort ändern.
Neue Verbindung auf 192.168.1.1 über ssh
Ändern der IP in /etc/config/network

3. Einrichten des Clients

Der Router soll als Client im WLAN registriert werden. Dazu das LAN-Kabel anschließen. Seine IP ist jetzt 192.168.1.2. Wir verbinden uns per putty über ssh mit Usernamen und Passwort. Die WLAN-Einstellungen können wir unter /etc/config/wireless verändern. Eine neue IP wird automatisch per dhcp zugewiesen.

4. Pakete nachinstallieren

Die Paketverwaltung unter OpenWRT erfolgt mit opkg. Für unseren Temperaturserver benötigen wir owfs (One Wire File System). Dazu geben wir ein:

# opkg update
# opkg install owfs

Nach dem Start von owfs werden alle 1wire-Devices in das Verzeichnis /tmp/1wire/ gemountet. Unsere Messdaten schreiben wir nach /tmp/owdata/.

5. Scripte

Wir erstellen nun einige Scripte, die die Messdaten auslesen, speichern und per ftp auf einen Server laden. Unser erstes Script heißt startowfs und soll ein Verzeichnis /tmp/1wire erstellen (so nicht vorhanden) und owfs in diesem Verzeichnis starten:

#!/bin/bash
if [ ! -d /tmp/1wire ]; then
    mkdir /tmp/1wire
fi
owfs –allow_other -u /tmp/1wire
mkdir /tmp/owdata

Das Script tempscript liest die Temperatur aus und schreibt die Daten in eine Datei $datum.log. Es wird später regelmäßig aufgerufen, zum Beispiel alle 10 Minuten.

#!/bin/bash
datum=$(date +%Y%m%d)
logfile=/tmp/owdata/$datum.log
if [ ! -f /tmp/owdata/$datum.log ]
then
    echo -e "YYYMMDD HH:MM measured temperature" >> $logfile
fi

messwert=$(date +%Y%m%d)" "$(date +%R)" "
messwert=$messwert$(cat /tmp/1wire/28.09390E020000/temperature)

echo -e $messwert >> $logfile

Das nächste Script upload lädt eine beliebige Datei (Übergabe des Dateinamens einfach hinter dem Script, abgefragt mit $1) per ftp auf die Webseite hoch:

#!/bin/bash
if [ -f /tmp/owdata/$1 ]
then
    wput -u /tmp/owdata/$1 ftp://ftpuser0815:Mf4jsZ7fb8d)m-T2@hofkoh.de/data/$1
fi

Am Anfang jeder Stunde (erste Minute) wird die aktuelle Temperatur, Auslastung der CPU etc. in eine Javascriptdatei data.js exportiert und durch folgendes uploadscript hochgeladen. So hat man stündlich die aktuellen Temperaturwerte beim Aufruf der Webseite:

#!/bin/bash
if [ -f /tmp/owdata/data.js ]
then
    rm /tmp/owdata/data.js
fi

up='uptime_now="'$(uptime)'";'
echo $up >> /tmp/owdata/data.js
tempe='temperatur="'$(date +%Y%m%d)" "$(date +%R)" "$(cat /tmp/1wire/28.09390E020000/temperature)'";'
echo -e $tempe >> /tmp/owdata/data.js
wlan='wlan="'`iwconfig wlan0 | grep 'Link Quality'`'";'
echo -e $wlan >> /tmp/owdata/data.js

sh /usr/1wire/upload data.js

Die aktuellen Messungen des Tages werden zur 58. Minute hochgeladen. Damit erhält man stündlich das Update der Messungen der letzten Stunde und überschreibt nicht die Werte des Vortages, sondern hat 2 Minuten vor Mitternacht alle Daten des Tages aktualisiert. Das Script heißt einfach uploadday.

#!/bin/bash
datum=$(date +%Y%m%d)
sh /usr/1wire/upload $datum.log

Im Verzeichnis /usr/1wire befinden sich jetzt also fünf Scripte: startowfs, tempscript, upload, uploadscript und uploadday. Diese sollten regelmäßig aufgerufen werden. Das erledigt die Datei crontab in /etc/crontabs/root und sieht wie folgt aus:

*/10 * * * * sh /usr/1wire/tempscript
1    * * * * sh /usr/1wire/uploadscript
58   * * * * sh /usr/1wire/uploadday

Das erste Script wird jeden Monat/Woche/Tag/Stunde im Abstand von jeweils 10 Minuten aufgerufen. Das zweite Script wird stündlich zur ersten Minute gestartet, das letzte Script stündlich in der 58. Minute. Nun müssen wir den cron-Daemon durch /etc/init.d/S60cron starten und unsere crontab ausführen lassen:

#!/bin/bash
# start crond
/usr/sbin/crond -c /etc/crontabs

Das ganze sollte auch nach dem Booten neu ausgeführt werden, daher wird in /etc/init.d/example das Folgende eingetragen:

#!/bin/sh /etc/rc.common
START=11
STOP=15
start() {
    echo start
}
stop() {
    echo stop
}
boot() {
    sh /usr/1wire/startowfs
}

6. Auswertung auf der Webseite mit JavaScript

Nun sind die Dateien im Verzeichnis des Webspace. Sie müssen aber noch angezeigt werden. Dazu schreiben wir eine entsprechende html-Datei. Ausgewertet werden die beiden Dateien /data/JJJJMMTT.log mit den Einträgen JJJJMMTT HH:MM Temperatur untereinander und Werten von allen 10 Minuten. Weiterhin wird die Datei /data.js mit Einträgen zur uptime_now, Temperatur tempe und dem Wlansignal wlan eingebunden. Der Quelltext einer möglichen index.html sieht folgendermaßen aus:

<!doctype html>
<html>
<head>
 <meta http-equiv="content-type" content="text/html; charset=utf-8">
 <meta name="viewport" content="width=device-width; initial-scale=1.0;" />

 <link rel="stylesheet" type="text/css" href="style.css">

 <script type="text/javascript" src="data.js"></script> <!-- Daten der letzten Stunde in Variablen -->
 <script type="text/javascript" src="jquery-1.4.1.min.js"></script><!-- um Datei laden zu können -->
 <script type="text/javascript" src="https://www.google.com/jsapi"></script><!-- für graph/charts -->
 <script type="text/javascript" src="tempdata.js"></script><!-- nur vorübergehend!-->
 <script type="text/javascript" src="dynamic.js"></script><!-- Visualisierung, Aktualisierung Daten-->
</head>
<body>
 <p>Datum und Zeit: <span id="tempea">[script loading]</span></p>
 <p>Temperatur:</p> <p style="text-align:center;">
  <span style="text-align:center; margin:10px; padding:10px; font-size: x-large; background:lightgreen;">
   <span id="tempeb">10</span> °C
  </span>
 </p>
 <p><span id="uptime">0d 00:00:01</span></p>
 <p><span id="wlan">00/00</span>
 <span style="float:right;"><a href="info.pdf">Information</a></span></p>

 <div id="chart_div" style="width: 100%; height: 500px;"></div>
 <p>heute:<pre style="margin:10px;"><span id="heute">text wird ersetzt</span></pre></p>
 <p>gestern:<pre style="margin:10px;"><span id="gestern">text wird ersetzt</span></pre></p>
 <div id="Fuss"><small><a name="bottom">© 2009-2016</a> Matthias Kreier</small></div>
</body>
</html>

Es sind offensichtlich 5 Scripte eingebunden: data.js für oben angegebene Daten, dann jquery zum Auswerten der Daten in JJJJMMDD.log und Einbinden in die html-Datei. Von Google ist google.com/jsapi für den Graphen eingebunden. Vorübergehend werden auch die Daten von tempdata eingelesen und ausgewertet und schlussendlich ist noch dynamic.js eingebunden, um mit jquery und Google die Daten auszuwerten. Letztgenannte hat folgenden Inhalt:

google.load("visualization", "1", {packages:["corechart"]});
$(document).ready(function() {
// Daten aus der data.js einfügen
document.getElementById("tempea").firstChild.nodeValue = temperatur.slice(0,14);
document.getElementById("tempeb").firstChild.nodeValue = temperatur.slice(15);
document.getElementById("uptime").firstChild.nodeValue = uptime_now;
document.getElementById("wlan").firstChild.nodeValue = wlan;
// Datenarray data erstellen und mit Daten füllen
var data = new google.visualization.DataTable();
data.addColumn('string','Uhrzeit');
data.addColumn('number', 'heute');
data.addColumn('number', 'gestern');
data.addRows(144);
// heute laden
var jetzt = new Date();
var dh = String(jetzt.getFullYear());
if (parseInt(jetzt.getMonth()+1,10) < 10) {
  dh = dh + "0" + String(jetzt.getMonth()+1)
} else {
  dh = dh + String(jetzt.getMonth()+1)
}
if (parseInt(jetzt.getDate(),10) < 10) {
  dh = dh + "0" + String(jetzt.getDate());
} else {
  dh = dh + String(jetzt.getDate());
}
var datei = "data/" + dh + ".log"; //Dateiname ist YYYYMMDD.log
$('#heute').load(datei); // pre mit Messdaten von heute füllen
$.get( datei, function( hdata ) {
  hdata=hdata.replace(/\n/g, " ");// regulärer Ausdruck /\n/g - siehe unten
  var harray = hdata.split(" ");
  var messende = (harray.length+1)/3 - 3 //- 6
  for (var i = 0; i < messende ; ++i)
    data.setValue(i, 1, parseFloat(harray[i*3+6])); // Temperatur heute
});

// Datum auf gestern setzen
jetzt.setDate(jetzt.getDate() - 1);
var dh = String(jetzt.getFullYear());
if (parseInt(jetzt.getMonth()+1,10) < 10) {
  dh = dh + "0" + String(jetzt.getMonth()+1)
} else {
  dh = dh + String(jetzt.getMonth()+1)
}
if (parseInt(jetzt.getDate(),10) < 10) {
  dh = dh + "0" + String(jetzt.getDate());
} else {
  dh = dh + String(jetzt.getDate());
}
datei = "data/" + dh + ".log"; // jetzt entspricht Dateinamen gestern
$('#gestern').load(datei); // pre mit Messdaten von gestern füllen
$.get( datei, function( gdata ) {
  gdata=gdata.replace(/\n/g, " "); // jeden Zeilenwechsel duch ein Leerzeichen ersetzen
  var garray = gdata.split(" ");
  for (var i = 0; i < 144 ; ++i) {
    data.setValue(i, 0, String(garray[i*3+5])); // Uhrzeit
    data.setValue(i, 2, parseFloat(garray[i*3+6])); // Temperatur gestern
  }
  var options = { title: 'Temperaturverlauf in Hofkoh' };
  var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
  chart.draw(data, options);
});
return false;
});

Diese gesamte Beschreibung gibt es auch als PDF-Datei auf dieser Seite. Der Quelltext und alle Dateien finden sich in der temperatur.zip zum Herunterladen.

Raspberry Pi

Webzugriff auf 8-Relaisplatine

Projektbeschreibung folgt. Zieladresse light.hofkoh.de

(C) 2015-2016 Matthias Kreier | Impressum | Kontakt