dragondrop

Introduction to the DragonDrop

By using this platform people can easily program robots and electronics by simple to use drag and drop interface where each block will have a corresponding function. Programming of the hardware will be via the web browser on the users machine i.e. the hardware could be programmed anywhere from the internet.

Tools and Technologies used

· Hardware platform : Raspberry Pi
· Operating System : Raspbian
· Web server: node.js, express.js as the web framework, MongoDB as database server
· User Frontend : HTML5 , CSS3, Javascript, JQuery, Bootstarp, Ajax

1. What is the Raspberry Pi?
As the official documentary states, “The Raspberry Pi is a low cost, credit-card sized computer that plugs into a computer monitor or TV, and uses a standard keyboard and mouse. It is a capable little device that enables people of all ages to explore computing, and to learn how to program in languages like Scratch and Python. It’s capable of doing everything you’d expect a desktop computer to do, from browsing the internet and playing high-definition video, to making spreadsheets, word-processing, and playing games.”

2. Setting up the Raspberry Pi
We have what is called a ‘headless’ setup, meaning that we won’t be hooking up the monitors, keyboard, mouse or any such peripherals to the Raspberry Pi directly. So, we need a way to remotely access it which is accomplished by SSH and VNC.

a. SSH
Secure Shell is a network protocol for secure data communication (and it is encrypted using RSA) and remote command-line login between two networked computers. It connects, via a secure channel over an insecure network, a server and a client running SSH server and SSH client programs, respectively.

We would be establishing a similar connection between a computer and the Raspberry Pi. For this it is necessary that we know the IP address of the Raspberry. This may be done either by looking up the IP address assigned dynamically to the Raspberry every time via the router interface, or, we can make the Raspberry assign itself a ‘static’ IP address.

· Assigning a Static IP Address to the Raspberry Pi
Go to the command line and type the following to edit the inbuilt crontab file so that the given IP address is fixed at each reboot.

crontab –e
@reboot sudo ifconfig eth0 169.254.0.2

Now, we can install Putty for Windows (www.putty.org) and login using default username and password combinations pi and raspberry after specifying the given IP address.

b. VNC
Virtual Network Computing is a graphical desktop sharing system that helps remotely control another computer. It transmits the keyboard and mouse events from one computer to another, relaying the graphical screen updates back in the other direction, over a network.
We will be using the same to control the Raspberry Pi through our PC where in the PC emulates the controls and the display.
For this, first we install ‘TightVNC server’ on the Raspberry and the client on our PC.
On the Raspberry:
1. To install TightVNC Server
sudo http_proxy="http://169.254.114.39:808/" apt-get install tightvncserver

2. To run the server
tightvncserver

vncserver :0 -geometry 1920x1080 -depth 24

NOTE: We use the proxy server 169.254.114.39 which is our PC, running CProxy (www.cproxy.com) since we did not have direct access to internet on the Raspberry Pi.

On the PC:
Install TightVNC client from the link http://www.tightvnc.com/download.php

c. Access the Raspberry using a Custom .local Domain
We can also provide our Raspberry Pi a .local domain which saves us from the headache pf memorizing the IP address. Also, as a .local domain is officially reserved as a Special Use Domain Name it will never be configured as a Fully Qualified Domain Name and hence will never conflict with existing external domains.
To install the service on your Raspberry Pi
sudo apt-get install avahi-daemon
This changes the domain to raspberry.local by default and now you can access the Raspberry Pi using this as a substitute to the IP address.
TIPS: Follow http://www.howtogeek.com/167195/how-to-change-your-raspberry-pi-or-other-linux-devices-hostname/ to change the raspberry.local to somethingelse.local!

3. More about the Raspberry Pi: The GPIO pins
Whatever the circuit user designs on our platform generates some desired output and it is crucial to obtain this output in the correct manner. This is done through the GPIO (general purpose input/output) pins on the Raspberry Pi which essentially give us the output.

You may refer to http://www.raspberrypi.org/documentation/usage/gpio/ for the official documentation on this topic.

Here’s a sample python script to demonstrate what the pins do.

GPIO layout

4. Building the Web Interface
a. jQuery Sortable and Draggable
As seen in our web interface the jQuery Sortable and Draggable enable us to drag and drop certain building blocks of the circuit each of which has a predefined meaning and function and then we interpret the combinational circuit depending on the sequence in which the blocks have been placed.
Here are two simple examples demonstrating the uses of each of these.

jQuery Sortable:
Lets us place elements one after the other in the desired sequence.

jQuery Draggable:
Lets us drag around an element.

b. Express JS
Express.js is a Node.js web application framework, designed for building single-page, multi-page, and hybrid web applications.
Here’s a simple tutorial for an application generator using Express:
https://www.udemy.com/blog/node-js-express-tutorial/

5. Miscellaneous Resources
a. https://github.com/ybogdanov/node-sync
b. https://www.npmjs.org/package/fibers
c. https://github.com/remy/nodemon

Our UI

s1.png

Our app generates a python code

