diff --git a/README.md b/README.md
index 86d7ceedad082ebd6cc0c7590d3398055939fe51..50f583eee6fb565f9e2041b9ab73c6ba7d2e8397 100644
--- a/README.md
+++ b/README.md
@@ -3,9 +3,9 @@
 Bibliothek zur Implementierung von vereinfachten Netzwerken auf Arduino-Boards.
 Die Funktionalitaeten entsprechen dem Stand der Technik, die Umsetzung ist didaktisch reduziert.
 
-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).
+Für eine Nutzung der Bibliothek wird eine drahtlose Schnittstelle benoetigt, wleche sich an der Seriellen Schnittstelle betreiben lässt.
+Wir empfehlen unsere IR-Link-Module, die Sie selbst herstellen koennen (Schaltplan und Layout bei uns anfragen - Kontakt über [letsgoING.org](httsp://letsgoING.org) 
+oder z. B. hier erwerben koennen: [Hinweise zur Bestellung bei Aisler](#bestellung-bei-aisler).
 
 
 ## Download
@@ -33,18 +33,23 @@ https://www.arduino.cc/en/guide/libraries section "Importing a .zip Library"
 ### Client
 
 ```cpp
-#Anlegen der Client-Instanz 
+#Anlegen der Client-Instanz
+// Anlegen des didacticPSNetClient-Objekts
+// psnClient -> moeglicher Name für Objekt
 didacticPSNetClient psnClient;
 
 #Starten der Client-Instanz
-void psnClient.begin(Stream& sSerial, fcn callback);
+void psnClient.begin(Stream& sSerial, fcn clientCallback);
 // param1: Schnittstelle (Serial | SoftSerial)
-// param2: Callback-Funktion
+// param2: Callback-Funktion (Bezeichnung frei waehlbar)
 
 #Netzwerkverwaltung Client (Daten senden und Empfangen, Zugriffsregelung)
 bool psnClient.handleNetwork();
 // return: true wenn Daten versendet / false wenn nicht
 
+void psnClient.setInterval(long intervalTime);
+// param: Mindestwartezeit in ms zwischen zwei Sendevorgängen (default 500 ms)
+
 #Topic eines anderen Clients abbonieren
 int psnClient.subscribe(char* topic);
 // param: Topic String/char-Array ("example" / char topic[n])
@@ -63,30 +68,71 @@ bool psnClient.unsubscribe(char* topic, int length);
 // param2: Anzahl Zeichen des Topics
 // return true wenn Daten versendet / false wenn nicht
 
-#Daten unter Topic veroeffentlichen
+#Daten unter Topic veroeffentlichen 
 int psnClient.publish(char* topic, char* payload); 
-// param1: Topic String/char-Array; param2: payload-char-Array
+// param1: Topic String/char-Array; 
+// param2: payload-char-Array
+// return: ERROR-Wert: DN_PUBLISH_SUCCESSULL, 
+//                     DN_ERROR_TOPIC_LEN (Topic zu lang - wird abgeschnitten), 
+//                     DN_ERROR_PAYLOAD_LEN (Payload zu lange - wird abgeschnitten)
+
+int psnClient.publish(char* topic, bool payload); 
+// param1: Topic String/char-Array; 
+// param2: payload vom Datentyp bool (wird in char-Array gewandelt)
+// return: ERROR-Wert: DN_PUBLISH_SUCCESSULL, 
+//                     DN_ERROR_TOPIC_LEN (Topic zu lang - wird abgeschnitten), 
+//                     DN_ERROR_PAYLOAD_LEN (Payload zu lange - wird abgeschnitten)
+
+int psnClient.publish(char* topic, int payload); 
+// param1: Topic String/char-Array; 
+// param2: payload vom Datentyp int (wird in char-Array gewandelt)
+// return: ERROR-Wert: DN_PUBLISH_SUCCESSULL, 
+//                     DN_ERROR_TOPIC_LEN (Topic zu lang - wird abgeschnitten), 
+//                     DN_ERROR_PAYLOAD_LEN (Payload zu lange - wird abgeschnitten)
+
 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, 
+// return: ERROR-Wert: DN_PUBLISH_SUCCESSULL, 
+//                     DN_ERROR_TOPIC_LEN (Topic zu lang - wird abgeschnitten), 
+//                     DN_ERROR_PAYLOAD_LEN (Payload zu lange - wird abgeschnitten)
+
+//Daten werden beim Zustandswechsel von payload (0->1 / 1->0) veroeffentlicht
+int psnClient.publishOnChange(char* topic, bool payload);
+// param1: Topic String/char-Array; 
+// param2: payload vom Datentyp bool (wird in char-Array gewandelt)
+// return: ERROR-Wert: DN_PUBLISH_SUCCESSULL,
+//                     DN_ERROR_NO_ERROR (Keine Daten veroeffentlicht und keine Fehler), 
+//                     DN_ERROR_TOPIC_LEN (Topic zu lang - wird abgeschnitten), 
+//                     DN_ERROR_PAYLOAD_LEN (Payload zu lange - wird abgeschnitten)
+
+// Daten werden veroeffentlicht, wenn Veränderung von payload groeßer als threshold ist 
+int psnClient.publishOnChange(char* topic, int payload, int threshold);
+// param1: Topic String/char-Array; 
+// param2: payload vom Datentyp bool (wird in char-Array gewandelt)
+// param1: Topic String/char-Array; 
+// return: ERROR-Wert: DN_PUBLISH_SUCCESSULL,
+//                     DN_ERROR_NO_ERROR (Keine Daten veroeffentlicht und keine Fehler), 
 //                     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)
+//Bezeichnung muss mit der in psnClient.begin(...) übereinstimmen
 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
+// param4: Laenge der Nachricht
 ```
 
 ### Broker
 
 ```cpp
 #Anlegen der Broker-Instanz
+// Anlegen des Broker-Objekts
+// psnBroker -> moeglicher Name für Objekt
 didacticPSNetBroker psnBroker; 
 
 #Starten der Broker-Instanz 
@@ -95,33 +141,51 @@ void psnBroker.begin(Stream& sSerial);
 
 #Netzwerkverwaltung Broker (Daten senden und Empfangen, Zugriffsregelung)
 bool psnBroker.handleNetwork();
+// return: true wenn Daten versendet / false wenn nicht
+
+void psnBroker.setInterval(long intervalTime);
+// param: Mindestwartezeit in ms zwischen zwei Sendevorgängen (default 0 ms)
 ```
 
 ### 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.
+Die Hiflsfunktionen sind als eigenständige Klassen implementiert und koennen so mehrfach (unter verschiedenen Namen) angelegt werden.
+So koennen die Funktionen mehrfach, mit unterschiedlichen Parametern, verwendet werden.
 
 ```cpp
 #Flankenerkennung z.B. fuer Taster
-int psnClient.edgeDetected(bool currentState);
+// Anlegen des EdgeDetector-Objekts
+// eDetector -> moeglicher Name für Objekt
+EdgeDetector eDetector;
+
+int eDetector.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);
+// Anlegen des ChangeDetector-Objekts
+// cDetector -> moeglicher Name für Objekt
+ChangeDetector cDetector
+
+bool cDetector.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);
+// Anlegen des UnblockingTimer-Objekts
+// uTimer -> moeglicher Name für Objekt
+UnblockingTimer uTimer;
+
+bool uTimer.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);
+// Anlegen des SerialReader-Objekts
+// sReader -> moeglicher Name für Objekt
+SerialReader sReader;
+
+int sReader.readSerialData(Stream&, char*, char);
 // param1: Schnittstelle (Serial | SoftSerial)
 // param2: Array in das die Zeichen eingelesen werden
 // param3: Endezeichen (char)
@@ -130,7 +194,7 @@ int psnClient.readSerialData(Stream&, char*, char);
 
 ### Konstanten
 
-Konstanten aus der Library die fuer die Programmierung genutzt werden und teilweise angepasst werden koennen.
+Konstanten aus der Library die fuer die Programmierung genutzt werden und angepasst werden koennen.
 ```cpp
 #ASCII Endezeichen
 DN_ASCII_CR "carriage return CR" (int) 13
@@ -144,7 +208,12 @@ MAX_LEN_PAYLOAD  default: 20
 MAX_NR_TOPICS_CLIENT  default: 5
 MAX_NR_TOPICS_BROKER  default: 20
 
-#ERRORs
+#Mindestwartezeiten zwischen Sendevorgängen (anpassen über psnClient.setInterval())
+INTERVAL_CLIENT	 default: 500 ms
+INTERVAL_BROKER	 default:   0 ms
+
+#ERRORs (nicht verändern)
+DN_PUBLISH_SUCCESSULL 1
 DN_ERROR_NO_ERROR     0
 DN_ERROR_TOPIC_LEN   -1
 DN_ERROR_PAYLOAD_LEN -2
@@ -164,11 +233,11 @@ MSG_TOPIC_MULTI '*'
 # Bestellung bei Aisler
 
 - Account anlegen
-- Link öffnen: [Nachkaufprojekt bei Aisler.net](https://aisler.net/p/NBAQNHFV)
+- Link oeffnen: [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**.
+**Hinweis:** Das Projekt letsgoING ist in **keiner Weise** an dem **Verkauf beteiligt**.
\ No newline at end of file
diff --git a/examples/brokerClient/brokerClient.ino b/examples/brokerClient/brokerClient.ino
deleted file mode 100644
index 8f8a63f1a3c04cb2eef5db064d17e6ff48b5e1e2..0000000000000000000000000000000000000000
--- a/examples/brokerClient/brokerClient.ino
+++ /dev/null
@@ -1,215 +0,0 @@
-  #include "Arduino.h"
-  #include "SoftwareSerial.h"
-  #include "didacticNet.h"
-
-
-  //#define BROKER
-  #define CLIENT
-  #define C5  // C1 C2 C3 C4 C5
-
-  #define SERIAL_BAUD 2400
-
-  SoftwareSerial sSerial(10, 11);
-
-  #ifdef BROKER
-    didacticPSNetBroker psnB;
-
-    void setup() {
-      Serial.begin(SERIAL_BAUD);
-      sSerial.begin(SERIAL_BAUD);
-      psnB.setStream(sSerial);
-    }
-
-    void loop() {
-      psnB.handleNetwork();
-    }
-  #endif
-
-  #ifdef CLIENT
-    unsigned long lastTime = 0L;
-    byte ledPin3 = 3;
-    byte ledPin5 = 5;
-    byte ledPin6 = 6;
-    byte buttonPin1= 2;
-
-    bool currentState = false;
-    bool lastState    = false;
-    bool togglestate  = true;
-    int lastValue     = 0;
-
-    bool dataReadDone = false;
-    char readData[MAX_LEN_DATA*5]={'\0'};
-    char arrayBuffer[MAX_LEN_DATA+1] = {'\0'};
-    int counter = 0;
-
-    void myCallback(char* mTopic, int mToLength, char* mData, int mDaLength) {
-
-
-    #if defined(C1) || defined(C2) ||  defined(C3) ||  defined(C4)
-      Serial.println("Callback: ");
-      Serial.print("Topic: ");
-      Serial.print(mTopic);
-      Serial.print("\tData: ");
-      Serial.println(mData);
-    #elif defined(C5)
-      Serial.print(mTopic);
-      Serial.print(":\t");
-      Serial.println(mData);
-    #endif
-
-    #if  defined(C1)
-      digitalWrite(ledPin3,(bool)atoi(mData));
-    #elif  defined(C3)
-      analogWrite(ledPin3, map(atoi(mData),0,1023,0,255));
-      analogWrite(ledPin5, map(atoi(mData),0,1023,255,0));
-    #elif  defined(C4)
-      digitalWrite(ledPin3,atoi(mData)<400);
-      digitalWrite(ledPin5,atoi(mData)<400);
-      digitalWrite(ledPin6,atoi(mData)<400);
-    #endif
-    }
-
-  #if  defined(C1)
-    char topicSub[MAX_LEN_TOPICS]={"button1"};
-    char topicPub[MAX_LEN_TOPICS]={"poti1"};
-  #elif  defined(C2)
-    char topicSub[MAX_LEN_TOPICS]={""};
-    char topicPub[MAX_LEN_TOPICS]={"ldr1"};
-  #elif  defined(C3)
-    char topicSub[MAX_LEN_TOPICS]={"poti1"};
-    char topicPub[MAX_LEN_TOPICS]={""};
-  #elif  defined(C4)
-    char topicSub[MAX_LEN_TOPICS]={"ldr1"};
-    char topicPub[MAX_LEN_TOPICS]={"button1"};
-  #elif  defined(C5)
-    char topicSub[MAX_LEN_TOPICS]={""};
-    char topicPub[MAX_LEN_TOPICS]={""};
-  #endif
-
-    didacticPSNetClient psnC;
-    void setup() {
-      Serial.begin(2400);
-      sSerial.begin(2400);
-
-      pinMode(ledPin3, OUTPUT);
-      pinMode(ledPin5, OUTPUT);
-      pinMode(ledPin6, OUTPUT);
-
-      pinMode(buttonPin1, INPUT);
-
-      psnC.setStream(sSerial);
-      psnC.setCallback(myCallback);
-
-      #if defined(C1) ||  defined(C3) ||  defined(C4)
-        psnC.subscribe(topicSub, strlen(topicSub));
-      #endif
-
-      #if defined(C5)
-        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();
-        Serial.println("HINWEIS:");
-        Serial.println("Stelle das Zeilenende im SerialMonitor auf \"Zeilenumbruch (CR)\"");
-        Serial.println("*********************************************************************\n");
-      #endif
-    }
-
-    void loop() {
-      psnC.handleNetwork();
-
-    #if defined(C1) ||  defined(C2)
-        int currentValue = analogRead(0);
-        if(abs(currentValue-lastValue) > 20){
-          delay(500);
-          currentValue = analogRead(0);
-          char data[MAX_LEN_DATA]={0};
-          itoa(currentValue, data, 10);
-          psnC.publish(topicPub, strlen(topicPub), data, strlen(data));
-          lastValue = currentValue;
-        }
-    #endif
-
-    #if defined(C3)
-      if(digitalRead(buttonPin1)){
-        togglestate = !togglestate;
-        if(!togglestate){
-          psnC.unsubscribe(topicSub, strlen(topicSub));
-          digitalWrite(ledPin3,LOW);
-          digitalWrite(ledPin5,LOW);
-          digitalWrite(ledPin6,LOW);
-        }
-        else{
-          psnC.subscribe(topicSub, strlen(topicSub));
-        }
-        delay(500);
-      }
-
-    #endif
-
-    #if defined(C4)
-      currentState = digitalRead(buttonPin1);
-      if(lastState != currentState){
-        char data[MAX_LEN_DATA]={0};
-        itoa(currentState, data, 10);
-        psnC.publish(topicPub, strlen(topicPub), data, strlen(data));
-        delay(500);
-      }
-      lastState = currentState;
-    #endif
-
-    #if defined(C5)
-      if(Serial.available()){
-        char buffer = Serial.read();
-        readData[counter] = buffer;
-        if(buffer == 13){
-          readData[counter] = '\0';
-          counter = 0;
-          dataReadDone = true;
-        }else{
-            counter++;
-        }
-      }
-      if(dataReadDone && strlen(readData)<= MAX_LEN_DATA*5 ){
-        if(readData[0] == '@'){
-          strcpy(readData, readData+1);
-          psnC.subscribe(readData, strlen(readData));
-          Serial.print("Kontakt zu ");
-          Serial.print(readData);
-          Serial.println(" hergestellt");
-        }
-        else if(readData[0] == '#'){
-            strcpy(topicPub, readData+1);
-            Serial.print("Dein Name:\t");
-            Serial.println(topicPub);
-          }
-        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);
-            psnC.publish(topicPub, strlen(topicPub), arrayBuffer, strlen(arrayBuffer));
-            while(psnC.isDataToSend()){
-              psnC.handleNetwork();
-            }
-            Serial.print("Ich:\t");
-            Serial.println(arrayBuffer);
-            /*Serial.print(topicPub);
-            Serial.print(" | ");
-            Serial.print(strlen(topicPub));
-            Serial.print(" | ");
-            Serial.print(arrayBuffer);
-            Serial.print(" | ");
-            Serial.print(strlen(arrayBuffer));
-            Serial.print(" | ");
-            Serial.println(i); */
-            //delay(1000);
-          }
-        }
-        dataReadDone = false;
-      }
-    #endif
-  }
-  #endif
diff --git a/examples/sPSN_Broker/sPSN_Broker.ino b/examples/sPSN_Broker/sPSN_Broker.ino
index 1aec4de47f1a6f83355889f44f998605e7bcd017..e2d142d2644ba0defd9a1c018852432d4ff17448 100644
--- a/examples/sPSN_Broker/sPSN_Broker.ino
+++ b/examples/sPSN_Broker/sPSN_Broker.ino
@@ -38,7 +38,7 @@
 SoftwareSerial sSerial(10, 11);
 
 //Erzeuge Broker-Instanz
-didacticPSNetBroker psnBroker;
+DidacticPSNetBroker psnBroker;
 
 void setup() {
   //Starte Serielle Schnittstelle (zum PC)
diff --git a/examples/sPSN_Chat/sPSN_Chat.ino b/examples/sPSN_Chat/sPSN_Chat.ino
index d480f6a8c5aa0e33a3b6a876ef339ee88449363c..e7b228bf1438dc7015d2dcc90f5f7b8953117193 100644
--- a/examples/sPSN_Chat/sPSN_Chat.ino
+++ b/examples/sPSN_Chat/sPSN_Chat.ino
@@ -44,7 +44,8 @@ void clientCallback(char* mTopic, int mToLength, char* mData, int mDaLength) {
 
 SoftwareSerial sSerial(10, 11); // SoftwareSerial an Rx = Pin10 -> Empfänger | Tx = Pin11 -> Sender
 
-didacticPSNetClient psnClient; //Erzeuge PubSub-Client-Instanz
+DidacticPSNetClient psnClient; //Erzeuge PubSub-Client-Instanz
+SerialReader sReader;
 
 
 void setup() {
@@ -54,6 +55,7 @@ void setup() {
   sSerial.begin(SERIAL_BAUD); //Starte SoftwareSerielle Schnittstelle (zu IR-Link-Modulen)
 
   psnClient.begin(sSerial, clientCallback); //Starte PubSubClient mit SoftwareSerial und Callbackfunktion "clientCallback"
+  sReader.begin(Serial);
 
   //AUSGABE INFOTEXT
   Serial.print("Bitte den eigenen Namen mit einem # eingeben\nund mit Enter bestaetigen. -> ");
@@ -72,7 +74,7 @@ void loop() {
 
   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)
+  int nrOfAscii = sReader.readSerialData(readData, DN_ASCII_CR); //Einlesen der Nutzereingabe am SerialMonitor (Rueckgabewert = Anzahl der gelesenen Zeichen)
 
   if (nrOfAscii > 0) { //Wenn Daten fertig eingelesen wurden
 
@@ -85,7 +87,7 @@ void loop() {
       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 '@')
+      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)
 
       Serial.print("Nachrichten von "); //Ausgabe welches Topic abonniert wurde
diff --git a/examples/sPSN_Client1/sPSN_Client1.ino b/examples/sPSN_Client1/sPSN_Client1.ino
index 249b4c3ce1446f68cc6187196ff50aa3df39c6df..e17005086f286493089dcf3ca436d9ab92b2147f 100644
--- a/examples/sPSN_Client1/sPSN_Client1.ino
+++ b/examples/sPSN_Client1/sPSN_Client1.ino
@@ -30,30 +30,31 @@
 #define POTI_PIN A0
 
 #define THRESHOLD   10  //Schwellwert für min. Wertänderung
-#define SEND_DELAY 500  //Mindestwarezeit zwischen zwei Sendevorgängen
 
-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 topicPublish[MAX_LEN_TOPICS]   = "potiVal";  //Topic unter dem (eigene) Daten veröffentlicht werden
+char topicSubscribe[MAX_LEN_TOPICS] = "btnState"; //Topic (von anderem TN) das abboniert werden soll
 
 char payload[MAX_LEN_PAYLOAD] = {0};
-boolean newData = false;
 
 SoftwareSerial sSerial(10, 11); //Erzeuge SoftwareSerial-Instanz mit Rx = Pin10 -> Empfänger | Tx = Pin11 -> Sender
 
-didacticPSNetClient psnClient;  //Erzeuge PubSub-Client-Instanz
+DidacticPSNetClient psnClient;  //Erzeuge PubSub-Client-Instanz
 
 
 //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.print(" | ");
   Serial.println(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
+  boolean static stateLED = false;
+  
+  //Wechsle Zustand der Variable "stateLED" wenn Taster beim Sender gedrueckt wurde
+  if(bool(atoi(mData)) == true){
+    stateLED = !stateLED;
+    digitalWrite(LED_PIN, stateLED);              //Setze Ausgang entsprechend dem empfangenen Wert
+  }        
 }
 
 
@@ -75,15 +76,7 @@ void loop() {
   psnClient.handleNetwork();               //Verarbeiten der Daten, prüfen ob Netzwerk frei und versenden der Daten
 
   int currentValue = analogRead(POTI_PIN); //lese Poti ein und speichere Wert
-
-  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
-  }
+  psnClient.publishOnChange(topicPublish, currentValue, THRESHOLD); 
+  
 }
 
diff --git a/examples/sPSN_Client2/sPSN_Client2.ino b/examples/sPSN_Client2/sPSN_Client2.ino
index ad31487990138e20535fad7c15f1ac5950b210e7..5e49f515a0ae66a38edcbd61446f3009e42a0ba3 100644
--- a/examples/sPSN_Client2/sPSN_Client2.ino
+++ b/examples/sPSN_Client2/sPSN_Client2.ino
@@ -24,12 +24,11 @@
 #define SERIAL_BAUD 2400 //lege Geschwindigkeit für serielle Schnittstellen fest
 
 #define LED_PIN    5
+#define LED2_PIN    6
 #define BUTTON_PIN 2
 
-#define SEND_DELAY 500  //Mindestwarezeit zwischen zwei Sendevorgängen
-
-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)
+char topicPublish[MAX_LEN_TOPICS]   = "btnState";   //Topic unter dem (eigene) Daten veröffentlicht werden
+char topicSubscribe[MAX_LEN_TOPICS] = "potiVal";    //Topic (von anderem TN) das abboniert werden soll
 
 char payload[MAX_LEN_PAYLOAD] = {0};
 boolean newData  = false;
@@ -37,21 +36,24 @@ boolean ledState = false;
 
 SoftwareSerial sSerial(10, 11); //Erzeuge SoftwareSerial-Instanz mit Rx = Pin10 -> Empfänger | Tx = Pin11 -> Sender
 
-didacticPSNetClient psnClient;  //Erzeuge PubSub-Client-Instanz
+DidacticPSNetClient psnClient;  //Erzeuge PubSub-Client-Instanz
+UnblockingTimer uTimer;
 
 
 //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.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
+  int valuePoti = atoi(mData);  //wandle ASCII-Zeichen in Wert
   //Alternativ: sscanf(mData, "%d", &stateLED); //wandle ASCII-Zeichen in Wert
 
-  analogWrite(LED_PIN, valueLED);              //Setze Ausgang entsprechend dem empfangenen Wert
+  int valueLED = constrain(map(valuePoti, 0, 1023, 0, 255), 0, 255); //passe analogRead-Wert für analogWrite an
+  
+  analogWrite(LED_PIN, valueLED);        //Setze Ausgang entsprechend dem empfangenen Wert
+  analogWrite(LED2_PIN, 255-valueLED);   //Setze Ausgang invertiert zum empfangenen Wert
 }
 
 
@@ -70,17 +72,7 @@ void loop() {
 
   psnClient.handleNetwork();               //Verarbeiten der Daten, prüfen ob Netzwerk frei und versenden der Daten
 
-  boolean buttonState = digitalRead(BUTTON_PIN); //lese Poti ein und speichere Wert
-
-  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
-  }
+  boolean buttonState = digitalRead(BUTTON_PIN); //lese Taster ein und speichere Wert
+  psnClient.publishOnChange(topicPublish, buttonState); //bereite Topic und Nutzdaten zum senden vor, wenn sich buttonState ändert
 }
 
diff --git a/examples/sPSN_ClientMinimal/sPSN_ClientMinimal.ino b/examples/sPSN_ClientMinimal/sPSN_ClientMinimal.ino
index 0e58d6bb209d2a2497290a1ece8f8f0464317507..1805cb58108e1a730c26dcee0223ef58ced973e2 100644
--- a/examples/sPSN_ClientMinimal/sPSN_ClientMinimal.ino
+++ b/examples/sPSN_ClientMinimal/sPSN_ClientMinimal.ino
@@ -25,8 +25,8 @@
 
 SoftwareSerial sSerial(10, 11); //Erzeuge SoftwareSerial-Instanz mit Rx = Pin10 -> Empfänger | Tx = Pin11 -> Sender
 
-didacticPSNetClient psnClient;  //Erzeuge PubSub-Client-Instanz
-
+DidacticPSNetClient psnClient;  //Erzeuge PubSub-Client-Instanz
+UnblockingTimer uTimer;
 
 //Callback-Funktion - wird beim Empfang neuer Daten aufgerufen
 void clientCallback(char* mTopic, int mToLength, char* mPayload, int mPayloadLength) {
@@ -53,13 +53,8 @@ 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
-  }
+  
+  //Hier SENDE-TOPIC ANPASSEN -> default "client1"
+  psnClient.publish("client1", currentValue);
 }
 
diff --git a/keywords.txt b/keywords.txt
index d70dbd25191371f0109951bed444664952040e3d..542b41df93aae8db0b8510a1d1aca8d2970ec1eb 100644
--- a/keywords.txt
+++ b/keywords.txt
@@ -5,9 +5,13 @@
 #######################################
 # Datatypes (KEYWORD1)
 #######################################
-didacticPSNet		KEYWORD1
-didacticPSNetBroker	KEYWORD1
-didacticPSNetClient	KEYWORD1
+DidacticPSNet	KEYWORD1
+DidacticPSNetBroker	KEYWORD1
+DidacticPSNetClient	KEYWORD1
+EdgeDetector	KEYWORD1
+ChangeDetector	KEYWORD1
+UnblockingTimer	KEYWORD1
+SerialReader	KEYWORD1
 
 #######################################
 # Methods and Functions (KEYWORD2)
@@ -16,13 +20,13 @@ setCallback	KEYWORD2
 setStream	KEYWORD2
 handleNetwork	KEYWORD2
 isDataToSend	KEYWORD2
+setInterval	KEYWORD2
 
 publish	KEYWORD2
+publishOnChange	KEYWORD2
 subscribe	KEYWORD2
 unsubscribe	KEYWORD2
 
-edgeDetected	KEYWORD2
-valueChanged	KEYWORD2
 timeElapsed	KEYWORD2
 readSerialData	KEYWORD2
 
@@ -46,6 +50,7 @@ MAX_LEN_PAYLOAD	LITERAL1
 DN_ASCII_CR	LITERAL1
 DN_ASCII_NL	LITERAL1
 
+DN_PUBLISH_SUCCESSULL	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/library.properties b/library.properties
index b103e4391dcb62375688e34d444308578b4aa79b..751f90f5310e978605b0f1e469ce70ca5f8e6dae 100644
--- a/library.properties
+++ b/library.properties
@@ -1,5 +1,5 @@
 name=didacticNetwork
-version=0.2
+version=0.9
 author=letsgoING
 maintainer=letsgoING <info@letsgoing.org>
 sentence=Library for implementing didactic reduced networks on Arduino boards.
diff --git a/src/didacticNet.cpp b/src/didacticNet.cpp
index 6529e29f65f275139ccda0158965048c4ec2ed56..f14ace21992e70b7d533ffd00d95831966f92b66 100644
--- a/src/didacticNet.cpp
+++ b/src/didacticNet.cpp
@@ -11,30 +11,30 @@
 //**************************************************************************
 //ROOT
 //**************************************************************************
-didacticPSNet::didacticPSNet(){}
+DidacticPSNet::DidacticPSNet(){}
 
-didacticPSNet::~didacticPSNet(){}
+DidacticPSNet::~DidacticPSNet(){}
 
-void didacticPSNet::begin(Stream& _port){
+void DidacticPSNet::begin(Stream& _port){
   setStream(_port);
 }
 
-void didacticPSNet::begin(Stream& _port, PSNET_CALLBACK_SIGNATURE){
+void DidacticPSNet::begin(Stream& _port, PSNET_CALLBACK_SIGNATURE){
   setStream(_port);
   setCallback(callback);
 }
 
-didacticPSNet& didacticPSNet::setCallback(PSNET_CALLBACK_SIGNATURE){
+DidacticPSNet& DidacticPSNet::setCallback(PSNET_CALLBACK_SIGNATURE){
     this->callback = callback;
     return *this;
 }
 
-void didacticPSNet::setStream(Stream& stream){
+void DidacticPSNet::setStream(Stream& stream){
     _port = &stream;
 }
 
-bool didacticPSNet::handleNetwork(){
-  if(_waitingTime <= millis()){
+bool DidacticPSNet::handleNetwork(){
+  //if(_waitingTime <= millis()){
   	if(checkData()){
   		if(recieveData()){
         //Serial.print("Message filter: ");Serial.println(_readBufferMessage[1]);
@@ -45,29 +45,31 @@ bool didacticPSNet::handleNetwork(){
   		}
   		_waitingTime = millis()+ random(CSMA_MIN_DELAY_MS, CSMA_MAX_DELAY_MS);
   	}
-  	else if(_dataToSend){
-  		//send data to network
+  	//else if(_dataToSend){
+    if(_dataToSend && _waitingTime <= millis()){
+      //send data to network
       //TODO: test added CSMA_CHECKDELAY + 2nd checkData()
       delayMicroseconds(CSMA_CHECK_DELAY_US);
       if(!checkData()){
-      	if(!sendData()){
-    			return false;
-    		}
+        if(!sendData()){
+          return false;
+        }
         else{
           _dataToSend = false;
-          _waitingTime = millis()+ random(CSMA_MID_DELAY_MS, CSMA_MAX_DELAY_MS);
+          //_waitingTime = millis()+ random(CSMA_MID_DELAY_MS, CSMA_MAX_DELAY_MS);
+          _waitingTime = millis()+ _intervalTime;//random(CSMA_MID_DELAY_MS, CSMA_MAX_DELAY_MS);
         }
       }
-  	}
-  }
+    }
+  //}
 	return true;
 }
 
-bool didacticPSNet::isDataToSend(){
+bool DidacticPSNet::isDataToSend(){
   return _dataToSend;
 }
 
-bool didacticPSNet::sendData(){
+bool DidacticPSNet::sendData(){
 	int counter = 0;
   bool messageSent = false;
 	while(!messageSent){
@@ -86,7 +88,7 @@ bool didacticPSNet::sendData(){
 	return true;
 }
 
-int didacticPSNet::extractData(int startCounter, int maxLength, char* buffer, char limiter){
+int DidacticPSNet::extractData(int startCounter, int maxLength, char* buffer, char limiter){
 	int counter = startCounter;
 	while(_readBufferMessage[counter]!= limiter){
 		buffer[counter-startCounter] = _readBufferMessage[counter];
@@ -100,11 +102,11 @@ int didacticPSNet::extractData(int startCounter, int maxLength, char* buffer, ch
 	return counter-startCounter; //length
 }
 
-int didacticPSNet::checkData(){
+int DidacticPSNet::checkData(){
 	return (int)_port->available();
 }
 
-bool  didacticPSNet::recieveData() {
+bool  DidacticPSNet::recieveData() {
 	static int msgCounter = 0;
 	static int topicCounter = 0;
 	static int payloadCounter = 0;
@@ -139,47 +141,26 @@ bool  didacticPSNet::recieveData() {
 	return false;
 }
 
+		void  DidacticPSNet::setInterval(long intervalTime){
+      _intervalTime = intervalTime;
+    }
+
+
 //**************************************************************************
 // CLIENT
 //**************************************************************************
-didacticPSNetClient::didacticPSNetClient(){}
-
-didacticPSNetClient::~didacticPSNetClient(){}
-
-int didacticPSNetClient::publish(char* topic,  char* payload){
-  int error = DN_ERROR_NO_ERROR;
-
-	int topicLength =  strlen(topic);
-	int payloadLength = strlen(payload);
-	_sendBufferMessage[0] = MSG_PRELIMITER;
-	_sendBufferMessage[1] = MSG_PUBLISH;
-	_sendBufferMessage[2+topicLength] = MSG_SEPARATOR;
-	_sendBufferMessage[2+topicLength+1+payloadLength] = MSG_DELIMITER;
-	_sendBufferMessage[2+topicLength+1+payloadLength+1] = '\0';
-
-  //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;
-  }
+DidacticPSNetClient::DidacticPSNetClient(){
+  _intervalTime = INTERVAL_CLIENT;
+}
 
-  for(int i = 0; i < topicLength; i++){
-			_sendBufferMessage[2+i] = topic[i];
-		}
-  for(int i = 0; i < payloadLength; i++){
-			_sendBufferMessage[2+topicLength+1+i] = payload[i];
-		}
+DidacticPSNetClient::~DidacticPSNetClient(){}
 
-  _dataToSend = true;
-	return error;
+int DidacticPSNetClient::publish(char* topic,  char* payload){
+	return publish(topic, strlen(topic), payload, strlen(payload));
 }
 
-int didacticPSNetClient::publish(char* topic, int topicLength, char* payload , int payloadLength){
-	int error = DN_ERROR_NO_ERROR;
+int DidacticPSNetClient::publish(char* topic, int topicLength, char* payload , int payloadLength){
+	int error = DN_PUBLISH_SUCCESSULL;
   
   _sendBufferMessage[0] = MSG_PRELIMITER;
 	_sendBufferMessage[1] = MSG_PUBLISH;
@@ -208,49 +189,44 @@ int didacticPSNetClient::publish(char* topic, int topicLength, char* payload , i
 	return error;
 }
 
-int didacticPSNetClient::subscribe(char* topic){
-  int error = DN_ERROR_NO_ERROR;
-
-  int topicLength = strlen(topic);
+//TODO: TEST TEST TEST
+int DidacticPSNetClient::publish(char* topic,  int data){
+  char sendPayload[MAX_LEN_PAYLOAD];
+  itoa(data, sendPayload, 10);
 
-  if( topicLength > MAX_LEN_TOPICS){
-   topicLength = MAX_LEN_TOPICS;
-   error = DN_ERROR_TOPIC_LEN;
-   }
+	return publish(topic, sendPayload);
+}
 
-  _sendBufferMessage[0] = MSG_PRELIMITER;
-	_sendBufferMessage[1] = MSG_SUBSCRIBE;
-	_sendBufferMessage[2+topicLength] = MSG_DELIMITER;
+int DidacticPSNetClient::publish(char* topic,  bool data){
+  char sendPayload[2];
+  itoa(data, sendPayload, 10);
 
-  int topicNumber = getTopicNr(topic);
+	return publish(topic, sendPayload);
+}
 
-  if(topicNumber < 0){
-    topicNumber = getFreeTopicNr();
-    if(topicNumber < 0){
-      topicNumber = 0;
+int DidacticPSNetClient::publishOnChange(char* topic, bool input){
+  if(!_dataToSend){
+    if(eDetector.edgeDetected(input)){
+      return publish(topic, input);
     }
-  		for(int i = 0; i < topicLength; i++){
-  			_topic[topicNumber][i] = topic[i];
-        _sendBufferMessage[2+i]= topic[i];
-  		}
-      _topic[topicNumber][topicLength] = '\0';
-      _sendBufferMessage[2+topicLength+1]= '\0';
-      _dataToSend = true;
   }
-  else{
-  		for(int i = 0; i < topicLength; i++){
-        _sendBufferMessage[2+i]= topic[i];
-  		}
-      _sendBufferMessage[2+topicLength+1]= '\0';
-      _dataToSend = true;
-  }
-  while(_dataToSend){
-    handleNetwork();
+  return DN_ERROR_NO_ERROR;
+}
+
+int DidacticPSNetClient::publishOnChange(char* topic, int input, int threshold){
+  if(!_dataToSend){
+    if(cDetector.valueChanged(input, threshold)){
+      return publish(topic, input);
+    }
   }
-	return error;
+  return DN_ERROR_NO_ERROR;
+}
+
+int DidacticPSNetClient::subscribe(char* topic){
+	return subscribe(topic, strlen(topic));
 }
 
-int didacticPSNetClient::subscribe(char* topic, int topicLength){
+int DidacticPSNetClient::subscribe(char* topic, int topicLength){
    int error = DN_ERROR_NO_ERROR;
 
    if( topicLength > MAX_LEN_TOPICS){
@@ -291,17 +267,11 @@ int didacticPSNetClient::subscribe(char* topic, int topicLength){
 }
 
 
-bool didacticPSNetClient::unsubscribe(char* topic){
-  int topicNumber = getTopicNr(topic);
-  int topicLength = strlen(topic);
-  if(topicNumber >= 0){
-    _topic[topicNumber][0]='\0';
-    return true;
-  }
-  return false;
+bool DidacticPSNetClient::unsubscribe(char* topic){
+  return unsubscribe(topic, strlen(topic));
 }
 
-bool didacticPSNetClient::unsubscribe(char* topic, int topicLength){
+bool DidacticPSNetClient::unsubscribe(char* topic, int topicLength){
   int topicNumber = getTopicNr(topic);
   if(topicNumber >= 0){
     _topic[topicNumber][0]='\0';
@@ -310,16 +280,16 @@ bool didacticPSNetClient::unsubscribe(char* topic, int topicLength){
   return false;
 }
 
-bool didacticPSNetClient::getMessageFilter(char messageType){
+bool DidacticPSNetClient::getMessageFilter(char messageType){
   return messageType == MSG_UPDATE;
 }
 
-bool didacticPSNetClient::savePayload(char* buffer, int position){
+bool DidacticPSNetClient::savePayload(char* buffer, int position){
   strcpy(_payload[position], buffer);
   return true;
 }
 
-bool didacticPSNetClient::handleData(){
+bool DidacticPSNetClient::handleData(){
   int currentTopicNr = 0;
   int topicLength = 0;
   int payloadLength = 0;
@@ -335,7 +305,7 @@ bool didacticPSNetClient::handleData(){
   return true;
 }
 
-int didacticPSNetClient::getTopicNr(char* topic){
+int DidacticPSNetClient::getTopicNr(char* topic){
 	for (int i = 0; i < MAX_NR_TOPICS_CLIENT; i++) {
     if (strcmp(_topic[i], topic) == 0 || _topic[i][0] == MSG_TOPIC_MULTI) { //TODO: check ... or equal MSG_TOPIC_MULTI
       return i;
@@ -344,7 +314,7 @@ int didacticPSNetClient::getTopicNr(char* topic){
  return -1;
 }
 
-int didacticPSNetClient::getFreeTopicNr() {
+int DidacticPSNetClient::getFreeTopicNr() {
   for (int i = 0; i < MAX_NR_TOPICS_CLIENT; i++) {
     if (strcmp(_topic[i], "") == 0) {
       return i;
@@ -353,89 +323,34 @@ 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
 //**************************************************************************
-didacticPSNetBroker::didacticPSNetBroker(){}
+DidacticPSNetBroker::DidacticPSNetBroker(){
+    _intervalTime = INTERVAL_BROKER;
+}
 
-didacticPSNetBroker::~didacticPSNetBroker(){}
+DidacticPSNetBroker::~DidacticPSNetBroker(){}
 
 
-bool didacticPSNetBroker::getMessageFilter(char messageType){
+bool DidacticPSNetBroker::getMessageFilter(char messageType){
   return (messageType == MSG_PUBLISH || messageType == MSG_SUBSCRIBE);
 }
 
-bool didacticPSNetBroker::savePayload(char* buffer, int position){
+bool DidacticPSNetBroker::savePayload(char* buffer, int position){
   strcpy(_data[position], buffer);
   return true;
 }
 
-void didacticPSNetBroker::writeDataToTopic(int topicNumber, char* usedTopic, char* newData) {
+void DidacticPSNetBroker::writeDataToTopic(int topicNumber, char* usedTopic, char* newData) {
     if(strcmp(_topic[topicNumber], "") == 0){
       strcpy(_topic[topicNumber], usedTopic);
     }
       strcpy(_data[topicNumber], newData);
 }
 
-bool didacticPSNetBroker::handleData(){
+bool DidacticPSNetBroker::handleData(){
   int currentTopicNr = 0;
   int topicLength = 0;
   int dataLength = 0;
@@ -462,7 +377,7 @@ bool didacticPSNetBroker::handleData(){
 return true;
 }
 
-bool didacticPSNetBroker::update(char* topic, int topicLength, char* data , int dataLength){
+bool DidacticPSNetBroker::update(char* topic, int topicLength, char* data , int dataLength){
 	_sendBufferMessage[0] = MSG_PRELIMITER;
 	_sendBufferMessage[1] = MSG_UPDATE;
 	_sendBufferMessage[2+topicLength] = MSG_SEPARATOR;
@@ -489,7 +404,7 @@ bool didacticPSNetBroker::update(char* topic, int topicLength, char* data , int
 	return true;
 }
 
-int didacticPSNetBroker::getTopicNr(char* topic){
+int DidacticPSNetBroker::getTopicNr(char* topic){
 	for (int i = 0; i < MAX_NR_TOPICS_BROKER; i++) {
   if (strcmp(_topic[i], topic) == 0) {
       return i;
@@ -498,7 +413,7 @@ int didacticPSNetBroker::getTopicNr(char* topic){
  return	getFreeTopicNr();
 }
 
-int didacticPSNetBroker::getFreeTopicNr() {
+int DidacticPSNetBroker::getFreeTopicNr() {
   for (int i = 0; i < MAX_NR_TOPICS_BROKER; i++) {
     if (strcmp(_topic[i], "") == 0) {
       return i;
@@ -506,3 +421,77 @@ int didacticPSNetBroker::getFreeTopicNr() {
   }
   return -1;
 }
+
+
+//**************************************************************************
+//LITTLE HELPERS FOR CLIENTS ;-)
+//*************************************************************************
+
+EdgeDetector::EdgeDetector(){};
+EdgeDetector::~EdgeDetector(){};
+
+int EdgeDetector::edgeDetected(bool currentState){
+  static bool lastState = false;
+  int edEdge = 0;
+
+  if(currentState && !lastState){
+    edEdge = RISING;
+  }
+  else if(!currentState && lastState){
+    edEdge = FALLING;
+  }
+  lastState = currentState;
+  return edEdge;
+}
+
+ChangeDetector::ChangeDetector(){}
+ChangeDetector::~ChangeDetector(){}
+
+bool ChangeDetector::valueChanged(int value, int threshold){
+  static int lastValue = 0;
+
+  if(abs(value-lastValue) > threshold){
+    lastValue = value;
+    return true;
+  }
+  return false;
+}
+
+
+UnblockingTimer::UnblockingTimer(){}
+UnblockingTimer::~UnblockingTimer(){}
+
+bool UnblockingTimer::timeElapsed(long delayTime){
+  long currentTime = millis();
+
+  if(lastTime + (delayTime-1) < currentTime){
+    lastTime = currentTime;
+    return true;
+  }
+  return false;
+}
+
+SerialReader::SerialReader(){}
+SerialReader::~SerialReader(){}
+
+void SerialReader::begin(Stream& rsStream){
+  _port = &rsStream;
+}
+
+int SerialReader::readSerialData(char* rsDataArray, char rsEndSign) {
+
+  if (_port->available()) {
+    char charBuffer = _port->read();
+    rsDataArray[charCounter] = charBuffer;
+
+    if (charBuffer == rsEndSign) {
+      rsDataArray[charCounter] = '\0';
+      int nrOfChars = charCounter;
+      charCounter = 0;
+      return nrOfChars; 
+    } else {
+      charCounter++;
+    }
+  }
+  return 0;
+}
\ No newline at end of file
diff --git a/src/didacticNet.h b/src/didacticNet.h
index fda76125d25b7ba99a791feecf4b73beec7f4979..596db882857b225191ab1d86fa05712d91df8856 100644
--- a/src/didacticNet.h
+++ b/src/didacticNet.h
@@ -31,20 +31,73 @@
 #define CSMA_MID_DELAY_MS    20
 #define CSMA_MAX_DELAY_MS    30
 
+#define INTERVAL_CLIENT	   500L
+#define INTERVAL_BROKER	     0L
+
 #define MAX_NR_TOPICS_CLIENT   5
 #define MAX_NR_TOPICS_BROKER  20
 #define MAX_LEN_TOPICS 		  10
 #define MAX_LEN_PAYLOAD       20
 
+#define DN_PUBLISH_SUCCESSULL 1
 #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
+
+class EdgeDetector
+{
+	private:
+
+	public:
+		EdgeDetector();
+		~EdgeDetector();
+		int edgeDetected(bool);
+
+};
+
+class ChangeDetector
+{
+	private:
+
+	public:
+		ChangeDetector();
+		~ChangeDetector();
+		bool valueChanged(int, int);
+
+};
+
+class UnblockingTimer
+{
+	private:
+		long lastTime = 0L;
+
+	public:
+		UnblockingTimer();
+		~UnblockingTimer();
+		bool timeElapsed(long);
+
+};
+class SerialReader
+{
+	private:
+		Stream* _port;
+		int charCounter = 0;
+
+	public:
+		SerialReader();
+		~SerialReader();
+		void begin(Stream&);
+		int readSerialData(char*, char);
+
+};
+
+class DidacticPSNet
 {
 	protected:
 		Stream* _port;
@@ -58,10 +111,11 @@ class didacticPSNet
 
 		bool _dataToSend = false; // int Data to send for queue?
 		unsigned long _waitingTime = 0L;
+		unsigned long _intervalTime = 0L;
 		int _currentTopicLength = 0;
 		int _currentPayloadLength  = 0;
 
-		didacticPSNet& setCallback(PSNET_CALLBACK_SIGNATURE);
+		DidacticPSNet& setCallback(PSNET_CALLBACK_SIGNATURE);
 		void setStream(Stream& _port);
 
 		int checkData();
@@ -76,19 +130,24 @@ class didacticPSNet
 		virtual bool handleData()=0;
 
 	public:
-		didacticPSNet();
-		~didacticPSNet();
+		DidacticPSNet();
+		~DidacticPSNet();
 
 		void begin(Stream& _port);
 		void begin(Stream& _port, PSNET_CALLBACK_SIGNATURE);
 		bool handleNetwork();
 		bool isDataToSend();
 
+		void setInterval(long);
+
 };
 
-class didacticPSNetClient : public  didacticPSNet
+class DidacticPSNetClient : public  DidacticPSNet
 {
 	private:
+	EdgeDetector 	eDetector;
+	ChangeDetector  cDetector;
+
 	char _topic[MAX_NR_TOPICS_CLIENT][MAX_LEN_TOPICS+1] = { { 0 } };
 	char _payload[MAX_NR_TOPICS_CLIENT][MAX_LEN_PAYLOAD+1] = { { 0 } };
 
@@ -98,26 +157,27 @@ class didacticPSNetClient : public  didacticPSNet
 	int getTopicNr(char*);
 	int getFreeTopicNr();
 
+	int edgeDetected(bool);
+	bool valueChanged(int, int);
+
 	public:
-	didacticPSNetClient();
-	~didacticPSNetClient();
+	DidacticPSNetClient();
+	~DidacticPSNetClient();
 
 	int publish(char*, char*);
 	int publish(char*, int, char*, int);
+	int publish(char*, int);
+	int publish(char*, bool);
+	int publishOnChange(char*, bool);
+	int publishOnChange(char*, int, 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
+class DidacticPSNetBroker: public  DidacticPSNet
 {
 	private:
 	char _topic[MAX_NR_TOPICS_BROKER][MAX_LEN_TOPICS+1] = { { 0 } };
@@ -131,11 +191,13 @@ class didacticPSNetBroker: public  didacticPSNet
 	int getFreeTopicNr();
 
 	public:
-	didacticPSNetBroker();
-	~didacticPSNetBroker();
+	DidacticPSNetBroker();
+	~DidacticPSNetBroker();
 
 	bool update(char*, int, char*, int);
 
 
 };
+
+
 #endif