Chapter 1. Building Robots with Lo-tech Materials

When you think about robots, you probably imagine drones, self-driving cars, or humanoid robots like Atlas or Asimo. Many of these more serious robots start their costs at thousands of dollars, and there is no real upper limit (Atlas costs over a $1M, for example). It is possible, however, to build small, interesting robots with a few inexpensive electronic components coupled with some materials you can readily find at home.

One of the great things about NodeBots is being able to prototype rapidly. The combination of an approachable language like JavaScript with friendly hardware such as Arduino means you can explore ideas and see how things work. Being able to prototype and play with robotic techniques quickly helps with learning and exploring concepts.

In this chapter, we’ll explore several robotic concepts using a basic robot called the SimpleBot (Figure 1-1). The first design of the SimpleBot came as the result of a challenge from my child, who asked to build a robot together one evening after dinner. With the clock ticking and only an hour to work before bedtime, it meant using things we had on hand—no laser cutters, CNC mills, or 3D printers. In true hacker spirit, we fabricated using cardboard, cable ties, and rubber bands to get something that worked.

mjsr 0101
Figure 1-1. Completed SimpleBot

Figure 1-2 shows the SimpleBot we made that night. After building it, we fell in love with prototyping using materials such as cardboard, cable ties, and more recently, corflute (corrugated plastic board) for robotics. These materials are inexpensive and easy to work with using scissors or a good craft knife. You don’t have to have access to tools such as a laser cutter, though if you do, then you can still work with these materials—it just becomes even faster to cut things out (and a bit more accurate). Working with these materials allows you to fabricate on your kitchen table and kids can easily work with them, too.

mjsr 0102
Figure 1-2. The very first SimpleBot

After that first effort, the SimpleBot has gone through numerous revisions and is now used as a teaching robot for some NodeBot events. I hope I’ve convinced you that building robots out of simple materials such as cardboard is a good idea. This chapter is going to cover:

Building the SimpleBot

Before you get building, remember there’s no right or wrong way to build your SimpleBot. The design of the SimpleBot was intentionally left open-ended so you can make it any way you want. Others have built versions as minimal as possible on one extreme, as well as automated Nerf-Gun-Toting platforms on the other. The point of the SimpleBot is to play, explore, and extend it, to further your understanding of robotics—so customize away.

Bill of Materials

The SimpleBot project is divided into two parts with components needed at each stage. All of the components for this chapter are listed in Table 1-1, and then the elements needed for each stage are listed again when you get to that point in the chapter. Table 1-2 lists the parts needed for the wireless version.

Table 1-1. SimpleBot materials
Count Part Estimated price Part numbers/source

1

Arduino Uno - R3

$24.95

MS MKSP99; AF 50; SF DEV-11021

1

Half-sized breadboard

$5

MS MKKN2, SF PRT-12002, AF 64

Multi

Jumper wires (male to male)

$4.95

MS MKSEEED3, SF PRT-11026, AF 758

Multi

Jumper wires (male to female)

$5

MS MKKN5, SF PRT-09385, AF 825

2

Continuous rotation (CR) servos; if you have standard servos, an Adafruit tutorial shows how to mod them into CR servos

$14

MS MKPX18, AF 154, SF ROB-09347

15

Cable ties (3–4mm wide and about 200mm long is perfect)

$1

Various suppliers/stores

1

7.4v RC battery pack (LiPo, Li-Ion, or whatever you can get a hold of)

$5

Old or broken RC toys are good sources of these

1

LM7806 or NTE962 6V voltage regulator (drops the voltage to something the servos can use)

$2

RadioShack or Amazon

1

Chassis material—a square of thick cardboard or corflute (3–5mm thick), approximately 400mm square

$2

Various suppliers/stores

1

A printout of the template file

Free

Included with source code

Table 1-2. Wireless SimpleBot materials
Count Part Notes Estimated price

4x

50V 0.1uF ceramic capacitors

Ceramic is best, but others will work

$0.50

1x

USR WiFi232-T module

http://www.usr.so

$15

