WiFi Tank Robot in about an hour


 (Left to Right, Auric and Oddjob)

If you've been reading here for a while, you will probably remember Auric my large quad-track robot.  If not, you can read all about it here.

Auric is still developing and getting smarter, but it's also really an expensive project.  I wanted something fun for the kids.  It had to be easy to build and able to handle indoor and outdoor conditions well.

The solution came in the form of a "Black Gladiator" chassis from DF Robot.  Mine came from Little Bird Electronics in Hornsby New South Wales, for the princely sum of $A50.

What I really like about this chassis is that unlike quite a few "budget" tracked chassis I have seen, this has an aluminum base plate which makes it not only stronger, but it shouldn't flex so much and cause damage to PCBs attached to it.

It's a kit so you will need a small phillips-head screwdriver, soldering iron, cutters and medium duty hook-up wire.  When I received mine, DF-Robot's website had some problems and the assembly instructions lacked any pictures.  However, Little Bird have step-by-step instructions on their product page.

I'm not going to repeat the details already published because that would be pointless, but I will offer some hints to make the job easier:
  1. Use a pair of small spanners (M5) to lock up the nuts which secure the non-driven wheels to the chassis.  This is the only part of the kit I wasn't happy with, because it took a couple of attempts to eliminate the free play from these wheels.  Bearings would have been nice, but then the cost would be higher.
  2. The cutouts in the tracks face away from the chassis, and then the pegs will slot nicely into the non-driven wheel as well.
  3. In my build I had to remove four segments from each track to get adequate tension.  Yours may vary.
  4. When wiring the motors, determine the polarity which drives each set of tracks forwards, then solder the wiring.  It makes it easier when it comes to hooking up the controller.  Remember that because the motors are opposed 180 degrees, that they need to turn in opposite directions  for normal motion.
  5. The battery holder takes two 18650 batteries, and while most photos show it on the top of the main deck, it mounts really neatly underneath, and there's even a screw hole or two in the right place.  This frees up space on top for other uses.
  6. Cable-tie your wiring to keep it out of harms way.
All up, the assembly should take 20 - 30 minutes if you've got even modest skills.  It's not a race, but it really is easy.


(Put the batteries underneath and save yourself space.  Looks neater too)

Since keeping the cost down was a major part of this exercise, I used a controller I already had.  Actually it's the original motor controller from Auric.  This is a NodeMCU attached to a common motor shield.  Both parts are readily available, but you could also use an Arduino UNO and Motor shield if you wish.


(Ready for action)


The end result is visually quite pleasing as well as fully functional.  To get you started, the code below can be loaded onto the NodeMCU using the Arduino IDE and and you have a simple web-serving remote controlled robot.  Just make sure you set the WiFi values to suit your home or office network.  The code is really very simple, and for the sake of making it easy to understand there is no authorisation or authentication involved.  Something I intend to fix later.


So there you have it...  A fun afternoon project that could serve as a base for future experiments.  I will definitely be looking into using something like Blynk to build a mobile phone control app for it, as well as adding some additional sensors and whatever navigation I can fit into the NodeMCU's memory.

Finally, all robots need to have a name, and this is no exception.  The newest member of the robot zoo is "Oddjob".  He was Auric Goldfinger's henchman in the movie "Goldfinger".  Curiously, he was supposed to be Korean, but all the "Koreans" in the film were actually speak Cantonese!

#include  <ESP8266WiFi.h>

int PWMA=5;//Right side
int PWMB=4;//Left side
int DA=0;//Right reverse
int DB=2;//Left reverse

const char* ssid = "YOUR_SSID_HERE";
const char* password = "PASSWORD_TO_MATCH";

WiFiServer server(80);

void setup() {
// Debug console
  Serial.begin(9600);
  pinMode(PWMA, OUTPUT);
  pinMode(PWMB, OUTPUT);
  pinMode(DA, OUTPUT);
  pinMode(DB, OUTPUT);
  stop();
  WiFi.begin(ssid, password);
  Serial.print("Network Connect: ");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
  }
  Serial.println("Connected");
  server.begin();
  Serial.print("IP Address of network: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  WiFiClient client = server.available();
  if(!client) {
    return;
  }

  Serial.println("Waiting for new client");
  while(!client.available()) {
    delay(1);
  }

  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();

  // Now decode what we got
  if(request.indexOf("/MODE=STOP") != -1) {
    stop();
  }
  if(request.indexOf("/MODE=FWD") != -1) {
    forward();
  }
  if(request.indexOf("/MODE=REV") != -1) {
    reverse();
  }
  if(request.indexOf("/MODE=LEFT") != -1) {
    left();
  }
  if(request.indexOf("/MODE=RIGHT") != -1) {
    right();
  }

  client.println("HTTP/1.1 200 OK"); // standalone web server with an ESP8266
  client.println("Content-Type: text/html");
  client.println("");
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");
  client.println("<br><br>");
  client.println("<table>");
  client.println("<tr>");
  client.println("<td>&nbsp</td>");
  client.println("<td><a href=\"/MODE=FWD\"\"><button>FWD</button></a></td>");
  client.println("<td>&nbsp</td>");
  client.println("</tr>");
  client.println("<tr>");
  client.println("<td><a href=\"/MODE=LEFT\"\"><button>LEFT</button></a></td>");
  client.println("<td><a href=\"/MODE=STOP\"\"><button>STOP</button></a></td>");
  client.println("<td><a href=\"/MODE=RIGHT\"\"><button>RIGHT</button></a></td>");
  client.println("</tr>");
  client.println("<tr>");
  client.println("<td>&nbsp</td>");
  client.println("<td><a href=\"/MODE=REV\"\"><button>REV</button></a></td>");
  client.println("<td>&nbsp</td>");
  client.println("</tr>");
  client.println("</table>");
  client.println("</html>");

  delay(1);
  Serial.println("Client disonnected");
  Serial.println("");
}

void forward(void) {
  digitalWrite(PWMA, HIGH);
  digitalWrite(DA, HIGH);
  digitalWrite(PWMB, HIGH);
  digitalWrite(DB, HIGH);
}


void reverse(void) {
  digitalWrite(PWMA, HIGH);
  digitalWrite(DA, LOW);
  digitalWrite(PWMB, HIGH);
  digitalWrite(DB, LOW);
}


void right(void) {
  digitalWrite(PWMA, HIGH);
  digitalWrite(DA, HIGH);
  digitalWrite(PWMB, HIGH);
  digitalWrite(DB, LOW);
}


void left(void) {
  digitalWrite(PWMA, HIGH);
  digitalWrite(DA, LOW);
  digitalWrite(PWMB, HIGH);
  digitalWrite(DB, HIGH);
}


void stop(void) {
  digitalWrite(PWMA, LOW);
  digitalWrite(DA, HIGH);
  digitalWrite(PWMB, LOW);
  digitalWrite(DB, HIGH);
}






Comments

Popular posts from this blog

The QYT KT-7900D

Exploring Solar Power - Let there be smoke!

Recording weather with Arduino, Elasticsearch and Kibana