3 Simple Ways to
Share What You Make

With Instructables you can share what you make with the world — and tap into an ever-growing community of creative experts.

PhotosPhotos

Share one or more photos of a project, recipe, or whatever you've made, quickly and easily.

Step by StepStep-By-Step

Share your step-by-step photos with text instructions of what you made so others can do it too!

VideoVideo

Share your how-to video. You'll need your embed code from a video site such as YouTube.

Make a Web Connected Robot (for about $500) (using an Arduino and Netbook)

Step 4Software - Robot Laptop (WebServer)

Software - Robot Laptop (WebServer)
(Processing is an open source programming language and environment which is super easy to get started with. For more details visit Processing )

The software that runs on the robot laptop is also quite simple. It is a rather rudimentary web-server (listening for web page requests from a web browser), a small user interface (to set it up), and facilities for passing the commands received from the Web Server to the Arduino.

To Install Quickly: (on windows)
  • Download the zip file below (06-WEBB-Processing Webserver (windows exe).zip)
  • Unzip it and run the .exe file (_WEBB_WebServer_RobotComputer.exe)

To Edit in Processing:
  • Download the zip file below (06-WEBB-Processing Webserver (source files).zip)
  • Unzip anywhere on your computer.
  • Open the Processing environment and open (_WEBB_WebServer_RobotComputer.pde)

To Test:
  • Run the program.
  • In box #1 there will be a list of the available comm ports on your computer (click on the one your Arduino is conneced to. (your robot will twitch a few times as the computer connects, and a cyan dot will appear beside the chosen comm port)
  • In box #2 test to see if your Arduino is connected. Click one of the arrows and hopefully your robot will move in the clicked direction for half a second.
  • In box #3 click the "Start" button to start the web server.
  • Open a web browser (on the Robot Laptop) and visit http://127.0.0.1:12345/ControlPage.html (hopefully the control web page with buttons on it will appear) -Details on how to use this page in the next step-

What is happening:
  • The Web Server listens to port 12345 for http requests (what is sent when you type in a web page address)
  • There are two types of requests it responds to.