Build Steps

  1. Start by cutting out the template on your cardboard. It doesn’t need to be perfect. A knife, a cutting mat, and a ruler make it easier to do the inside holes than scissors. With the wheels, the center hole can be cut out or just left, it’s only a target so you know where the center is so you can screw through it to the servo.

    You should now have a full set of chassis pieces. The large piece with the bumps at the end is the base, and the bumps are the front. Use the bumps to push through the small holes on the smaller rectangle, which you can use as a bumper to mount things on.

  2. Next, mount the wheels to the servo. Take the cross-shaped servo horn (you should have a packet of different shaped plastic fittings with your servo) and align the center with the center of the wheel. You can use a piece of wire or a needle to poke small holes in your material to mark the points to screw (Figure 1-3).

    Screw the wheels securely to the servo horn. If you prefer, just glue them on (but then you can’t reuse the servo horns later)—either way works fine. Once you have the wheels mounted on the servo horns, screw through the center of the wheel and the horn into the small gear on the servo. Go easy and hold everything in place while you turn the screwdriver; being rough here can strip the gears in your servo and cause them to slip. Do this for both servos so you now have two wheels.

    mjsr 0103
    Figure 1-3. Mark screw points using the servo horn and a piece of wire

    Gently rotate the servo to ensure it turns freely. If you’re using cardboard or corflute, your mounting screws may be a little long. They don’t have to go all the way through, but make sure they clear the body of the servo when you turn them.

  1. Next, mount the servos to the chassis, as shown in Figure 1-4. You want to place these more or less to the front so the weight balances. You can put them anywhere, but bear in mind you may need to weigh down one end if you find it’s tipping. Mount the servos so the side with the wheel is closest to the front of the chassis, and attach them with two cable ties through the mounting holes to keep them in place. Use two cable ties so the servo body doesn’t twist when you start driving.

When you attach the cable ties, only tighten them enough to stop movement, but not so tight as to rip the cardboard or corflute.

mjsr 0104
Figure 1-4. Servo mounted to the chassis
  1. Mount the battery between the wheels as in Figure 1-5. Again, you can use a cable tie, but double-sided tape or a bit of Blu-Tack works well here, too, if you want to recharge easily. Trim the cable tie excess off as you go or it gets a little hard to mount everything.

  2. Next, fashion a simple “skid” for the SimpleBot to stay balanced. You can do this by looping a cable tie toward the back of the SimpleBot in the middle of the chassis. Do this from the top so the catch of the tie doesn’t get caught on anything. The underside of the loop should be about the same height as half the wheel so the body sits level. It will feel “loose,” but don’t worry, you secure this with the breadboard in the next step.

mjsr 0105
Figure 1-5. Battery mounted to the chassis
  1. Finally, add the breadboard. Mount this across the point you put the skid cable tie so the board holds the skid down. The cable tie can go down the length of the board where the channel is and you can still place ICs across it.

    Now that you’ve finished the mechanics, it’s time for the electronics. The complete wiring diagram is shown in Figure 1-6, with each piece explained next.

  1. Start by creating a battery power rail. This goes to the back of the breadboard and gives you at least 7.4V. Join the grounds on both sides of the breadboard together. Mount the Arduino Nano at one end and join its ground. As you can see with the Nano, position it to either side of the main channel, over the cable tie, and position the USB connection on one side so it’s easy to plug in, as shown in Figure 1-7.

mjsr 0106
Figure 1-6. SimpleBot wiring diagram
mjsr 0107
Figure 1-7. Distributing power
  1. Now create the power for the servos. The servos want 6V so the battery will give them a bit too much, so use a +6V voltage regulator to output a nice clean 6V for the servos. Put that 6V on the other rail of the breadboard so you can attach the servos there.

Note that we’re using the breadboard to bring power from the battery to the regulator from “behind,” then power from the regulator to the other rail from the “front.” This is a good way of keeping what is going on straight in your head when it comes time to debug the circuit later in this chapter.

  1. The servos can be attached to the front power rail with voltage and ground going to each. The left servo signal wire goes to pin 9 and the right servo signal wire goes to pin 8 on the Arduino, as shown in Figure 1-8.

mjsr 0108
Figure 1-8. Servo wiring

Give yourself a pat on the back and tidy up all the wires so nothing is dangling on the floor—you are now ready to start working on your code.

All source code for the examples in this book can be found on GitHub.

Installing Node.js Packages

Ensure Node.js is installed (see “Installing Node.js”). You only need a couple of packages for the SimpleBot, which can be installed from a terminal shell with:

npm install johnny-five temporal keypress

Testing the Build with a Basic Program

