Samstag, 12. Januar 2013

12. Eine neue DeviceCard wird hinzugefügt


Ich habe von einem lieben Menschen ein etwas älteres IPhone geschenkt bekommen. Mit iPeng wird es zum vollwertigen Squeezedevice. Das wollen wir dem Programm nun hinzufügen.

Achtung: ich habe lange daran gerätselt, warum die Gerätekarte nicht funktioniert. Bei der Fehlersuche hat mir das Squeezeforum (deutsch), inbesondere pippin sehr geholfen. Hier noch einmal meinen herzlichen Dank. 

Folgendes ist grundsätzlich zu beachten: Alles nachfolgend Beschriebenes funktioniert nur, wenn bei iPeng das ausgewählte Gerät der Master ist!!! Das bedeutet, dass der Name des Gerätes oben angezeigt werden muss. Siehe nachfolgendes Bild.



1. Schritt: Das IPhone bekommt einen Namen
Wir müssen dem iPhone einen Namen geben, da wir eine Bestätigung auf das Display schreiben werden, dass der Datenstrom erfolgreich umgeleitet wurde. Ich werde werde es SB-iPhone nennen.


2. Schritt: Das 2-dimensionale Array wird angepasst
Das 2-dimensionale Array im Programm muss angepasst weren und muss nachher wie folgt aussehen. Die blaue Schrift markiert die Änderungen:


//**2-dimensionales Array der Namen der Squeeezegeräte-Namen
char namSbox[8][18]={             // von 7 nach 8 verändert
{"SB-Classic%2001"},
{"SB-Classic%2002"},
{"SB-Touch"},
{"SB-Touch%20PC"},
{"SB-Touch%20Mac"},
{"SB-Classic%20PC"},
{"SB-iPod"},
{"SB-iPhone"} };                  // hinzugefügt


3. Schritt: Die Mac-Adresse des iPhones
Wir benötigen aus dem iPhone die Mac-Adresse. Die gibt es unter Einstellungen-Allgemein-Info-WLAN-Adresse. Meine lautet: 64:B9:E8:28:23:9A, und die tragen wir jetzt in das Programm ein:


//**2-dimensionales Array für alle Mac-Adressen
byte macAdrSbox[8][6]={
{0x00,0x04,0x20,0x12,0xde,0x14},
{0x00,0x04,0x20,0x12,0xdc,0x55},
{0x00,0x04,0x20,0x23,0x72,0x16},
{0x00,0x15,0xaf,0xb8,0xac,0x25},
{0x00,0x26,0xbb,0x0b,0x59,0x2d},
{0xe3,0xf8,0xd4,0xd8,0xae,0xce},
{0x00,0x24,0x36,0x89,0xc4,0x87},
{0x64,0xB9,0xE8,0x28,0x23,0x9A} };


4.Schritt: Die DeviceCard einbinden
Ich habe immer einige RFID-Karten vorrätig, bei denen die UID/PZ schon ausgelesen sind. Davon wähle ich nun die Karte 62-222-174-209-159 und die binden wir nun in dei Software ein.


//**2-dimensionales Array für alle Squeezeboxen (Gerätekarten)
const uchar Squeezebox[8][5]= {
  {110,190,163,209,162},
  {222,225,153,209,119},
  {30,211,170,209,182},
  {94,111,152,209,120},
  {158,29,168,209,250},
  {222,91,164,209,240},
  {142,72,165,209,178},
  {62,222,174,209,159}   };

War es das schon? Nein im Programm muss noch etwas geändert werden:


5. Schritt: Programmänderungen
Es gibt in der loop eine while Schleife, die alle UID/PZ der bekannten DeviceCards abfragt.Die Menge war bisher "7". Das muss in "8" geändert werden.

 while( i<8)            // es werden 8 DeviceCards überprüft
{
  if (memcmp(Squeezebox[i],serNum,5)==0) //Wenn eine DeviceCard gefunden wurde
  {
    memcpy(namTmp,namSbox[i],18);        // Der Name der SBox wird in eine temporäre Variable geschrieben


6.Schritt:  Software aktualisieren
Das sollte jeder können, deshalb: kein Kommentar :-)


7. Schritt: Der Test
Es ist zu beachten, dass die Software wiederholtes Auflegen der gleichen Karte nicht auswertet! Das bedeutet, wenn man die Funktion wiederholt testen möchte, muss man eine andere RFID-Karte zwischendurch auswerten lassen. Wenn alles richtig gemachte wurde, wird nach dem Auflegen der DeviceCard vom SB-iPhone folgende Meldung angezeigt:



Durch die Software iPeng mit der Playerfunktion wird das iPone in einer Dockinstation zu einem vollwertigen Squeezedevice.

soweit für heute ... an dem beabsichtigten Video arbeite ich noch.

Freitag, 11. Januar 2013

11. Die CDCard - und die Playlist für Squeezebox

Als ich die ersten Versuche in diesem Projekt begonnen hatte, bestand das eigentliche Ziel daraus, einen schnellen Zugriff auf die Musik meiner CD's zu haben. Dass es sich so entwickelt hat, war mir auch nicht bewusst. Also wollen wir uns kurz der CDCard zuwenden.

Eigentlich ist die theoretische Seite klar: Wir benötigen eine erweiterte Playlist im Format .m3u . Wie die grundsätzlich auszusehen hat, haben wir gestern gesehen. Also grundsätzlich gibt es keine Probleme. Keine Probleme?? Die meisten Playlists von anderen Programmen sind nicht erweitert - sie funktionieren nicht. Also habe ich dafür ein funktionierendes Verfahren für mich vorgesehen. Ich möchte es an dieser Stelle für all diejenigen vorstellen, die mit der Playlist genauso kämpfen wie ich.

Ich gehe davon aus, dass das Rippen einer CD sehr wohl fast jedem bekannt ist. Zur Info: ich rippe mit Audiograbber. Die Files liegen danach im mp3-Format in einem speziellen CD-Ordner vor.

Ich habe diese Woche von meinem Heizöllieferanten eine CD "Après Ski Classics" geschenkt bekommen, die soll mir jetzt als Beispiel dienen.

Beim Grabben kann Audiograbber auch eine Playlist m3u erzeugen. Die sieht dann so aus - einfach arm:

01 - Tim Toupet - Du hast die Haare schön-1.mp3
02 - K2 - Der Berg ruft (Remix 2000).mp3
03 - Olaf Henning - Cowboy & Indianer (komm hol das Lasso raus).mp3
04 - Jürgen Drews - König an der Schneebar.mp3
05 - The BossHoss - Hey Ya!.mp3
06 - Peter Wackel - Après Ski.mp3
07 - Helmut Aus Mallorca - Der alte Holzmichel.mp3
08 - A-Teens - Gimme! Gimme! Gimme!.mp3
09 - Scooter - The Question is what is the Question.mp3
10 - Didi Diesel - I bin der Champ.mp3
11 - Henning & Holm - Maddalena 2001 (Du Luder).mp3
12 - Bata Illic - Michaela.mp3
13 - Sonthofen Allstars - Alles Wunderbar.mp3
14 - Cascada - Everytime we touch.mp3
15 - Hermes House Band - I will Survive (Radio Edit).mp3


Das ist definitiv kein erweitertes Format!!  Da lacht sich der LMS schlapp!!! Das geht besser.  Dazu benötigen wir das für mich beste Editier-Programm für MP3's - MP3Tag. Zum Zeitpunkt dieses Blogs mit Version 2.54. Die RFID-Karte ist schon identifiziert und hat die UID/PZ 78-12-179-209-32. Ich habe nun in die ID3-Tags ein neues Feld hinzugefügt: RFID-Karte.

MP3Tag mit den neuen Feldern EAN-Nummer und RFID-Karte


Wir benötigen dieses Feld später beim Export noch.

In MP3Tag gibt es unter Datei - Export die Möglichkeit, eine Exportdatei zu beschreiben. Mein Export heißt natürlich Squeezebox-Playlist (wie denn sonst). Die Syntax dafür lautet:

$filename(U:\playlists\%RFID_CARD%.m3u,utf-8)
#CURTRACK 0
#EXTM3U$loop(%track%)
#EXTURL:file:///volume1/music/$cutLeft($replace(%_path%,\,/, ,'%20'),3)
#EXTINF:%_length_seconds%,%title%
/volume1/music/$cutLeft($replace(%_path%,\,/),3)$loopend()


Da wir hier als Schwerpunkt definitiv nicht MP3Tag haben, nehmt es an und legt euch euren eigenen Export an. beim Export öffnet sich dieses Fenster. Wichtig ist, dass der Dateiname wie im Bild eingetragen wird. Dann holt sich das Programm automatisch die RFID-Nr. aus dem ID3-Tag. Wenn wir jetzt OK drücken bekommen wir DIE Playliste die wir benötigen und das im richtigen Ordner gespeichert. Toll!!

Die Playliste hat jetzt folgenden Inhalt:











#CURTRACK 0
#EXTM3U
#EXTURL:file:///volume1/music/Pop/Sampler/Après%20Ski%20Classics/01%20-%20Tim%20Toupet%20-%20Du%20hast%20die%20Haare%20schön.mp3
#EXTINF:223,Du hast die Haare schön
/volume1/music/Pop/Sampler/Après Ski Classics/01 - Tim Toupet - Du hast die Haare schön.mp3
#EXTURL:file:///volume1/music/Pop/Sampler/Après%20Ski%20Classics/02%20-%20K2%20-%20Der%20Berg%20ruft%20(Remix%202000).mp3
#EXTINF:236,Der Berg ruft (Remix 2000)
/volume1/music/Pop/Sampler/Après Ski Classics/02 - K2 - Der Berg ruft (Remix 2000).mp3
... usw,

Das sieht doch definitiv eher nach erweiterter Playlist aus - und funktioniert auch.

Hier liegt sie im Verzeichnis playlist mit all den Anderen.



Funktioniert????  Nein! Eine Fehlermeldung macht sich breit. Die kann ich heute gar nicht gebrauchen!!


Das liegt mit Sicherheit in dem Playlist-Script. Da fällt mir direkt auf:

#EXTURL:file:///volume1/music/Pop/Sampler/Après%20Ski%20Classics/01%20-%20Tim%20Toupet%20-%20Du%20hast%20die%20Haare%20schön.mp3

Im ersten Track ist ein deutsches Sonderzeichen enthalten. Und Sonderzeichen mag der LMS überhaupt nicht. Das "ö" macht Ärger!!

Im Script wird in derZeile

#EXTURL:file:///volume1/music/$cutLeft($replace(%_path%,\,/, ,'%20'),3)

in der ein "\" durch "/" und ein " " durch %20 ersetzt ($replace) wird, wie folgt geändert:

#EXTURL:file:///volume1/music/$cutLeft($replace(%_path%,\,/, ,'%20',ä,%C3%A4,ö,%C3%B6,ü,%C3%BC),3)


Die Fehlermeldung bleibt nun aus! Sollte es doch noch mal zu solchen Fehlermeldungen kommen müsst ihr in diesem Umfeld suchen!

Die RFID-Karte wird nun im CD-Cover versteckt und ist von außen nicht zu sehen.



Das habe ich mit allen meinen CD's gemacht: Gerippt - in der Datenbank gespeichert - RID-Karte vorbereitet - Playlist erzeugt und gespeichert - CDCard in CD-Cover versteckt. FERTIG!  Bei über 300 CD's keine Arbeit für einen Tag - das ziiiiieeeeeht sich! :-)  Das Ergebnis ist aber immer wieder eine Freude.

Ich hatte am Anfang gedacht, dass es irre lange dauert eine bestimmte Playlist in dieser Menge zu finden. Das Gegenteil ist der Fall! Dadurch, dass die Inhalte in einem Verzeichnis sortiert werden ist alles schön "durchnummeriert", Macht euch die Mühe, die UID und PZ auf die Karte zu schreiben! Das vereinfacht eine eventuelle Fehlersuche erheblich.

Wir gehen langsam auf die Zielgerade. Wie nun eine PlaylistCard gebaut wird, sollte nach den Durchlesen der letzten Blogs keine Schwierigkeiten mehr bereiten. Das überlasse ich euch! WEr dabei trotzdem noch Probleme hat, kann sich ja bei mir melden.

Das nächste Mal wollen wir das Ding im Einsatz sehen. Video? Mal sehen. Es wird definitiv etwas dauern.



Donnerstag, 10. Januar 2013

