Zoomkat's router/arduino/ssc-32 wifi bot

It also worked for me, but they don’t have any of the products in stock…

when i try to start controlling the robot it goes to internet explorer cannot display the webpage some one please help :cry: :cry: :cry:
matt

You will need to explain what hardware you are using, what code you are using, and specifically what you are doing that isn’t working.

Hey all!

Zoomkat I have used this code and it works great but, at least for me, with only 1 servo connected.
When I add a second servo and click the html link the command goes through and displays on the Arduino serial monitor as it should but on the next click whatever that may be, the Arduino crashs. Never happens with same code on 1 servo.

Have you seen this previously?

If you are talking about two servos in parallel using the same code and arduino servo signal pin, then it might be a power supply problem. How is your arduino and the servos being powered? If your code is modified for two servos, then it could be a code issue. As they say in the arduino forum, if your code is different you probably need to post it.

Thanks for the quick repsonce. :mrgreen:

Its exactly the same code. I have 1 servo in D6 and 1 in D2

Both were powered by the arduino and that was the problem! Once I added a seperate supply its all good.

Great code by the way, I shall need a few more servos so I will have a play with adding extra code.

Hey Zoomkat
I have the choice of either using the same exact netgear router you have in your demonstration or a much smaller router that would probably be more practical. The problem I’m having is what should i use for a power source? Should I use the power port on the arduino or could I pick up something at radio-shack that’s small enough to fit in my robots structure and power full enough to provide voltage for my router. I inserted an image to give you an idea of what I’m working with.

I used the netgear router because it is my normal router and was available. It uses 12v power from an unregulated wallwart (unloaded output is ~15v). All I had to do for the router was disconnect it from my cable modem and switch its power supply from the ~12v wallwart to the 12v drill battery. I used a 5v 7805 regulator chip to power the arduino and ssc-32 (the external power supply on either the arduino or the ssc-32 probably could be used to power both boards at 5v). For the servo power I used another 7805 regulator chip (with a diode on the ground leg to up the output voltage to ~5.7v) connected to the 12v battery. The “pocket router” should work, but may have only one Ethernet input. The netgear router has several ethernet inputs, so an IP cam for vision could also be connected.

Thanks for the reply Zoomkat
I guess with the netgear I can do more things with it but i gotta find a way to build some kind hardware that would allow me to mount it on my rover. As far as setting up the router do I 1st set up the sketch and upload, then use the same port (COM 3) that I used before I mounted the shield or do I have to create another port in the code for the router or better yet how do i test and see if my router/Ethernet connection is active?
Also are there any preliminary actions i must perform on the router directly before i set this up?
i notice when I upload the sketch to the controller a light on my small router blinks for like 3 to 5 seconds which tells me something is happening i just don’t know what if any.

I appreciate all your help
I think I’m close to getting this going I’m just a little unsure about a couple things.
Thanks again

I’d first setup the pocket router (or the netgear as I’m not familiar with the pocket router) per its instructions and see if you can access the internet with the pc connecting via the router. Once that is accomplished, connect the arduino with Ethernet shield to the pc via the usb cable, and connect the Ethernet shield to the router with an Ethernet cable. Below is some simple server code you can load on the arduino and see if the browser on the pc can connect to the arduino server via the router.

//zoomkat 4-1-12
//simple button GET for servo and pin 5
//for use with IDE 1.0
//open serial monitor to see what the arduino receives
//use the \ slash to escape the " in the html, or use ' instead of " 
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields

#include <SPI.h>
#include <Ethernet.h>
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

byte mac] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip] = { 192, 168, 1, 102 }; // ip in lan
byte gateway] = { 192, 168, 1, 1 }; // internet access via router
byte subnet] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port

String readString; 

//////////////////////

