diff --git a/src/main/java/com/ardublock/Main.java b/src/main/java/com/ardublock/Main.java
index 2e9c717cfe44f4cf32a3e182d9c794a8288a5993..21b762d15a0a557d01a927a910b4c42571fd909a 100644
--- a/src/main/java/com/ardublock/Main.java
+++ b/src/main/java/com/ardublock/Main.java
@@ -2,7 +2,13 @@ package com.ardublock;
 
 import java.awt.Color;
 import java.awt.event.WindowEvent;
+import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
 
 import javax.swing.JFrame;
 import javax.swing.UIManager;
@@ -28,6 +34,7 @@ public class Main
 	{
 		startOpenblocksFrame();
 		//startConsoleFrame();
+		
 	}
 	
 	private void startOpenblocksFrame() throws SAXException, IOException, ParserConfigurationException
diff --git a/src/main/java/com/ardublock/core/Context.java b/src/main/java/com/ardublock/core/Context.java
index 2b11994cfe8a33cc5c8bf3e2db8207e01fcb23b3..7ab7e7d6dc4b4bce300832ccb1dc3745a9835851 100644
--- a/src/main/java/com/ardublock/core/Context.java
+++ b/src/main/java/com/ardublock/core/Context.java
@@ -44,7 +44,6 @@ public class Context
 	//TODO change AppName? by letsgoING
 	final public static String APP_NAME = "ArduBlock";
 	
-	//TODO: ADD saveDefaultArdublockProgram()
 	
 	private Editor editor;
 	
@@ -197,7 +196,7 @@ public class Context
 			e.printStackTrace();
 		}
 		
