diff --git a/.gitignore b/.gitignore
index 12a5de458818d9652e3110e932d4de0c3b6df64d..231fb3a0f8f145f92db50e3a9376090f92ec5dfa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
 didacticNet.h.gch
+.vscode
+.log
diff --git a/README.md b/README.md
index fc8eff8e36c5fc233b72124da973c40ded9e050b..86d7ceedad082ebd6cc0c7590d3398055939fe51 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,12 @@
 # didacticNetwork
 
-Library for implementing networks on Arduino boards.
-The functionalities correspond to state of the art technologies, which are didactically reduced.
+Bibliothek zur Implementierung von vereinfachten Netzwerken auf Arduino-Boards.
+Die Funktionalitaeten entsprechen dem Stand der Technik, die Umsetzung ist didaktisch reduziert.
 
-## Supported so far:
-publish/subscribe network
+Für eine Nutzung der Bibliothek wird eine drahtlose Schnittstelle benötigt, wleche sich an der Seriellen Schnittstelle betreiben lässt.
+Wir empfehlen unsere IR-Link-Module, die Sie selbst herstellen können (Schaltplan und Layout bei uns anfragen - Kontakt über [letsgoING.org](httsp://letsgoING.org) 
+oder z. B. hier erwerben können: [Hinweise zur Bestellung bei Aisler](#bestellung-bei-aisler).
 
-### usage
-see example-files
 
 ## Download
 Start download with the button on the right side. Choose the right format and start the download.
@@ -16,3 +15,160 @@ Start download with the button on the right side. Choose the right format and st
 
 After download install library:
 https://www.arduino.cc/en/guide/libraries section "Importing a .zip Library"
+
+# publish/subscribe network
+
+## Beispiele
+
+**Broker:**
+- sPSN_Broker.ino        **->** Broker Applikation (muss nicht angepasst werden)
+
+**Clients:**
+- sPSN_Client1(2).ino    **->** Client Applikationen die sich gegenseitig einen analogen bzw. digtalen Wert senden
+- sPSN-ClientMinimal.ino **->** Minimal-Code für den einfachen Einstieg
+- sPSN-Chat.ino          **->** Chat-Applikation die Nachrichten unter eigenem Namen austauschen lässt
+
+## Funktionen und Parameter 
+
+### Client
+
+```cpp
+#Anlegen der Client-Instanz 
+didacticPSNetClient psnClient;
+
+#Starten der Client-Instanz
+void psnClient.begin(Stream& sSerial, fcn callback);
+// param1: Schnittstelle (Serial | SoftSerial)
+// param2: Callback-Funktion
+
+#Netzwerkverwaltung Client (Daten senden und Empfangen, Zugriffsregelung)
+bool psnClient.handleNetwork();
+// return: true wenn Daten versendet / false wenn nicht
+
+#Topic eines anderen Clients abbonieren
+int psnClient.subscribe(char* topic);
+// param: Topic String/char-Array ("example" / char topic[n])
+int psnClient.subscribe(char* topic, int length);
+// param1: Topic String/char-Array
+// param2: Anzahl Zeichen des Topics
+// return ERROR-Wert: DN_ERROR_NO_ERROR, 
+//                    DN_ERROR_TOPIC_LEN (Topic zu lang - wird abgeschnitten)
+
+#Topic eines anderen Clients entfernen
+bool psnClient.unsubscribe(char* topic);            
+// param: Topic String/char-Array
+
+bool psnClient.unsubscribe(char* topic, int length); 
+// param1: Topic String/char-Array
+// param2: Anzahl Zeichen des Topics
+// return true wenn Daten versendet / false wenn nicht
+
+#Daten unter Topic veroeffentlichen
+int psnClient.publish(char* topic, char* payload); 
+// param1: Topic String/char-Array; param2: payload-char-Array
+int psnClient.publish(char* topic, int topicLength, char* payload, int payloadLength); 
+// param1: Topic String/char-Array
+// param2: Anzahl Zeichen des Topics
+// param3: payload-char-Array
+// param4: Anzahl Zeichen der Payload
+// return: ERROR-Wert: DN_ERROR_NO_ERROR, 
+//                     DN_ERROR_TOPIC_LEN (Topic zu lang - wird abgeschnitten), 
+//                     DN_ERROR_PAYLOAD_LEN (Payload zu lange - wird abgeschnitten)
+
+#Callback-Funktion (wird bei neuen Daten aufgerufen)
+void clientCallback(char* topic, int topicLength, char* payload, int payloadLength){...}
+// param1: Topic der Nachricht
+// param2: Lange des Topics
+// param3: Nutdaten der Nachricht
+// param4: Laenge der
+```
+
+### Broker
+
+```cpp
+#Anlegen der Broker-Instanz
+didacticPSNetBroker psnBroker; 
+
+#Starten der Broker-Instanz 
+void psnBroker.begin(Stream& sSerial); 
+// param: Schnittstelle (Serial | SoftwareSerial)
+
+#Netzwerkverwaltung Broker (Daten senden und Empfangen, Zugriffsregelung)
+bool psnBroker.handleNetwork();
+```
+
+### Hilfreiche Funktionen
+
+Wichtiger Hinweis: 
+Diese Funktionen koennen derzeit nur einmal pro Programm/Client-Instanz eingesetzt werden.
+Werden diese an verschiedenen Stellen mit verschiedenen Werten verwendet, werden Werte u. U. ueberschrieben.
+
+```cpp
+#Flankenerkennung z.B. fuer Taster
+int psnClient.edgeDetected(bool currentState);
+// param: aktueller binärer Zustand
+// return: 0 -> keine Flanke, RISING, FALLING
+
+#Auf Wertaenderung groeßer Schwellwert pruefen
+bool psnClient.valueChanged(int currentvalue, int threshold);
+// param1: aktueller Wert
+// param2: Schwellwert
+// return: true -> Aenderung groeßer als Schwellwert; sonst false
+
+#Nicht blockierendes Warten
+bool psnClient.timeElapsed(long);
+// param: zu wartende Zeit in Millisekunden
+// return: true, wenn Zeit Wartezeit abgelaufen; sonst false
+
+#Einlesen von Text ueber Serialle Schnittstelle bis Endezeichen empfangen wird
+int psnClient.readSerialData(Stream&, char*, char);
+// param1: Schnittstelle (Serial | SoftSerial)
+// param2: Array in das die Zeichen eingelesen werden
+// param3: Endezeichen (char)
+// return: Anzahl der eingelesenen Zeichen (0 wenn noch kein Endezeichen)
+```
+
+### Konstanten
+
+Konstanten aus der Library die fuer die Programmierung genutzt werden und teilweise angepasst werden koennen.
+```cpp
+#ASCII Endezeichen
+DN_ASCII_CR "carriage return CR" (int) 13
+DN_ASCII_NL "new line NL"(int) 10
+
+#Laenge Topics und Payload (Client und Broker)
+MAX_LEN_TOPICS   default: 10
+MAX_LEN_PAYLOAD  default: 20
+
+#Anzahl Topics
+MAX_NR_TOPICS_CLIENT  default: 5
+MAX_NR_TOPICS_BROKER  default: 20
+
+#ERRORs
+DN_ERROR_NO_ERROR     0
+DN_ERROR_TOPIC_LEN   -1
+DN_ERROR_PAYLOAD_LEN -2
+
+#Frame
+MSG_PRELIMITER '<'
+MSG_DELIMITER  '>'
+MSG_SEPARATOR  '|'
+
+#Dienste
+MSG_PUBLISH     '@'
+MSG_SUBSCRIBE   '?'
+MSG_UPDATE      '#'
+MSG_TOPIC_MULTI '*'
+```
+
+# Bestellung bei Aisler
+
+- Account anlegen
+- Link öffnen: [Nachkaufprojekt bei Aisler.net](https://aisler.net/p/NBAQNHFV)
+- Projekt importieren (Fehlermeldung / Hinweis ignorieren)
+- Auf eigenen Account zurück gehen
+- unter "Projekte -> Sandbox" befindet sich dann die Platine und die Bauteilliste
+- vor der Bestellung Bauteilliste (Preise) aktualisieren
+- Bestellung der Platinen (Peautiful Boards) und der Bauteile (Precious Parts)
+
+**Hinweis:** Das Projekt letsgoING ist in **keiner Weise** an dem **Verkauf beteiligt**.
diff --git a/examples/brokerClient/brokerClient.ino b/examples/brokerClient/brokerClient.ino
index ccabaa076185898ac5dedfff7502f3910b830e80..8f8a63f1a3c04cb2eef5db064d17e6ff48b5e1e2 100644
--- a/examples/brokerClient/brokerClient.ino
+++ b/examples/brokerClient/brokerClient.ino
@@ -1,4 +1,4 @@
-#include "Arduino.h"
+  #include "Arduino.h"
   #include "SoftwareSerial.h"
   #include "didacticNet.h"
 
diff --git a/examples/sPSN_Broker/sPSN_Broker.ino b/examples/sPSN_Broker/sPSN_Broker.ino
index 662ecf03641f9d69a3289d9f9be861024f9514bd..1aec4de47f1a6f83355889f44f998605e7bcd017 100644
--- a/examples/sPSN_Broker/sPSN_Broker.ino
+++ b/examples/sPSN_Broker/sPSN_Broker.ino
@@ -26,7 +26,7 @@
  *date:  14.12.2020
  *version: 1.0
  */
-
+#include <Arduino.h>
 #include "SoftwareSerial.h"
 #include "didacticNet.h"
 
@@ -56,3 +56,5 @@ void loop() {
   //hier verarbeitet der Broker alle Daten
   psnBroker.handleNetwork();
 }
+
+
diff --git a/examples/sPSN_Chat/sPSN_Chat.ino b/examples/sPSN_Chat/sPSN_Chat.ino
index df7dbe6bdd0abbdab2821ce70bb16757a8f9e34f..d480f6a8c5aa0e33a3b6a876ef339ee88449363c 100644
--- a/examples/sPSN_Chat/sPSN_Chat.ino
+++ b/examples/sPSN_Chat/sPSN_Chat.ino
@@ -1,84 +1,67 @@
 /**
- *file:  sPSN_Chat.ino
- *author:  letsgoING -> info@letsgoing.de
+ * file:  sPSN_Chat.ino
+ * author:  letsgoING -> info@letsgoing.de
+ * 
+ * description:
+ *   Dieses Programm ist ein Teil eines Beispiels für ein einfaches Pub-Sub-Chat-Netzwerk.
  *
- *description:
- * Dieses Programm ist ein Teil eines Beispiels für ein einfaches Pub-Sub-Chat-Netzwerk.
-
- * Für dieses Chat-Netzwerk werden mindestens 3 Arduinos benötigt:
+ *   Für dieses Chat-Netzwerk werden mindestens 3 Arduinos benötigt:
  *
- * Arduino1:   sPSN_Broker.ino
- *            - IR-Sender an Pin 11 IR-Empfänger an Pin10
+ *   Arduino1:   sPSN_Broker.ino
+ *              - IR-Sender an Pin 11 IR-Empfänger an Pin10
  *
- * Arduino2-n: sPSN_Chat.ino (dieses Programm)
- *            - IR-Sender an Pin 11 IR-Empfänger an Pin10
+ *   Arduino2-n: sPSN_Chat.ino (dieses Programm)
+ *              - IR-Sender an Pin 11 IR-Empfänger an Pin10
  * Funktion:
- * Am Arduino2-n kann ein eigner Name (Sende-Topic) angeben werden.
- * Danach kann angeben werden wem zugehört werden soll (Empfangs-Topics).
- * Arduino1 (Server) übernimmt das Verteilen der Nachrichten.
+ *   Am Arduino2-n kann ein eigner Name (Sende-Topic) angeben werden.
+ *   Danach kann angeben werden wem zugehört werden soll (Empfangs-Topics).
+ *   Arduino1 (Server) übernimmt das Verteilen der Nachrichten.
  *
- *date:  14.12.2020
- *version: 1.0
- */
-
+ * parameter:
+ *   MAX_LEN_PAYLOAD = 20 Zeichen (didacticNet.h)
+ *   MAX_LEN_TOPICS = 10 Zeichen (didacticNet.h)
+ *   max Laenge der Eingegebenen Daten: 100 Zeichen (5*MAX_LEN_PAYLOAD)
+ *
+ * date:  13.07.2021
+*/
+#include <Arduino.h>
 #include "SoftwareSerial.h"
 #include "didacticNet.h"
 
-//lege Geschwindigkeit für serielle Schnittstellen fest
-#define SERIAL_BAUD 2400
-
-
-unsigned long lastTime = 0L;
+#define SERIAL_BAUD 2400                         //lege Geschwindigkeit für serielle Schnittstellen fest
 
-bool dataReadDone = false;
+char readData[MAX_LEN_PAYLOAD * 5]      = {'\0'};  //Array für eingelesene Daten (mit Puffer für zu lange Eingaben)
 
-//Maximale Nachrichten- und Topic-Länge:
-//MAX_LEN_DATA = 20 Zeichen
-//MAX_LEN_TOPICS = 10 Zeichen
-//kann erhöht werden (z. B. #define MAX_LEN_TOPICS 20) , dann aber Arduino-Mega als Server sinnvoll
+char topicSub[MAX_LEN_TOPICS] = {""};           //Array für neues Empfangs-Topic
+char topicPub[MAX_LEN_TOPICS] = {""};           //Array für eigenes Sende-Topic
 
-char readData[MAX_LEN_DATA * 5] = {'\0'};
-char arrayBuffer[MAX_LEN_DATA + 1] = {'\0'};
-int counter = 0;
-
-//Arrays für Empfangs- und Sende Topic
-char topicSub[MAX_LEN_TOPICS] = {""};
-char topicPub[MAX_LEN_TOPICS] = {""};
-
-void myCallback(char* mTopic, int mToLength, char* mData, int mDaLength) {
+//Callback-Funktion wird bei neuen Daten automatisch aufgerufen
+void clientCallback(char* mTopic, int mToLength, char* mData, int mDaLength) {
   Serial.print(mTopic);
   Serial.print(":\t");
   Serial.println(mData);
 }
 
-//lege Pins für SoftwareSerielle Schnittstelle fest
-// Rx = 10 -> Empfänger | Tx = 11 -> Sender
-SoftwareSerial sSerial(10, 11);
+SoftwareSerial sSerial(10, 11); // SoftwareSerial an Rx = Pin10 -> Empfänger | Tx = Pin11 -> Sender
 
-//Erzeuge Client-Instanz
-didacticPSNetClient psnClient;
+didacticPSNetClient psnClient; //Erzeuge PubSub-Client-Instanz
 
 
 void setup() {
-  //Starte Serielle Schnittstelle (zum PC)
-  Serial.begin(SERIAL_BAUD);
 
-  //Starte SoftwareSerielle Schnittstelle (zu IR-Link-Modulen)
-  sSerial.begin(SERIAL_BAUD);
+  Serial.begin(SERIAL_BAUD);  //Starte Serielle Schnittstelle (zum PC)
 
-  //Lege fest welche Serielle Schnittstelle für sPSN verwendet werden soll
-  //psnClient.setStream(sSerial);
+  sSerial.begin(SERIAL_BAUD); //Starte SoftwareSerielle Schnittstelle (zu IR-Link-Modulen)
 
-  //Lege Callback-Funktion fest (wird ausgeführt wenn neue Daten ankommen)
-  //psnClient.setCallback(myCallback);
-
-  psnClient.begin(sSerial, myCallback);
+  psnClient.begin(sSerial, clientCallback); //Starte PubSubClient mit SoftwareSerial und Callbackfunktion "clientCallback"
 
+  //AUSGABE INFOTEXT
   Serial.print("Bitte den eigenen Namen mit einem # eingeben\nund mit Enter bestaetigen. -> ");
   Serial.println("#DeinName");
   Serial.print("Gebe dann die Namen deiner Chatpartner mit einem @ ein. -> ");
   Serial.println("@ChatPartner");
-  Serial.println("Anschließend kannst du mit ihnen schreiben");
+  Serial.println("Anschließend kannst du mit ihnen schreiben.");
+  Serial.println("Pro Nachricht duerfen maximal 20 Zeichen eingegeben werden!");
   Serial.println();
   Serial.println("HINWEIS:");
   Serial.println("Stelle das Zeilenende im SerialMonitor auf \"Zeilenumbruch (CR)\"");
@@ -86,60 +69,44 @@ void setup() {
 }
 
 void loop() {
-  //Verarbeiten der Daten, prüfen ob Netzwerk frei und versenden der Daten
-  psnClient.handleNetwork();
-
-  //Lese Daten ein bis zum Zeichen Zeilenumbruch "CR"
-  if (Serial.available()) {
-    char buffer = Serial.read();
-    readData[counter] = buffer;
-    //Wenn Zeilenumbruch "CR", dann merke, dass Einlesen fertig
-    //und setze String Abschluss "\0" ans Ende
-    if (buffer == 13) {
-      readData[counter] = '\0';
-      counter = 0;
-      dataReadDone = true;
-    } else {
-      counter++;
+
+  psnClient.handleNetwork();  //Verarbeiten der Daten, prüfen ob Netzwerk frei und versenden der Daten
+
+  int nrOfAscii = psnClient.readSerialData(Serial, readData, DN_ASCII_CR); //Einlesen der Nutzereingabe am SerialMonitor (Rueckgabewert = Anzahl der gelesenen Zeichen)
+
+  if (nrOfAscii > 0) { //Wenn Daten fertig eingelesen wurden
+
+    if (readData[0] == '@') {         //Wenn '@' vorne steht, dann neuer Chatpartner anlegen (neues Topic abonnieren)
+      strcpy(readData, &readData[1]); //verschiebe um ein Zeichen (entferne '@')
+      psnClient.subscribe(readData);  //Lege fest zu welchem Topic Daten empfangen werden sollen (den Namen des Chatpartners)
+
+      Serial.print("Nachrichten von "); //Ausgabe welches Topic abonniert wurde
+      Serial.print(readData);
+      Serial.println(" abonniert.");
     }
-  }
+    else if (readData[0] == '!') {         //Wenn '@' vorne steht, dann neuer Chatpartner anlegen (neues Topic abonnieren)
+      strcpy(readData, &readData[1]); //verschiebe um ein Zeichen (entferne '@')
+      psnClient.unsubscribe(readData);  //Lege fest zu welchem Topic Daten empfangen werden sollen (den Namen des Chatpartners)
 
-  //Wenn Daten fertig eingelesen wurden
-  if (dataReadDone && strlen(readData) <= MAX_LEN_DATA * 5 ) {
-    //Wenn "@" vorne steht, dann neuer Chatpartner anlegen (neues Topic dem zugehört wird)
-    if (readData[0] == '@') {
-      //kopiere das neue Topic (den Namen des Chatpartners) in das passende Array
-      strcpy(readData, readData + 1);
-      //Lege fest zu welchem Topic Daten empfangen werden sollen (den Namen des Chatpartners)
-      psnClient.subscribe(readData);
-      Serial.print("Kontakt zu ");
+      Serial.print("Nachrichten von "); //Ausgabe welches Topic abonniert wurde
       Serial.print(readData);
-      Serial.println(" hergestellt");
+      Serial.println(" nicht mehr abonniert.");
     }
-    //Wenn "#" vorne steht, dann neuer eigener Name (neues Topic unter dem gesendet wird)
-    else if (readData[0] == '#') {
-      //kopiere das neue Topic (deinen neuen Namen) in das passende Array
-      strcpy(topicPub, readData + 1);
-      Serial.print("Dein Name:\t");
+
+    else if (readData[0] == '#') {    //Wenn '#' vorne steht, dann neuer eigener Name (neues Topic unter dem gesendet wird)
+      //strcpy(topicPub, readData + 1); //kopiere das neue Topic (deinen neuen Namen) in das passende Array (+ 1 = entferne '#')
+      strcpy(topicPub, &readData[1]); //kopiere das neue Topic (deinen neuen Namen) in das passende Array (+ 1 = entferne '#')
+      
+      Serial.print("Dein Name:\t");   //Ausgabe unter welchem Topic veröffentlicht wird
       Serial.println(topicPub);
     }
-    //Wenn normale Nachrichten eingegeben wurden, dann Daten unter eigenem Topic versenden
-    else {
-      for (int i = 0; i * MAX_LEN_DATA < strlen(readData); i++) {
-        memset(arrayBuffer, '\0', MAX_LEN_DATA + 1);
-        strncpy(arrayBuffer, &readData[MAX_LEN_DATA * i], MAX_LEN_DATA);
-        //Serial.print("ReadData: ");Serial.print(readData);Serial.print("\t");Serial.print(arrayBuffer);
-        psnClient.publish(topicPub, arrayBuffer);
-        //Solange Daten zu versenden sind (wenn Text länger als max Länge einer Nachricht)
-        while (psnClient.isDataToSend()) {
-          //Verarbeiten der Daten, prüfen ob Netzwerk frei und versenden der Daten
-          psnClient.handleNetwork();
-        }
-        Serial.print("Ich:\t");
-        Serial.println(arrayBuffer);
-      }
+
+    else { //Wenn "normale" Nachrichten eingegeben wurden, dann Daten unter eigenem Topic versenden
+      psnClient.publish(topicPub, readData);  //Bereite eingegebene Daten zum Senden vor
+      
+      Serial.print("Ich:\t");   //Ausgabe was unter deinem Topic veröffentlicht wird
+      Serial.println(readData);
     }
-    dataReadDone = false;
   }
 
-}
+}
\ No newline at end of file
diff --git a/examples/sPSN_Client1/sPSN_Client1.ino b/examples/sPSN_Client1/sPSN_Client1.ino
index 61997358952e0f61d7bcbb755b57b0f1135b7650..249b4c3ce1446f68cc6187196ff50aa3df39c6df 100644
--- a/examples/sPSN_Client1/sPSN_Client1.ino
+++ b/examples/sPSN_Client1/sPSN_Client1.ino
@@ -7,115 +7,83 @@
  * Für das Netwerk werden 3 Arduinos mit IR-Link-Modulen benötigt:
  *
  * Arduino1: sPSN_Broker.ino
- *           - IR-Sender an Pin 11 IR-Empfänger an Pin10
+ * 
+ * Arduino2: sPSN_Client1.ino (dieses Programm)  -> Sendet Wert des Potis | Empfängt Zustand des Tasters
+ * (Poti an PinA0 | LED an Pin5)
+ * 
+ * Arduino3: sPSN_Client2.ino -> Sendet Zustand des Tasters | Empfängt Wert des Potis
+ * (Taster an Pin2 | LED an Pin5)
  *
- * Arduino2: sPSN_Client1.ino (dieses Programm)
- *           - IR-Sender an Pin 11 IR-Empfänger an Pin10
- *           - Taster an Pin2
- *           - LED an Pin9
- *
- * Arduino3: sPSN_Client2.ino
- *           - IR-Sender an Pin 11 IR-Empfänger an Pin10
- *           - Poti an PinA0
- *           - LED an Pin9
- *
- * Funktion:
- * Mit dem Poti an Arduino3 kann die LED am Arduino2 gedimmt werden.
- * Mit dem Taster an Arduino2 kann die LED an Arduino2 ein-/ausgeschaltet werden.
- * Arduino1 übernimmt das Verteilen der Nachrichten.
- *
- *date:  14.12.2020
- *version: 1.0
+ * parameter:
+ *  MAX_LEN_PAYLOAD = 20 Zeichen (didacticNet.h)
+ *  MAX_LEN_TOPICS = 10 Zeichen (didacticNet.h)
+ * 
+ *date:  06.07.2021
  */
-
+#include <Arduino.h>
 #include "SoftwareSerial.h"
 #include "didacticNet.h"
 
-//lege Geschwindigkeit für serielle Schnittstellen fest
-#define SERIAL_BAUD 2400
+#define SERIAL_BAUD 2400 //lege Geschwindigkeit für serielle Schnittstellen fest
 
+#define LED_PIN   5
+#define POTI_PIN A0
 
-byte ledPin    = 9;
-byte potiPin   = A0;
+#define THRESHOLD   10  //Schwellwert für min. Wertänderung
+#define SEND_DELAY 500  //Mindestwarezeit zwischen zwei Sendevorgängen
 
-int lastValue     = 0;
+char topicPublish[MAX_LEN_TOPICS]   = "potiVal";    //Topic für zu sendende (eigene) Daten
+char topicSubscribe[MAX_LEN_TOPICS] = "buttonVal"; //Topic für zu empfangende Daten (von anderem TN)
 
+char payload[MAX_LEN_PAYLOAD] = {0};
+boolean newData = false;
 
-//Maximale Nachrichten- und Topic-Länge:
-//MAX_LEN_DATA = 20 Zeichen
-//MAX_LEN_TOPICS = 10 Zeichen
-//kann erhöht werden (z. B. #define MAX_LEN_TOPICS 20) , dann aber Arduino-Mega als Server sinnvoll
+SoftwareSerial sSerial(10, 11); //Erzeuge SoftwareSerial-Instanz mit Rx = Pin10 -> Empfänger | Tx = Pin11 -> Sender
 
-//Arrays für Empfangs- und Sende Topic
-char topicSub[MAX_LEN_TOPICS] = "buttonVal";
-char topicPub[MAX_LEN_TOPICS] = "potiVal";
+didacticPSNetClient psnClient;  //Erzeuge PubSub-Client-Instanz
 
-void myCallback(char* mTopic, int mToLength, char* mData, int mDaLength) {
-  Serial.println("Callback: ");
-  Serial.print("Topic: ");
+
+//Callback-Funktion - wird beim Empfang neuer Daten aufgerufen
+void clientCallback(char* mTopic, int mToLength, char* mData, int mDaLength) {
+  Serial.print("CB: ");
   Serial.print(mTopic);
-  Serial.print("\tData: ");
+  Serial.print(" - ");
   Serial.println(mData);
 
-  //Setze Ausgang entsprechend dem gesendeten Wert
-  digitalWrite(ledPin, (bool)atoi(mData));
+  boolean stateLED = bool(atoi(mData));         //wandle ASCII-Zeichen in Wert
+  //Alternativ: sscanf(mData, "%d", &stateLED); //wandle ASCII-Zeichen in Wert
+  Serial.print(stateLED);
+  digitalWrite(LED_PIN, stateLED);              //Setze Ausgang entsprechend dem empfangenen Wert
 }
 
 
-//lege Pins für SoftwareSerielle Schnittstelle fest
-// Rx = 10 -> Empfänger | Tx = 11 -> Sender
-SoftwareSerial sSerial(10, 11);
-
-//Erzeuge Client-Instanz
-didacticPSNetClient psnClient;
-
-
 void setup() {
-  //Starte Serielle Schnittstelle (zum PC)
-  Serial.begin(SERIAL_BAUD);
+  
+  Serial.begin(SERIAL_BAUD);    //Starte Serielle Schnittstelle (zum PC)
+  sSerial.begin(SERIAL_BAUD);   //Starte SoftwareSerielle Schnittstelle (zu IR-Link-Modulen)
 
-  Serial.print("\nStarting sPSNet: \nlistening to:\t");
-  Serial.println(topicSub);
-  Serial.print("sending to:\t");
-  Serial.println(topicPub);
+  pinMode(LED_PIN,OUTPUT);
 
-  //Starte SoftwareSerielle Schnittstelle (zu IR-Link-Modulen)
-  sSerial.begin(SERIAL_BAUD);
+  psnClient.begin(sSerial, clientCallback); //Starte PubSub Client an SoftwareSerial Schnittstelle
+  //psnClient.begin(Serial, clientCallback); //Starte PubSub Client an Serial Schnittstelle
 
-  pinMode(ledPin, OUTPUT);
-
-  //Lege fest welche Serielle Schnittstelle für sPSN verwendet werden soll
-  //psnClient.setStream(sSerial);
+  psnClient.subscribe(topicSubscribe); //Lege fest zu welchem Topic Daten empfangen werden sollen
+}
 
-  //Lege Callback-Funktion fest (wird ausgeführt wenn neue Daten ankommen)
-  //psnClient.setCallback(myCallback);
+void loop() {
 
-  psnClient.begin(sSerial, myCallback);
+  psnClient.handleNetwork();               //Verarbeiten der Daten, prüfen ob Netzwerk frei und versenden der Daten
 
-  //Lege fest zu welchem Topic Daten empfangen werden sollen
-  psnClient.subscribe(topicSub);
-}
+  int currentValue = analogRead(POTI_PIN); //lese Poti ein und speichere Wert
 
-void loop() {
-  //Verarbeiten der Daten, prüfen ob Netzwerk frei und versenden der Daten
-  psnClient.handleNetwork();
-
-  //lese Poti ein und speichere Wert
-  int currentValue = analogRead(potiPin);
-
-  //Übertrage Werte nur, wenn sie sich geändert haben
-  if (abs(currentValue - lastValue) > 20) {
-    //warte kurz, um nicht zu oft zu senden
-    delay(500);
-    //lese den Poti erneut ein
-    currentValue = analogRead(potiPin);
-    //setze den Inhalt des Puffer-Arrays auf 0
-    char data[MAX_LEN_DATA] = {0};
-    //wandle int-Wert in ASCII-Zeichen
-    itoa(currentValue, data, 10);
-    //sende analog-Wert
-    psnClient.publish(topicPub, data);
-    //speichere aktuellen Wert, um zu erkennen, ob er sich ändert
-    lastValue = currentValue;
+  if(psnClient.valueChanged(currentValue, THRESHOLD)){
+    itoa(currentValue, payload, 10);                    //wandle Wert in ASCII-Zeichen
+    //Alternativ: sprintf(payload, "%d", currentValue); //wandle Wert in ASCII-Zeichen
+    newData = true;                                     //Flag: neue Daten zum Senden
+  }
+  if(psnClient.timeElapsed(SEND_DELAY) && newData){     //Sende neue Daten wenn Mindestwaretzeit abgelaufen
+    psnClient.publish(topicPublish, payload); //bereite Topic und Nutzdaten zum senden vor
+    newData = false;                          //Flag: keine neuen Daten vorhanden
   }
 }
+
diff --git a/examples/sPSN_Client2/sPSN_Client2.ino b/examples/sPSN_Client2/sPSN_Client2.ino
index dc3be3bf1df9dec594464c653d6dfe7714bc963f..ad31487990138e20535fad7c15f1ac5950b210e7 100644
--- a/examples/sPSN_Client2/sPSN_Client2.ino
+++ b/examples/sPSN_Client2/sPSN_Client2.ino
@@ -1,119 +1,86 @@
 /**
- *file:  sPSN_Client2
+ *file:  sPSN_Client1
  *author:  letsgoING -> info@letsgoing.de
  *
  *description:
  * Dieses Programm ist ein einfaches Beispiel für ein einfaches Pub-Sub-Netzwerk.
  * Für das Netwerk werden 3 Arduinos mit IR-Link-Modulen benötigt:
  *
- * Arduino1: sPSN_Broker..ino
- *           - IR-Sender an Pin 11 IR-Empfänger an Pin10
+ * Arduino1: sPSN_Broker.ino
+ * 
+ * Arduino2: sPSN_Client1.ino -> Sendet Wert des Potis | Empfängt Zustand des Tasters
+ * (Poti an PinA0 | LED an Pin5)
+ * 
+ * Arduino3: sPSN_Client2.ino (dieses Programm) -> Sendet Zustand des Tasters | Empfängt Wert des Potis
+ * (Taster an Pin2 | LED an Pin5)
  *
- * Arduino2: sPSN_Client1.ino
- *           - IR-Sender an Pin 11 IR-Empfänger an Pin10
- *           - Taster an Pin2
- *           - LED an Pin9
- *
- * Arduino3: sPSN_Client2.ino (dieses Programm)
- *           - IR-Sender an Pin 11 IR-Empfänger an Pin10
- *           - Poti an PinA0
- *           - LED an Pin9
- *
- * Funktion:
- * Mit dem Poti an Arduino3 kann die LED am Arduino2 gedimmt werden.
- * Mit dem Taster an Arduino2 kann die LED an Arduino2 ein-/ausgeschaltet werden.
- * Arduino1 übernimmt das Verteilen der Nachrichten.
- *
- *date:  14.12.2020
- *version: 1.0
+ *date:  06.07.2021
  */
 
+#include <Arduino.h>
 #include "SoftwareSerial.h"
 #include "didacticNet.h"
 
-//lege Geschwindigkeit für serielle Schnittstellen fest
-#define SERIAL_BAUD 2400
+#define SERIAL_BAUD 2400 //lege Geschwindigkeit für serielle Schnittstellen fest
 
-byte ledPin    = 9;
-byte buttonPin = 2;
+#define LED_PIN    5
+#define BUTTON_PIN 2
 
-bool lastState     = 0;
+#define SEND_DELAY 500  //Mindestwarezeit zwischen zwei Sendevorgängen
 
-//Maximale Nachrichten- und Topic-Länge:
-//MAX_LEN_DATA = 20 Zeichen
-//MAX_LEN_TOPICS = 10 Zeichen
-//kann erhöht werden (z. B. #define MAX_LEN_TOPICS 20) , dann aber Arduino-Mega als Server sinnvoll
+char topicPublish[MAX_LEN_TOPICS]   = "buttonVal";    //Topic für zu sendende (eigene) Daten
+char topicSubscribe[MAX_LEN_TOPICS] = "potiVal"; //Topic für zu empfangende Daten (von anderem TN)
 
-//Arrays für Empfangs- und Sende Topic
-char topicSub[MAX_LEN_TOPICS] = {"potiVal"};
-char topicPub[MAX_LEN_TOPICS] = {"buttonVal"};
-
-void myCallback(char* mTopic, int mToLength, char* mData, int mDaLength) {
-  Serial.println("Callback: ");
-  Serial.print("Topic: ");
-  Serial.print(mTopic);
-  Serial.print("\tData: ");
-  Serial.println(mData);
+char payload[MAX_LEN_PAYLOAD] = {0};
+boolean newData  = false;
+boolean ledState = false;
 
-  //Setze Ausgang entsprechend dem gesendeten Wert
-  analogWrite(ledPin, map(atoi(mData), 0, 1023, 0, 255));
-}
+SoftwareSerial sSerial(10, 11); //Erzeuge SoftwareSerial-Instanz mit Rx = Pin10 -> Empfänger | Tx = Pin11 -> Sender
 
+didacticPSNetClient psnClient;  //Erzeuge PubSub-Client-Instanz
 
-//lege Pins für SoftwareSerielle Schnittstelle fest
-// Rx = 10 -> Empfänger | Tx = 11 -> Sender
-SoftwareSerial sSerial(10, 11);
 
-//Erzeuge Client-Instanz
-didacticPSNetClient psnClient;
+//Callback-Funktion - wird beim Empfang neuer Daten aufgerufen
+void clientCallback(char* mTopic, int mToLength, char* mData, int mDaLength) {
+  Serial.print("CB: ");
+  Serial.print(mTopic);
+  Serial.print(" - ");
+  Serial.println(mData);
 
+  int valueLED = atoi(mData);                                      //wandle ASCII-Zeichen in Wert
+  valueLED = constrain(map(valueLED, 0, 1023, 0, 255), 0, 255); //passe analogRead-Wert für analogWrite an
+  //Alternativ: sscanf(mData, "%d", &stateLED); //wandle ASCII-Zeichen in Wert
 
-void setup() {
-  //Starte Serielle Schnittstelle (zum PC)
-  Serial.begin(SERIAL_BAUD);
+  analogWrite(LED_PIN, valueLED);              //Setze Ausgang entsprechend dem empfangenen Wert
+}
 
-  Serial.print("\nStarting sPSNet: \nlistening to:\t");
-  Serial.println(topicSub);
-  Serial.print("sending to:\t");
-  Serial.println(topicPub);
 
-  //Starte SoftwareSerielle Schnittstelle (zu IR-Link-Modulen)
-  sSerial.begin(SERIAL_BAUD);
+void setup() {
+  
+  Serial.begin(SERIAL_BAUD);    //Starte Serielle Schnittstelle (zum PC)
+  sSerial.begin(SERIAL_BAUD);   //Starte SoftwareSerielle Schnittstelle (zu IR-Link-Modulen)
 
-  pinMode(ledPin, OUTPUT);
-  pinMode(buttonPin, INPUT);
+  psnClient.begin(sSerial, clientCallback); //Starte PubSub Client an SoftwareSerial Schnittstelle
+  //psnClient.begin(Serial, clientCallback); //Starte PubSub Client an Serial Schnittstelle
 
-  //Lege fest welche Serielle Schnittstelle für sPSN verwendet werden soll
-  //psnClient.setStream(sSerial);
+  psnClient.subscribe(topicSubscribe); //Lege fest zu welchem Topic Daten empfangen werden sollen
+}
 
-  //Lege Callback-Funktion fest (wird ausgeführt wenn neue Daten ankommen)
-  //psnClient.setCallback(myCallback);
+void loop() {
 
-  psnClient.begin(sSerial, myCallback);
+  psnClient.handleNetwork();               //Verarbeiten der Daten, prüfen ob Netzwerk frei und versenden der Daten
 
-  //Lege fest zu welchem Topic Daten empfangen werden sollen
-  psnClient.subscribe(topicSub);
-}
+  boolean buttonState = digitalRead(BUTTON_PIN); //lese Poti ein und speichere Wert
 
-void loop() {
-  //Verarbeiten der Daten, prüfen ob Netzwerk frei und versenden der Daten
-  psnClient.handleNetwork();
-
-  //lese aktuellen Zustand des Tasters ein
-  bool currentState = digitalRead(buttonPin);
-
-  //Wenn Flanke erkannt (fallend/steigend) dann übertrage den aktuellen Wert
-  if (lastState != currentState) {
-    //setze den Inhalt des Puffer-Arrays auf 0
-    char data[MAX_LEN_DATA] = {0};
-    //wandle bool-Wert in ASCII-Zeichen
-    itoa(currentState, data, 10);
-    //sende digital-Wert
-    psnClient.publish(topicPub, data);
-    //warte kurz, um nicht zu oft zu senden
-    delay(500);
+  if(psnClient.edgeDetected(buttonState) == RISING){
+    ledState = !ledState;                               //Invertiere zu sendenden Wert "LED-Zustand"
+    itoa(ledState, payload, 10);                        //wandle Wert in ASCII-Zeichen
+    //Alternativ: sprintf(payload, "%d", currentValue); //wandle Wert in ASCII-Zeichen 
+    newData = true;                                     //Flag: neue Daten zum Senden
+  }
+  if(psnClient.timeElapsed(SEND_DELAY) && newData){     //Sende neue Daten wenn Mindestwaretzeit abgelaufen
+    psnClient.publish(topicPublish, payload); //bereite Topic und Nutzdaten zum senden vor
+    newData = false;                          //Flag: keine neuen Daten vorhanden
   }
-
-  //speichere aktuellen Wert, um zu erkennen, ob er sich ändert
-  lastState = currentState;
 }
+
diff --git a/examples/sPSN_ClientMinimal/sPSN_ClientMinimal.ino b/examples/sPSN_ClientMinimal/sPSN_ClientMinimal.ino
new file mode 100644
index 0000000000000000000000000000000000000000..0e58d6bb209d2a2497290a1ece8f8f0464317507
--- /dev/null
+++ b/examples/sPSN_ClientMinimal/sPSN_ClientMinimal.ino
@@ -0,0 +1,65 @@
+/**
+ *file:  sPSN_Client1
+ *author:  letsgoING -> info@letsgoing.de
+ *
+ *description:
+ * Dieses Programm ist das Minimal-Beispiel für ein einfaches Pub-Sub-Netzwerk.
+ * Es wird jede Sekunde ein analoger Messwert (AO) übertragen 
+ * und die empfangenen Daten auf dem SerialMonitor ausgegeben
+ * 
+ * Für das Netwerk werden 3 oder mehr Arduinos mit IR-Link-Modulen benötigt:
+ *
+ * Arduino1: sPSN_Broker.ino
+ * 
+ * Arduino2-n: sPSN_ClientMinimal.ino (dieses Programm)  
+ * 
+ * parameter:
+ *  MAX_LEN_PAYLOAD = 20 Zeichen (didacticNet.h)
+ *  MAX_LEN_TOPICS = 10 Zeichen (didacticNet.h)
+ * 
+ *date:  06.07.2021
+ */
+#include <Arduino.h>
+#include "SoftwareSerial.h"
+#include "didacticNet.h"
+
+SoftwareSerial sSerial(10, 11); //Erzeuge SoftwareSerial-Instanz mit Rx = Pin10 -> Empfänger | Tx = Pin11 -> Sender
+
+didacticPSNetClient psnClient;  //Erzeuge PubSub-Client-Instanz
+
+
+//Callback-Funktion - wird beim Empfang neuer Daten aufgerufen
+void clientCallback(char* mTopic, int mToLength, char* mPayload, int mPayloadLength) {
+  Serial.print("Nachricht von: ");
+  Serial.print(mTopic);
+  Serial.print(" - ");
+  Serial.println(mPayload);
+}
+
+
+void setup() {
+  
+  Serial.begin(2400);    //Starte Serielle Schnittstelle (zum PC)
+  sSerial.begin(2400);   //Starte SoftwareSerielle Schnittstelle (zu IR-Link-Modulen)
+
+  psnClient.begin(sSerial, clientCallback); //Starte PubSub Client an SoftwareSerial Schnittstelle
+  
+  //Hier EMPFANGS-TOPIC ANPASSEN -> default "client2"
+  psnClient.subscribe("client2");           //Lege fest zu welchem Topic Daten empfangen werden sollen
+}
+
+void loop() {
+
+  psnClient.handleNetwork();         //Verarbeiten der Daten, prüfen ob Netzwerk frei und versenden der Daten
+
+  int currentValue = analogRead(A0); //lese Poti ein und speichere Wert
+
+  char payload[5];
+  itoa(currentValue, payload, 10);
+
+  if(psnClient.timeElapsed(1000)){      //Sende neue Daten wenn Mindestwaretzeit 1 Sekunde abgelaufen
+    //Hier SENDE-TOPIC ANPASSEN -> default "client1"
+    psnClient.publish("client1", payload); //bereite Topic und Nutzdaten zum senden vor
+  }
+}
+
diff --git a/examples/sPSN_Server/sPSN_Server.ino b/examples/sPSN_Server/sPSN_Server.ino
deleted file mode 100644
index 849fcb72e38200df68acac04fe11957d251b610e..0000000000000000000000000000000000000000
--- a/examples/sPSN_Server/sPSN_Server.ino
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- *file:  sPSN_Server.ino
- *author:  letsgoING -> info@letsgoing.de
- *
- *description:
- * Dieses Programm ist ein Teil eines Beispiels für ein einfaches Pub-Sub-Netzwerk.
- *
- * Für ein Sensor-Netwerk werden 3 Arduinos mit IR-Link-Modulen benötigt:
- * Arduino1: sPSN_Broker.ino (dieses Programm)
- *           - IR-Sender an Pin 11 IR-Empfänger an Pin10
- * Arduino2: sPSN_Client1.ino
- *           - IR-Sender an Pin 11 IR-Empfänger an Pin10
- *           - Taster an Pin2
- *           - LED an Pin9
- * Arduino3: sPSN_Client2.ino
- *           - IR-Sender an Pin 11 IR-Empfänger an Pin10
- *           - Poti an PinA0
- *           - LED an Pin9
- *
- * Für ein Chat-Netzwerk werden mindestens 3 Arduinos benötigt:
- * Arduino1:   sPSN_Server.ino (dieses Programm)
- *            - IR-Sender an Pin 11 IR-Empfänger an Pin10
- * Arduino2-n: sPSN_Chat.ino
- *            - IR-Sender an Pin 11 IR-Empfänger an Pin10
- *
- *date:  14.12.2020
- *version: 1.0
- */
-
-#include "SoftwareSerial.h"
-#include "didacticNet.h"
-
-//lege Geschwindigkeit für serielle Schnittstellen fest
-#define SERIAL_BAUD 2400
-
-//lege Pins für SoftwareSerielle Schnittstelle fest
-// Rx = 10 -> Empfänger | Tx = 11 -> Sender
-SoftwareSerial sSerial(10, 11);
-
-//Erzeuge Server-Instanz
-didacticPSNetServer psnBroker;
-
-void setup() {
-  //Starte Serielle Schnittstelle (zum PC)
-  Serial.begin(SERIAL_BAUD);
-
-  //Starte SoftwareSerielle Schnittstelle (zu IR-Link-Modulen)
-  sSerial.begin(SERIAL_BAUD);
-
-  //Lege fest welche Serielle Schnittstelle für sPSN verwendet werden soll
-  //psnBroker.setStream(sSerial);
-  psnClient.begin(sSerial);
-}
-
-void loop() {
-  //hier verarbeitet der Server alle Daten
-  psnBroker.handleNetwork();
-}
diff --git a/keywords.txt b/keywords.txt
index 65ad9e5f2a21b798d29803b614b1849510abd967..d70dbd25191371f0109951bed444664952040e3d 100644
--- a/keywords.txt
+++ b/keywords.txt
@@ -5,7 +5,6 @@
 #######################################
 # Datatypes (KEYWORD1)
 #######################################
-
 didacticPSNet		KEYWORD1
 didacticPSNetBroker	KEYWORD1
 didacticPSNetClient	KEYWORD1
@@ -22,12 +21,17 @@ publish	KEYWORD2
 subscribe	KEYWORD2
 unsubscribe	KEYWORD2
 
+edgeDetected	KEYWORD2
+valueChanged	KEYWORD2
+timeElapsed	KEYWORD2
+readSerialData	KEYWORD2
+
 #######################################
 # Constants (LITERAL1)
 #######################################
-MSG_PRELIMITER		LITERAL1
-MSG_DELIMITER		LITERAL1
-MSG_SEPARATOR		LITERAL1
+MSG_PRELIMITER	LITERAL1
+MSG_DELIMITER	LITERAL1
+MSG_SEPARATOR	LITERAL1
 
 MSG_PUBLISH		LITERAL1
 MSG_SUBSCRIBE		LITERAL1
@@ -37,4 +41,11 @@ MSG_TOPIC_MULTI	LITERAL1
 MAX_NR_TOPICS_CLIENT	LITERAL1
 MAX_NR_TOPICS_BROKER	LITERAL1
 MAX_LEN_TOPICS		LITERAL1
-MAX_LEN_DATA		LITERAL1
+MAX_LEN_PAYLOAD	LITERAL1
+
+DN_ASCII_CR	LITERAL1
+DN_ASCII_NL	LITERAL1
+
+DN_ERROR_NO_ERROR	LITERAL1
+DN_ERROR_TOPIC_LEN	LITERAL1
+DN_ERROR_PAYLOAD_LEN	LITERAL1
\ No newline at end of file
diff --git a/src/didacticNet.cpp b/src/didacticNet.cpp
index 54dacbcf39745d212d3a932c5b49f58184fa28e7..6529e29f65f275139ccda0158965048c4ec2ed56 100644
--- a/src/didacticNet.cpp
+++ b/src/didacticNet.cpp
@@ -8,9 +8,8 @@
 #include "Arduino.h"
 #include "didacticNet.h"
 
-
 //**************************************************************************
-//BASIC
+//ROOT
 //**************************************************************************
 didacticPSNet::didacticPSNet(){}
 
@@ -70,12 +69,19 @@ bool didacticPSNet::isDataToSend(){
 
 bool didacticPSNet::sendData(){
 	int counter = 0;
-	while(_sendBufferMessage[counter]!= '\0'){
+  bool messageSent = false;
+	while(!messageSent){
+    if(counter >= MAX_LEN_TOPICS + MAX_LEN_PAYLOAD + LEN_OVERHEAD - 1){
+      //TODO: check!!!
+      _sendBufferMessage[counter] = MSG_DELIMITER; //cut message and stop sending
+      messageSent = true;
+		} 
+    else if(_sendBufferMessage[counter] == MSG_DELIMITER){
+      messageSent = true;
+    }
+
 		_port->write(_sendBufferMessage[counter]);
 		counter++;
-		if(counter > MAX_LEN_TOPICS + MAX_LEN_DATA + 5){
-		return false;
-		}
 	}
 	return true;
 }
@@ -86,11 +92,12 @@ int didacticPSNet::extractData(int startCounter, int maxLength, char* buffer, ch
 		buffer[counter-startCounter] = _readBufferMessage[counter];
 		counter++;
 		if((counter-startCounter) > maxLength){
-		return -1;
+      counter--;
+      break; //if > maxLenght -> leave while and return
 		}
 	}
 	buffer[counter-startCounter] = '\0';
-	return counter-startCounter; //length of Topic
+	return counter-startCounter; //length
 }
 
 int didacticPSNet::checkData(){
@@ -100,7 +107,7 @@ int didacticPSNet::checkData(){
 bool  didacticPSNet::recieveData() {
 	static int msgCounter = 0;
 	static int topicCounter = 0;
-	static int dataCounter = 0;
+	static int payloadCounter = 0;
 	//if(msgCounter == NULL){	msgCounter = 0;	}
 	//if(topicCounter == NULL){ topicCounter = 0; }
 	//if(dataCounter == NULL){ dataCounter = 0; }
@@ -109,7 +116,7 @@ bool  didacticPSNet::recieveData() {
 		if (localBuffer == MSG_PRELIMITER) {
 			msgCounter = 0;
 			topicCounter = 0;
-			dataCounter = 0;
+			payloadCounter = 0;
 			_readBufferMessage[msgCounter] = localBuffer;
     }
 		else if (localBuffer == MSG_DELIMITER && _readBufferMessage[0] == MSG_PRELIMITER) {
@@ -139,64 +146,78 @@ didacticPSNetClient::didacticPSNetClient(){}
 
 didacticPSNetClient::~didacticPSNetClient(){}
 
-bool didacticPSNetClient::publish(char* topic,  char* data){
+int didacticPSNetClient::publish(char* topic,  char* payload){
+  int error = DN_ERROR_NO_ERROR;
+
 	int topicLength =  strlen(topic);
-	int dataLength = strlen(data);
+	int payloadLength = strlen(payload);
 	_sendBufferMessage[0] = MSG_PRELIMITER;
 	_sendBufferMessage[1] = MSG_PUBLISH;
 	_sendBufferMessage[2+topicLength] = MSG_SEPARATOR;
-	_sendBufferMessage[2+topicLength+1+dataLength] = MSG_DELIMITER;
-	_sendBufferMessage[2+topicLength+1+dataLength+1] = '\0';
+	_sendBufferMessage[2+topicLength+1+payloadLength] = MSG_DELIMITER;
+	_sendBufferMessage[2+topicLength+1+payloadLength+1] = '\0';
 
-	if(topicLength <= MAX_LEN_TOPICS){
-		for(int i = 0; i < topicLength; i++){
+  //TODO: check
+  if(topicLength > MAX_LEN_TOPICS){
+    topicLength = MAX_LEN_TOPICS;
+    error += DN_ERROR_TOPIC_LEN;
+  }
+  if(payloadLength > MAX_LEN_PAYLOAD){
+    payloadLength = MAX_LEN_PAYLOAD;
+    error += DN_ERROR_PAYLOAD_LEN;
+  }
+
+  for(int i = 0; i < topicLength; i++){
 			_sendBufferMessage[2+i] = topic[i];
 		}
-	}else {
-    _dataToSend = false;
-		return false;
-	}
-	if(dataLength <= MAX_LEN_DATA){
-		for(int i = 0; i < dataLength; i++){
-			_sendBufferMessage[2+topicLength+1+i] = data[i];
+  for(int i = 0; i < payloadLength; i++){
+			_sendBufferMessage[2+topicLength+1+i] = payload[i];
 		}
-	}else {
-    _dataToSend = false;
-		return false;
-	}
+
   _dataToSend = true;
-	return true;
+	return error;
 }
 
-bool didacticPSNetClient::publish(char* topic, int topicLength, char* data , int dataLength){
-	_sendBufferMessage[0] = MSG_PRELIMITER;
+int didacticPSNetClient::publish(char* topic, int topicLength, char* payload , int payloadLength){
+	int error = DN_ERROR_NO_ERROR;
+  
+  _sendBufferMessage[0] = MSG_PRELIMITER;
 	_sendBufferMessage[1] = MSG_PUBLISH;
 	_sendBufferMessage[2+topicLength] = MSG_SEPARATOR;
-	_sendBufferMessage[2+topicLength+1+dataLength] = MSG_DELIMITER;
-	_sendBufferMessage[2+topicLength+1+dataLength+1] = '\0';
+	_sendBufferMessage[2+topicLength+1+payloadLength] = MSG_DELIMITER;
+	_sendBufferMessage[2+topicLength+1+payloadLength+1] = '\0';
 
-	if(topicLength <= MAX_LEN_TOPICS){
-		for(int i = 0; i < topicLength; i++){
+	//TODO: check
+  if(topicLength > MAX_LEN_TOPICS){
+    topicLength = MAX_LEN_TOPICS;
+    error += DN_ERROR_TOPIC_LEN;
+  }
+  if(payloadLength > MAX_LEN_PAYLOAD){
+    payloadLength = MAX_LEN_PAYLOAD;
+    error += DN_ERROR_PAYLOAD_LEN;
+  }
+
+  for(int i = 0; i < topicLength; i++){
 			_sendBufferMessage[2+i] = topic[i];
 		}
-	}else {
-    _dataToSend = false;
-		return false;
-	}
-	if(dataLength <= MAX_LEN_DATA){
-		for(int i = 0; i < dataLength; i++){
-			_sendBufferMessage[2+topicLength+1+i] = data[i];
+  for(int i = 0; i < payloadLength; i++){
+			_sendBufferMessage[2+topicLength+1+i] = payload[i];
 		}
-	}else {
-    _dataToSend = false;
-		return false;
-	}
+
   _dataToSend = true;
-	return true;
+	return error;
 }
 
-bool didacticPSNetClient::subscribe(char* topic){
+int didacticPSNetClient::subscribe(char* topic){
+  int error = DN_ERROR_NO_ERROR;
+
   int topicLength = strlen(topic);
+
+  if( topicLength > MAX_LEN_TOPICS){
+   topicLength = MAX_LEN_TOPICS;
+   error = DN_ERROR_TOPIC_LEN;
+   }
+
   _sendBufferMessage[0] = MSG_PRELIMITER;
 	_sendBufferMessage[1] = MSG_SUBSCRIBE;
 	_sendBufferMessage[2+topicLength] = MSG_DELIMITER;
@@ -208,7 +229,6 @@ bool didacticPSNetClient::subscribe(char* topic){
     if(topicNumber < 0){
       topicNumber = 0;
     }
-    if( topicLength <= MAX_LEN_TOPICS){
   		for(int i = 0; i < topicLength; i++){
   			_topic[topicNumber][i] = topic[i];
         _sendBufferMessage[2+i]= topic[i];
@@ -216,28 +236,28 @@ bool didacticPSNetClient::subscribe(char* topic){
       _topic[topicNumber][topicLength] = '\0';
       _sendBufferMessage[2+topicLength+1]= '\0';
       _dataToSend = true;
-  	}
-  	else {
-      _dataToSend = false;
-  		return false;
-  	}
   }
   else{
-    if( topicLength <= MAX_LEN_TOPICS){
   		for(int i = 0; i < topicLength; i++){
         _sendBufferMessage[2+i]= topic[i];
   		}
       _sendBufferMessage[2+topicLength+1]= '\0';
       _dataToSend = true;
-  	}
   }
   while(_dataToSend){
     handleNetwork();
   }
-	return true;
+	return error;
 }
 
-bool didacticPSNetClient::subscribe(char* topic, int topicLength){
+int didacticPSNetClient::subscribe(char* topic, int topicLength){
+   int error = DN_ERROR_NO_ERROR;
+
+   if( topicLength > MAX_LEN_TOPICS){
+    topicLength = MAX_LEN_TOPICS;
+    error = DN_ERROR_TOPIC_LEN;
+    }
+
   _sendBufferMessage[0] = MSG_PRELIMITER;
 	_sendBufferMessage[1] = MSG_SUBSCRIBE;
 	_sendBufferMessage[2+topicLength] = MSG_DELIMITER;
@@ -249,7 +269,6 @@ bool didacticPSNetClient::subscribe(char* topic, int topicLength){
     if(topicNumber < 0){
       topicNumber = 0;
     }
-    if( topicLength <= MAX_LEN_TOPICS){
   		for(int i = 0; i < topicLength; i++){
   			_topic[topicNumber][i] = topic[i];
         _sendBufferMessage[2+i]= topic[i];
@@ -257,25 +276,18 @@ bool didacticPSNetClient::subscribe(char* topic, int topicLength){
       _topic[topicNumber][topicLength] = '\0';
       _sendBufferMessage[2+topicLength+1]= '\0';
       _dataToSend = true;
-  	}
-  	else {
-      _dataToSend = false;
-  		return false;
-  	}
   }
   else{
-    if( topicLength <= MAX_LEN_TOPICS){
   		for(int i = 0; i < topicLength; i++){
         _sendBufferMessage[2+i]= topic[i];
   		}
       _sendBufferMessage[2+topicLength+1]= '\0';
       _dataToSend = true;
-  	}
   }
   while(_dataToSend){
     handleNetwork();
   }
-	return true;
+	return error;
 }
 
 
@@ -302,22 +314,22 @@ bool didacticPSNetClient::getMessageFilter(char messageType){
   return messageType == MSG_UPDATE;
 }
 
-bool didacticPSNetClient::saveData(char* buffer, int position){
-  strcpy(_data[position], buffer);
+bool didacticPSNetClient::savePayload(char* buffer, int position){
+  strcpy(_payload[position], buffer);
   return true;
 }
 
 bool didacticPSNetClient::handleData(){
   int currentTopicNr = 0;
   int topicLength = 0;
-  int dataLength = 0;
+  int payloadLength = 0;
   topicLength = extractData(2, MAX_LEN_TOPICS, _bufferTopic, MSG_SEPARATOR);
   if(topicLength > 0){
     currentTopicNr = getTopicNr(_bufferTopic);
-    dataLength  = extractData(topicLength+3, MAX_LEN_DATA, _bufferData, MSG_DELIMITER);
+    payloadLength  = extractData(topicLength+3, MAX_LEN_PAYLOAD, _bufferPayload, MSG_DELIMITER);
     if( currentTopicNr >= 0){
-      saveData( _bufferData, currentTopicNr);
-      callback(_topic[currentTopicNr], topicLength, _data[currentTopicNr], dataLength);
+      savePayload( _bufferPayload, currentTopicNr);
+      callback(_topic[currentTopicNr], topicLength, _payload[currentTopicNr], payloadLength);
     }
   }
   return true;
@@ -325,7 +337,7 @@ bool didacticPSNetClient::handleData(){
 
 int didacticPSNetClient::getTopicNr(char* topic){
 	for (int i = 0; i < MAX_NR_TOPICS_CLIENT; i++) {
-    if (strcmp(_topic[i], topic) == 0) {
+    if (strcmp(_topic[i], topic) == 0 || _topic[i][0] == MSG_TOPIC_MULTI) { //TODO: check ... or equal MSG_TOPIC_MULTI
       return i;
 		}
 	}
@@ -341,6 +353,63 @@ int didacticPSNetClient::getFreeTopicNr() {
   return -1;
 }
 
+//**************************************************************************
+//LITTLE HELPERS FOR CLIENTS ;-)
+//**************************************************************************
+int didacticPSNetClient::edgeDetected(bool edCurrentState){
+  static bool edLastState = false;
+  int edEdge = 0;
+
+  if(edCurrentState && !edLastState){
+    edEdge = RISING;
+  }
+  else if(!edCurrentState && edLastState){
+    edEdge = FALLING;
+  }
+  edLastState = edCurrentState;
+  return edEdge;
+}
+
+bool didacticPSNetClient::valueChanged(int vcValue, int vcThreshold){
+  static int vcLastValue = 0;
+
+  if(abs(vcValue-vcLastValue) > vcThreshold){
+    vcLastValue = vcValue;
+    return true;
+  }
+  return false;
+}
+
+bool didacticPSNetClient::timeElapsed(long teDelayTime){
+  static long teLastTime = 0L;
+  long currentTime = millis();
+
+  if(teLastTime + (teDelayTime-1) < currentTime){
+    teLastTime = currentTime;
+    return true;
+  }
+  return false;
+}
+
+int didacticPSNetClient::readSerialData(Stream& rsStream, char* rsDataArray, char rsEndSign) {
+  static int rsCounter = 0;
+
+  if (rsStream.available()) {
+    char charBuffer = rsStream.read();
+    rsDataArray[rsCounter] = charBuffer;
+
+    if (charBuffer == rsEndSign) {
+      rsDataArray[rsCounter] = '\0';
+      int nrOfChars = rsCounter;
+      rsCounter = 0;
+      return nrOfChars; 
+    } else {
+      rsCounter++;
+    }
+  }
+  return 0;
+}
+
 
 //**************************************************************************
 //Broker
@@ -354,7 +423,7 @@ bool didacticPSNetBroker::getMessageFilter(char messageType){
   return (messageType == MSG_PUBLISH || messageType == MSG_SUBSCRIBE);
 }
 
-bool didacticPSNetBroker::saveData(char* buffer, int position){
+bool didacticPSNetBroker::savePayload(char* buffer, int position){
   strcpy(_data[position], buffer);
   return true;
 }
@@ -374,9 +443,9 @@ bool didacticPSNetBroker::handleData(){
     topicLength = extractData(2, MAX_LEN_TOPICS, _bufferTopic, MSG_SEPARATOR);
     if(topicLength > 0){
       currentTopicNr = getTopicNr(_bufferTopic);
-      dataLength  = extractData(topicLength+3, MAX_LEN_DATA, _bufferData, MSG_DELIMITER);
+      dataLength  = extractData(topicLength+3, MAX_LEN_PAYLOAD, _bufferPayload, MSG_DELIMITER);
       if( currentTopicNr >= 0){
-        writeDataToTopic(currentTopicNr, _bufferTopic, _bufferData);
+        writeDataToTopic(currentTopicNr, _bufferTopic, _bufferPayload);
         update(_topic[currentTopicNr], topicLength, _data[currentTopicNr], dataLength);
       }
     }
@@ -408,7 +477,7 @@ bool didacticPSNetBroker::update(char* topic, int topicLength, char* data , int
     _dataToSend = false;
 		return false;
 	}
-	if(dataLength <= MAX_LEN_DATA){
+	if(dataLength <= MAX_LEN_PAYLOAD){
 		for(int i = 0; i < dataLength; i++){
 			_sendBufferMessage[2+topicLength+1+i] = data[i];
 		}
diff --git a/src/didacticNet.h b/src/didacticNet.h
index 6d4642ea8e3ee1769dbd47da74a560bf04bb0492..fda76125d25b7ba99a791feecf4b73beec7f4979 100644
--- a/src/didacticNet.h
+++ b/src/didacticNet.h
@@ -1,9 +1,7 @@
-/**************************************************************************/
-/*!
+/**************************************************************************
     @file     didacticNet.h
     @author   anian buehler @ letsgoING
-*/
-/**************************************************************************/
+**************************************************************************/
 
 
 #ifndef _DIDACTICNET_
@@ -23,18 +21,28 @@
 #define MSG_PUBLISH   '@'
 #define MSG_SUBSCRIBE '?'
 #define MSG_UPDATE    '#'
-
 #define MSG_TOPIC_MULTI     '*'
 
+//<@topic|payload>
+#define LEN_OVERHEAD  4
+
 #define CSMA_CHECK_DELAY_US 400
-#define CSMA_MIN_DELAY_MS 10
-#define CSMA_MID_DELAY_MS 20
-#define CSMA_MAX_DELAY_MS 30
+#define CSMA_MIN_DELAY_MS    10
+#define CSMA_MID_DELAY_MS    20
+#define CSMA_MAX_DELAY_MS    30
 
-#define MAX_NR_TOPICS_CLIENT  5
+#define MAX_NR_TOPICS_CLIENT   5
 #define MAX_NR_TOPICS_BROKER  20
-#define MAX_LEN_TOPICS 10
-#define MAX_LEN_DATA   20
+#define MAX_LEN_TOPICS 		  10
+#define MAX_LEN_PAYLOAD       20
+
+#define DN_ERROR_NO_ERROR     0
+#define DN_ERROR_TOPIC_LEN   -1
+#define DN_ERROR_PAYLOAD_LEN -2
+
+//little helpers
+#define DN_ASCII_CR 13
+#define DN_ASCII_NL 10
 
 class didacticPSNet
 {
@@ -43,15 +51,15 @@ class didacticPSNet
 
 		PSNET_CALLBACK_SIGNATURE;
 
-		char _bufferTopic[MAX_LEN_TOPICS+1] = {0};
-		char _bufferData[MAX_LEN_DATA+1] = {0};
-		char _readBufferMessage[MAX_LEN_TOPICS + MAX_LEN_DATA +4+1];
-		char _sendBufferMessage[MAX_LEN_TOPICS + MAX_LEN_DATA +4+1];
+		char _bufferTopic[MAX_LEN_TOPICS +1] = {0};
+		char _bufferPayload[MAX_LEN_PAYLOAD +1] = {0};
+		char _readBufferMessage[MAX_LEN_TOPICS + MAX_LEN_PAYLOAD + LEN_OVERHEAD +1];
+		char _sendBufferMessage[MAX_LEN_TOPICS + MAX_LEN_PAYLOAD + LEN_OVERHEAD +1];
 
 		bool _dataToSend = false; // int Data to send for queue?
 		unsigned long _waitingTime = 0L;
 		int _currentTopicLength = 0;
-		int _currentDataLength  = 0;
+		int _currentPayloadLength  = 0;
 
 		didacticPSNet& setCallback(PSNET_CALLBACK_SIGNATURE);
 		void setStream(Stream& _port);
@@ -64,7 +72,7 @@ class didacticPSNet
 		virtual int getTopicNr(char*)=0;
 		virtual int getFreeTopicNr()=0;
 		virtual bool getMessageFilter(char)=0;
-		virtual bool saveData(char*, int)=0;
+		virtual bool savePayload(char*, int)=0;
 		virtual bool handleData()=0;
 
 	public:
@@ -81,11 +89,10 @@ class didacticPSNet
 class didacticPSNetClient : public  didacticPSNet
 {
 	private:
-
 	char _topic[MAX_NR_TOPICS_CLIENT][MAX_LEN_TOPICS+1] = { { 0 } };
-	char _data[MAX_NR_TOPICS_CLIENT][MAX_LEN_DATA+1] = { { 0 } };
+	char _payload[MAX_NR_TOPICS_CLIENT][MAX_LEN_PAYLOAD+1] = { { 0 } };
 
-	bool saveData(char*, int);
+	bool savePayload(char*, int);
 	bool getMessageFilter(char);
 	bool handleData();
 	int getTopicNr(char*);
@@ -95,24 +102,28 @@ class didacticPSNetClient : public  didacticPSNet
 	didacticPSNetClient();
 	~didacticPSNetClient();
 
-	bool publish(char*, char*);
-	bool publish(char*, int, char*, int);
-	bool subscribe(char*);
-	bool subscribe(char*, int);
+	int publish(char*, char*);
+	int publish(char*, int, char*, int);
+	int subscribe(char*);
+	int subscribe(char*, int);
 	bool unsubscribe(char*);
 	bool unsubscribe(char*, int);
 
+	//little helpers
+	int edgeDetected(bool);
+	bool valueChanged(int, int);
+	bool timeElapsed(long);
+	int readSerialData(Stream&, char*, char);
 };
 
 
 class didacticPSNetBroker: public  didacticPSNet
 {
 	private:
-
 	char _topic[MAX_NR_TOPICS_BROKER][MAX_LEN_TOPICS+1] = { { 0 } };
-	char _data[MAX_NR_TOPICS_BROKER][MAX_LEN_DATA+1] = { { 0 } };
+	char _data[MAX_NR_TOPICS_BROKER][MAX_LEN_PAYLOAD+1] = { { 0 } };
 
-	bool saveData(char*, int);
+	bool savePayload(char*, int);
 	bool getMessageFilter(char);
 	void writeDataToTopic(int, char*, char*);
 	bool handleData();