10. Die RadioCard als "Stationstaste"

Manchmal ist es schon lästig sich seine Lieblingsstation auszuwählen. Zugegebenermaßen helfen die Favoriten da erheblich.

Damit sind wir wieder beim WAF (siehe blog vom 07.01.13). Das Navigieren, wohlmöglich noch durch einen Verzeichnisbaum (weil alles so schön geordnet sein soll) ist manchmal mehr als lästig.

Hier soll die RadioCard einspringen. RadioCard auflegen und schon gibt's was auf die Ohren.

Schauen wir uns mal den SW-Teil an. Nachdem die Gerätekennung durchlaufen wurde und feststeht, dass keine DeviceCard vorliegt, muss es eine von den Karten sein, für die eine Playlist hinterlegt wurde.

if (steuerkarte == 0)
          {
          Serial.println(steuerkarte);
          // dsplRFID(macAdrTmp);
          playPlaylist(macAdrTmp);
          }


Das war es schon und ab in das Unterprogramm (nun nehmen wir aber die temporäre Mac-Adresse mit).

Hier das Unterprogramm in seiner kompletten Pracht:

void playPlaylist(byte* macAdrSbox)
{
  snprintf(SBox, 150, "GET /status?p0=playlist&p1=resume&p2=%d-%d-%d-%d-%d&player=%02x:%02x:%02x:%02x:%02x:%02x HTTP/1.1", serNum[0], serNum[1], serNum[2], serNum[3], serNum[4], macAdrSbox[0], macAdrSbox[1], macAdrSbox[2], macAdrSbox[3], macAdrSbox[4], macAdrSbox[5]);
  client.stop();
  client.connect(server,9002);
  delay(1000);
  Serial.println(F("connecting..."));
  if (client.connected())
    {
    Serial.println(F("connected"));
    while (client.available())
    {
      char c = client.read();
    }
    Serial.println(SBox);
    client.println(SBox);
    client.println();
    Serial.println(F("abgesetzt"));
    }
   
  else
    {
    Serial.println(F("connection failed"));
    }
    Serial.println(F("Serverdaten lesen"));

  if (!client.connected())
    {
    Serial.println();
    Serial.println(F("disconnecting."));
    client.stop();
    }
}


Das, was hier an den Server gesendet wird, ist wohlvertraut. Lediglich die gesendeten Parameter sehen anders aus.

Nun wird gesendet (Beispiel);
GET /status?p0=playlist&p1=resume&p2=254-122-179-209-230&player=00:15:af:b8:ac:25 HTTP/1.1

Kurze Erläuterung:
p0 = es soll eine playlist gespielt werden
p1 = resume bedeutet, dass eine aktuelle Playlist abgebrochen wird und durch die unter p2 ersetzt wird. Auf die Dateierweiterung wird verzichtet, muss aber als .m3u vorhanden sein

Erst hier werden die Bindestriche zwischen den einzelnen UID-Werten erzeugt,

Der Befehl playlist kennt jede Menge weitere Parameter. Hier sei wieder auf das Command Line Interface (CLI) verwiesen. Siehe gestern (9.).

Auf dem Server gibt es ein Verzeichnis music/playlists. Dort "wohnt" die Playliste 254-122-179-209-230.m3u   mit dem Inhalt:

#EXTM3U
http://opml.radiotime.com/Tune.ashx?id=s96815&formats=aac,ogg,mp3,wmpro&partnerId=16&serial=158f087abcf88503358ccf826d66a5b0