void setup(){

  pinMode(5, OUTPUT); //pin selected to control
  //start Ethernet
  Ethernet.begin(mac, ip, gateway, gateway, subnet);
  server.begin();

  myservo.write(90); //set initial servo position if desired
  myservo.attach(7);  //the pin for the servo control
  //enable serial data print 
  Serial.begin(9600); 
  Serial.println("server servo/pin 5 test 1.0"); // so I can keep track of what is loaded
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string 
          readString += c; 
          //Serial.print(c);
        } 

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging 

          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Arduino GET test page</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");

          client.println("<H1>Zoomkat's simple Arduino button</H1>");
          
          client.println("<a href=\"/?on\">ON</a>"); 
          client.println("<a href=\"/?off\">OFF</a>"); 

          client.println("</BODY>");
          client.println("</HTML>");
 
          delay(1);
          //stopping client
          client.stop();

          ///////////////////// control arduino pin
          if(readString.indexOf("on") >0)//checks for on
          {
            myservo.write(40);
            digitalWrite(5, HIGH);    // set pin 5 high
            Serial.println("Led On");
          }
          if(readString.indexOf("off") >0)//checks for off
          {
            myservo.write(140);
            digitalWrite(5, LOW);    // set pin 5 low
            Serial.println("Led Off");
          }
          //clearing string for next read
          readString="";

        }
      }
    }
  }
} 

Why not just use a compatible WiFi shield or WiFi-Bee?
robotshop.com/productinfo.as … lang=en-US

The pocket router looks like it would suit the rover’s size perfectly - just need to find a way to power it. You’d also need the Ethernet shield.

With regard to the large router - that’s usually used on larger robots - and it also consumes more current.
If you want to mount something large on top of the Rover, consider the expansion plate here:
robotshop.com/productinfo.as … lang=en-US

From what I’ve seen the wifi shields are some what complicated to setup, don’t have any method to add a video stream, and don’t have provisions to be assigned an ip address (which may be needed when used as a server). Lower cost might also be a factor, as an Ethernet shield is ~$10 shipped on ebay, and the last time I looked, the 614 netgear router was $25 at the local walmart. A standard router can be connected to by most any wifi enabled device now days.

Hey Zoomkat
I’m trying to get this router-bot to just do basic operations like forward back left right.
I’m still having trouble with getting the router set up for interaction.
Would loading something like OpenWRT to the router be a wise choice?
the problem is the entire set up for the router is in Chinese
could you walk me through what needs to be set up for the router or could it be a plug and play because the router is giving me indication that it is receiving some kind of signal when i upload the sketch.
I just want to get this operational by tonight so i can give a demonstration to a group of kids tomorrow.

Please help
Thank You

I was also wondering is how do I get the controller page to work with the bot. when I click something on the controller page A little LED light blinks on my microcontroller but no motion from my bot. How do I make sure everything is all right and working together?

I assume you have an Ethernet shield on your arduino, and have gotten it to work using some of the basic arduino Ethernet code. What router are you using? The netgear 614 manual is below. A basic setup for testing would be to use your usual home router and have the arduino Ethernet connected to the router, and the arduino connected to your pc with the USB cable.

documentation.netgear.com/wgr614 … Manual.pdf

Hey Zoomkat
sorry to bother you again but I found this awesome code to control my rover with the accelerometer inside my phone or tablet via a phonegap API I’ve been trying to get it to work with the Arduino code you provided (though I modified it) but I’m having problems with it.
I was wondering if you could give me some hints on how to adjuct the code so that they can interact together.