1. It listens for "ControlPage.html" and will send the control Webpage
2. It listens for requests of the form "/request?command=F&param1=100" (these commands are parsed and sent to the Arduino (this example would result in the robot going Forward for 10 seconds)

Appendix: (The code for the WebServer)

/* * Arduino Controlled Web Connected Robot (WEBB) - Webserver * For more details visit: http://www.oomlout.com/serb  *  * Behaviour: The program listens for http (webpage) requests in the form *            "/request?command=F&param1=100" and then passes them to the *            Arduino               *            Supported Commands - 'F' - 70 - Forward *                                 'B' - 66 - Backward *                                 'L' - 76 - Left *                                 'R' - 82 - Right *                                 'S' - 83 - Speed *                                 'X' - 88 - SetSpeedLeft *                                 'Y' - 89 - SetSpeedRight  *                                 'C' - 67 - Stop  *            param1's - 0 - 255 (0 to 25.5 Seconds) value * 100 milliseconds  * *            also serves the control webpage to the browser if asking for ControlPage.html * * Operation: 1. Click on the Comm port your Arduino is connected to *            2. Use the test buttons to see if your arduino is listening  *               (will move in the direction clicked for half a second) *            3. Click Start and your webserver will be listening for requests * * * License: This work is licenced under the Creative Commons  *          Attribution-Share Alike 3.0 Unported License. To  *          view a copy of this licence, visit  *          http://creativecommons.org/licenses/by-sa/3.0/  *          or send a letter to Creative Commons, 171 Second  *          Street, Suite 300, San Francisco, California 94105,  *          USA. *         */import processing.serial.*;         //import the serial library to use Serial (for talking to Arduino)import processing.net.*;            //import the net library to use Server    (for talking to the internet)/* Serial Port Related Variables */int serialPortIndex = -1;           //the index of the serial port we are using in the Serial.list() listString[] commOptions;               //A variable to store Serial.list() in so there is no need to poll                                     //the serial ports each time we wish to refrence it (polling causes a                                     //jump in the arduino servos)Serial serialPort;                  //Makes the serial port addressable throughout this sketch/* Graphic and Rendering Related Variables */PFont font;                        //makes font public so it only needs to be loaded once (Arial-72)/* Network Related Variables */Server wServer;                    //The Server which handles web requestsint port = 12345;                  //The port the Server listens toint cycleCount = 0;                //Counts the number of times the draw loop executes (used to                                    //animate the "running" text)           /* Utility Variables */ PImage bg;     //The background image currently \WEBB-background.png/* * Button Related Variables * (buttons are implemented very roughly, bounding boxes are stored and graphic and text are *  drawn on the background image) ie. moving button variables will not move appearance of buttons */Button comm1; Button comm2; Button comm3; Button comm4; //The buttons to choose the correct serial portButton up; Button right; Button left; Button down;//The direction buttons to test if the robot is respondingButton webServer;                                       //The button to start the webServer/* * sets evrything up */void setup() {  frameRate(5);                          //Slows the sketch down a little so it is not as taxing on the system  bg = loadImage("WEBB-background.png"); //Loads the background image (stored in the sketch folder)  size(700, 400);                        //Sets the size of the sketch window  font = loadFont("ArialMT-72.vlw");     //Loads the font we will use throught this sketch  commOptions = Serial.list();           //Polls the Serial ports and gets a list of available ports                                          //(doing this only once keeps the robot from twitching everytime it's                                          //serial port is polled)  defineButtons();            //Defines the bounding boxes for each button  background(bg);             //Paints the background image (this image has all the button graphics on it)}/* The sketches main loop */void draw() {  if(cycleCount==0){  //-- call draw routines    drawCommBox();                        //Draws the emelments in the Comm Box (box 1)    drawTestBox();                        //Draws all the elements in the Test Box (box 2)     drawWebServerBox();                   //Draws all the elements in the WebServer Box (box 3)  }  //-- call working routines  pollWebServer();              //Polls the web server to see if any requests have come in via the network}//----------------------------------------------------------------------------//Start of draw routines (split up just to make code nicer to read)/* * The draw update routine (executed every cycle) for items in the comm box (box 1) */void drawCommBox(){  fill(0,0,0);                                 //Set the fill to black  textFont(font, 15);                          //Set the font to the right size  for(int i = 0; i < commOptions.length; i++){ //For each comm option    text(commOptions[i], 100, 102 + i*70);     //Writes the name of each comm option beside                                                //the appropriate button  }  /* Draw the dot beside the currently active comm port */  if(serialPortIndex != -1){                    //checks to see if a comm port has been chosen    fill(0,147,221);                            //Set fill to cyan    ellipse(180, 96 + 70 * serialPortIndex, 30, 30);     //Draw a circle beside the currently active Comm port  } }/* The draw update routine (executed every cycle) for items in the test box (box 2)*/void drawTestBox(){}/* The draw update routine (executed every cycle) for items in the webserver box (box 3) */void drawWebServerBox(){  fill(0,0,0);                                  //Set the fill to black  textFont(font, 30);                           //Set the font to the right size  if(wServer == null){text("Start", 553, 210);  //If the Webserver has not started writes Start on the button  }else{                                                     String running = "Running.";                        //If the Webserver is running writes running and                                                         //a progression of dots for movement    if((cycleCount / 1) > 0){running = running + ".";} //the number of dots is based on cycleCount         if((cycleCount / 1) > 1){running = running + ".";}    if((cycleCount / 1) > 2){running = running + ".";}    if((cycleCount / 1) > 3){cycleCount=0;}    text(running, 520, 210);  }  cycleCount++;                                     //Every time through cycleCount is incremented by one}  //End of Draw routines//-------------------------------------------------------------//-------------------------------------------------------------//Start of Service routines/* * mousePressed is called everytime the mouse is pressed this  * checks if the mouse is inside any of the button bounding boxes * and if it is the appropriate routine is called*/void mousePressed(){    if(comm1.pressed())      {updateSerialPort(0);}       //Changes to the comm port at index 0 in Serial.list()    else if(comm2.pressed()) {updateSerialPort(1);}       //Changes to the comm port at index 1 in Serial.list()    else if(comm3.pressed()) {updateSerialPort(2);}       //Changes to the comm port at index 2 in Serial.list()    else if(comm4.pressed()) {updateSerialPort(3);}       //Changes to the comm port at index 3 in Serial.list()    else if(up.pressed())    {sendRobotCommand("F", 5);} //Sends a command to move the robot Forward for 0.5 seconds    else if(left.pressed())  {sendRobotCommand("L", 5);} //Sends a command to move the robot Left for 0.5 seconds    else if(right.pressed()) {sendRobotCommand("R", 5);} //Sends a command to move the robot Right for 0.5 seconds    else if(down.pressed())  {sendRobotCommand("B", 5);} //Sends a command to move the robot Backward for 0.5 seconds    else if(webServer.pressed()) {startWebServer();}      //Starts the webServer           cycleCount = 0;    background(bg);                       //Repaints the background image (this image has all the button graphics on it)    draw();}/* * Called once an execution it checks the Server to see if there are any waiting connections * if there is a waiting connection it pulls out the request and passes it to the parseRequest(String) * routine to strip away extra text. This is then sent to the interpretRequest(String) routine to  * call the appropriate action routine (ie send instructions to robot).  * * A Request is passed by entering the computers address and port into a web browser * For local machine "http://127.0.0.1:12345/request?command=F&param1=100" * * Example Request: *   GET /request?command=F&param1=100 HTTP/1.1 *   User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) *   Accept: *//* *   Accept-Language: en-US,en *   Accept-Charset: ISO-8859-1,*,utf-8 *   Accept-Encoding: gzip,deflate,bzip2 *   Host: 127.0.0.1:12345 *   Connection: Keep-Alive * * Example Reply (for processed request) *   HTTP/1.1 200 OK *   Connection: close *   Content-Type: text/html * *   command: F param1: 100    */void pollWebServer(){  if(wServer != null){                               //If the webServer is running    Client request = wServer.available();            //Load the next Client in line in the                                                      //server (null if no requests waiting)    if(request != null){                             //if there is a request process it      String fullRequest = request.readString();     //Store request contents as a string      String ip = request.ip();                      //Store the clients ip address as a string       String requestString = parseRequest(fullRequest.toUpperCase());  //Strip away all the extra                                          //information leaving only the request string (text after GET)                                         //(shifts to upper case to make string testing easier)       if(requestString.indexOf("REQUEST?") != -1){        //Checks if the request has "REQUEST?"         String reply = interpretRequest(requestString);   //Sends the request to the request interpreter         request.write("HTTP/1.1 200 OK\nConnection: close\nContent-Type: text/html\n\n" + reply);                                                             //Sends the reply a 200 to say the request was                                                           //handled and the "reply" string as the response          wServer.disconnect(request);                     //Disconnects the Client       }else if(requestString.indexOf("CONTROLPAGE") != -1){  //If the request is for the control web page         String[] webPageArray = loadStrings("WEBB-ControlPage.html");                                                            //Loads the control webPage from \data\WEBB-ControlPage.html                                                           //(loaded as an array of lines)         String webPage ="";                              //To make editing easier the webpage has been left with                                                           //line breaks so this for loop striops those lines out         for(int i = 0; i < webPageArray.length; i++){           webPage = webPage + webPageArray[i];         }         request.write("HTTP/1.1 200 OK\nConnection: close\nContent-Type: text/html\n\n" + webPage);                                                           //sends the browser the instructions that the request was not                                                           //processed and the webpage as a string         wServer.disconnect(request);                     //Disconnects the client       }else if(requestString.indexOf("/TEST/") != -1){   //For Testing outputs the request as a println         println(fullRequest);         println(ip);         request.write("HTTP/1.1 200 OK\nConnection: close\nContent-Type: text/html\n\n");                                                           //sends the browser the instructions that the request was not                                                           //processed and the webpage as a string         wServer.disconnect(request);                     //Disconnects the client       }else{         request.write("HTTP/1.1 404 FILE NOT FOUND\nConnection: close\n");                                                           //sends the browser the instructions that the request was                                                           //not processed (usually due to a typo) then tells it to                                                           //close the connection         wServer.disconnect(request);                     //Disconnects the client       }    }  } }//End of Service Routines//-------------------------------------------------------------//-------------------------------------------------------------//Start of setup routines (routines called once or not very often/* * Defines all the bounding boxes for the buttons used in this sketch */void defineButtons(){  comm1 = new Button(30, 65, 60, 60);  //Defines the comm1 button  comm2 = new Button(30, 135, 60, 60); //Defines the comm2 button  comm3 = new Button(30, 205, 60, 60); //Defines the comm3 button  comm4 = new Button(30, 275, 60, 60); //Defines the comm1 button  up = new Button(320, 110, 60, 60);   //Defines the up/forward button  left = new Button(260, 170, 60, 60); //Defines the left button  right = new Button(380, 170, 60, 60);//Defines the right button  down = new Button(320, 230, 60, 60); //Defines the down/backward button  webServer = new Button(493, 170, 180, 60); //Defines the webserver button}/* * When the "Start" button in the webserver box is pressed the server starts listening * for incoming connections on port port (12345) defined in the preamble */void startWebServer(){    if(wServer == null) {wServer = new Server(this, port);}  }/* * This takes a verbose http request from a client and * returns only the request line (what comes after GET) */String parseRequest(String fullRequest){  fullRequest = fullRequest.substring(fullRequest.indexOf("GET ") + "GET ".length());                                               //Cuts off everything in the string before GET  fullRequest = fullRequest.substring(0, fullRequest.indexOf(" "));                                                                 //Takes from the begining of the new string to the first space  return fullRequest;                       //returns the shortened request}/* * updates the serial port being used to comunicate with the arduino * portIndex is the index of the port we wish to use in Serial.list(); * as Serial.list() is loaded into memory at startup adding serial ports  * after startup could cause unexcpected operation */void updateSerialPort(int portIndex){  if(commOptions.length > portIndex){ //if the passed portIndex is a valid index in Serial.list()                                       //(ie. not option three in a list of two)     serialPortIndex = portIndex;     //set the serialPortIndex variable to the new serialport index                                       //(this is used to display the dot beside the active port)  }  if(serialPortIndex != -1){                    //check to make sure a port has been chosen sometime previous    if(serialPort != null){serialPort.stop();}  //if a Serial port is already being used stop it before loading a new one     serialPort = new Serial(this, Serial.list()[serialPortIndex], 9600);                                                  //Create a new Serial object to comunicate with the Arduino 9600 Baud  }}/* * Takes a request string (ex: "request?command=F&param1=100") and will strip out the command * and param1 and pass it to the arduino (adding extra parameters or non arduino commands would be done here) */String interpretRequest(String requestString){ String returnValue = "OK";                     //Prepares a returnValue variable String command;                                //Next three lines extract the value after "command="                                                 //(the extra line is in case the command parameter is at the                                                 //end of the request and not followed by an & if(requestString.indexOf("COMMAND=") != -1){   command = requestString.substring(requestString.indexOf("COMMAND=") + "COMMAND=".length());} else{command = "Z";} if(command.indexOf("&") != -1){   command = command.substring(0,command.indexOf("&"));}else{command = command;} String param1String;                         //Next three lines extract the value after "param1="                                               //(the extra line is in case the command parameter is at                                               //the end of the request and not followed by an & if(requestString.indexOf("PARAM1=") != -1){   param1String = requestString.substring(requestString.indexOf("PARAM1=") + "PARAM1=".length());} else{param1String = "0";} if(param1String.indexOf("& ") != -1){   param1String = param1String.substring(0,param1String.indexOf("&"));} else{param1String = param1String;} int param1 = Integer.parseInt(param1String);  //Turns the param1 String into an integer sendRobotCommand(command,param1);            //Sends the command to the routine that sends it to the Arduino returnValue = "command: " + command + " param1: " + param1;  //at the moment just the parsed command but sending                                                               //as html so formatting can be included return returnValue;}/* * Takes a command (currently one letter) and a parameter (one byte 0-255) and sends it to the arduino * which is listening and reasts * Currrently Supported Commands * F -*/void sendRobotCommand(String command, int param1){  println("command: " + command + " time: " + param1);  String checkString = "AAA";  if(serialPort != null){    serialPort.write(checkString + command);    serialPort.write(byte(param1));  }}//End of setup/not very commonly called routines//-------------------------------------------------------------------------------------//Example button and RectButton code from processing.org example with some changes //made mostly to simplify and remove roll over animation//http://processing.org/learning/topics/buttons.html (2008-09-23)class Button{  int x, y;  int width, height;  Button(int ix, int iy, int iwidth, int iheight) {    x = ix;  y = iy;  width = iwidth;  height = iheight;  }    boolean pressed() {    if(overRect()) { return true; }     else {           return false;}      }  boolean overRect() {    if (mouseX >= x && mouseX <= x+width && mouseY >= y && mouseY <= y+height) { return true; }     else { return false; }  }}

« Previous StepDownload PDFView All StepsNext Step »
2 comments
Feb 6, 2011. 1:11 PMPuze says:
Does anyone know how you can run this on linux?
Aug 9, 2010. 11:53 PMcrxksa says:
can any one sent me The code for the arduino webserver crx.ksa@gmail.com
Sep 8, 2010. 9:45 AMkyle brinkerhoff says:
dude just use vspe , all your problems will be solved, for the video feed use webcam xp

Pro

Get More Out of Instructables

Already have an Account?

close

All Steps Viewing
View all steps of an Instructable on the same page when you're a Pro Member.

Upgrade to Pro today!
408
Followers
14
Author:oomlout