Blog
Experiment #2: Lego NXT als Fernbedienung
Ich sitze nun oft auf meinem Bettsofa und möchte auf einen anderen Sender meines TV-Streams, der wie in Experiment #1 aufgebaut ist, umschalten.
Da ich mir keinen Infrarotempfänger kaufen/basteln will, habe ich meinen NXT gezückt und ein Programm mit C# und NXC, einer Sprache für den NXT ähnlich zu C, geschrieben. Das ganze funktioniert über Bluetooth. Hier ist der C# Quelltext:
SerialPort btConnection = new SerialPort("/dev/rfcomm0");
/* Öffnet eine Verbindung zur COM Verbindung /dev/rfcomm0
wie man eine Bluetooth Serialschnitstelle erstellen können Sie nachlesen:
http://juju.org/articles/2006/10/22/bluetooth-serial-port-to-nxt-in-linux
*/
btConnection.Open(); //Öffnet die Verbindung
while(true)
{
if(btConnection.BytesToRead >= 9) /* Wenn Bytes zum Lesen vorhanden sind,
hier 9 Bytes, weil meine Nachrichten immer
nur 9 Bytes lang sind. Da meist alle Bytes auf einmal
ankommen (schätze ich), kann man hier auch weniger
angeben */
{
byte[] buffer = new byte[btConnection.BytesToRead];
// Buffer für die zu empfangenden Bytes
btConnection.BaseStream.Read(buffer, 0, btConnection.BytesToRead);
// Hier werden die vorhandenen Bytes oder noch mehr in den buffer eingelesen
string recived = "";
// Dieser string wird die Nachricht enthalten
for(int i = 0; i < style="color: rgb(51, 102, 255);">/* Wenn das jetztige Byte ein 0 Zeichen enthält, wird das bis jetztige gelesene gelöscht, da dort nur Kontrollinfos sind (?). Nur der letze Inhalt, die Daten, werden behalten. Deshalb das 2.Statment im if */
recived = ""; //Löschen der gelesenen Daten
else
recived += Encoding.ASCII.GetString(new byte[] { buffer[i] });
/Ansonsten Zeichen hinzufügen
}
switch(recived.Substring(0, 3)) /* Nun überprüfen wir die Nachricht. Sehen Sie sich dazu das NXC Programm an */
{
case "CHN": //CHN soll channel bedeuten
Console.WriteLine("wechsle zu Sender " + recived.Substring(4)); /* todo, hier werde ich mit einer shh Bibliothek zu meinem
Server eine Verbindung herstellen, um den Sender mittels
v4lctl zu wechseln. */
break;
case "VOL": //VOL bedeuted volume
Console.WriteLine("Lautstärke: " + recived.Substring(4));
// todo
break;
default:
Console.WriteLine("unbekannter Befehl: " + recived.Substring(0, 3));
break;
}
}
Thread.Sleep(100);
Nun starte ich zuerst dieses Programm (Komplimieren mit gmcs - mono 2.0 C# compiler), danach öffne ich auf meinem NXT dieses NXC Programm (mit linxt schicke ich es zum NXT):/* Öffnet eine Verbindung zur COM Verbindung /dev/rfcomm0
wie man eine Bluetooth Serialschnitstelle erstellen können Sie nachlesen:
http://juju.org/articles/2006/10/22/bluetooth-serial-port-to-nxt-in-linux
*/
btConnection.Open(); //Öffnet die Verbindung
while(true)
{
if(btConnection.BytesToRead >= 9) /* Wenn Bytes zum Lesen vorhanden sind,
hier 9 Bytes, weil meine Nachrichten immer
nur 9 Bytes lang sind. Da meist alle Bytes auf einmal
ankommen (schätze ich), kann man hier auch weniger
angeben */
{
byte[] buffer = new byte[btConnection.BytesToRead];
// Buffer für die zu empfangenden Bytes
btConnection.BaseStream.Read(buffer, 0, btConnection.BytesToRead);
// Hier werden die vorhandenen Bytes oder noch mehr in den buffer eingelesen
string recived = "";
// Dieser string wird die Nachricht enthalten
for(int i = 0; i < style="color: rgb(51, 102, 255);">/* Wenn das jetztige Byte ein 0 Zeichen enthält, wird das bis jetztige gelesene gelöscht, da dort nur Kontrollinfos sind (?). Nur der letze Inhalt, die Daten, werden behalten. Deshalb das 2.Statment im if */
recived = ""; //Löschen der gelesenen Daten
else
recived += Encoding.ASCII.GetString(new byte[] { buffer[i] });
/Ansonsten Zeichen hinzufügen
}
switch(recived.Substring(0, 3)) /* Nun überprüfen wir die Nachricht. Sehen Sie sich dazu das NXC Programm an */
{
case "CHN": //CHN soll channel bedeuten
Console.WriteLine("wechsle zu Sender " + recived.Substring(4)); /* todo, hier werde ich mit einer shh Bibliothek zu meinem
Server eine Verbindung herstellen, um den Sender mittels
v4lctl zu wechseln. */
break;
case "VOL": //VOL bedeuted volume
Console.WriteLine("Lautstärke: " + recived.Substring(4));
// todo
break;
default:
Console.WriteLine("unbekannter Befehl: " + recived.Substring(0, 3));
break;
}
}
Thread.Sleep(100);
#include "NXCDefs.h"
//Dieses Programm ist noch nicht ausgereift :-)
string taskList[]; /*Hier sind Einträge wie "zu ORF1 wechseln" oder "zu SF2 wechseln" */
string command[]; /* Hier werden die tatsächlichen Befehle, die zum Computer gesendet werden */
void SendCommand(string command)
{
BluetoothWrite(0, command);
Wait(500); //Warten bis die Taste losgelassen wird.
}
void DrawMenu(int act) /* Zeichnen des Menüs, es ist ein einfaches Menü, dass in pro Zeile einen Befehl enthält. */
{
ClearScreen(); //Displayinhalt löschen
for(int i = 0; i < i ="=" style="color: rgb(51, 102, 255);">/*act ist die zur Zeit gewählte Aktion, diese wird weiter rechts geschrieben. */
TextOut(10, 56 - i * 8, taskList[i]); /* ich habe hier i * 8
geschrieben, da eine Zeile 8 Pixel hoch ist. 56 - i * 8, damit
das ganze am oberen Displayrand zu sehen ist. */
else
TextOut(0, 56 - i * 8, taskList[i]); //das ist ein normaler Eintrag
}
Wait(500); /* Diese Funktion wird meist aufgerufen, wenn eine Taste betätigt wurde, deshalb wird hier 500 ms gewartet */
}
task main()
{
ArrayBuild(taskList, "zu SF2 wechseln", "zu PRO7 wechseln",
"zu ORF1 wechseln", "channel RTL2", "raise volume");
//Dieser Array ist parallel zu dem command Array
ArrayBuild(command, "CHN SF2", "CHN PRO7", "CHN ORF1",
"CHN RTL2", "VOL UPP");
int active = 0; /* Das aktive Element, bei Programmstart ist das erste gewählt hier wäre das "zu SF2 wechseln" */
DrawMenu(active); //Das Menü zum ersten Mal anzeigen.
while(1)
{
if(ButtonPressed(BTNRIGHT, true) &&
(active + 1) < style="color: rgb(51, 102, 255);">/* Der rechte Button am NXT wurde gedrückt, deshalb wird, falls der Index des aktiven Menüelements + 1 noch ein gültiges Element im Menüarray ist, um 1 erhöht. */
{
active += 1;
DrawMenu(active); /* Da das aktive Menüelement
geändert wurde, muss das Menü neu gezeichnet werden. */ }
if(ButtonPressed(BTNLEFT, true) && (active - 1) >= 0) /* Der linke
Button vom NXT wurde gedrückt. Das heißt, dass wenn der
Index - 1nicht negativ ist, um 1 subtrahiert wird. */
{
active -= 1;
DrawMenu(active);
}
if(ButtonPressed(BTNCENTER, true)) /* Der mittlere Button,
auf dem NXT der orange, wurde gedrückt. Das heißt, dass
der dazugehörige Befehl zum aktiven Menüelement zum
Computer gesendet wird. */
SendCommand(command[active]);
}
}
Den Quelltext oben kann man mit "nbc datei.nxc -O=out.rxe" komplimieren und mit "linxt -u out.rxe" auf den NXT uploaden. Nun hat man einen vollständigen Fernsehersatz, falls der TV-Stream auch vorhanden ist!//Dieses Programm ist noch nicht ausgereift :-)
string taskList[]; /*Hier sind Einträge wie "zu ORF1 wechseln" oder "zu SF2 wechseln" */
string command[]; /* Hier werden die tatsächlichen Befehle, die zum Computer gesendet werden */
void SendCommand(string command)
{
BluetoothWrite(0, command);
Wait(500); //Warten bis die Taste losgelassen wird.
}
void DrawMenu(int act) /* Zeichnen des Menüs, es ist ein einfaches Menü, dass in pro Zeile einen Befehl enthält. */
{
ClearScreen(); //Displayinhalt löschen
for(int i = 0; i < i ="=" style="color: rgb(51, 102, 255);">/*act ist die zur Zeit gewählte Aktion, diese wird weiter rechts geschrieben. */
TextOut(10, 56 - i * 8, taskList[i]); /* ich habe hier i * 8
geschrieben, da eine Zeile 8 Pixel hoch ist. 56 - i * 8, damit
das ganze am oberen Displayrand zu sehen ist. */
else
TextOut(0, 56 - i * 8, taskList[i]); //das ist ein normaler Eintrag
}
Wait(500); /* Diese Funktion wird meist aufgerufen, wenn eine Taste betätigt wurde, deshalb wird hier 500 ms gewartet */
}
task main()
{
ArrayBuild(taskList, "zu SF2 wechseln", "zu PRO7 wechseln",
"zu ORF1 wechseln", "channel RTL2", "raise volume");
//Dieser Array ist parallel zu dem command Array
ArrayBuild(command, "CHN SF2", "CHN PRO7", "CHN ORF1",
"CHN RTL2", "VOL UPP");
int active = 0; /* Das aktive Element, bei Programmstart ist das erste gewählt hier wäre das "zu SF2 wechseln" */
DrawMenu(active); //Das Menü zum ersten Mal anzeigen.
while(1)
{
if(ButtonPressed(BTNRIGHT, true) &&
(active + 1) < style="color: rgb(51, 102, 255);">/* Der rechte Button am NXT wurde gedrückt, deshalb wird, falls der Index des aktiven Menüelements + 1 noch ein gültiges Element im Menüarray ist, um 1 erhöht. */
{
active += 1;
DrawMenu(active); /* Da das aktive Menüelement
geändert wurde, muss das Menü neu gezeichnet werden. */ }
if(ButtonPressed(BTNLEFT, true) && (active - 1) >= 0) /* Der linke
Button vom NXT wurde gedrückt. Das heißt, dass wenn der
Index - 1nicht negativ ist, um 1 subtrahiert wird. */
{
active -= 1;
DrawMenu(active);
}
if(ButtonPressed(BTNCENTER, true)) /* Der mittlere Button,
auf dem NXT der orange, wurde gedrückt. Das heißt, dass
der dazugehörige Befehl zum aktiven Menüelement zum
Computer gesendet wird. */
SendCommand(command[active]);
}
}
Schlüsselwörter: C#,VLC,Mono,Lego NXT,
zuletzt geändert: 29. Juli 2007 21:49
Link zu diesem Artikel: (in die Zwischenablage)
(c) 2011 | Impressum |
| Empfehlenswerte Blog Einträgebaska.jpg)