Your Arduino needs Firmata on it (see “Arduino”) so the first thing to do is test that everything works before building something more complex to control the SimpleBot. The following code connects to the Arduino over USB and then runs the servos forward for 3 seconds, stops for 3 seconds, goes backward for 3 seconds, and finally stops before exiting.

Connect your SimpleBot to your computer and run the script shown in Example 1-1 and replace <serialport> with the serial port your Arduino is connected to.

Example 1-1. servo-test.js (servo testing code)
var five = require("johnny-five");
var temporal = require("temporal");

var opts = {};
opts.port = process.argv[2] || "";

var board = new five.Board(opts);

board.on("ready", function() {

  var left_wheel = new five.Servo.Continuous(9);
  var right_wheel = new five.Servo.Continuous(8);

  temporal.queue([
    {
      delay: 5000,
      task: function() {
        console.log("going forward");
        left_wheel.cw();
        right_wheel.ccw();
      }
    }, {
      delay: 3000,
      task: function() {
        console.log("stopping");
        left_wheel.stop();
        right_wheel.stop();
      }
    }, {
      delay: 3000,
      task: function() {
        console.log("going backward");
        left_wheel.ccw();
        right_wheel.cw();
      }
    }, {
      delay: 3000,
      task: function() {
        console.log("stopping");
        left_wheel.stop();
        right_wheel.stop();
      }
    }, {
      delay: 1500,
      task: function() {
        console.log("Test complete. Exiting.");
        process.exit();
      }
    }
  ]);
});

If this all works, great! Your SimpleBot is working properly.

A Simple Driving Program

Now that the SimpleBot is working correctly, you can create a simple program to drive it around. As a starting point, let’s take input from the keyboard in order to drive the SimpleBot forward and backward, spin it left or right, and also to stop it. The code shown in Example 1-2 is a very basic example of how to drive using keyboard control.

Example 1-2. simplebot.js (driving example)
var five = require("johnny-five");
var keypress = require("keypress");
keypress(process.stdin);

var opts = {};
opts.port = process.argv[2] || ""; 1
var board = new five.Board(opts);

board.on("ready", function() {

  console.log("Control the bot with the arrow keys, the space bar to stop, Q to exit.")

  var left_wheel = new five.Servo.Continuous(9);
  var right_wheel = new five.Servo.Continuous(8);

  // Configure stdin for the keyboard controller
  process.stdin.resume();
  process.stdin.setEncoding("utf8");
  process.stdin.setRawMode(true);

  process.stdin.on("keypress", function(ch, key) { 2

    if (!key) {
      return;
    }

    if (key.name == "q") {
      console.log("Quitting");
      process.exit();
    } else if (key.name == "up") { 3

      console.log("Forward");
      left_wheel.cw();
      right_wheel.ccw();

    } else if (key.name == "down") {

      console.log("Backward");
      left_wheel.ccw();
      right_wheel.cw();

    } else if (key.name == "left") {

      console.log("Left");
      left_wheel.ccw();
      right_wheel.ccw();

    } else if (key.name == "right") {

      console.log("Right");
      left_wheel.cw();
      right_wheel.cw();

    } else if (key.name == "space") {

      console.log("Stopping");
      left_wheel.to(90);
      right_wheel.to(90);
    }
  });
});
1

Connect to the board using the serial connection supplied from the command line.

2

Set up an event waiting for a keypress on the keyboard.

3

Check the key that was pressed and then, depending on which direction you want to go, engage the motors as discussed in the section on differential drive.

Connect your SimpleBot to your computer and run the script with:

node simplebot.js &lt;serialport&gt;

You should now be able to drive your SimpleBot around the table or floor using the arrow keys on your keyboard and hitting the spacebar to stop.

Troubleshooting

Here are some tips in case you get stuck:

One or both of the servos don’t move

See the previous troubleshooting section on tracking down wiring issues.

You hit the space bar to stop, but the robot keeps moving a little bit

This is due to continuous rotation servos being a hack on normal servos, as well as each servo being manufactured slightly differently. Some servos have a “tuning pot” at the back, which you can turn so that it stops when you set it to stop.

If you don’t have one of these, then you can set your stop point in code.

On a CR servo, the stop position is defined as the center (recall a normal servo operates in an arc that is usually 180°), which is usually 90°. Setting a lower value than this will rotate the servo one direction and above this will rotate the other.