-		path = path + "/../../../"; //from tools/ArduBlockTool/tool/ to Arduino-root 
+		path = path + File.separatorChar+".."+ File.separatorChar+".."+ File.separatorChar+".."+ File.separatorChar; //from tools/ArduBlockTool/tool/ to Arduino-root 
 		
 		//TODO: check on MAC and WIN
 		/*
diff --git a/src/main/java/com/ardublock/ui/OpenblocksFrame.java b/src/main/java/com/ardublock/ui/OpenblocksFrame.java
index 806ad1d8c03f8d214b6b4744454269c3a7b5b951..8d06f091f633c22c5d4d5488090356d0ba04f57b 100644
--- a/src/main/java/com/ardublock/ui/OpenblocksFrame.java
+++ b/src/main/java/com/ardublock/ui/OpenblocksFrame.java
@@ -13,7 +13,10 @@ import java.awt.event.ActionListener;
 import java.awt.event.KeyEvent;
 import java.awt.image.BufferedImage;
 import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.URL;
 import java.net.URLDecoder;
@@ -36,6 +39,7 @@ import javax.swing.ToolTipManager;
 import javax.swing.filechooser.FileFilter;
 import javax.swing.filechooser.FileNameExtensionFilter;
 
+import com.ardublock.ArduBlockTool;
 import com.ardublock.core.Context;
 import com.ardublock.ui.listener.ArdublockWorkspaceListener;
 import com.ardublock.ui.listener.ButtonMouseListener;
@@ -125,6 +129,10 @@ public class OpenblocksFrame extends JFrame
 		appPrefix = uiMessageBundle.getString("ardublock.ui.appprefix.standard");
         setTitle(makeFrameTitle());
         
+        //TODO: TEST addLibrary functionality
+        addLibrary("LGI_QTouch");
+		addLibrary("didacticNet");
+        
 		initOpenBlocks();
 		
 	}
@@ -1278,5 +1286,88 @@ public class OpenblocksFrame extends JFrame
 	public boolean getModeState(){ //letsgoING
 		return workspaceModeState; 
 	}
+	
+	//TODO: TESTTESTTEST
+	private void addLibrary(String libraryName) 
+	{
+		//TEST TODO: validate
+		//copy provided libraries to ArduinoLibraries
+		String libraryPath           = null;
+		String libraryResource        ="/com/ardublock/libraries/"+libraryName;
+		String arduinoLibraryPath     = null;
+		File   libraryHeaderFile        = null;	
+		File   librarySourceFile        = null;	
+		
+		
+		System.out.println("copy libraries...");
+		
+		//get current .jar path for temp files
+		//TODO: change path to sketchbook-folder
+        try {
+    		arduinoLibraryPath = new File(URLDecoder.decode(getClass().getProtectionDomain().getCodeSource().getLocation().getFile(), "UTF-8")).getParentFile().getPath();
+    		arduinoLibraryPath = arduinoLibraryPath +File.separatorChar+".."+File.separatorChar+".."+File.separatorChar+".."+File.separatorChar+"libraries";
+		} catch (UnsupportedEncodingException e1) {
+			// TODO Auto-generated catch block
+			e1.printStackTrace();
+		}
+    	
+    	System.out.println("Path: "+arduinoLibraryPath);
+    	
+    	File arduinoLibFolder = new File(arduinoLibraryPath);
+    	
+    	if(!arduinoLibFolder.exists()) {
+    		System.out.println("No libraries-folder - Nothing to do for me...");
+    	}else {
+    		libraryPath = arduinoLibraryPath + File.separatorChar + libraryName;
+    		File libraryFolder = new File(libraryPath);
+    		if(!libraryFolder.exists()) {
+    			libraryFolder.mkdir();
+    			while(!libraryFolder.exists());
+    		}
+			try {
+	            InputStream inputHeader = getClass().getResourceAsStream(libraryResource+".h");
+	        	if(inputHeader != null) {
+		            libraryHeaderFile = new File(libraryPath+File.separatorChar+libraryName+".h");
+		            OutputStream outHeader = new FileOutputStream(libraryHeaderFile);
+		            int read;
+		            byte[] bytes = new byte[1024];
+		    	    while ((read = inputHeader.read(bytes)) != -1) {
+		   	            outHeader.write(bytes, 0, read);
+		   	        }
+		    	    outHeader.close();
+	        	}else {
+	        		//TODO: handle if no lib is found
+	        	}
+	            InputStream inputSource = getClass().getResourceAsStream(libraryResource+".cpp");
+	    	  	if(inputSource != null) {
+  		    	  	int read;
+		            byte[] bytes = new byte[1024];
+		            librarySourceFile = new File(libraryPath+File.separatorChar+libraryName+".cpp");
+	    	        OutputStream outSource = new FileOutputStream(librarySourceFile);
+		    	    while ((read = inputSource.read(bytes)) != -1) {
+		    	    	outSource.write(bytes, 0, read);
+		   	        }
+		    	    outSource.close();
+	    	  	}else {
+	    	  	//TODO: handle if no lib is found
+	        	}
+	    	  	InputStream inputCSource = getClass().getResourceAsStream(libraryResource+".c");
+	    	  	if(inputCSource != null) {
+  		    	  	int read;
+		            byte[] bytes = new byte[1024];
+		            librarySourceFile = new File(libraryPath+File.pathSeparator+libraryName+".c");
+	    	        OutputStream outSource = new FileOutputStream(librarySourceFile);
+		    	    while ((read = inputSource.read(bytes)) != -1) {
+		    	    	outSource.write(bytes, 0, read);
+		   	        }
+		    	    outSource.close();
+	    	  	}else {
+	    	  	//TODO: handle if no lib is found
+	    	  	}
+	   	    } catch (IOException ex) {
+	   	        ex.printStackTrace();
+	   	    }
+    	}
+	}
 
 }
diff --git a/src/main/resources/com/ardublock/block/ardublock_de.properties b/src/main/resources/com/ardublock/block/ardublock_de.properties
index 9f8503682d6be4e4953e5eb6512cf65f03a987db..eb574f2f213e080cc4d2de4ad4ffbe1fc904d0da 100644
--- a/src/main/resources/com/ardublock/block/ardublock_de.properties
+++ b/src/main/resources/com/ardublock/block/ardublock_de.properties
@@ -706,19 +706,6 @@ bg.tele_read_data_frame=lese Daten aus Frame
 bg.mqtt_set_frame=erstelle MQTT Frame
 bg.mqtt_read_frame=lese aus MQTT Frame
 
-bg.psn_broker=Broker psnName
-bg.psn_client=Client psnName
-bg.psn_callback=psnClientCallback
-bg.psn_handle_network=psnName handleNetwork
-bg.psn_data_to_send=psnName isDataToSend?
-bg.psn_publish=psnName publish
-bg.psn_publish_analog=psnName publish
-bg.psn_publish_digital=psnName publish
-bg.psn_publish_onchange=psnName publishOnChange
-bg.psn_publish_onchange_bool=psnName publishOnChange
-bg.psn_subscribe=psnName subscribe
-bg.psn_unsubscribe=psnName unsubscribe 
-
 bg.serial_write.description=Sende Nachricht via Serial
 bg.serial_print.description=Sende Nachricht via Serial
 bg.serial_read.description=Lese Zeichen via Serial als kurze analoge Variable ein\n(siehe ASCII-Tabelle)
@@ -771,6 +758,19 @@ bg.didacticnetworkDivider2=|       PubSub publish      |
 bg.didacticnetworkDivider3=|       PubSub subscribe      |
 bg.didacticnetworkDivider4=|       PubSub callback      |
 
+bg.psn_broker=Broker psnName
+bg.psn_client=Client psnName
+bg.psn_callback=psnClientCallback
+bg.psn_handle_network=psnName handleNetwork
+bg.psn_data_to_send=psnName isDataToSend?
+bg.psn_publish=psnName publish
+bg.psn_publish_analog=psnName publish
+bg.psn_publish_digital=psnName publish
+bg.psn_publish_onchange=psnName publishOnChange
+bg.psn_publish_onchange_bool=psnName publishOnChange
+bg.psn_subscribe=psnName subscribe
+bg.psn_unsubscribe=psnName unsubscribe 
+
 bg.psn_broker.description=Broker fuer PubSub Netzwerk erzeugen
 bg.psn_client.description=Client fuer PubSub Netzwerk erzeugen
 bg.psn_callback.description=Funktion wird automatisch aufgefufen wenn neue Daten empfangen werden
diff --git a/src/main/resources/com/ardublock/block/ardublock_en_GB.properties b/src/main/resources/com/ardublock/block/ardublock_en_GB.properties
index dea7645ffed8547d3a6011874f6d7782d697d99c..2a04923287e4ce65037914e1fbba47e272acfef4 100644
--- a/src/main/resources/com/ardublock/block/ardublock_en_GB.properties
+++ b/src/main/resources/com/ardublock/block/ardublock_en_GB.properties
@@ -758,6 +758,19 @@ bg.didacticnetworkDivider2=|       PubSub publish      |
 bg.didacticnetworkDivider3=|       PubSub subscribe      |
 bg.didacticnetworkDivider4=|       PubSub callback      |
 
+bg.psn_broker=Broker psnName
+bg.psn_client=Client psnName
+bg.psn_callback=psnClientCallback
+bg.psn_handle_network=psnName handleNetwork
+bg.psn_data_to_send=psnName isDataToSend?
+bg.psn_publish=psnName publish
+bg.psn_publish_analog=psnName publish
+bg.psn_publish_digital=psnName publish
+bg.psn_publish_onchange=psnName publishOnChange
+bg.psn_publish_onchange_bool=psnName publishOnChange
+bg.psn_subscribe=psnName subscribe
+bg.psn_unsubscribe=psnName unsubscribe 
+
 bg.psn_broker.description=Broker fuer PubSub Netzwerk erzeugen
 bg.psn_client.description=Client fuer PubSub Netzwerk erzeugen
 bg.psn_callback.description=Funktion wird automatisch aufgefufen wenn neue Daten empfangen werden
diff --git a/src/main/resources/com/ardublock/libraries/LGI_QTouch.cpp b/src/main/resources/com/ardublock/libraries/LGI_QTouch.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..efb1f882593f59d78e0ce2412f6690bb06d7019f
--- /dev/null
+++ b/src/main/resources/com/ardublock/libraries/LGI_QTouch.cpp
@@ -0,0 +1,304 @@
+/*
+Library zur Verwendung der Analogeingänge für Touchsensoren
+Diese Librarie basiert auf dem ATMEL QTouch-Prinzip und dem Basis Code von
+J.Geisler -> https://github.com/jgeisler0303/QTouchADCArduino
+
+Hardware:
+Kupferfläche oder sonstige leitfähige Fläche über 1-10kOhm Widerstand an AnalogIn 
+Attiny 25/45/85 AIN1-3
+
+Anian Bühler 09.01.2015
+AB	27.05.2015
+*/
+
+#include "LGI_QTouch.h"
+
+ 
+//QTouch
+//******************************************************************
+//******************************************************************
+
+//Konstruktor
+//******************************************************************
+QTouch :: QTouch(){}
+
+//setup
+//******************************************************************
+void QTouch :: init(uint8_t TouchPin, uint8_t PartnerPin) { //Abfrage bei mehereren Objekten über ifndef _TOUCHINIT_
+
+
+	
+	this -> _TouchPin   = TouchPin;
+	this -> _PartnerPin = PartnerPin;
+	
+	#ifndef _TOUCHINIT_
+	#define _TOUCHINIT_
+	    // prepare the ADC unit for one-shot measurements
+		// see the atmega328 datasheet for explanations of the registers and values
+		ADMUX = ADMUX_SETUP; // Vcc as voltage reference (bits76), right adjustment (bit5), use ADC0 as input (bits3210)
+		ADCSRA = 0b11000100; // enable ADC (bit7), initialize ADC (bit6), no autotrigger (bit5), don't clear int-flag (bit4), no interrupt (bit3), clock div by 16@16Mhz=1MHz (bit210) ADC should run at 50kHz to 200kHz, 1MHz gives decreased resolution
+		ADCSRB = 0b00000000; // autotrigger source free running (bits210) doesn't apply
+		while(ADCSRA & (1<<ADSC)){} // wait for first conversion to complete 
+  #endif;
+}
+
+//getter
+//******************************************************************
+int QTouch :: getRawValue(uint8_t iterMeasure){
+	int adc1 = 0;
+	int adc2 = 0;
+	
+	for(int i = 1; i <= iterMeasure; i++){
+		adc1 += touch_probe(this-> _TouchPin, this-> _PartnerPin, true);
+		adc2 += touch_probe(this-> _TouchPin, this-> _PartnerPin, false);
+	}
+
+	adc1 /= iterMeasure;
+	adc2 /= iterMeasure;
+	
+	return (adc2-adc1);
+}
+
+uint16_t QTouch :: touch_probe(uint8_t pin, uint8_t partner, bool dir) {
+      uint8_t MUXPin;
+	  uint8_t MUXPartner;
+	  
+	  	 // IF Attiny 8Pin is used --> ADC1 (PB2), ADC2(PB4), ADC3 (PB3)
+	#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)			
+		MUXPin     = _tiny8AnalogToMux[pin];
+		MUXPartner = _tiny8AnalogToMux[partner];
+		pin = (pin < 6 ? pin : pin - 6);//analogPinToChannel(pin);
+		partner = (partner < 6 ? partner : partner - 6);
+
+	#else // IF Standard Arduino Boards are used
+		//if const A0-A5 is used
+		pin = (pin < 14 ? pin : pin - 14);//analogPinToChannel(pin);
+		partner = (partner < 14 ? partner : partner - 14);
+		MUXPin = pin;
+		MUXPartner = partner;
+	#endif;
+
+	  uint8_t mask= _BV(pin) | _BV(partner);
+	  
+	  ADC_DIR|= mask; // config pins as push-pull output
+	  if(dir)
+		ADC_PORT= (ADC_PORT & ~_BV(pin)) | _BV(partner); // set partner high to charge the s&h cap and pin low to discharge touch probe cap
+	  else
+		ADC_PORT= (ADC_PORT & ~_BV(partner)) | _BV(pin); // set pin high to charge the touch probe and pin low to discharge s&h cap cap
+	  // charge/discharge s&h cap by connecting it to partner
+	  ADMUX = MUX_REF_VCC | MUXPartner; // select partner as input to the ADC unit
+	  delayMicroseconds(CHARGE_DELAY); // wait for the touch probe and the s&h cap to be fully charged/dsicharged
+	  ADC_DIR&= ~mask; // config pins as input
+	  ADC_PORT&= ~mask; // disable the internal pullup to make the ports high Z
+	  // connect touch probe cap to s&h cap to transfer the charge
+	  ADMUX= MUX_REF_VCC | MUXPin; // select pin as ADC input
+	  delayMicroseconds(TRANSFER_DELAY); // wait for charge to be transfered
+	  // measure
+	  ADCSRA|= (1<<ADSC); // start measurement
+	  while(ADCSRA & (1<<ADSC)){ 
+	  } // wait for conversion to complete
+
+	  return ADC; // return conversion result
+}
+
+
+//QTouch BUTTON
+//******************************************************************
+//******************************************************************
+
+
+//Konstruktor
+//******************************************************************
+QTouchButton :: QTouchButton(uint8_t TouchPin, uint8_t PartnerPin):_QTouch(){
+
+	this->_QTouch.init(TouchPin, PartnerPin);
+
+	this-> _Offset		= 0;
+	this-> _hysteresis = 30;
+	
+}
+
+
+//setup
+//******************************************************************
+void QTouchButton :: init(){ //Abfrage bei mehereren Objekten über ifndef _TOUCHINIT_
+  this-> _Offset = this->_QTouch.getRawValue(10);
+}
+
+
+//setter
+//******************************************************************
+void QTouchButton :: setHysteresis(uint8_t hysteresis){
+	this-> _hysteresis = hysteresis;
+	}
+
+void QTouchButton :: setOffset(uint8_t Offset){
+	this-> _Offset = Offset;
+	}
+
+	
+//getter
+//******************************************************************
+uint8_t QTouchButton :: getHysteresis(){
+	return this-> _hysteresis;
+	}
+
+int QTouchButton :: getOffset(){
+	return this-> _Offset;
+	}
+
+bool QTouchButton :: isTouched(){
+	return ((this->_QTouch.getRawValue(4) - this-> _Offset) >  this-> _hysteresis);
+}
+
+int QTouchButton :: getRawTouch(){
+	return this->_QTouch.getRawValue(4);
+}
+
+
+//QTouch SLIDER
+//******************************************************************
+//******************************************************************
+
+//Konstruktor
+//******************************************************************
+QTouchSlider :: QTouchSlider(uint8_t TouchPin1, uint8_t TouchPin2, uint8_t TouchPin3):_QTouch1(), _QTouch2(), _QTouch3(){
+
+	this->_QTouch1.init(TouchPin1, TouchPin3);
+	this->_QTouch2.init(TouchPin2, TouchPin1);
+	this->_QTouch3.init(TouchPin3, TouchPin2);
+
+	this-> _Offset1		= 0;
+	this-> _Offset2		= 0;
+	this-> _Offset3		= 0;
+	this-> _hysteresis  = 30;
+	this-> _threshold   = 10;
+	this-> _maxVal1     = 0;
+	this-> _maxVal2     = 0;
+	this-> _maxVal3     = 0;
+	this-> _lastSliderPos = 0;
+}
+
+
+//setup
+//******************************************************************
+void QTouchSlider :: init(){ //Abfrage bei mehereren Objekten über ifndef _TOUCHINIT_
+	this-> _Offset1		=  this->_QTouch1.getRawValue(10);
+	this-> _Offset2		=  this->_QTouch2.getRawValue(10);
+	this-> _Offset3		=  this->_QTouch3.getRawValue(10);
+}
+
+
+//setter
+//******************************************************************
+void QTouchSlider :: setHysteresis(uint8_t hysteresis){
+	this-> _hysteresis = hysteresis;
+	}
+
+void QTouchSlider :: setOffset(uint8_t Offset1, uint8_t Offset2, uint8_t Offset3){
+	this-> _Offset1 = Offset1;
+	this-> _Offset2 = Offset2;
+	this-> _Offset3 = Offset3;
+	}
+	
+	void QTouchSlider :: setThreshold(uint8_t threshold){
+	this-> _threshold = threshold;
+	}
+
+	
+//getter
+//******************************************************************
+uint8_t QTouchSlider :: getHysteresis(){
+	return this-> _hysteresis;
+	}
+	
+uint8_t QTouchSlider :: getThreshold(){
+	return this-> _threshold;
+}
+
+int QTouchSlider :: getOffset(uint8_t num){
+	switch(num){
+		case 1:
+			return this-> _Offset1;
+			break;
+		case 2:
+			return this-> _Offset2;
+			break;
+		case 3:
+			return this-> _Offset3;
+			break;
+	}
+}
+
+
+
+int QTouchSlider :: getRawTouch(uint8_t field){
+	switch(field){
+		case 1:
+			return this->_QTouch1.getRawValue(4);
+			break;
+		case 2:
+			return this->_QTouch2.getRawValue(4);
+			break;
+		case 3:
+			return this->_QTouch3.getRawValue(4);
+			break;
+	}
+}
+
+uint8_t QTouchSlider :: getTouchPosition(){
+	bool _mode = true;
+	
+	int raw1, raw2, raw3;
+	int map1, map2, map3;
+	uint8_t sliderPosition = 0;
+	
+	raw1 = getRawTouch(1)- getOffset(1);
+    raw2 = getRawTouch(2)- getOffset(2);
+    raw3 = getRawTouch(3)- getOffset(3);
+	
+	this-> _maxVal1 = max(this-> _maxVal1, raw1);
+    this-> _maxVal2 = max(this-> _maxVal2, raw2);
+    this-> _maxVal3 = max(this-> _maxVal3, raw3);
+	
+	map1 = constrain(map( raw1, this-> _threshold, this-> _maxVal1, 0, 100), 0, 100);
+    map2 = constrain(map( raw2, this-> _threshold, this-> _maxVal2, 0, 100), 0, 100);
+    map3 = constrain(map( raw3, this-> _threshold, this-> _maxVal3, 0, 100), 0, 100);
+	
+	//not touched
+    if( map1 <= 0 && map2 <= 0 && map2 <= 0){ 
+		if(_mode) 
+			sliderPosition = _lastSliderPos;
+		else
+			sliderPosition = 0;
+    }
+	//upper half is touched
+    else if( (map1 - map3) > 0 ){
+		if( map2 > 0){
+			sliderPosition = map(map2 - map1, -100, 100, 0, 50);
+			_lastSliderPos = sliderPosition;
+		}
+		else{
+			sliderPosition = 0;
+			_lastSliderPos = sliderPosition;
+		}
+    }
+	//middle is touched
+	else if( map2 > 0 && map1 == 0 && map3 == 0 ){
+			sliderPosition = 50;
+			_lastSliderPos = sliderPosition;
+	}
+	//lower half is touched
+    else if((map1 - map3) < 0){
+		if( map2 > 0){
+			sliderPosition = map(map3 - map2, -100, 100, 50, 100); 
+			_lastSliderPos = sliderPosition;
+		}
+		else{
+			sliderPosition = 100;
+			_lastSliderPos = sliderPosition;
+		}
+    }
+
+	return sliderPosition;
+}
diff --git a/src/main/resources/com/ardublock/libraries/LGI_QTouch.h b/src/main/resources/com/ardublock/libraries/LGI_QTouch.h
new file mode 100644
index 0000000000000000000000000000000000000000..bd4817beeba311c6ae60ca081802b3f2a578e88e
--- /dev/null
+++ b/src/main/resources/com/ardublock/libraries/LGI_QTouch.h
@@ -0,0 +1,149 @@
+/*
+Library zur Verwendung der Analogeingänge für Touchsensoren
+Diese Librarie basiert auf dem ATMEL QTouch-Prinzip und dem Basis Code von
+J.Geisler -> https://github.com/jgeisler0303/QTouchADCArduino
+
+Hardware:
+Kupferfläche oder sonstige leitfähige Fläche über 1kOhm Widerstand an AnalogIn 
+
+Anian Bühler 01.09.2014
+*/
+#include "Arduino.h"
+
+
+#ifndef _LGIQTOUCH_
+#define _LGIQTOUCH_
+
+#define ADMUX_MASK 0b00001111 // mask the mux bits in the ADMUX register
+#define MUX_GND 0b00001111 // mux value for connecting the ADC unit internally to GND
+#define CHARGE_DELAY 5 // time it takes for the capacitor to get charged/discharged in microseconds
+#define TRANSFER_DELAY 5 // time it takes for the capacitors to exchange charge
+
+	 // IF Attiny 8Pin is used
+#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)         
+	#define ADC_PORT  PORTB     //USE PORT B
+	#define ADC_DIR   DDRB	      //
+	#define ADMUX_SETUP 0b10010000// Set Vref  to Vcc
+	#define MUX_REF_VCC 0b10010000 // value to set the ADC reference to Vcc
+	#define ADC_SETUP   0b10000100//0b11000011  // Set ADC pre-scaler to 8
+#else // IF Standard Arduino Boards are used
+	#define ADC_PORT  PORTC       //USE PORT C
+	#define ADC_DIR   DDRC	      // 
+	#define ADMUX_SETUP 0b01000000// Set Vref to AVcc with ext Cap 
+	#define MUX_REF_VCC 0b01000000 // value to set the ADC reference to Vcc
+	#define ADC_SETUP 0b11000100  // Set ADC pre-scaler to 16
+#endif;
+
+class QTouch
+{
+	private:
+		uint8_t _TouchPin,		
+				_PartnerPin;	
+				
+	const uint8_t _tiny8AnalogToMux[10] = {
+				0, //D0
+				0, //D1
+				1, //D2 Ain1
+				3, //D3 Ain3
+				2, //D4 Ain2
+				0, //RESET D5 Ain0
+				0, //A0->Ain0(Reset)
+				1, //A1->Ain1 
+				2, //A2->Ain2
+				3, //A3->Ain3
+			};			
+	
+
+	public:
+
+
+	
+	//Konstruktoren
+	//******************************************************************
+	QTouch();
+	
+	//setup
+	//******************************************************************
+	void init(uint8_t TouchPin1, uint8_t PartnerPin);
+	
+	//getter
+	//******************************************************************
+	int getRawValue(uint8_t iterMeasure);
+	uint16_t touch_probe(uint8_t pin, uint8_t partner, bool dir);
+};
+
+
+class QTouchButton
+{
+private:
+	
+	QTouch 	_QTouch;
+	uint8_t _hysteresis;
+	
+	int		_Offset;
+
+
+	
+
+public:
+	//Konstruktoren
+	//******************************************************************
+	QTouchButton(uint8_t TouchPin1, uint8_t PartnerPin);
+	
+	//setup
+	//******************************************************************
+	void init();
+	
+	//setter
+	//******************************************************************
+	void setHysteresis(uint8_t hysteresis);
+	void setOffset(uint8_t Offset);
+	
+	//getter
+	//******************************************************************
+	uint8_t getHysteresis();
+	int getOffset();
+	bool isTouched();
+	int getRawTouch();	
+};
+
+
+class QTouchSlider
+{
+private:
+	
+	QTouch 	_QTouch1, _QTouch2, _QTouch3;
+	uint8_t _hysteresis, _threshold,
+			_maxVal1, _maxVal2, _maxVal3,
+			_lastSliderPos;
+	
+	int		_Offset1, _Offset2, _Offset3;
+
+
+	
+
+public:
+	//Konstruktoren
+	//******************************************************************
+	QTouchSlider(uint8_t TouchPin1, uint8_t TouchPin2, uint8_t TouchPin3);
+	
+	//setup
+	//******************************************************************
+	void init();
+	
+	//setter
+	//******************************************************************
+	void setHysteresis(uint8_t hysteresis);
+	void setOffset(uint8_t Offset1, uint8_t Offset2, uint8_t Offset3);
+	void setThreshold(uint8_t threshold);
+	
+	//getter
+	//******************************************************************
+	uint8_t getHysteresis();
+	uint8_t getThreshold();
+	int getOffset(uint8_t num);
+	int getRawTouch(uint8_t field);	
+	uint8_t getTouchPosition();
+};
+
+#endif;
\ No newline at end of file
diff --git a/src/main/resources/com/ardublock/libraries/didacticNet.cpp b/src/main/resources/com/ardublock/libraries/didacticNet.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f14ace21992e70b7d533ffd00d95831966f92b66
--- /dev/null
+++ b/src/main/resources/com/ardublock/libraries/didacticNet.cpp
@@ -0,0 +1,497 @@
+/**************************************************************************/
+/*!
+    @file     didacticNet.cpp
+    @author   anian buehler @ letsgoING.org
+*/
+/**************************************************************************/
+
+#include "Arduino.h"
+#include "didacticNet.h"
+
+//**************************************************************************
+//ROOT
+//**************************************************************************
+DidacticPSNet::DidacticPSNet(){}
+
+DidacticPSNet::~DidacticPSNet(){}
+
+void DidacticPSNet::begin(Stream& _port){
+  setStream(_port);
+}
+
+void DidacticPSNet::begin(Stream& _port, PSNET_CALLBACK_SIGNATURE){
+  setStream(_port);
+  setCallback(callback);
+}
+
+DidacticPSNet& DidacticPSNet::setCallback(PSNET_CALLBACK_SIGNATURE){
+    this->callback = callback;
+    return *this;
+}
+
+void DidacticPSNet::setStream(Stream& stream){
+    _port = &stream;
+}
+
+bool DidacticPSNet::handleNetwork(){
+  //if(_waitingTime <= millis()){
+  	if(checkData()){
+  		if(recieveData()){
+        //Serial.print("Message filter: ");Serial.println(_readBufferMessage[1]);
+        //Serial.print("Check Message filter: ");Serial.println(getMessageFilter(_readBufferMessage[1]));
+  			if(getMessageFilter(_readBufferMessage[1])){
+          handleData();
+  			}
+  		}
+  		_waitingTime = millis()+ random(CSMA_MIN_DELAY_MS, CSMA_MAX_DELAY_MS);
+  	}
+  	//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;
+        }
+        else{
+          _dataToSend = false;
+          //_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(){
+  return _dataToSend;
+}
+
+bool DidacticPSNet::sendData(){
+	int 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++;
+	}
+	return true;
+}
+
+int DidacticPSNet::extractData(int startCounter, int maxLength, char* buffer, char limiter){
+	int counter = startCounter;
+	while(_readBufferMessage[counter]!= limiter){
+		buffer[counter-startCounter] = _readBufferMessage[counter];
+		counter++;
+		if((counter-startCounter) > maxLength){
+      counter--;
+      break; //if > maxLenght -> leave while and return
+		}
+	}
+	buffer[counter-startCounter] = '\0';
+	return counter-startCounter; //length
+}
+
+int DidacticPSNet::checkData(){
+	return (int)_port->available();
+}
+
+bool  DidacticPSNet::recieveData() {
+	static int msgCounter = 0;
+	static int topicCounter = 0;
+	static int payloadCounter = 0;
+	//if(msgCounter == NULL){	msgCounter = 0;	}
+	//if(topicCounter == NULL){ topicCounter = 0; }
+	//if(dataCounter == NULL){ dataCounter = 0; }
+	while (checkData()) {
+		char localBuffer = _port->read();
+		if (localBuffer == MSG_PRELIMITER) {
+			msgCounter = 0;
+			topicCounter = 0;
+			payloadCounter = 0;
+			_readBufferMessage[msgCounter] = localBuffer;
+    }
+		else if (localBuffer == MSG_DELIMITER && _readBufferMessage[0] == MSG_PRELIMITER) {
+			msgCounter++;
+			_readBufferMessage[msgCounter] = localBuffer;
+      _readBufferMessage[msgCounter+1] = '0';
+      msgCounter = 0;
+			return true;
+		}
+		else if (localBuffer == MSG_SEPARATOR && _readBufferMessage[0] == MSG_PRELIMITER) {
+			topicCounter = msgCounter -2;
+			msgCounter++;
+			_readBufferMessage[msgCounter] = localBuffer;
+    }
+		else if (_readBufferMessage[0] == MSG_PRELIMITER && localBuffer != MSG_DELIMITER) {
+			msgCounter++;
+			_readBufferMessage[msgCounter] = localBuffer;
+    }
+	}
+	return false;
+}
+
+		void  DidacticPSNet::setInterval(long intervalTime){
+      _intervalTime = intervalTime;
+    }
+
+
+//**************************************************************************
+// CLIENT
+//**************************************************************************
+DidacticPSNetClient::DidacticPSNetClient(){
+  _intervalTime = INTERVAL_CLIENT;
+}
+
+DidacticPSNetClient::~DidacticPSNetClient(){}
+
+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_PUBLISH_SUCCESSULL;
+  
+  _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;
+  }
+
+  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];
+		}
+
+  _dataToSend = true;
+	return error;
+}
+
+//TODO: TEST TEST TEST
+int DidacticPSNetClient::publish(char* topic,  int data){
+  char sendPayload[MAX_LEN_PAYLOAD];
+  itoa(data, sendPayload, 10);
+
+	return publish(topic, sendPayload);
+}
+
+int DidacticPSNetClient::publish(char* topic,  bool data){
+  char sendPayload[2];
+  itoa(data, sendPayload, 10);
+
+	return publish(topic, sendPayload);
+}
+
+int DidacticPSNetClient::publishOnChange(char* topic, bool input){
+  if(!_dataToSend){
+    if(eDetector.edgeDetected(input)){
+      return publish(topic, input);
+    }
+  }
+  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 DN_ERROR_NO_ERROR;
+}
+
+int DidacticPSNetClient::subscribe(char* topic){
+	return subscribe(topic, strlen(topic));
+}
+
+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;
+
+  int topicNumber = getTopicNr(topic);
+
+  if(topicNumber < 0){
+    topicNumber = getFreeTopicNr();
+    if(topicNumber < 0){
+      topicNumber = 0;
+    }
+  		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 error;
+}
+
+
+bool DidacticPSNetClient::unsubscribe(char* topic){
+  return unsubscribe(topic, strlen(topic));
+}
+
+bool DidacticPSNetClient::unsubscribe(char* topic, int topicLength){
+  int topicNumber = getTopicNr(topic);
+  if(topicNumber >= 0){
+    _topic[topicNumber][0]='\0';
+    return true;
+  }
+  return false;
+}
+
+bool DidacticPSNetClient::getMessageFilter(char messageType){
+  return messageType == MSG_UPDATE;
+}
+
+bool DidacticPSNetClient::savePayload(char* buffer, int position){
+  strcpy(_payload[position], buffer);
+  return true;
+}
+
+bool DidacticPSNetClient::handleData(){
+  int currentTopicNr = 0;
+  int topicLength = 0;
+  int payloadLength = 0;
+  topicLength = extractData(2, MAX_LEN_TOPICS, _bufferTopic, MSG_SEPARATOR);
+  if(topicLength > 0){
+    currentTopicNr = getTopicNr(_bufferTopic);
+    payloadLength  = extractData(topicLength+3, MAX_LEN_PAYLOAD, _bufferPayload, MSG_DELIMITER);
+    if( currentTopicNr >= 0){
+      savePayload( _bufferPayload, currentTopicNr);
+      callback(_topic[currentTopicNr], topicLength, _payload[currentTopicNr], payloadLength);
+    }
+  }
+  return true;
+}
+
+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;
+		}
+	}
+ return -1;
+}
+
+int DidacticPSNetClient::getFreeTopicNr() {
+  for (int i = 0; i < MAX_NR_TOPICS_CLIENT; i++) {
+    if (strcmp(_topic[i], "") == 0) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+
+//**************************************************************************
+//Broker
+//**************************************************************************
+DidacticPSNetBroker::DidacticPSNetBroker(){
+    _intervalTime = INTERVAL_BROKER;
+}
+
+DidacticPSNetBroker::~DidacticPSNetBroker(){}
+
+
+bool DidacticPSNetBroker::getMessageFilter(char messageType){
+  return (messageType == MSG_PUBLISH || messageType == MSG_SUBSCRIBE);
+}
+
+bool DidacticPSNetBroker::savePayload(char* buffer, int position){
+  strcpy(_data[position], buffer);
+  return true;
+}
+
+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(){
+  int currentTopicNr = 0;
+  int topicLength = 0;
+  int dataLength = 0;
+  if(_readBufferMessage[1] == MSG_PUBLISH){
+    topicLength = extractData(2, MAX_LEN_TOPICS, _bufferTopic, MSG_SEPARATOR);
+    if(topicLength > 0){
+      currentTopicNr = getTopicNr(_bufferTopic);
+      dataLength  = extractData(topicLength+3, MAX_LEN_PAYLOAD, _bufferPayload, MSG_DELIMITER);
+      if( currentTopicNr >= 0){
+        writeDataToTopic(currentTopicNr, _bufferTopic, _bufferPayload);
+        update(_topic[currentTopicNr], topicLength, _data[currentTopicNr], dataLength);
+      }
+    }
+  }
+  else if(_readBufferMessage[1] == MSG_SUBSCRIBE){
+    topicLength = extractData(2, MAX_LEN_TOPICS, _bufferTopic, MSG_DELIMITER);
+    if(topicLength > 0){
+      currentTopicNr = getTopicNr(_bufferTopic);
+      if(currentTopicNr >= 0){
+        update(_topic[currentTopicNr], strlen(_topic[currentTopicNr]), _data[currentTopicNr], strlen(_data[currentTopicNr]));
+      }
+    }
+  }
+return true;
+}
+
+bool DidacticPSNetBroker::update(char* topic, int topicLength, char* data , int dataLength){
+	_sendBufferMessage[0] = MSG_PRELIMITER;
+	_sendBufferMessage[1] = MSG_UPDATE;
+	_sendBufferMessage[2+topicLength] = MSG_SEPARATOR;
+	_sendBufferMessage[2+topicLength+1+dataLength] = MSG_DELIMITER;
+	_sendBufferMessage[2+topicLength+1+dataLength+1] = '\0';
+
+	if(topicLength <= MAX_LEN_TOPICS){
+		for(int i = 0; i < topicLength; i++){
+			_sendBufferMessage[2+i] = topic[i];
+		}
+	}else {
+    _dataToSend = false;
+		return false;
+	}
+	if(dataLength <= MAX_LEN_PAYLOAD){
+		for(int i = 0; i < dataLength; i++){
+			_sendBufferMessage[2+topicLength+1+i] = data[i];
+		}
+	}else {
+    _dataToSend = false;
+		return false;
+	}
+  _dataToSend = true;
+	return true;
+}
+
+int DidacticPSNetBroker::getTopicNr(char* topic){
+	for (int i = 0; i < MAX_NR_TOPICS_BROKER; i++) {
+  if (strcmp(_topic[i], topic) == 0) {
+      return i;
+		}
+	}
+ return	getFreeTopicNr();
+}
+
+int DidacticPSNetBroker::getFreeTopicNr() {
+  for (int i = 0; i < MAX_NR_TOPICS_BROKER; i++) {
+    if (strcmp(_topic[i], "") == 0) {
+      return i;
+    }
+  }
+  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/main/resources/com/ardublock/libraries/didacticNet.h b/src/main/resources/com/ardublock/libraries/didacticNet.h
new file mode 100644
index 0000000000000000000000000000000000000000..596db882857b225191ab1d86fa05712d91df8856
--- /dev/null
+++ b/src/main/resources/com/ardublock/libraries/didacticNet.h
@@ -0,0 +1,203 @@
+/**************************************************************************
+    @file     didacticNet.h
+    @author   anian buehler @ letsgoING
+**************************************************************************/
+
+
+#ifndef _DIDACTICNET_
+#define _DIDACTICNET_
+
+#include "Arduino.h"
+//callback(topic, topicLength, data, dataLength)
+#define PSNET_CALLBACK_SIGNATURE void (*callback)(char*, int, char*, int)
+
+#define MSG_PRELIMITER '<'
+#define MSG_DELIMITER  '>'
+#define MSG_SEPARATOR  '|'
+
+//@ publish   → on publish check topic, then send topic-update
+//? subscribe → subscribe starts update, topic filter @client
+//# update    → update to specific topic Broker to client
+#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 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 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;
+
+		PSNET_CALLBACK_SIGNATURE;
+
+		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;
+		unsigned long _intervalTime = 0L;
+		int _currentTopicLength = 0;
+		int _currentPayloadLength  = 0;
+
+		DidacticPSNet& setCallback(PSNET_CALLBACK_SIGNATURE);
+		void setStream(Stream& _port);
+
+		int checkData();
+		bool recieveData();
+		bool sendData();
+		int extractData(int, int, char*, char);
+		void writeDataToTopic(char*, char*);
+		virtual int getTopicNr(char*)=0;
+		virtual int getFreeTopicNr()=0;
+		virtual bool getMessageFilter(char)=0;
+		virtual bool savePayload(char*, int)=0;
+		virtual bool handleData()=0;
+
+	public:
+		DidacticPSNet();
+		~DidacticPSNet();
+
+		void begin(Stream& _port);
+		void begin(Stream& _port, PSNET_CALLBACK_SIGNATURE);
+		bool handleNetwork();
+		bool isDataToSend();
+
+		void setInterval(long);
+
+};
+
+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 } };
+
+	bool savePayload(char*, int);
+	bool getMessageFilter(char);
+	bool handleData();
+	int getTopicNr(char*);
+	int getFreeTopicNr();
+
+	int edgeDetected(bool);
+	bool valueChanged(int, int);
+
+	public:
+	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);
+};
+
+
+class DidacticPSNetBroker: public  DidacticPSNet
+{
+	private:
+	char _topic[MAX_NR_TOPICS_BROKER][MAX_LEN_TOPICS+1] = { { 0 } };
+	char _data[MAX_NR_TOPICS_BROKER][MAX_LEN_PAYLOAD+1] = { { 0 } };
+
+	bool savePayload(char*, int);
+	bool getMessageFilter(char);
+	void writeDataToTopic(int, char*, char*);
+	bool handleData();
+	int getTopicNr(char*);
+	int getFreeTopicNr();
+
+	public:
+	DidacticPSNetBroker();
+	~DidacticPSNetBroker();
+
+	bool update(char*, int, char*, int);
+
+
+};
+
+
+#endif