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.