s2.png
a =  abs(0)
while(a < 10):
    gpioWrite(24,True)
    wait(1000)
    gpioWrite(24,False)
    wait(1000)
    a =  (a+1)

Python Functions that we made

This is the basic python heated which is prepended on the software generated code which provides functions to the code.

import RPi.GPIO as GPIO

import time

from random import randint

import math

GPIO.setmode(GPIO.BOARD)

# so that we dont have to do pinmode in begning

NOTHING = 0

OUPTUT = 1

INPUT = 2

allPinModes = [NOTHING for x in range(55)]

def gpioWrite(a,b):

    if(allPinModes[a] != OUPTUT):

        GPIO.setup(a,GPIO.OUT)

    GPIO.output(a,b)

def gpioRead(pin):

    if(allPinModes[a] != INPUT):

        GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

    return GPIO.input(pin)

def wait(ms):

    time.sleep(ms/1000)

def random(x,y):

    return randint(x,y)

def exp(x,y):

    return math.pow( x, y )

def add_inv(x):

    return x*(-1)

def rnd(x):

    return int(x)

def flr(x):

    return math.floor(x)

def ceiling(x):

    return math.ceil(x)

def sin(x):

    return math.sin(x)

def cos(x):

    return math.cos(x)

def tan(x):

    return math.tan(x)

def strlen(x):

    return len(x)

#your code goes here

Running python scripts via node.js

npm install python-shell

A simple way to run Python scripts from Node.js with basic but efficient inter-process communication and better error handling.

· Reliably spawn Python scripts in a child process

· Text, JSON and binary modes

· Simple and efficient data transfers through stdin and stdout streams

· Extended stack traces when an error is thrown

Our Code

function runExtPY(jsText)

{

            fs.readFile('header.py', {}, function(err,Tdata){

                        console.log("hh");

                        jsText = '\n' + Tdata + jsText; // prepend headers to the code

                        fileName = makeRandomString(8)+'.py';

                        filePath =  + "python/"+ fileName;

                        fs.writeFile('python/' + fileName, jsText, function(err) {

                            if(err) {

                                console.log(err);

                            } else {

                                console.log("The file was saved!");

                                PythonShell.run(fileName, function (err) {

                                                            if (err) throw err;

                                                            console.log('finished');

                                                });

                            }

                        }); 

            });

}

Generating Code

We have a really Hacky code for generating the python code.

Although the code is stable.

Generating code with braces

function generateCodeTags()

{

  $(".theHiddenCode").each(function( i, hiddenObj ){

      parent = $( hiddenObj ).parent();

      params = "";

      parent.children('.inputParamaterFunction').each(function (i, textBoxVal) {

         params += $(textBoxVal).val() + ',';

      });

      params = params.substring(0, params.length - 1);

     // console.log(params);

      tex = $(hiddenObj).html();

      tex = tex.split('(')[0];

      //tex = tex.split('=')[1];

      tex += '(' + params + ')';

       $(hiddenObj).html(tex);

       // this if for getting eqns linke x = abs(a);

       var vvv;

       parent.children('.theResultVariableName').each(function (i, t1extBoxVal) {

       vvv = $(t1extBoxVal).val();

      });

       tex2 = tex;

       if(vvv!='' && vvv !=undefined && typeof vvv != 'undefined') tex2 = vvv + ' = ' + tex;

       // this is a jogaar and we will take multiple hidden tags

          hiddenObj2 = $(hiddenObj).parent().children('.theHiddenCode2')[0];

          console.log(hiddenObj2);

          $(hiddenObj2).html(tex2);

  });

}

Convert Braces to python indentation

function DecodeBraces(input)

{

                current_depth = 0

                indent_width = 4

                len = input.length;

                lines = input.split('\n')

                acc=[];

                for(iii=0;iii<lines.length; iii++)

                {

                                l = lines[iii];

                                l = l.strip()

                                console.log(l)

                                if(l.endsWith(';'))

                                {

                                                l = l.popLastCh();

                                }

                                if(l.endsWith('{'))

                                {

                                                acc.push(' '.multiplyStr(current_depth) + l.popLastCh().strip() + ':');

                                                current_depth += indent_width;

                                }

                                else if(l.startsWith('{'))

                                {

                                                current_depth -= indent_width;

            acc.push(' ' .multiplyStr(current_depth) + l.slice(1));

                                }

                                else if(l.endsWith('}'))

                                {

                                                acc.push(' '.multiplyStr (current_depth) +l.popLastCh().strip());

            current_depth -= indent_width;;

                                }

                                else

                                {

                                                acc.push(' '.multiplyStr (current_depth )+ l);

                                                // console.log(acc)

                                }

                }

                // a fix for the brace in next line bug

                for(i=1;i<acc.length;i++)

                {

                                if(acc[i].strip() == ':')

                                {

                                                acc[i] = "";

                                                acc[i-1] += ":";

                                }

                }

                // removing blank lines

                acc2=[]

                for(i=0;i<acc.length;i++)

                {

                                if(acc[i].strip() != '')

                                {

                                                acc2.push(acc[i]);

                                }

                }

                return(acc2.join('\n'));

}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License