===== Matrix =====
Ziel ist es eine über den Arduino laufende LED-Matrix über die serielle Schnittstelle zum Raspberry Pi über Internet zu programmieren.
{{:computer:raspberrypi:projekte:dsc_0012.jpg?320|}}{{:computer:raspberrypi:projekte:dsc_0007.jpg?320|}}
==== Arduino Programm ====
Dazu wird das Arduino Programm ([[computer:raspberrypi:mit_arduino_koppeln|RaspberryPi mit Arduino koppeln]]) an ein weiteres Programm, welches eine Laufschrift anzeigen lässt angepasst:
const int zeilenstart=2; // Pin ab dem die Zeilen anfangen
const int spaltenstart=10; // Pin ab dem die Spalten anfangen
const int max_x=8; // maximal zu übergebende Werte
int i = 0; // seriell übergebener Wert
int q = 0; //
int modus=0;
int schrift[max_x]={1,2,4,8,16,32,64,128}; // Anfangsdiagonale
int pot[8]={1,2,4,8,16,32,64,128}; // Zweierpotenzen
// --------------------------------------------------
void show_grid() {
for (int s=0;s<8;s++) { // für jede Spalte
for (int z=0;z<8;z++) { // und für jede Zeile
if ( (schrift[s] & pot[z]) == pot[z]) // schrift[] auf der Matrix ausgeben
digitalWrite(zeilenstart+z,LOW);
else
digitalWrite(zeilenstart+z,HIGH);
}
digitalWrite(spaltenstart+7-s,HIGH);
digitalWrite(spaltenstart+7-s,LOW);
}
}
// --------------------------------------------------
void setup () {
Serial.begin(9600); // serielle Schnittstelle starten
for (int i=0; i<8; i++) {
pinMode(zeilenstart+i, OUTPUT); // Pins als Ausgang nutzen
pinMode(spaltenstart+i, OUTPUT); // Pins als Ausgang nutzen
digitalWrite(zeilenstart+i,HIGH);// Die Zeile ausschalten
digitalWrite(spaltenstart+i,LOW);// Die Spalte ausschalten
}
}
void loop () {
if (Serial.available() > 0) { // wenn serielle Signale verfügbar sind:
i = Serial.read(); // empfangene Signale lesen
if ( modus==0 ) { //auf drei aufeinanderfolgende Nullen warten
if ( i==0 ) {
q++; //zählt aufeinanderfolgende Nullen
} else {
q=0;
}
if ( q==3 ) { modus=1; q=0; } // Bei dreimal 0:
} else {
schrift[q]=i; // schrift[] abhängig von i definieren
q++;
if ( q==8 ) { modus=0; q=0; } // Nach 8 Zeichen auf Startsignal warten
}
} else {
show_grid(); // schrift[] auf Matrix ausgeben
}
}
Da der Arduino über weniger als 64 Ausgänge verfügt, die Matrix allerdings 64 LEDs besitzt, kann durch Umwandlung in das Binärsystem/Zweierpotenzen jede LED angesteuert werden.
Jede Spalte verfügt so über eine andere Spaltensumme, die das Arduinoprogramm als übergebene Parameter vom Raspberry Pi erwartet. Um einen Informationsbeginn zu deklarieren, muss dreimal eine 0 an den Anfang jeder Datenübertragung gesetzt werden.
==== Raspberry Pi Programme ====
Zunächst sollte man den Raspberry Pi auf die serielle Kommunikation vorbereiten (siehe [[computer:raspberrypi:mit_arduino_koppeln#raspberry_pi|RaspberryPi mit Arduino koppeln]]).
Damit man nun nicht jedesmal die drei 0 an den Anfang setzen muss und der Raspberry Pi auch nur 8 Parameter übergibt wird das Programm für den Raspberry Pi aus "[[computer:raspberrypi:mit_arduino_koppeln|RaspberryPi mit Arduino koppeln]]" ein wenig angepasst:
=== Parameterübergabe ===
import serial
import time
import sys
delay = 0.01
comunicacion = serial.Serial('/dev/ttyAMA0', 9600)
comunicacion.close()
comunicacion.open()
for a in [0,0,0]:
comunicacion.write(chr( 0 ))
time.sleep(delay)
for a in range(1,9):
comunicacion.write(chr( int(sys.argv[a]) ))
time.sleep(delay)
=== Internetseite ===
Um das ganze übers Internet zu programmieren, benötigt man zunächst einmal einen [[computer:raspberrypi:webserver|Webserver]] auf dem Pi und eine php-Datei, die man in den Ordner /var/www speichert. (siehe [[computer:raspberrypi:steuern_ueber_website|Steuern über Website]] )
Über diese Internetseite kann man die benötigten Werte an das Python-Programm weiterreichen.
$v) {
$a[$k]=(int)$v;
}
passthru("/usr/bin/python senden ".implode(" ",$a));
} else {
echo 'Fehler bei der Eingabe!
Nicht genau 8 Werte!
Adresse muss folgende Form haben:
?v=1,2,4,8,16,32,64,128';
}
?>
=== erweiterte Internetseite ===
Da es auf Dauer wenig Spaß macht jedesmal die LEDs bzw. die Parameter auszurechnen, programmiert man sich kurz eine Internetseite, die das ganze durch anklicken einer virtuellen Martix für einen berechnet und sofort an über die anderen Programme (Internetseite, Parameterübergabe, etc.) an den Arduino bzw. die Matrix selbst weiterleitet.
Davor muss man sich jedoch noch folgendes runterladen, um nicht über andere Server gehen zu müssen (Vgl. [[computer:raspberrypi:projekte:blinken|Blinken]]):
wget http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
==== Netzwerkkontrolle ====
Wenn man den Raspberry Pi über Wlan steuert (siehe [[computer:raspberrypi:netzwerk|Netzwerk]] ), sollte man sicherstellen, dass der Pi nicht die Verbindung zum Netz verliert. Dazu gibt es ein Script (/home/pi/checkping), welches prüft ob eine Verbindung vorliegt und gegebenenfalls das Wlan deaktiviert und wieder aktiviert:
#!/bin/bash
IP=192.168.0.1
DEV=wlan0
ping -q -W 5 -c 3 $IP >/dev/null
if [ ! $? -eq "0" ]
then
ifdown $DEV
sleep 15
ifup $DEV
fi
Damit dieses Script alle 5 Minuten ausgeführt wird speichert man eine Datei mit folgendem Inhalt im Ordner **/etc/cron.d** :
*/5 * * * * root /home/pi/checkping > /dev/null 2>&1
==== Uhr ====
Um eine Uhr auf der Matrix anzeigen zu lassen, die sich für 20 Sekunden durch ein über Website programmierstes Muster überschreiben lässt benötigt man folgendes Script:
import serial
import time
import sys
import os
import os.path
delay = 0.01
comunicacion = serial.Serial('/dev/ttyAMA0', 9600)
comunicacion.close()
comunicacion.open()
m=([0,0,0,0,0,0,0,0])
h=([0,0,0,0,0,0,0,0])
s=([0,0,0,0,0,0,0,0])
H = 0
M = 0
S = 0
while True:
try:
timea = os.path.getmtime("/tmp/block")
except:
timea = time.time()
if os.path.isfile("/tmp/block") and time.time()-timea>20:
H=time.localtime().tm_hour%12
M=int(time.localtime().tm_min/5)
S=int(time.localtime().tm_sec/2)
while int(time.localtime().tm_sec/2)==S:
time.sleep(delay)
#-----------------------------------------------------------------------
#Minuten
m=[[0,0,0,1,1,0,0,0],
[0,0,0,0,0,1,1,0],
[0,0,0,0,0,0,0,6],
[0,0,0,0,0,0,0,24],
[0,0,0,0,0,0,0,96],
[0,0,0,0,0,128,128,0],
[0,0,0,128,128,0,0,0],
[0,128,128,0,0,0,0,0],
[96,0,0,0,0,0,0,0],
[24,0,0,0,0,0,0,0],
[6,0,0,0,0,0,0,0],
[0,1,1,0,0,0,0,0]]
#-----------------------------------------------------------------------
#Stunden
h=[[0,0,0,2,2,0,0,0],
[0,0,0,0,2,2,0,0],
[0,0,0,0,0,2,4,0],
[0,0,0,0,0,0,24,0],
[0,0,0,0,0,0,48,0],
[0,0,0,0,0,64,32,0],
[0,0,0,64,64,0,0,0],
[0,0,64,64,0,0,0,0],
[0,32,64,0,0,0,0,0],
[0,24,0,0,0,0,0,0],
[0,12,0,0,0,0,0,0],
[0,4,2,0,0,0,0,0]]
#-----------------------------------------------------------------------
#Sekunden
s=[[0,0,0,1,0,0,0,0],
[0,0,0,0,1,0,0,0],
[0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,1,0],
[0,0,0,0,0,0,0,1],
[0,0,0,0,0,0,0,2],
[0,0,0,0,0,0,0,4],
[0,0,0,0,0,0,0,8],
[0,0,0,0,0,0,0,16],
[0,0,0,0,0,0,0,32],
[0,0,0,0,0,0,0,64],
[0,0,0,0,0,0,0,128],
[0,0,0,0,0,0,0,128],
[0,0,0,0,0,0,128,0],
[0,0,0,0,0,128,0,0],
[0,0,0,0,128,0,0,0],
[0,0,0,128,0,0,0,0],
[0,0,128,0,0,0,0,0],
[0,128,0,0,0,0,0,0],
[128,0,0,0,0,0,0,0],
[64,0,0,0,0,0,0,0],
[32,0,0,0,0,0,0,0],
[16,0,0,0,0,0,0,0],
[8,0,0,0,0,0,0,0],
[4,0,0,0,0,0,0,0],
[2,0,0,0,0,0,0,0],
[1,0,0,0,0,0,0,0],
[1,0,0,0,0,0,0,0],
[0,1,0,0,0,0,0,0],
[0,0,1,0,0,0,0,0]]
#-----------------------------------------------------------------------
for a in [0,0,0]:
comunicacion.write(chr( 0 ))
time.sleep(delay)
for i in range(0,8):
t_i = m[M][i] | h[H][i] | s[S][i]
print t_i
comunicacion.write(chr( int(t_i) ))
time.sleep(delay)
else:
time.sleep(1)
Damit das Programm uhr.py automatisch beim Start des Raspberry Pis im Hintergrund mitgestartet wird, fügt man folgende Zeilen in **/etc/rc.local** hinzu:
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
python /home/pi/uhr.py &
exit 0