diff --git a/src/main/java/com/ardublock/translator/block/numbers/DefineBlock.java b/src/main/java/com/ardublock/translator/block/numbers/DefineBlock.java
index a8bcdaa0c5290798974062deddb973897b4f3cb1..8cef1cbf2bbbb7bc9f823e63ae4c60c343d93895 100644
--- a/src/main/java/com/ardublock/translator/block/numbers/DefineBlock.java
+++ b/src/main/java/com/ardublock/translator/block/numbers/DefineBlock.java
@@ -8,10 +8,6 @@ import com.ardublock.translator.block.exception.BlockException;
 import com.ardublock.translator.block.exception.SocketNullException;
 import com.ardublock.translator.block.exception.SubroutineNotDeclaredException;
 
-import tec.letsgoing.ardublock.simulator.simcode.SimCode;
-import tec.letsgoing.ardublock.simulator.simcode.datatypes.SimTypeBool;
-import tec.letsgoing.ardublock.simulator.simcode.datatypes.SimTypeString;
-import tec.letsgoing.ardublock.simulator.simcode.vars.CodeBoolSet;
 
 public class DefineBlock extends TranslatorBlock
 {
@@ -25,7 +21,7 @@ public class DefineBlock extends TranslatorBlock
 	public String toCode() throws SocketNullException, SubroutineNotDeclaredException
 	{
 		//Label autoText set in edu.mit.blocks.renderable.BlockLabel -> generateLabelText()
-		String suffix = "";
+		//String suffix = "";
 		String newMarker = "_.new";
 		String regex = "\\s*"+newMarker+"\\b\\s*";
 		
diff --git a/src/main/java/com/ardublock/translator/block/operators/PidBlock.java b/src/main/java/com/ardublock/translator/block/operators/PidBlock.java
new file mode 100644
index 0000000000000000000000000000000000000000..8fce63b60bef1d5e01772c9bc33a58dd18c87995
--- /dev/null
+++ b/src/main/java/com/ardublock/translator/block/operators/PidBlock.java
@@ -0,0 +1,108 @@
+package com.ardublock.translator.block.operators;
+
+import java.util.ResourceBundle;
+import java.util.function.ToIntFunction;
+
+import com.ardublock.translator.Translator;
+import com.ardublock.translator.block.TranslatorBlock;
+import com.ardublock.translator.block.exception.BlockException;
+import com.ardublock.translator.block.exception.SocketNullException;
+import com.ardublock.translator.block.exception.SubroutineNotDeclaredException;
+
+public class PidBlock extends TranslatorBlock
+{
+	private static ResourceBundle uiMessageBundle = ResourceBundle.getBundle("com/ardublock/block/ardublock");
+	
+	public PidBlock(Long blockId, Translator translator, String codePrefix, String codeSuffix, String label)
+	{
+		super(blockId, translator, codePrefix, codeSuffix, label);
+	}
+
+	@Override
+	public String toCode() throws SocketNullException, SubroutineNotDeclaredException
+	{
+		TranslatorBlock tb_input 	= this.getRequiredTranslatorBlockAtSocket(0);
+		TranslatorBlock tb_setpoint = this.getRequiredTranslatorBlockAtSocket(1);
+		TranslatorBlock tb_interval = this.getRequiredTranslatorBlockAtSocket(2);
+		TranslatorBlock tb_kp 		= this.getRequiredTranslatorBlockAtSocket(3);
+		TranslatorBlock tb_ki 		= this.getTranslatorBlockAtSocket(4);
+		TranslatorBlock tb_kd 		= this.getTranslatorBlockAtSocket(5);
+		TranslatorBlock tb_limitL 	= this.getTranslatorBlockAtSocket(6);
+		TranslatorBlock tb_limitH 	= this.getTranslatorBlockAtSocket(7);
+		
+		boolean integrative = tb_ki != null;
+		boolean derivative  = tb_kd != null;
+		boolean limited     = (tb_limitL != null) && (tb_limitH != null);
+		
+		
+		//FUNCTION CODE ASSEMBLY
+		String functionCode = "int computePID(int input, int setpoint, long interval, int kp";
+		
+		if(integrative) {
+			functionCode +=", double ki";
+		}
+		if(derivative) {
+			functionCode +=", double kd";
+		}
+		if(limited) {
+			functionCode +=", int limitLow, int limitHigh";
+		}
+		
+		functionCode += "){"
+					+ "  static int  lastError = 0;\n"
+					+ "  static int  out       = 0;\n"
+					+ "  static long lastTime  = 0L;\n\n"
+					+ "  long currentTime     = millis();\t//get current time\n\n"
+					+ "  if (currentTime >= lastTime + interval) {\n"
+					+ "    long elapsedTime = (double)(currentTime - lastTime);  //compute time elapsed from previous computation\n"
+					+ "    \n" 
+					+ "    long error       = setpoint - input;                  // get error\n" 
+					+ "    out = kp * error;                                     //P output\n\n";
+		if(integrative) {
+			functionCode +="    long cumError    = cumError + error * elapsedTime;    // compute integral\n" 
+						+  "    out = out + ki * cumError;                            //I output\n\n";
+		}
+		if(derivative) {
+			functionCode +="    long rateError   = (error - lastError) / elapsedTime; // compute derivative\n" 
+						+  "    out = out + kd * rateError;                           //D output\n\n";
+		}
+		if(limited) {
+			functionCode +="    out = constrain(out, limitLow, limitHigh);            //limit output\n\n";
+		}
+		
+		functionCode += "    lastError = error;         //remember current error\n" 
+					+	"    lastTime = currentTime;    //remember current time\n" 
+					+   "  }\n" 
+					+   "  return out;                  //return the PID output\n" 
+					+	"}";
+		
+		translator.addDefinitionCommand(functionCode);
+		
+		//RETURN (BLOCK) CODE ASSEMBLY
+		String ret = "computePID(";
+		ret += tb_input.toCode().replaceAll("\\s*_.new\\b\\s*", "")+", "+tb_setpoint.toCode().replaceAll("\\s*_.new\\b\\s*", "") + ", " + tb_interval.toCode().replaceAll("\\s*_.new\\b\\s*", "") + ", " + tb_kp.toCode().replaceAll("\\s*_.new\\b\\s*", "");
+		
+		if(integrative) {
+			ret +=", " + tb_ki.toCode().replaceAll("\\s*_.new\\b\\s*", "");
+		}
+		if(derivative) {
+			ret +=", " + tb_kd.toCode().replaceAll("\\s*_.new\\b\\s*", "");
+		}
+		if(limited) {
+			String limitL = tb_limitL.toCode().replaceAll("\\s*_.new\\b\\s*", "");
+			String limitH = tb_limitH.toCode().replaceAll("\\s*_.new\\b\\s*", "");
+			
+			if(Integer.parseInt(limitL) < Integer.parseInt(limitH)) {
+				ret +=", " + limitL + ", " + limitH;
+			}else {
+				throw new BlockException(blockId, uiMessageBundle.getString("ardublock.error_msg.pid_limit_error"));
+			}
+			
+			
+		}
+		ret += ")";
+		
+		return codePrefix + ret + codeSuffix;
+	}
+	
+}
diff --git a/src/main/resources/com/ardublock/block/ardublock.properties b/src/main/resources/com/ardublock/block/ardublock.properties
index ca99fceb935884207a6ef29d2386c0d7bde9517e..27c9c3bf957921b20c42b265cf4dcde7b544aca1 100644
--- a/src/main/resources/com/ardublock/block/ardublock.properties
+++ b/src/main/resources/com/ardublock/block/ardublock.properties
@@ -118,6 +118,7 @@ ardublock.error_msg.stepper_duplicated=There is already a stepper with this name
 ardublock.error_msg.stepper_not_existing=There is no stepper with this name
 ardublock.error_msg.paste.invalid=clipboard contains no blocks
 ardublock.error_msg.paste.notpossible=Past not possible without Blocks
+ardublock.error_msg.pid_limit_error=PID-Block: Upper limit is smaller or equal to lower limit
 
 ardublock.error_msg.no_sim_for_block=This Block is not suitable for simulation
 
@@ -490,6 +491,7 @@ bd.operators=Math Operators
 bg.mathDivider1=|       operators       |
 bg.mathDivider2=|       signal attributes      |
 bg.mathDivider3=|       random       |
+bg.mathDivider4=|       PID-Controller       |
 
 bg.constrain=constrain
 bg.abs=abs
@@ -537,6 +539,20 @@ bc.low=lower
 bc.high=higher
 bc.element = element
 
+bg.pid=PID
+bg.pid_limit=PID
+bg.pid.description= PID controller block
+bg.pid_limit.description= PID controller block with limit
+
+bc.input=input
+bc.setpoint=setpoint
+bc.interval=interval
+bc.kp=Kp
+bc.ki=Ki
+bc.kd=Kd
+bc.limitL=lower limit
+bc.limitH=upper limit
+
 #CAST
 #****************************
 bd.cast=type cast
diff --git a/src/main/resources/com/ardublock/block/ardublock.xml b/src/main/resources/com/ardublock/block/ardublock.xml
index 59f7d9de2e4a3e0daadafec8fab369de6d84da35..6be7bd5d0c091d346a55ac8b074f1b67864be477 100644
--- a/src/main/resources/com/ardublock/block/ardublock.xml
+++ b/src/main/resources/com/ardublock/block/ardublock.xml
@@ -1257,6 +1257,7 @@
 		<BlockGenus name="mathDivider1" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.mathDivider1" color="150 150 150" />
 		<BlockGenus name="mathDivider2" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.mathDivider2" color="150 150 150" />
 		<BlockGenus name="mathDivider3" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.mathDivider3" color="150 150 150" />
+		<BlockGenus name="mathDivider4" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.mathDivider3" color="150 150 150" />
 		
 		<BlockGenus name="addition" kind="function" initlabel="bg.addition" color="160 32 240">
 			<description>
@@ -1473,6 +1474,56 @@
 			</BlockConnectors>
 		</BlockGenus>
 		
+		<BlockGenus name="pid" kind="function" color="160 32 240" initlabel="bg.pid">
+			<description>
+				<text>PID</text>
+			</description>
+			<BlockConnectors>
+				<BlockConnector connector-type="number" connector-kind="plug" />
+				<BlockConnector connector-type="number" connector-kind="socket" label="bc.input" />
+				<BlockConnector connector-type="number" connector-kind="socket" label="bc.setpoint">
+					<DefaultArg genus-name="number" label="512" />
+				</BlockConnector>
+				<BlockConnector connector-type="number" connector-kind="socket" label="bc.interval">
+					<DefaultArg genus-name="number" label="100" />
+				</BlockConnector>
+				<BlockConnector connector-type="number" connector-kind="socket" label="bc.kp">
+					<DefaultArg genus-name="number" label="2" />
+				</BlockConnector>
+				<BlockConnector connector-type="number" connector-kind="socket" label="bc.ki">
+				</BlockConnector>
+				<BlockConnector connector-type="number" connector-kind="socket" label="bc.kd">
+				</BlockConnector>
+			</BlockConnectors>
+		</BlockGenus>
+		
+		<BlockGenus name="pid_limit" kind="function" color="160 32 240" initlabel="bg.pid_limit">
+			<description>
+				<text>PID with limits</text>
+			</description>
+			<BlockConnectors>
+				<BlockConnector connector-type="number" connector-kind="plug" />
+				<BlockConnector connector-type="number" connector-kind="socket" label="bc.input" />
+				<BlockConnector connector-type="number" connector-kind="socket" label="bc.setpoint">
+					<DefaultArg genus-name="number" label="512" />
+				</BlockConnector>
+				<BlockConnector connector-type="number" connector-kind="socket" label="bc.interval">
+					<DefaultArg genus-name="number" label="100" />
+				</BlockConnector>
+				<BlockConnector connector-type="number" connector-kind="socket" label="bc.kp">
+					<DefaultArg genus-name="number" label="2" />
+				</BlockConnector>
+				<BlockConnector connector-type="number" connector-kind="socket" label="bc.ki">
+				</BlockConnector>
+				<BlockConnector connector-type="number" connector-kind="socket" label="bc.kd">
+				</BlockConnector>
+				<BlockConnector connector-type="number" connector-kind="socket" label="bc.limitL">
+				</BlockConnector>
+				<BlockConnector connector-type="number" connector-kind="socket" label="bc.limitH">
+				</BlockConnector>
+			</BlockConnectors>
+		</BlockGenus>
+		
 		<!-- ******************** Cast *************** -->
 		<BlockGenus name="castDivider1" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.castDivider1" color="150 150 150" />
 		<BlockGenus name="castDivider2" kind="command" is-starter="yes" is-terminator="yes" initlabel="bg.castDivider2" color="150 150 150" />
@@ -3134,6 +3185,10 @@
 				<BlockGenusMember>mathDivider3</BlockGenusMember>
 				<BlockGenusMember>random</BlockGenusMember>
 				<BlockGenusMember>random_range</BlockGenusMember>
+				
+				<BlockGenusMember>mathDivider4</BlockGenusMember>
+				<BlockGenusMember>pid</BlockGenusMember>
+				<BlockGenusMember>pid_limit</BlockGenusMember>
 			</BlockDrawer>
 			<BlockDrawer button-color="160 32 240" name="bd.operators"	type="page">
 				<BlockGenusMember>mathDivider1</BlockGenusMember> 
diff --git a/src/main/resources/com/ardublock/block/ardublock_de.properties b/src/main/resources/com/ardublock/block/ardublock_de.properties
index 9fab4dfd01a87277d7ad3a76597b327cac358ff9..c74aa134b1c720e0d798307a53e01d0493cb77af 100644
--- a/src/main/resources/com/ardublock/block/ardublock_de.properties
+++ b/src/main/resources/com/ardublock/block/ardublock_de.properties
@@ -121,6 +121,8 @@ ardublock.error_msg.stepper_not_existing=Es gibt keinen Stepper mit diesem Namen
 ardublock.error_msg.paste.invalid=Zwischenablage enthält keine ArduBlock-Blöcke
 ardublock.error_msg.paste.notpossible=Einfügen ohne Blöcke nicht möglich.
 
+ardublock.error_msg.pid_limit_error=PID-Block: Oberes Limit ist kleiner oder gleich wie unteres Limit
+
 ardublock.error_msg.no_sim_for_block=Dieser Block ist für die Simulation nicht geeignet.
  
 #TRANSLATOR
@@ -486,7 +488,8 @@ bd.operators=Math. Operatoren
 
 bg.mathDivider1=|       Operatoren       |
 bg.mathDivider2=|       Signalanpassung      |
-bg.mathDivider3=|       Zufallszahl      |       
+bg.mathDivider3=|       Zufallszahl      |     
+bg.mathDivider4=|       PID-Regler       |  
 
 bg.constrain=einschränken
 bg.abs=abs
@@ -534,6 +537,22 @@ bc.low=unterer
 bc.high=oberer
 bc.element = Element
 
+
+bg.pid=PID
+bg.pid_limit=PID
+bg.pid.description= PID Regler-Block
+bg.pid_limit.description= PID Regler-Block mit Begrenzung
+
+
+bc.input=Istwert
+bc.setpoint=Sollwert
+bc.interval=Intervall
+bc.kp=Kp
+bc.ki=Ki
+bc.kd=Kd
+bc.limitL=unteres Limit
+bc.limitH=oberes Limit
+
 #CAST
 #****************************
 bd.cast=Typ Konvertierung
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 b960082f81b34042abf930aea08a08b90e0e6e2d..b403f4162ae3fb446cb7f7a1a845ec8e4e564224 100644
--- a/src/main/resources/com/ardublock/block/ardublock_en_GB.properties
+++ b/src/main/resources/com/ardublock/block/ardublock_en_GB.properties
@@ -122,6 +122,8 @@ ardublock.error_msg.stepper_not_existing=Es gibt keinen Stepper mit diesem Namen
 ardublock.error_msg.paste.invalid=Zwischenablage enthält keine ArduBlock-Blöcke
 ardublock.error_msg.paste.notpossible=Einfügen ohne Blöcke nicht möglich.
 
+ardublock.error_msg.pid_limit_error=PID-Block: Oberes Limit ist kleiner oder gleich wie unteres Limit
+
 ardublock.error_msg.no_sim_for_block=Dieser Block ist für die Simulation nicht geeignet.
  
 #TRANSLATOR
@@ -487,7 +489,8 @@ bd.operators=Math. Operatoren
 
 bg.mathDivider1=|       Operatoren       |
 bg.mathDivider2=|       Signalanpassung      |
-bg.mathDivider3=|       Zufallszahl      |       
+bg.mathDivider3=|       Zufallszahl      | 
+bg.mathDivider4=|       PID-Regler       |      
 
 bg.constrain=constrain
 bg.abs=abs
@@ -535,6 +538,20 @@ bc.low=unterer
 bc.high=oberer
 bc.element = Element
 
+bg.pid=PID
+bg.pid_limit=PID
+bg.pid.description= PID Regler-Block
+bg.pid_limit.description= PID Regler-Block mit Begrenzung
+
+bc.input=Istwert
+bc.setpoint=Sollwert
+bc.interval=Intervall
+bc.kp=Kp
+bc.ki=Ki
+bc.kd=Kd
+bc.limitL=unteres Limit
+bc.limitH=oberes Limit
+
 #CAST
 #****************************
 bd.cast=Typ Konvertierung
diff --git a/src/main/resources/com/ardublock/block/block-mapping.properties b/src/main/resources/com/ardublock/block/block-mapping.properties
index 0036c25d10427ebd40f3adb5680ba32bc3a438f5..3707487a5c2d749304800134b59c9078700f13d9 100644
--- a/src/main/resources/com/ardublock/block/block-mapping.properties
+++ b/src/main/resources/com/ardublock/block/block-mapping.properties
@@ -167,6 +167,9 @@ random_range=com.ardublock.translator.block.operators.RandomRangeBlock
 map_common=com.ardublock.translator.block.operators.MapCommonBlock
 map=com.ardublock.translator.block.operators.MapBlock
 
+pid=com.ardublock.translator.block.operators.PidBlock
+pid_limit=com.ardublock.translator.block.operators.PidBlock
+
 #CAST
 #****************************
 cast_atoi=com.ardublock.translator.block.cast.CastAtoi