In the stop code, set the servo to move to the 90° position. As such, you might have to tune your stop point a little, changing the stop code to be like this:

left_servo.to(87);
right_servo.to(94);

There’s no “correct” number and every servo will be slightly different, so a few minutes of tinkering will enable you to figure out the number you need for that servo.

Cutting the Cord

Now that you have your SimpleBot driving around the table, you’ll notice one big limitation—the length of the USB cable tethering your bot to your computer. Obviously one solution is to use a longer cable; however, anything over 3 meters long starts having signal issues, not to mention the potential of tangles and the weight the robot has to drag around.

A better solution is to cut the cord altogether—letting the SimpleBot roam free and unshackled from its USB tether!

Wiring Up

Before starting, unplug your Arduino from the USB so you don’t short anything out while building this circuit.

  1. The first thing to do is add decoupling capacitors to the Arduino ground and VIN, as this will be powered from battery. Also add capacitors to the power and ground for each of the servos, as shown in Figure 1-9.

mjsr 0109
Figure 1-9. WiFi wiring diagram
  1. The wireless module uses 2mm pitch headers, so it can’t be plugged into the breadboard directly. Use the M-F jumper wires to connect the module to the breadboard instead. Add the WiFi module with the connections illustrated in Figure 1-10 and mapped in Table 1-3.

Table 1-3. WiFi module connections
WiFi232 Pin Arduino Pin

1

GND

2

VCC (3.3v); don’t plug this into 5V!

5 (RX)

Arduino (TX) Pin 1

6 (TX)

Arduino (RX) Pin 0

mjsr 0110
Figure 1-10. Added wireless module
  1. Check, check, and triple check your wiring. There’s no reverse or over-current protection on these modules, and applying power with too much voltage or GND and VCC back to front will quickly toast your WiFi module.

    These modules are designed to take an external antenna, so your range will be drastically reduced if you don’t use it. The antenna can be readily attached to the chassis with a nice lump of Blu-Tack or hot glue.

  2. Finally, put a jumper wire from the battery power rail to the VIN pin on the Arduino. This will give the Arduino 7.4V, which is plenty for it to run.

That was easy; now for the software side.

Controlling the SimpleBot

Let’s walk through the wireless portion in stages. When you remove wires, there’s more complexity, so you need to make sure each element works before moving onto the next. If anything goes wrong, just backtrack a little and try again.

Test and configure the module

Once 3.3V is supplied, the WiFi module will power up. By default, it will be in Access Point mode. Wait about 10–15 seconds and then in your available WiFi networks on your computer you should see the “USR-WIFI232-T” SSID appear. Connect to this network and once connected, you can try two things to see if it’s all working.

The module IP address is 10.10.100.254, and it has a DHCP server so it should assign you something in that range once you connect. Test pinging 10.10.100.254 and if you’re getting responses like those shown in Example 1-3, move to the next step.

Example 1-3. Checking connection to the module
$ ping 10.10.100.254

PING 10.10.100.254 (10.10.100.254) 56(84) bytes of data.
64 bytes from 10.10.100.254: icmp_req=1 ttl=255 time=2.21 ms
64 bytes from 10.10.100.254: icmp_req=2 ttl=255 time=23.5 ms
64 bytes from 10.10.100.254: icmp_req=3 ttl=255 time=29.5 ms
^C
--- 10.10.100.254 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 5013ms
rtt min/avg/max/mdev = 2.215/20.281/29.502/9.622 ms

If this doesn’t work, diagnose your network interface and make sure you’re not using a static IP or some other configuration that overrides DHCP.

Now open a web browser and point it at 10.10.100.254. The username and password by default are both “admin.” In this interface, you can configure the common aspects of the module itself. Try setting it to operate in STA+A mode, which means it operates as a WiFi station (connects to your WiFi network), but also operates as an access point if you need it (like when taking a SimpleBot to the park).

If you’ve ever configured a WiFi router, then everything will look pretty familiar. Supply the connection details for your network and get the module to connect. You should now see all of the connection information.

Network test

The next step is to make sure communication is occurring properly before trying to send messages from Johnny-Five and the application.

The WIFI232 module exposes TCP port 8899, and whatever is sent to and from the serial connection is sent through that TCP port. Messages will get passed like this:

PC <--> WiFi Network Interface (TCP 8899)
   <--> WIFI232 Network Interface (TCP 8899)
   <--> WIFI232 Serial Interface
   <--> Arduino Serial Interface