here it is

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
                      "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <title>Jaytee's Rover</title>
    <meta name="viewport" content="width=device-width, user-scalable=no"/>
    <style type="text/css" charset="utf-8">
      body {
        margin: 0pt;
        background-color: #000033;
        overflow: hidden;
        font-size: 8pt;
        font-family: Arial, Verdana, Helvetica, sans-serif;
        border: none;
        border-style: none;
        color: #FFFFFF;
        font-size: 12pt;
        text-align: center;
      }
      button, input, textarea, select, option {
        color: #FFFFFF;
        font-size: 12pt;
        font-family: Arial, Verdana, Helvetica, sans-serif;
        border: solid #003399 1px;
        background-color: #000440;
        overflow: hidden;
      }
      button {
        width: 40%;
        height: 50px;
      }
    </style>
    <script type="text/javascript" charset="utf-8" src="phonegap.js"/>
    <script type="text/javascript" charset="utf-8">
   
    //Mapping Table for Wheel Motion Directions
    var F   = [1,1,-1,-1];
    var R   = -1,1,1,-1];
    var CW  = -1,-1,-1,-1];
   
    var accelID = null;
    var compassID = null;
    var servoPositions = [0,0,0,0];
    var servoPositionCentre = [1500,1500,1500,1500];
    var lastCommandTime = 0;
   
    var servoCentre = 1500;
    var servoRange = 500;
    var servoRangeMin = servoCentre-servoRange;
    var servoRangeMax = servoCentre+servoRange;

    var AccelX = 0;
    var AccelY = 0;
    var AccelZ = 0;
    var AccelXOrigin = 0;
    var AccelYOrigin = 0;
    var AccelZOrigin = 0;
    var CompassHeading = 0;
    var CompassHeadingOrigin = 0;
   
    var bEnabled = false;
    var bRotate = false;
    var bFlipDir = true;  //True for default accelerometer
   //I know I need to change this ip address##########################
    commandURL = "http://10.10.10.10:8080/command/";
   
    // Wait for PhoneGap to load
    function onLoad(){
      document.addEventListener("deviceready", onDeviceReady, false);
     
      move   = document.getElementById("move");
      rotate = document.getElementById("rotate");
     
      move.onmousedown = move.ontouchstart = startMove;
      rotate.onmousedown = rotate.ontouchstart = startRotate;
     
      document.onmouseup = document.ontouchend = stop;      
    }

    // PhoneGap is ready
    function onDeviceReady(){
      startWatch();
      document.getElementById("start").disabled = false;
      document.getElementById("stop").disabled = true;
    }
   
    // Start watching the acceleration
    function startWatch(){
        var options = { frequency: 250 }; //Update Interval
        accelID = navigator.accelerometer.watchAcceleration(onSuccessAccel, onError, options);
        compassID = navigator.compass.watchHeading(onSuccessCompass, onError, options);
    }

    // Stop watching the acceleration
    function stopWatch(){
        if (accelID) {
                navigator.accelerometer.clearWatch(accelID);
                accelID = null;
        }
        if (compassID){
            navigator.compass.clearWatch(compassID);          
            compassID = null;
        }
    }
   
    // onSuccessAccel: Get a snapshot of the current acceleration
    function onSuccessAccel(acceleration){
        var element = document.getElementById('accelerometer');
        element.innerHTML = 'Acceleration X: ' + acceleration.x + '
' +
                            'Acceleration Y: ' + acceleration.y + '
' +
                            'Acceleration Z: ' + acceleration.z + '
' +
                            'Timestamp: '      + acceleration.timestamp + '
';
        AccelX = acceleration.x;
        AccelY = acceleration.y;
        AccelZ = acceleration.z;
       
        accelMove();
    }
   
    // onSuccessCompass: Get a snapshot of the current compass heading
    function onSuccessCompass(heading){
        var element = document.getElementById('heading');
        element.innerHTML = 'Heading: ' + heading;
        CompassHeading = heading;
    }
   
    // onError: Failed to get the acceleration/heading
    function onError(){
        stopWatch();
    }
   
    function accelMove(){
      //This is really accel/compass change... but I'm too lazy to rename
      if(!bEnabled){
        return;
      }

      //Calculate difference to start position      
      if(bRotate){
        var headingChange = 0;
        headingChange = CompassHeading - CompassHeadingOrigin;
        if(headingChange<-180){headingChange+=360;}
        if(headingChange>180){headingChange-=360;}
        servoX = servoRange * (headingChange)/30;
      } else {
        servoX = servoRange * (AccelX - AccelXOrigin)/5;
        servoY = servoRange * (AccelY - AccelYOrigin)/5;
        if(bFlipDir){
          servoX = servoX * -1;
        }
      }
     
      date = new Date();
      currentTime = date.getTime();
     
      //Limit command rate to 4Hz to avoid spamming the controller
      if(currentTime-lastCommandTime > 250){
        for(x in servoPositions){
          if(bRotate){
            servoPositions[x] = Math.round((CW[x] * servoX + servoCentre)*100)/100;
            servoPositions[x] = ((servoPositions[x] < servoRangeMin) ? servoRangeMin : ((servoPositions[x] > servoRangeMax) ? servoRangeMax : servoPositions[x]));
            document.getElementById("debug").innerHTML = "Rotating " + servoPositions;
          } else {
            servoPositions[x] = Math.round((-F[x] * servoY + -R[x] * servoX + servoCentre)*100)/100;
            servoPositions[x] = ((servoPositions[x] < servoRangeMin) ? servoRangeMin : ((servoPositions[x] > servoRangeMax) ? servoRangeMax : servoPositions[x]));
            document.getElementById("debug").innerHTML = "Moving " + servoPositions;
          }
        }
        lastCommandTime = currentTime;
        sendCommand(servoPositions);
      }

      return false;
    }    


    var commandSend = new XMLHttpRequest();
   
    function sendCommand(commandPositions){
      var PostString = "";
      //Get all input fields
      for(x in commandPositions){
        if(PostString != ""){
          PostString += "&";
        }
        PostString = PostString += x + "=" + commandPositions[x];
      }
      //Send the request
     
      commandSend.open('POST', commandURL, false);
      commandSend.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      commandSend.send(PostString);  
    }
   
    function setURL(){
      commandURL = document.getElementById('serverurl').value;
    }
   
    function setZeroPoint(){
      AccelXOrigin = AccelX;
      AccelYOrigin = AccelY;
      AccelZOrigin = AccelZ;
      CompassHeadingOrigin = CompassHeading;
    }
   
    function startMove(){
      //Zero on start
      setZeroPoint();
      bEnabled = true;
      bRotate = false;
    }
   
    function startRotate(){
      //Zero on start
      setZeroPoint();
      bEnabled = true;
      bRotate = true;      
    }
   
    function stop(){
      bEnabled = false;
      //Send stop command too
      sendCommand(servoPositionCentre);
      document.getElementById("debug").innerHTML = "STOPPED";
    }
   
    function flipDir(){
      if(bFlipDir){
        bFlipDir = false;
        document.getElementById("direction").innerHTML = "Direction : Normal";
      } else {
        bFlipDir = true;
        document.getElementById("direction").innerHTML = "Direction : Bruce Special";
      }
    }
   
    </script>
  </head>
  <body onload="onLoad()">
    <h1>MWRover Test</h1>
    <div id="accelerometer">Waiting for accelerometer...</div>
    <div id="heading">Waiting for Compass...</div>
    <br>
    <div id="direction">Direction : Normal</div>
    <div id="debug">Debug Line</div>
    <br>
    <input  id="commandurl" type="text" size="30" value="http://10.10.10.10:8080/command/"/>
    <br>
    <button id="seturl" onclick="setURL();">Set URL</button>
    <br>
    <br>
    <button id="flipdir" onclick="flipDir();">Flip Left/Right</button>
    <br>
    <br>
    <button id="move">Move</button>
    <button id="rotate">Rotate</button>
  </body>
