3
\$\begingroup\$

I am building a 3D printed self-balancing robot, and use the attached server script to control it. I coded using node.io, express and socket.io.

The system is working, but I would appreciate some coding suggestions as I am quite new to these programming framework, and I would love to understand how to improve my knowledge of this domain.

In particular I would like your feedback on:

  • Best practices and application design
  • Performances and resources utilization of the Raspberry Pi
  • Correctness in unanticipated cases

The setup is:

  • Raspberry Pi running the node server and connected via USB serial to Arduino Mega

  • Android tablet as remote to set several parameters of the robot such as switching the motors on and off and also receive data from the robot

  • Arduino Mega to control the balancing, to read sensors etc

The folder structure is:

\server
  \-public
      \-css
                \-js
                \-foundation
                \-[other self-contained frameworks]

  [html files]
        \scripts
robotserver.js

Just for curiosity, here is a video of the robot.

robotserver.js

// Variables for serial port
var com = require("/usr/local/lib/node_modules/serialport");
var serPort = "/dev/ttyACM0";
var serBaud = 38400;

//Container for data from Arduino
var ArduRead = new Object();
{
ArduRead['READ Read_APIDKp'] = 0;
ArduRead['READ Read_APIDKi'] = 0;
ArduRead['READ Read_APIDKd'] = 0;
ArduRead['READ Read_APIDAggKp']=0;
ArduRead['READ Read_APIDAggKi']=0;
ArduRead['READ Read_APIDAggKd']=0;
ArduRead['READ Read_SPIDKp']=0;
ArduRead['READ Read_SPIDKi']=0;
ArduRead['READ Read_SPIDKd']=0;
ArduRead['READ Read_Yaw']=0;
ArduRead['READ Read_Roll']=0;
ArduRead['READ Read_Pitch']=0;
ArduRead['READ Read_MotorsON']='False';
ArduRead['READ Read_LoopT']=0;
ArduRead['READ Read_SetsteerGain']=0;
ArduRead['READ Read_SetthrottleGain']=0;
ArduRead['READ Read_TriggerAngleAggressive']=0;
ArduRead['READ Read_Info']='',
ArduRead['READ Read_anglePIDOutput']=0;
ArduRead['READ Read_LMO'] = 0;
ArduRead['READ Read_RMO'] = 0;
}

var serialPort = new com.SerialPort(serPort, {
  baudrate: serBaud,
  parser: com.parsers.readline('\n')
  });

serialPort.on('open',function() {
  console.log('Arduino connected on '+ serPort + ' @' + serBaud);
});

//Read input from Arduino and stores it into a dictionary
serialPort.on('data', function(data, socket) {
    if (data.match(/ /g) && data.match(/READ/g))
    {
      var tokenData = data.split(" ");                                        
      ArduRead[tokenData[0] + ' ' + tokenData[1]]=tokenData[2] ;                                      
      //console.log(ArduRead[tokenData[0] + ' ' + tokenData[1]]);
    }

});
//--------------------------------------

var serverPort = 54321;
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var sys = require('sys');
var exec = require('child_process').exec;

app.use(express.static(__dirname + '/public'));

// Routers
{
app.get('/', function(req, res){
  res.sendFile('/public/chat.html');
  res.end;
});

//This is to serve the remote to be coded in Foundation
app.get('/found', function(req, res) {
  res.sendFile(__dirname + '/public/foundation/index.html');
  res.end;
});

//Serves Yaw Pitch Roll gauge
app.get('/ypr', function(req, res) {
  res.sendFile(__dirname + '/public/ypr2.htm');
  res.end;
});

//Serves Temp and battery gauge 
app.get('/tb', function(req, res) {
  res.sendFile(__dirname + '/public/tempbatt.htm');
  res.end;
});

//Serves Virtual joystick
app.get('/vj', function(req, res) {
  res.sendFile(__dirname + '/public/robotj.html');
  res.end;
});

//execute script to start viedo feed
app.get('/VIFE', function(req, res) {
  var postData = req.url;  
  postData = postData.replace("/VIFE?", "");
  function puts(error, stdout, stderr) { sys.puts(stdout) }
  exec('sudo bash /home/pi/Documents/Sketches/Bailey/server/' + postData, puts);
  console.log(postData);  
  res.end;
});

//Reads data from Arduino via ArduRead data structure
app.get('/READ', function(req, res) {
  var postData = req.url;  
  postData = postData.replace("?", " ");
  postData = postData.replace("/", "");
//console.log(req.url+ ' ' + ArduRead[postData.toString()]);  
  res.write(req.url+ ' ' + ArduRead[postData.toString()]);
  res.end();
});

//Sends a command to Arduino, find a better way to use format the string!
app.get('/SCMD', function(req, res) {
  var postData = req.url;  
  postData = postData.replace("?", " ");
  postData = postData.replace("/", "");
  postData = postData.replace("_", " ");
  postData = postData.replace("=", " ");
  serialPort.write(postData + '\n');
  res.end();

});

}

// Logging middleware goes here

// 'ping' and 'chat message' events are for debug purposes

io.on('connection', function(socket){
  console.log('New socket.io connection - id: %s', socket.id);
  setInterval(function(){
  socket.emit('status', ArduRead['READ Read_Yaw'], ArduRead['READ Read_Pitch'], ArduRead['READ Read_Roll']);
  }, 200);
  socket.on('ping', function(data, data2){console.log('event: ', data2);});

  socket.on('move', function(dX, dY){

    //console.log('event: ', dX, dY);
    serialPort.write('SCMD Steer ' + dX + '\n');
    serialPort.write('SCMD Throttle ' + -1*dY + '\n');

    });
  socket.on('chat message', function(msg){
    io.emit('chat message', msg);
    console.log(msg);
  });

  socket.on('disconnect', function(){
    console.log('Disconnected id: %s', socket.id);
  });  

});

io.on('disconnect', function () {
        console.log('A socket with sessionID ' + hs.sessionID 
            + ' disconnected!');
    });

http.listen(serverPort, function(){
  console.log('listening on *: ', serverPort);
});
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Just wanted to let you know quickly this:

  postData = postData.replace("/VIFE?", "");
  function puts(error, stdout, stderr) { sys.puts(stdout) }
  exec('sudo bash /home/pi/Documents/Sketches/Bailey/server/' + postData, puts);

This is incredibly dangerous, anybody with some some basic hacking knowledge can take complete control of your machine. I hope this server is not connected to the internets.

\$\endgroup\$
2
  • \$\begingroup\$ thanks, the raspberry is not connected to the Internet. Can you suggest a better way to execute bash scripts from node.io? \$\endgroup\$
    – Paolo
    Sep 9, 2014 at 13:28
  • \$\begingroup\$ @Paolo I am thinking about it.. \$\endgroup\$
    – konijn
    Sep 9, 2014 at 21:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.