If you connect to the module using Telnet, you should be able to see any serial messages coming from the Arduino. Although most Firmata data is encoded, one message is in clear text—when it sends the name of the Firmata sketch being used to the receiver as part of startup.

On my networks, the module is using IP: 10.0.1.12 so telnet there on port 8899 with telnet 10.0.1.12 8899.

This gives the following response:

Trying 10.0.1.12...
Connected to 10.0.1.12.
Escape character is '^]'.

That’s good, because everything is connected. Hit the reset button on the Arduino so the sketch restarts. You should see the telltale Pin 13 LED blink sequence and within a few seconds something like this:

Trying 10.0.1.12...
Connected to 10.0.1.12.
Escape character is '^]'.
��yStandardFirmata.ino

Success! You just received a message from Firmata onto your PC without any wires. Quit Telnet (press Ctrl+] then type “quit”). You’re now ready for the step you’ve been waiting for.

Controlling the SimpleBot wirelessly

Now that you have Firmata messages traveling over the network, all you have to do is get Johnny-Five to read and write them. The problem is that Johnny-Five assumes you have a Serial device connected—something like “/dev/ttyUSB0” or “/dev/tty.USBSerial.” Instead, you have a network socket. One option is to go and write an IO interface for Johnny-Five, but that’s overkill for a simple socket, and it’s not like you’re writing a new messaging protocol—you’re just sending messages via the magic of WiFi rather than a pair of wires. Instead, follow the steps described here (for Mac/Linux, use socat, and for Windows, use VSPE):

Socat for Mac/Linux computers

Socat creates relays between two otherwise independent data channels. Knowing this, you can use pseudoterminals to allow you to create a “fake” serial terminal. A “faked” serial terminal can then be used by Johnny-Five and our application. You should be able to install socat on Linux from your distribution’s package manager. On Mac OS X, you could use Homebrew.

Make a relay between a pseudoterminal that looks like a serial port and connect that to the TCP socket used to talk to the WIFI232 module. On my networks, the WiFi module is at 10.0.1.12—yours will be different, so just replace that. Here’s how it will work:

  PC <--> Pseudo terminal (~/dev/ttyV0)
     <--> TCP Socket (10.0.1.12:8899)

To create this route, use this command (remember to replace 10.0.1.12 with the correct address for your WiFi module):

socat -d  pty,nonblock,link=$HOME/dev/ttyV0 tcp:10.0.1.12:8899

The -d switch is a debugging parameter, so remove it if you don’t want details, and use it up to four times for lots of messages if something doesn’t work.

This command tells socat to create a pseudoterminal (pty). Don’t block it (nonblock; you can use it from other processes) and link it to $HOME/dev/ttyV0 (in this case that puts it at /home/ajfisher/dev/ttyV0, but put it wherever you fancy). Socat then connects that terminal to a TCP connection at 10.0.1.12 using port 8899. Once socat is running, create another terminal window and use screen to connect to a fake serial connection:

screen ~/dev/ttyV0

Do the Arduino reset trick again and you will see the Firmata sketch name. If that all works, then you’re ready to wirelessly control your SimpleBot. All you need to do is pass in the fake serial connection to the program you wrote before, and away you go. At this point, it will work just like it did before, but your SimpleBot will now be wireless:

node simplebot.js /home/user/dev/ttyV0
VSPE for Windows computers

On Windows, use a piece of software called Virtual Serial Ports Emulator (VSPE). This allows you to define a COM port and then create mappings for other endpoints such as to network services.

In the end, the messages should route like this:

PC <--> Virtual COM Port (COM10)
   <--> Bridge
   <--> TCP Client (10.0.1.12:8899)

Download and install the software and once you have it open create two devices:

Create the first one as a “Connector” from New Devices and set it to be COM10—this creates a COM port for Windows to talk to and will be what is passed to the Node.js application:

  • TCP Client

  • Host: 10.0.1.12 (or whatever your WIFI232 IP is)

  • Port: 8899

    1. The next one created is a “Bridge” type, which bridges between two data streams:

  • Serial port

  • Port: COM10 (type it in—it won’t be in the drop-down as it’s not “real”)

  • Speed: 115200

Save the config and press the “play” button to have it all run.

You should now just be able to run the SimpleBot application like before:

node simplebot.js COM10