</html>

Wow this is relay what I am looking for. But I’m very new to this Arduino and Ertharnet shield. so can you guide me to make RC car with internet controlling. in this method.

Below is a more up to date arduino routerbot code.

//zoomkat 11-20-12//routerbot code
//for use with Arduino IDE 1.0
//open serial monitor to see what the arduino receives
//address will look like http://192.168.1.102:84 when submited
//servos are continous rotation for drive wheels 

#include <SPI.h>
#include <Ethernet.h>
#include <Servo.h>

byte mac] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip] = { 192, 168, 1, 102 }; // ip in lan
byte gateway] = { 192, 168, 1, 1 }; // internet access via router
byte subnet] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(84); //server port
String readString, servo1, servo2; //strings to hold data
Servo myservo1, myservo2;  // create servo object to control a servo 
//Servo myservo2;
//////////////////////
void setup(){
  //start Ethernet
  Ethernet.begin(mac,ip,gateway,gateway,subnet);
  server.begin();

  //enable serial data print 
  Serial.begin(9600); 
  myservo1.attach(7);
  myservo2.attach(6);
  Serial.println("routerbot-11-20-12"); // so I can keep track of what is loaded
}

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        //read char by char HTTP request
        if (readString.length() < 100) {
          //store characters to string 
          readString += c; 
        } 
        //if HTTP request has ended
        if (c == '\n') {
          ///////////////
          //readString looks like "GET /?-1500-1500 HTTP/1.1"
          Serial.print(readString);
          //now output HTML data header
          if(readString.indexOf('?') >=0) { //don't send new page
            client.println(F("HTTP/1.1 204 Zoomkat"));
            client.println();
            client.println();  
          }
          else {   
            client.println(F("HTTP/1.1 200 OK")); //send new page on browser request
            client.println(F("Content-Type: text/html"));
            client.println();
            client.println(F("<HTML><HEAD>"));
            client.println(F("<H3>Zoomkat's Routerbot<BR>Web Control Page<BR>11-20-12</H3>"));
            client.println(F("<TITLE>Zoomkat's Routerbot Control Page</TITLE>"));
            client.println(F("</HEAD><BODY>"));
            client.println(F("Foward&nbsp;&nbsp;&nbsp;-*Stop*-&nbsp;&nbsp;&nbsp;Reverse<BR>"));
            client.println(F("<a href=/?-1000-2000 target=inlineframe>F-F</a>|"));
            client.println(F("<a href=/?-1450-1550 target=inlineframe>S-F</a>|"));
            client.println(F("<a href=/?-1500-1500 target=inlineframe>*-Stop-*</a>|"));
            client.println(F("<a href=/?-1550-1450 target=inlineframe>S-R</a>|"));
            client.println(F("<a href=/?-2000-1000 target=inlineframe>F-R</a>|<BR><BR>"));
            client.println(F("Turn-L&nbsp;&nbsp;&nbsp;-*Stop*-&nbsp;&nbsp;&nbsp;Turn-R<BR>"));
            client.println(F("<a href=/?-1000-1000 target=inlineframe>F-L</a>|"));
            client.println(F("<a href=/?-1450-1450 target=inlineframe>S-L</a>|"));
            client.println(F("<a href=/?-1500-1500 target=inlineframe>*-Stop-*</a>|"));
            client.println(F("<a href=/?-1550-1550 target=inlineframe>S-R</a>|"));
            client.println(F("<a href=/?-2000-2000 target=inlineframe>F-R</a>|<BR>"));
            client.println(F("<IFRAME name=inlineframe style='display:none'>")); 
            client.println(F("</IFRAME><BR><BR>"));
            client.println(F("<a href=\"#\"onClick=\"MyWindow=window.open('http://192.168.1.102:84/',"));
            client.println(F("'MyWindow','width=200,height=200');\">Popout Control Window</a>"));
            client.println(F("</body></html>"));
          }
          delay(1);
          //stopping client
          client.stop();

          if (readString.length() >0) {
            //Serial.println(readString);
            servo1 = readString.substring(7, 11);
            servo2 = readString.substring(12, 16);

            int n1 = servo1.toInt();
            int n2 = servo2.toInt();

            Serial.println("the numbers are :");
            Serial.println(n1);  //print to serial monitor to see number results
            Serial.println(n2);
            Serial.println("");
            myservo1.writeMicroseconds(n1); //set servo position 
            myservo2.writeMicroseconds(n2);
            //clearing string for next read            
            readString="";
            servo1="";
            servo1="";
          } 
        }
      }
    }
  }
}