text: var http = require("http").createServer(handler); // on req - hand
  var io = require("socket.io").listen(http); // socket library
  var fs = require("fs"); // variable for file system for providing html
  var firmata = require("firmata");
  
  console.log("Starting the code");
  
  var board = new firmata.Board("/dev/ttyACM0", function(){
      console.log("Connecting to Arduino");
      board.pinMode(0, board.MODES.ANALOG); // enable analog pin 0
      board.pinMode(1, board.MODES.ANALOG); // enable analog pin 1
      board.pinMode(2, board.MODES.OUTPUT); // direction of DC motor
      board.pinMode(3, board.MODES.PWM); // PWM of motor
      board.pinMode(4, board.MODES.OUTPUT); // direction of DC motor
  });
  
  function handler(req, res) {
      fs.readFile(__dirname + "/Untitled17.html",
      function (err, data) {
          if (err) {
              res.writeHead(500, {"Content-Type": "text/plain"});
              return res.end("Error loading html page.");
          }
      res.writeHead(200);
      res.end(data);
      })
  }
  
  var desiredValue = 0; // desired value var
  var actualValue = 0; // actual value var
  
  var performanceMeasure = 0;
  
  var Kp = 0.55; // proportional factor of PID controller
  var Ki = 0.008; // integral factor of PID controller
  var Kd = 0.15; // differential factor of PID controller
  
  
  var factor = 0.3; // proportional factor that deterimes speed of res.
  var pwm = 0; // set pwm as global variable
  var pwmLimit = 110; // to limit value of the pwm that is sent to the motor
  
  var err = 0; // error
  var errSum = 0; // sum of errors as integral
  var dErr = 0; // difference of error
  var lastErr = 0; // to keep the value of previous error to estimate derivative
  var KpE = 0; // multiplication of Kp x error
  var KiIedt = 0; // multiplication of Ki x integ. of error
  var KdDe_dt = 0; // multiplication of Kd x differential of err.
  
  var parametersStore ={}; // variable for json structure of parameters
  
  var errSumAbs = 0; // sum of absolute errors as performance measure
  
  var errAbs = 0; // absolute error
  var errLast = 0;
  
  var controlAlgorithmStartedFlag = 0; // variable for indicating weather the Alg has benn sta.
  var intervalCtrl; // var for setInterval in global scope
  
  var intervalPulseFunction; // for setTimeout / setInterval
  var performanceMeasure = 0;
  
  
  var readAnalogPin0Flag = 1; // flag for reading the pin if the pot is driver
  
  
  
  http.listen(8080); // server will listen on port 8080
  
  var sendValueViaSocket = function(){}; // var for sending messages
  var sendStaticMsgViaSocket = function(){}; // for sending static messages
  
  board.on("ready", function(){
      
  board.analogRead(0, function(value){
      if (readAnalogPin0Flag == 1) desiredValue = value; // continuous read of analog pin 0
  });
  
  board.analogRead(1, function(value){
      actualValue = value; // continuous read of analog pin 1
  });
  
  io.sockets.on("connection", function(socket) {
      socket.emit("messageToClient", "Srv connected, board OK");
      socket.emit("staticMsgToClient", "Srv connected, board OK");
      
  
      setInterval(sendValues, 40, socket); // on 40ms trigerr func. sendValues
      
      socket.on("startControlAlgorithm", function(numberOfControlAlgorithm){
         startControlAlgorithm(numberOfControlAlgorithm); 
      });
      
      socket.on("sendPosition", function(position) {
          readAnalogPin0Flag = 0; // we don't read from the analog pin anymore, value comes from GUI
          desiredValue = position; // GUI takes control
          socket.emit("messageToClient", "Position set to: " + position)
      });
      
      socket.on("sendInput", function(position) {
          readAnalogPin0Flag = 0; // we don't read from the analog pin anymore, value comes from GUI
          desiredValue = position; // GUI takes control
          socket.emit("messageToClient", "Position set to: " + position)
      });
      
      socket.on("sendStep", function(position) {
          readAnalogPin0Flag = 0; // we don't read from the analog pin anymore, value comes from GUI
          desiredValue = position; // GUI takes control
          socket.emit("messageToClient", "Position set to: " + position)
      });    
  
      socket.on("stopControlAlgorithm", function(){
         stopControlAlgorithm(); 
      });
      
      sendValueViaSocket = function (value) {
          io.sockets.emit("messageToClient", value);
      };
      
      sendStaticMsgViaSocket = function(value) {
          io.sockets.emit("staticMsgToClient", value);  
      };
      
  }); // end of sockets.on connection
  
  }); // end of board.on ready
  
  function controlAlgorithm (parameters) {
      if (parameters.ctrlAlgNo == 1) {
          pwm = parameters.pCoeff*(desiredValue-actualValue);
          err = desiredValue-actualValue;
          errAbs = Math.abs(err);
          errSumAbs += Math.abs(err);
          if (pwm > pwmLimit) {pwm =  pwmLimit}; // to limit pwm values
          if (pwm < -pwmLimit) {pwm = -pwmLimit}; // to limit pwm values
          if (pwm > 0) {board.digitalWrite(2,1); board.digitalWrite(4,0);}; // direction if > 0
          if (pwm < 0) {board.digitalWrite(2,0); board.digitalWrite(4,1);}; // direction if < 0
          board.analogWrite(3, Math.abs(pwm));
      }
      if (parameters.ctrlAlgNo == 2) {
          err = desiredValue - actualValue; // error as difference between desired and actual val.
          errSum += err; // sum of errors | like integral
          errSumAbs += Math.abs(err);
          dErr = err - lastErr; // difference of error
          // we will put parts of expression for pwm to
          // global workspace
          KpE = parameters.Kp1*err;
          KiIedt = parameters.Ki1*errSum;
          KdDe_dt = parameters.Kd1*dErr;
          errAbs = Math.abs(err);
          pwm = KpE + KiIedt + KdDe_dt; // we use above parts
          lastErr = err; // save the value of error for next cycle to estimate the derivative
          if (pwm > pwmLimit) {pwm =  pwmLimit}; // to limit pwm values
          if (pwm < -pwmLimit) {pwm = -pwmLimit}; // to limit pwm values
          if (pwm > 0) {board.digitalWrite(2,1); board.digitalWrite(4,0);}; // direction if > 0
          if (pwm < 0) {board.digitalWrite(2,0); board.digitalWrite(4,1);}; // direction if < 0
          board.analogWrite(3, Math.abs(pwm));        
      }
      if (parameters.ctrlAlgNo == 3) {
          err = desiredValue - actualValue; // error as difference between desired and actual val.
          errSum += err; // sum of errors | like integral
          errSumAbs += Math.abs(err);
          dErr = err - lastErr; // difference of error
          // we will put parts of expression for pwm to
          // global workspace
          errAbs = Math.abs(err);
          KpE = parameters.Kp2*err;
          KiIedt = parameters.Ki2*errSum;
          KdDe_dt = parameters.Kd2*dErr;
          pwm = KpE + KiIedt + KdDe_dt; // we use above parts
          console.log(parameters.Kp2 + "|" + parameters.Ki2 + "|" + parameters.Kd2);
          lastErr = err; // save the value of error for next cycle to estimate the derivative
          if (pwm > pwmLimit) {pwm =  pwmLimit}; // to limit pwm values
          if (pwm < -pwmLimit) {pwm = -pwmLimit}; // to limit pwm values
          if (pwm > 0) {board.digitalWrite(2,1); board.digitalWrite(4,0);}; // direction if > 0
          if (pwm < 0) {board.digitalWrite(2,0); board.digitalWrite(4,1);}; // direction if < 0
          board.analogWrite(3, Math.abs(pwm));        
          }
      if (parameters.ctrlAlgNo == 4) {
          errLast = err;
          err = desiredValue - actualValue; // error
          errSum += err; // sum of errors, like integral
          errAbs = Math.abs(err);
          errSumAbs += errAbs;
          dErr = err - lastErr; // difference of error
          // for sending to client we put the parts to global scope
          KpE=parameters.Kp3*err;
          KiIedt=parameters.Ki3*errSum;
          KdDe_dt=parameters.Kd3*dErr;
          console.log(parameters.Ki3 + " " + 254/parameters.Ki3 + " " + errSum)
          if(errSum > 254/parameters.Ki3)
          errSum = 254/parameters.Ki3;
          if(errSum < -254/parameters.Ki3)
          errSum = -254/parameters.Ki3;
          if(err*errLast < 0)
          errSum = 0;
          pwm = KpE + KiIedt + KdDe_dt; // above parts are used
          lastErr = err; // save the value for the next cycle
          if(pwm > pwmLimit) {pwm = pwmLimit}; // to limit the value for pwm / positive
          if(pwm < -pwmLimit) {pwm = -pwmLimit}; // to limit the value for pwm / negative
          if (pwm > 0) {board.digitalWrite(2,1); board.digitalWrite(4,0);}; // določimo smer če je > 0
          if (pwm < 0) {board.digitalWrite(2,0); board.digitalWrite(4,1);}; // določimo smer če je < 0
          board.analogWrite(3, Math.abs(pwm));    
          console.log("algorithm 4 444");
      }
      if (parameters.ctrlAlgNo == 5) { // only input
          pwm = desiredValue;
          if(pwm > pwmLimit) {pwm = pwmLimit}; // to limit the value for pwm / positive
          if(pwm < -pwmLimit) {pwm = -pwmLimit}; // to limit the value for pwm / negative
          if (pwm > 0) {board.digitalWrite(2,1); board.digitalWrite(4,0);}; // določimo smer če je > 0
          if (pwm < 0) {board.digitalWrite(2,0); board.digitalWrite(4,1);}; // določimo smer če je < 0
          board.analogWrite(3, Math.round(Math.abs(pwm)));
          console.log(Math.round(pwm));
      }
      if (parameters.ctrlAlgNo == 6) { // feedback
          pwm = desiredValue - actualValue;
          if(pwm > pwmLimit) {pwm = pwmLimit}; // to limit the value for pwm / positive
          if(pwm < -pwmLimit) {pwm = -pwmLimit}; // to limit the value for pwm / negative
          if (pwm > 0) {board.digitalWrite(2,1); board.digitalWrite(4,0);}; // določimo smer če je > 0
          if (pwm < 0) {board.digitalWrite(2,0); board.digitalWrite(4,1);}; // določimo smer če je < 0
          board.analogWrite(3, Math.round(Math.abs(pwm)));
          console.log(Math.round(pwm));
      }
      };
  
  function startControlAlgorithm (parameters) {
      if (controlAlgorithmStartedFlag == 0) {
          controlAlgorithmStartedFlag = 1;
          intervalCtrl = setInterval(function(){controlAlgorithm(parameters);}, 30); // call the alg. on 30ms
          console.log("Control algorithm has been started.");
          sendStaticMsgViaSocket("Control alg " + parameters.ctrlAlgNo + " started | " + json2txt(parameters));
          parametersStore = parameters; // store to report back to the client on algorithm stop
      }
  
  };
  
  function stopControlAlgorithm () {
      clearInterval(intervalCtrl); // clear the interval of control algorihtm
      board.analogWrite(3, 0);
      sendStaticMsgViaSocket("Control algorithm " + parametersStore.ctrlAlgNo + " stopped | " + json2txt(parametersStore) + " | errSumAbs = " + errSumAbs);
      controlAlgorithmStartedFlag = 0; // set flag that the algorithm has stopped
      err = 0; // error as difference between desired and actual val.
      errSum = 0; // sum of errors | like integral
      dErr = 0;
      lastErr = 0; // difference
      pwm = 0;
      errSumAbs = 0;
      errLast = 0;
  
      controlAlgorithmStartedFlag = 0;
      console.log("Control algorithm has been stopped.");
      parametersStore = {}; // empty temporary json object to report at controAlg stop
  };
  
  function sendValues (socket) {
      socket.emit("clientReadValues",
      {
      "desiredValue": desiredValue,
      "actualValue": actualValue,
      "pwm": pwm,
      "err": err,
      "errSum": errSum,
      "dErr": dErr,
      "KpE": KpE,
      "KiIedt": KiIedt,
      "KdDe_dt": KdDe_dt,
      "errSumAbs": errSumAbs,
      "errAbs": errAbs
      });
  };
  
  function json2txt(obj) // function to print out the json names and values
  {
    var txt = '';
    var recurse = function(_obj) {
      if ('object' != typeof(_obj)) {
        txt += ' = ' + _obj + '\n';
      }
      else {
        for (var key in _obj) {
          if (_obj.hasOwnProperty(key)) {
            txt += '.' + key;
            recurse(_obj[key]);
          } 
        }
      }
    };
    recurse(obj);
    return txt;
  }