Wir haben es hier auf jeden Fall mit einer erweiterten Playliste zu tun. Hierzu ein Zitat aus Wiki (http://de.wikipedia.org/wiki/M3U):

Die erste Zeile #EXTM3U ist die Einleitung der Kopfdaten und legt das Format der M3U fest, bei erweiterten M3Us ist immer als erste Zeile #EXTM3U zu verwenden.
Nach der ersten Zeile folgt der eigentliche Inhalt der M3U. Pro Mediendatei werden 2 Zeilen benötigt:

  • Die 1. Zeile beginnt immer mit #EXTINF:, danach folgt die Länge der Mediendatei in ganzen Sekunden. Nach der Länge wird ein Komma als Trennzeichen verwendet, danach folgt der Name der Mediendatei, welcher zur Anzeige im Medienspieler dient. Wenn die angegebene Länge kleiner als die tatsächliche Länge ist, wird wie beim PLS-Format die angegebene Länge nicht beachtet. (Setzt man die Länge auf −1, wird sie ebenfalls nicht beachtet.)
  • Die 2. Zeile ist identisch mit der Spezifikation von einfachen M3Us, hier wird der volle Dateiname mit absolutem oder relativem Pfad oder eine URL zu einer Datei auf einem Webserver angegeben
Also beginnen wir uns ein Playliste für die Freunde des WDR4 (not my favorite) zu basteln. Eine neue RFID-Karte wird einfach mit geöffnetem Serial Monitor des Arduino gelesen. Dort ist dann der Befehl in seiner kompletten Form zu sehen:

GET /status?p0=playlist&p1=resume&p2=238-8-172-209-155&player=00:15:af:b8:ac:25 HTTP/1.1

Also muss die Playliste 238-8-172-209-155.m3u heißen-

Dazu benötigen wir ein leeres Dokument, welches wir über einen Editor erzeugen.

dahinein schreiben wir schon mal 
#EXTM3U
#EXTINF:-1,


Jetzt benötigen wir nur noch den Link auf den externen Stream. Es gibt Links mit und ohne Stationslogo. Die Besten sind immer noch die, die durch den LMS erzeugt werden. Dazu suchen wir die Radiostation WDR4 im Menüpunkt Radio und fügen sie den Favoriten hinzu. Wenn wir jetzt in den LMS gehen, Und dort Hauptmenü - Favoriten auswählen, finden wir  rechts in der Zeile von Favoriten das Symbol eines Stiftes. Anklicken und WDR4 auswählen. Auch dort finden wir den Stift erneut. Anklicken. Jetzt ist folgendes Bild zu sehen:


Wir sehen zwei Felder, in denen wir etwas ändern könnten. Auf der linken Seite können wir die Anzeige anpassen. Die Änderung hier würde sich nicht auf die RadioCard auswirken, sondern nur auf die Favoriten-Anzeige. In der Mitte sehen wir den Link:

http://opml.radiotime.com/Tune.ashx?id=s100166&formats=aac,ogg,mp3,wmpro&partnerId=16&serial=158f087abcf88503358ccf826d66a5b0

Das ist unser gesuchter Link! Den wollen wir nicht ändern, sondern ihn nur ins Clipboard kopieren. Wir fügen den Link aus dem Clipboard in unser Dokument ein. Zum Schluss unter 238-8-172-209-155.m3u im Ordner music/playlists/  speichern und FERTIG!

Nach Auflegen der RadioCard zeigt der SqueezePlay-Player den nachfolgenden Bildschirm:


Als Gimmik gibt es noch die UID und PZ dazu. Alle anderen Links im Internet, die ich gefunden habe, zeigten kein Sender Logo! Leider gibt es auch Stationen, die im LMS kein Logo haben, z.B. BBC4.

Es gibt noch eine einfachere Möglichkeit. Unter Internetradio - Suchen im LMS den gewünschten Sender eingeben und danach auswählen. Dann ist der Link ebenfalls sichtbar.


Beim nächsten Mal geht es um die CDCard. Da schauen wir uns an, wie die Playlisten aus der Musik-Datenbank schnell erzeugt werden können.

Mittwoch, 9. Januar 2013

9. Die DeviceCard sendet eine Nachricht



Heute schauen wir uns mal den Codeschnipsel an, der für die gestern gezeigte Nachricht zuständig ist.

Ich hatte schon erwähnt, dass, bevor eine CDCard  oder RadioCard abgearbeitet werden kann, sichergestellt werden muss, dass es keine DeviceCard ist. Das Ergebnis der Überprüfung befindet sich in der Varablen boolean deviceCard=0;  // Erkennungsflag, ob DeviceCard.  Die Variable hatten wir gestern in den Squeezebox-Settings. Der folgende Code steht in der void loop(void)


// ****** Dieser Block überprüft ob die Karte eine Gerätekarte ist.
i=0;

while( i<7) {
   if (memcmp(Squeezebox[i],serNum,5)==0)   //Prüfung ob Gerätekarte für SB3 01 {

Hier ein klassischer Vergleich von zwei Speicherbereichen (memory compare). Squeezebox[i] wird aus dem 2-dimensionalen Array gelesen, in dem alle UID/PZ enthalten sind. serNum ist mit 5 Byte definiert worden. Das Ergebnis des Vergleichs muss Null sein. Wenn das Ergebnis Null ist beginnen die Vorbereitungen der Anzeige.

Für Squeezebox-Fans kann ich an dieser Stelle die Informationen zum Command Line Interpreter (CLI) empfehlen. Zu finden über: Hilfe > Technische Informationen > Command Line Interface des LMS. Der Hilfe-Button ist unten links auf der Eingangsseite zum Logitech Media Server. 

Wir benötigen folgende Zeichenfolge:
"GET /status?p0=display&p1=<Nachricht1.Zeile>&p2=<Nachricht 2. Zeile>&p3=<Dauer in Sekunden>&player=<Mac-Adresse des Zielplayers>HTTP/1.0"


memcpy(namTmp,namSbox[i],18);

Der Name der SB wird in einen temporäre Variable gespeichert. Damit steht beim nächsten Schleifendurchlauf auch der letzte aufgerufene Name

memcpy(macAdrTmp,macAdrSbox[i],6); 

bzw. Mac-Adresse zur Verfügung. Jetzt ist alles da, was ich zum vernünftgen Anzeigen benötige. Also rufe ich das Unterprogramm


dsplMsgSB();

auf. Damit klar ist, dass wir uns in einer Subroutine befinden wird der Code in blau geschrieben.

void dsplMsgSB() {

Jetzt müssen wir uns aber dringend um die Parameter p1, p2 und player kümmern.

p1 = RFID-Steuerung%%20wurde%%20erfolgreich%%20nach (die %%20 sind zwischenräume weil das %-Zeichen anderweitig belegt ist.)
p2 = %s%%20umgeleitet (%s steht für die variable namTmp.)
player = %02x:%02x:%02x:%02x:%02x:%02x (an die Stelle von %02x wird der Reihe nach eine Variable eingetragen. Also macAdrTmp[0], macAdrTmp[1], macAdrTmp[2],... u.s.w. bis macAdrTmp[5]

Das schreiben wir jetzt in geordneter Art und Weise in einen vorgesehenen Speicherbereich.

snprintf(SBox, 150, "GET /status?p0=display&p1=RFID-Steuerung%%20wurde%%20erfolgreich%%20nach&p2=%s%%20umgeleitet&p3=10&player=%02x:%02x:%02x:%02x:%02x:%02x HTTP/1.0",
namTmp, macAdrTmp[0], macAdrTmp[1], macAdrTmp[2], macAdrTmp[3], macAdrTmp[4], macAdrTmp[5]);

Alles was in "  " steht ist anschließend in der 150 Byte Variablen mit dem Namen SBox gespeichert

Der Rest ist einfach. Server verbinden und SBox senden.

client.connect(server,9002);
  if (client.connected())  

  {
    while (client.available())   

      {
      char c = client.read();
       }
  client.println(SBox);
  client.println();
  }
  else
  {
    Serial.println(F("connection failed"));
  }
  client.stop();

}

... und nun nichts wie zurück!!!!



devicecard = 1;
Serial.println("DeviceCard ist 1"); // zu Testzwecken
break;
}
i++;
}

Die Variable deviceCard wird auf true(1) gesetzt und fertig. Damit wird ein nachfolgender Teil nicht ausgeführt. Dort wird erst abgefragt, welchen Wert deviceCard hat.

Was ist, wenn die Karte auf dem Leser liegenbleibt? SBox wird immer wieder gesendet; wenn nicht beim jedem Durchlauf überprüft würde, ob eine neue (andere) UID/PZ vorliegt. Wenn das nicht der Fall ist, wird alles, was oben beschrieben ist, nicht ausgeführt!

if (memcmp(data,serNum,5)!=0)
   {
   memcpy(serNum,data,5);

Beim ersten loop-Durchlauf ist serNum ohnehin leer und der Vergleich wird  != 0 sein. Danach werden die empfangenen Daten (data) nach serNum kopiert. Beim nächsten Durchlauf wird data == serNum sein; das bedeutet: alles wird übersprungen. Das gilt für die DeviceCard genauso wie für die RadioCard oder CDCard.

Zum Schluss eine kleine Übung:
Auf dem Display soll folgende Nachricht erscheinen "Herzliche Grüße aus Entenhausen!". MacAdresse ist 00:15:af:b8:ac:25 und soll für 30 Sekunden angezeigt werden.

Da wir "nur" eine konstante Nachricht haben lautet die Zeile

snprintf(SBox, 150, "GET /status?p0=display&p1=Herzliche%%20Gruesse%%20aus&p2=Entenhausen%%20von%%20Dagobert&p3=30&player=00:15:af:b8:ac:25 HTTP/1.0");

 ... und das sieht nachher auf einer Squeezebox-Touch so aus:



Ungeahnte Möglichkeiten tun sich nun auf. Mit einem Arduino und einem Ethernet Shield kann ich mir beliebige Systemmeldungen auf dem Display anzeigen lassen. Wer laute Musik hört, bekommt bei einem Besucher vor der Tür die Anzeige "Es klingelt!!!". Die Möglichkeiten sind dank der Offenlegung der Schnittstelle beliebig. Das erkennt man auch an den vielen Add-Ons, die für den LMS verfügbar sind.


Das nächste Mal wenden wir uns der RadioCard zu. Das ist wirklich einfach.

Dienstag, 8. Januar 2013

8. Software-Settings und die DeviceCard

Die Software ist zum Download bei Google.code eingestellt. Hier der


Die Software ist eine funktionsfähige Version, die in einigen Punkten auf die eigenen Bedürfnisse angepasst werden müssen. Wer Fehler entdeckt oder Verbesserungen hat, möge mich benachrichtigen.

Nachdem die allgemeine Abfrage der RFID-Karte durch den downloadbaren Adafruit-Sketch (Link bereits geblogged) sehr einfach ist, geht es jetzt um die Steuerung der Squeezegeräte und die Zusammenarbeit mit dem SqueezeCenter (heute Logitech Media Server = LMS).

Grundsätzliches
Alle Media Geräte der Squeezegruppe benötigen zum Abspielen von Musikinhalten einen Server. Das ist entweder der Server im Internet (mysqueezbox.com) oder wie bei mir der LMS, der auf einem Gerät im Netz läuft; einzelne Geräte haben einen Server in der internen SW (Squeezebox Touch).

Ich betrachte nur die Variante LMS im lokalen Netz. Die meist genutzte Betriebsart dürfte die Einzelsteuerung sein.


Jeder Player wird vom LMS individuell gesteuert. Um diese Individualität beizubehalten, ist bei einer RFID-Steuerung im Netz erforderlich, dem Server mitzuteilen, für welches Gerät der/die folgende/n Befehl/e gedacht sind. Diese Mitteilung an den LMS, welches Zielgerät gewünscht wird, übernimmt die DeviceCard.

Wenn es eine Einzelsteuerung gibt, muss es auch eine Gruppensteuerung geben. Über das Setup der Geräte kann man einzelne Gruppen bilden oder alle Geräte logisch zusammenschalten. Die Gruppenbildung kann nicht über diese Software vorgenommen werden!!  Dazu reicht leider die Kapazität des Arduino nicht.  


Alle Aktionen an einem Gerät innerhalb einer Gruppe wirken sich auf alle anderen in gleicher Weise aus! Ich bezeichne die Gruppensteuerung gerne als Partymode. In allen Räumen die gleiche Musik!

Wenn alle Geräte in Gruppensteuerung laufen, ist es unerheblich an welches Gerät der Datenstrom geleitet wird. Es betrifft ja ohnehin alle Geräte. Dann kann man sich die DeviceCard auch sparen.

Zur Software:
Ich beschreibe die SW in den wesentlichen Teilen, die projektspezifisch sind.


// ***** Squeezebox-Settings *****
uchar serNum[5]; // Seriennummer der gelesenen Karte 
char namTmp[20]="SB%20Touch PC";  // Aktueller Gerätename mit default
char SBox[150]; // Reservierter Speicherplatz für die Zeichenkette an den Server

boolean steuerkarte=0; // Erkennungsflag, ob GeräteCard

In diesem Teil werden Speicherbereiche für bestimmte Inhalte reserviert. Ich arbeite bewusst nicht mit Strings, weil die unkontrolliert Speicherbereich belegen. Das führte bei mir dann dazu, dass irgendwann das Programm stehen bleibt. Also habe ich mit Hilfe des deutschen Forums umgestellt. Jetzt werden die oben gezeigten Speicherstellen gezielt "befüllt".


// +++++++++++++++++++++++++++ zur Information ++++++++++++++++++++++++++++
/**** Geräte-Karten-ID's unter denen die Geräte angesprochen werden ****
 * const uchar Squeezebox01[5]={110,190,163,209,162};    //Squeezebox1 = SBClassic Wohnzimmer
 * const uchar Squeezebox02[5]={222,225,153,209,119};    //Squeezebox2 = SBClassic Küche
 * const uchar Squeezebox03[5]={30,211,170,209,182};     //Squeezebox3 = SBTouch
 * const uchar SqueezeplayPC[5]={94,111,152,209,120};    //Squeezebox4 = SBTouch PC (Squeezeplay)
 * const uchar SqueezeplayMAC[5]={158,29,168,209,250};   //Squeezebox5 = SBTouch MAC (Squeezeplay)
 * const uchar SoftsqueezePC[5]={222,91,164,209,240};    //Squeezebox6 = SBClassic PC (Softsqueeze)
 * const uchar iPengIPOD[5]={142,72,165,209,178};        //Squeezebox7 = SBiPeng (iPOD) */



In diesem Bereich sind lediglich die UID/PZ informativ aufgeführt. Könnte man auch löschen, wenn man möchte. 

//**2-dimensionales Array für alle Squeezeboxen (DeviceCards)
const uchar Squeezebox[7][5]= {
  {110,190,163,209,162},
  {222,225,153,209,119},
  {30,211,170,209,182},
  {94,111,152,209,120},
  {158,29,168,209,250},
  {222,91,164,209,240},
  {142,72,165,209,178}   };



Es gibt im Ablauf zuerst einen Bereich, in dem überprüft wird ob es sich um eine DeviceCard handelt. Dazu müssen alle UID der DeviceCards bekannt sein.


//**2-dimensionales Array für alle Mac-Adressen
byte macAdrSbox[7][6]={
  {0x00,0x04,0x20,0x00,0x00,0x00},
  {0x00,0x04,0x20,0x00,0x00,0x00},
  {0x00,0x04,0x20,0x00,0x00,0x00},
  {0x00,0x15,0xaf,0x00,0x00,0x00},
  {0x00,0x26,0xbb,0x00,0x00,0x00},
  {0xe3,0xf8,0xd4,0x00,0x00,0x00},
  {0x00,0x24,0x36,0x00,0x00,0x00}  };

 

Der Befehl an den Logitech Media Server enthält die Zieladresse der angesprochenen Squeezebox. Diese Zieladresse muss SW-mäßig eingestellt werden. Deshalb stelle ich immer einen Default-Wert ein.  

// +++++++++++++++++++++++++ Einstellen des aktuellen Default-Wertes ++++++++++++++++++++++++
//byte macAdrTmp[6]= {0x00,0x04,0x20,0x00,0x00,0x00}; //default SBClassic Wohnzimmer
//byte macAdrTmp[6]= {0x00,0x04,0x20,0x00,0x00,0x00}; //default SBClassic Küche
//byte macAdrTmp[6]= {0x00,0x04,0x20,0x00,0x00,0x00}; //default SBTouch

byte macAdrTmp[6]= {0x00,0x15,0xaf,0xab,0xcd,0xef}; //default SBTouch PC (Squeezeplay)
//byte macAdrTmp[6]= {0x00,0x04,0x20,0x00,0x00,0x16}; //default SBTouch MAC (Squeezeplay)
//byte macAdrTmp[6]= {0x00,0x04,0x20,0xab,0xcd,0xef}; //default SBClassic PC (Softsqueeze)
//byte macAdrTmp[6]= {0x00,0x04,0x20,0xab,0xcd,0xef}; //default SBiPeng (iPod)

 

Damit das einfacher geht, habe ich alle Möglichkeiten vorab aufgeführt, von denen ich mir eine aussuche. Für meine Testversuche war das sehr hilfreich.
 

//**2-dimensionales Array der Namen der Squeeezegeräte-Namen
// Hier nicht über 18 Zeichen hinausgehen! Sonst ändern!

char namSbox[7][18]={
  {"SB-Classic%20(WZ)"},
  {"SB-Classic%20(KU)"},
  {"SB-Touch"},
  {"SB-Touch%20PC"},
  {"SB-Touch%20Mac"},
  {"SB-Classic%20PC"},
  {"SB-iPeng%20iPOD"}   };



Wenn der Datenstrom auf ein anderes Squeezebox-Gerät umgeleitet wurde, wird eine Meldung für das neue Gerät generiert, dass der Datenstrom erfolgreich umgeleitet wurde. Wie das gemacht wird zeige ich später.
Nachricht auf SB-Touch PC

Nachricht auf SB-Classic PC


Die Bilder zeigen die Software-Varianten der SB-Touch und der SB-Classic.

Beim nächsten Mal sehen wir und den Codeschnipsel an, der für die Nachricht zuständig ist.

Montag, 7. Januar 2013

7. So sieht die RadioCard von innen aus!!

Nun habe ich mein Board verdrahtet. Wie zu sehen ist, war das wirklich keine große Sache. Nicht gerade schön, aber zweckmäßig. Für die zusätzliche Steckerleite ist das Lochrasterfeld sehr gut zu gebrauchen.





Leider unscharf















Jetzt noch schnell die Verdrahtung zum Arduino und nun kann der erste Test beginnen. Ich habe vorher schon die Dateien aus github mir heruntergeladen und im Ordner F:\arduino\arduino-1.0.3\libraries untergebracht.

Ich möchte mir einen Hex-Dump von dem 1K Speicher auf der Karte anzeigen lassen. Dafür lade ich den Sketch mifareclassic_memdump.pde in den Arduino. Unsere RadioCard in die Nähe gebracht und schon rattert der Arduino los!

Mein RFID-Board lebt!!

Der SerialMonitor zeigt folgendes Ergebnis:


Das sieht sehr gut aus!! Alles HEX-Werte :-(. Ich  wollten doch dezimale Zahlen haben. Erst mal der Reihe nach. Zum Bild: Die Mifare S50 Karte hat -wie bekannt- 1K Speicher und der ist unterteilt in 16 Sektoren (0-15). Jeder Sektor hat 4 Blöcke mit je 16 Byte (0-15). Wenn wir mal rechnen:

16 Sektoren*4 Blöcke*16 Byte= 1024 Byte = 1KByte

Ich habe im Bild oben nur die ersten vier Sektoren dargestellt, die restlichen 12 sehen genauso aus - versprochen!

Der Sektor "0" ist etwas Besonderes. Dort liegt der Block 0, der dem Hersteller gehört. Die ersten vier Bytes sind die UID (hier: FE 48 98 D1) gefolgt von der Prüfsumme (hier: FF). Das ist genau die Information, an die ich herankommen muss, um daraus meine Playlist-Nummer zu basteln.


Wenn ich die Hex-Werte FE 48 98 D1 FF in dezimale Werte umrechne, erhalte ich:

 
254 72 152 209 255....und das kommt mir sehr bekannt vor! Die RadioCard !










Sonntag, 6. Januar 2013

6. Das Platinen-Layout von ID:789

Den gestrigen Tag habe ich mit dem Hinweis auf die .brd-Datei verlassen. Die .brd-Datei hat nichts mit der Bunderepublik Deutschland zu tun, sondern zeigt das Layout der Platine.

Hier mal ein Überblick:
Copyright Adafruit

Zusammen mit der .sch-Datei kann ich alle relevanten Punkte auf dem Board finden. In der .brd-Datei finden sich alle Bauteile-Bezeichnungen, auch die, die nicht auf dem Shield aufgedruckt sind. Ich habe mal alle wichtigen Baugruppen und Platinenpunkte in einem Bild zusammengefasst.


Allgemein kann ich sagen, dass genügend Möglichkeiten, um irgendetwas anzuschließen, vorhanden sind. Es ist gut erkennbar, dass viele Ein-/Ausgänge nicht verwendet werden, sondern nur deshalb vorhanden sind, um das Board stapelbar zu machen. Für jemanden, der das Board wirklich als Shield benutzt, ist es quasi plug 'n play. Wer aber - so wie ich - das Shield "auslagern" möchte, muss sich schon mit der Pinbelegung auseinandersetzen.

Auf dem Foto, sieht es so aus, als hätte ich vier Lötpunkte, um Ground anzuschließen. Wirklich vier? Ein Blick auf das Layout gibt Auskunft. Aha!! Nur ein einziger ist möglich. Das ist genau das, was ich gestern meinte: Ein Blick auf das Layout lohnt sich!

Kurze Erläuterung zu den gelben Kästchen:
Q1 = Pegelwandler SDA
Q2 = Pegelwandler SCL
Q3 = Pegelwandler SCK
Q4 = Pegelwandler RSTP
FSR = Festspannungsregler 5V/3.3V
IRQ = Anschaltung einer LED an den Interrupt (IRQ)

Die grünen Leitungen stellen die beiden Leitungen SDA und SCL dar. Sie sind an fünf verschiedenen Punkten abgreifbar:

SDA: Oben links 2x (SDA), MOSI (gesonderte Steckerleiste), und unten rechts 2x (Analog In 4)
SCL: Oben rechts 2x (SCL), SS (gesonderte Steckerleiste) und unten rechts 2x (Analog In 5).

Die gelben Leitungen sind die Punkte, die ich auf eine gesonderte Steckerleiste führen werde.


Als Nächstes geht es an die "Verdrahtung" und es gibt den 1. Testlauf.

Samstag, 5. Januar 2013

5. Der RFID-Karte auf den Zahn gefühlt

Ich habe mir also  die RFID-Karte ID:789 von Adafruit zugelegt. Wie es sich gehört, wird zuerst mal nachgesehen, was denn bei Adafruit dafür verfügbar ist. Mich interessiert zum jetzigen Zeitpunkt nur die Hardware.

In dem Produktblatt sind verschiedene Reiter zu finden, die wir uns der Reihe nach mal ansehen wollen:

Reiter "Beschreibung"
Hier sind wertvolle Beschreibungen und Hinweise zum Aufbau enthalten. Auch wer die SPI-Schnittstelle benutzen möchte, soll sich die Hinweise zu Gemüte führen. Kurz und gut: Pflichtlektüre.

Reiter "Technische Einzelheiten"
Die nackte Größenangabe ist hier definitiv zu mager. Ich hätte grundsätzlich Angaben zum Stromverbrauch bei verschiedenen Zuständen erwartet. Welche Spannungen werden/können verwendet werden? Leider keine Antworten.

Reiter "Tutorials"

  • Sehr gute Zusatzinformationen zum Thema RFID. Hier konnte ich auch tiefergehende Daten zu den RFID-Karten, die ich  einsetzen werde, finden. Ich benutze Mifare S50 - Karten. In dem genannten Dokument gibt es dazu mehr. Wirklich lesenswert!
  • Da ich nicht die Funktion NFC von Handys benutzen werde und ich da nicht 'reingeschaut habe, kann ich hierzu auch nichts schreiben.
  • Die weiteren Informationen sind Datenblätter und Zeitdiagramme. Die Datenblätter können viele Fragen beantworten, wenn es nicht mehr weitergeht. Ich komme auf die Datenblätter nochmal zurück
Reiter "Download"
Hier bin ich auf eine falsche Fährte geführt worden. Da muss man höllisch aufpassen!!

Die Links zu den Libraries funktionieren und leiten uns auf die benötigten I2C-Sketche. Die werde ich zu einem späteren Zeitpunkt ausprobieren.

Das Antennen-Design bezieht sich auf den verwendeten RFID-Chip PN532 von NXP. Der wird auf meinem Board verwendet. Also auch ok.

Das Schaltbild unter Schematics soll später folgen; es gibt aber einen Link, der funktioniert - und der landet auf dem Schaltbild des Breakout-Boards (ID:364)!! Ich habe es nicht sofort gemerkt, und mich gefragt, wie das mit der Spannungsversorgung und den Pegeln auf den Ein und Ausgängen ist. Ein Blick in die Datenblätter sagt mir, dass die max. Spannung 3,6V ist. Aus- und Eingangspegel liegen bei 3.3V. Die Frage, die ich mir stelle: Wie kann ich den Pegel anpassen? Das Tutorail zeigt nämlich das Breakout-Board mit einer zusätzlichen Pegelanpassung. Brauche ich die auch?

Dann habe ich mal im Forum bei Adafruit gesucht und bin auch fündig geworden. In einem Post vom 13.11.2012 fragt jemand nach dem Schaltbild von dem NFC-Shield. In der Antwort gibt es einen Link auf github, Dort gibt es u.a. eine .brd und eine .sch-Datei. Was zum Teufel soll/kann ich mit der Datei machen? Das zu diesem Format gehörende Programm heißt eagle und ist als Download verfügbar. Bei der Installation kann man eine freie Version mit eingeschränkten Möglichkeiten auswählen (eagle-light).

Und dann sehe ich im Schaltbild (*.sch-Datei) , was ich brauche:

Copyright Adafruit
Beide Leitungen, sowohl die SDA als auch die SCL haben je einen Pegelwandler (Levelshifter) verwendet. Die IRQ-Leitung benötigt keinen Pegelwandler, da es ein Ausgang ist und der Arduino-Eingang mit den 3.3V spielend leicht fertig werden sollte.

Auch die Frage nach der Versorgungsspannung wird durch das Schaltbild klar:
Copyright Adafruit
Das Shield hat einen eigenen Festspannungsregler "onboard". Der macht aus 5V die notwendigen 3.3V.

Die Platine hat also alles, was mein Herz begehrt!

Aber wo ist denn was auf der Platine? Dazu schau ich morgen mal auf die *.brd-Datei.





.

Freitag, 4. Januar 2013

4. Die Eingeweide des DuinoSqueeze

In dem Übersichtsschaubild von gestern habe ich die benötigten Baugruppen aufgeführt. Im nachfolgenden Bild sind sie in aller Pracht zu sehen.

Von links nach rechts: Das Ethernet-Shield, der Arduino Uno und die RFID-Karte


Der Arduino Uno
Zu dieser Baugruppe gibt es am wenigsten zu sagen, da hierzu am meisten im Netz zu finden ist. Ich habe mein Uno aus China erworben und er hat mich bis jetzt nicht im Stich gelassen. Ich überlege noch, ob er aus Platzgründen nicht einem Nano weichen soll. Ich würde vorschlagen, dass wir das zu einem späteren Zeitpunkt entscheiden, wenn der DuinoSqueeze läuft.

Das Ethernet-Shield
Ebenfalls ein Board aus China. Die wichtigsten zwei Ethernet-Shields haben entweder den ENC28J60 oder den WIZnet W5100 Chip verbaut. Ich habe mich für die Wiznet-Variante entschieden, da sie einfacher zu handhaben ist. Das Shield wird huckepack auf den Arduino verbaut werden. Ethernet und Arduino arbeiten via SPI-Schnittstelle zusammen.

Das RFID-Shield 
Ich habe nicht vor, den Leser huckepack zu verwenden, sondern etwas abgesetzt von der restlichen Elektronik. Die Gründe liegen alleine in der Optik. Die Elektronik werde ich irgendwo im Schrank verstecken, den Leser nicht. Also ist auf jeden Fall eine Schnittstelle zu benutzen, die solch eine abgesetzte Funktionsweise ermöglicht. Hier habe ich mich für eine I2C-Schnittstelle entschieden. Also benötige ich ein Board/Shield welches diese Schnittstelle bedient. Da hält sich die Auswahl schon in Grenzen. Wenn man/frau dann noch einen Leseabstand von mindestens 5cm benötigt, spielt die Antennengröße schon eine große Rolle.  

So ist meine Entscheidung letztendlich auf das Board von Adafruit (ID:789) gefallen. Das Board ist im Auslieferungszustand bereits für die I2C-Schnittstelle vorbereitet.

Verwendung der Arduino-Ports
Damit es nicht zu Kollisionen auf den Ports kommt, sollte man/frau die Verwendung sorgfältig planen.

Die SPI-Schnittstelle belegt von Hause aus folgende Pins:

MOSI (MasterOut/SlaveIn)                Pin D11 (nicht veränderbar)
MISO (MasterIn/SlaveOut)                Pin D12 (nicht veränderbar)

SCK (Slaveclock)                              Pin D13 (nicht veränderbar)
SS/CS (Slaveselect bzw. ChipSelect) Pin Dx (veränderbar)

Die I2C-Schnittstelle des Readers besteht aus:
SDA (Serial Data)
SCL (serial Clock)

Zusätzlich müssen wir den IRQ (Interrupt) noch unterbringen. Er gehört nicht zur I2C-Schnittstelle.

Die nachfolgende Tabelle zeigt die beabsichtigte Pinbelegung:

Dx = Digitale Ein/Ausgänge,  Ax = Analoge Ein/Ausgänge

Wer sich für SPI und I2C tiefergehend interessiert, dem sei diese Seminararbeit empfohlen..

Alle Geräte am I2C-Bus benötigen eine eindeutige Adresse, mit der sie am Bus identifiziert und angesprochen werden können. Wichtig wäre zu wissen, welche Adresse der RFID-Reader hat. Das machen wir aber später. Dafür gibt es sogenannte Sniffer (Schnüffler).

Das nächste Mal schauen wir uns das RFID Board und das Innenleben mal genauer an. Jetzt könnte man/frau sagen "unwichtig", aber ganz so unwichtig ist das doch nicht. 

Donnerstag, 3. Januar 2013

3. Die RadioCard spielt die Musik

Ich möchte heute die beabsichtigte Funktionsweise anhand des nachfolgenden Schaubildes erläutern:

Übersichtsschaubild des Heimnetzwerkes für DuinoSqueeze

Dazu werde ich die Abfolge der Arbeitsweise an einer RadioCard darstellen. Die RadioCard hat die UID incl Prüfziffer (PZ), mit der wir es schon einmal zu tun hatten:

254 72 152 209 255

Dahinter wird sich der Internetsender MemoryhitsFM  verbergen. Also auf geht's
  1. Der RFID-Leser erkennt die Karte und sendet die UID als Zeichenfolge 25472152209255 an den Arduino.
  2. Der Arduino speichert die UID und PZ als Variable intern ab.
  3. Der Arduino wandelt die Zeichenfolge 25472152209255 in 254-72-152-209-255 um. Diese Zeichenfolge wird unsere gewünschte Playlistnummer (PL-Nr.)!
  4. Der Arduino hat nun eine PL-Nr., die er via Ethernet-Shield an den Musikserver Logitech Media Server (früher:SqueezeCenter) übermittelt. Wo ist denn auf dem Schaubild der Logitech Media Server? Der Logitech Media Server "wohnt" bei mir im Heimnetz auf dem NAS Synology 409+. Wer den Begriff Logitech MediaServer googlet, findet mit Sicherheit die kostenfreie Variante für Windows oder Linux.
  5. Der Logitech Media Server (ab jetzt nur noch LMS) steuert die Kommunikation mit den angeschlossenen Mediaplayern. Im Schaubild sind das die Squeezebox Touch und Squeezbox Classic (SB3).
  6. Der LMS prüft, ob es eine Playliste mit der Bezeichnung 254-72-152-209-255.m3u in der Datenbank gibt. Findet der LMS die passende Playlist, sendet sie den Datenstrom an einen oder mehrere Player.
So einfach ist die Funktionsweise einer RadioCard. Die Funktion einer CDCard oder PlaylistCard wird vom Prinzip her identisch behandelt. Lediglich die Inhalte der Playlisten sind unterschiedlich. Das wird dann, wenn es benutzt wird, genauer erläutert.

In der Playliste 254-72-152-209-255.m3u steht (nur) folgender Text:

#EXTM3U
#EXTINF:-1, - Memoryhits FM, DE
http://www.surfmusik.de/m3u/memoryhits-fm,13851.m3u


Diese Playliste wird von mir "zu Fuß" erzeugt.

Für jeden anderen Internetsender wird die RadioCard nach dem gleichen Prinzip arbeiten.

Das ist Alles, damit die Musik spielt!!

Zusätzlich gibt es noch eine DeviceCard, mit der bei Bedarf, den oben genannten Datenstrom an eine andere Squeezebox leiten kann.