Friday, March 8, 2013

FrizzleBot

Quick update: I ran an experiment tonight and was able to send FrizzleBot on a mission from the living room of my apartment to the kitchen and back. No big problems, except there was a bluetooth connection reset at one point, but the connection was quickly restored, and disaster was averted. Otherwise, the experiment was a success.

Thursday, March 7, 2013

FrizzleBot


I'm starting this log later than I should have,
but after some success, I've decided it is crucial
to start documenting my experiences with FrizzleBot.
Let's start from the beginning.

Early February this year I finally received the
package containing the pieces to a kit I ordered from
Bizoner.com. It includes a 4-wheel chasis with 4
servo motors (one for each wheel). Also included 
was an Arduino Duemilanove microcontroller board,
a motor shield and an I/O expansion shield from 
DFRduino. Other hardware included 4 wheels, panels,
standoffs, screws for mounting, a 9v battery
connector, a 4xAA battery pack as an additional
external power source, and some other miscellaneous
equipment for mounting. The kit came almost completely
disassembled, but the motor controller board and 
servos in the chasis were already wired. There were
also a couple of APC220 wireless serial chips, but
it turns out that I never used them for programming
the Arduino (more details on this later).

First, I tried assembling the pieces without disconnecting
the wiring or opening up the chasis. Once assembled,
I began experimenting with programming the Arduino using
the very simple Arduino IDE over a wired USB connection
to my laptop. Programming the microcontroller worked
without much trouble, but when I sent signals to the motors,
the wheels would move in opposite directions on the same side.
For example, sending a PWM signal to the left motors (they are
wired in tandem on each side) would cause one of the left 
wheels to move forward and the other to move backward. No matter
how I wired the motors to the board, I could not get both wheels
on one side to move in the same direction. Clearly this 
behavior could never be useful, so I was stuck.

Eventually, I decided to open up the chasis and look at how
the motors were wired together on each side. It turns out that
they came mis-wired, and I after I rewired them, the motors
would cooperate. This was the first roadblock I was able to
circumvent. I began experimenting with driving the motors, first
by writing a series of simple Arduino sketches, which worked easily
except for some difficulty figuring out what pins on the Arduino 
with which I needed to interact.

My goal was to eventually be able to control the motors from my
Verizon Samsung Galaxy S3 smart phone, which I had been hacking
on for a few months prior. I had been flashing custom ROMs and 
building my own kernels for a while.

Aside: I once flashed a ROM on my phone using a utility called Odin
which overwrote some partition, causing my phone to be unable to 
connect to the Verizon services. I couldn't use 4g, make calls, 
or send text messages. Even if I flashed the stock ROM I couldn't
get it to function properly, so first I went to a Verizon store in 
Boston. They tried resetting and flashing the device with their
equipment, but still the same problem persisted. That was December 
2012, and I went home to Texas to visit my family for Christmas. 
When I was there I went to another Verizon store, and they couldn't 
fix it either. I had them send me a new phone, and so far I haven't 
bricked this one.

My phone is now running Cyanogenmod 10.1 MR1, Android Jellybean 4.2.1,
with a custom built Android Linux kernel from ktoonsez (https://github.com/ktoonsez), version 
3.0.62. I built the kernel myself from source. 

I wanted to get the phone to communicate with the Arduino on
the robot without a wired connection. The reason is that I wanted 
to easily attach/detach the phone to/from the robot without having 
to deal with wires, and I also thought it would be an interesting 
exercise.

There were two options for wireless communication: bluetooth and
wireless ethernet. After thinking about this and shopping around,
I realized that there was no reason to use wireless ethernet, for
two reasons: (1) my phone already has a wifi adapter, so if it is
able to communicate with the Arduino, there is no reason to duplicate
the functionality, and (2) bluetooth adapters are generally less
expensive. For these reasons, I chose bluetooth as the communication
bus between the phone and the Arduino.

The I/O expansion shield that came with the robot kit has an XBee
socket which supports the BluetoothBee chips. I ordered one of these
for around $25, hoping that I could figure out how to get it functioning
with my board and not waste my money. This was the next major hurdle, and
at first I had no idea what I was doing, or whether or not the bluetooth
device was even compatible with my hardware.

After reading countless blog posts and tutorials, I had an idea of how to
write Arduino sketches for controlling the bluetooth device. It seemed 
simple in theory, but in practice this has been the most time consuming part
of this project so far. None of my initial sketches succeeded in pairing the
BluetoothBee with my phone's bluetooth device. At first I thought I had a
defective BluetoothBee, but from experience I suspected that I had probably 
missed some important step. Finally, I discovered the correct TX/RX pins to
use and the proper sequence of AT commands to send to the bluetooth device to
configure and put it into slave pairing mode, with automatic reconnect enabled.

It is worth noting that initially I was using an application on the phone
called BlueTerm to test connections with the Arduino. One day I was
astonished to see the red and green blinking LEDs on the BlueToothBee,
signifying that I finally had correctly programmed it to enter pairing mode
and start listening for pairing and connection requests from remote devices.
I fired up BlueTerm on the phone, paired with the Arduino, and established my 
first bluetooth connection.

Now I could send data from the phone to the Arduino, which would allow me to
write a very simple command set that the Arduino program would translate to
PWM signals sent to the servo controller outputs. Although the basic operations
worked, it took some time to get a somewhat robust motor control program
running, without experiencing random bluetooth connection resets or power
resets due to driving the motors incorrectly. It took a lot of experimentation
to find the right bounds for speed and timing parameters. At this point it
is somewhat stable, but occasionally I still get random connection resets. To
get around this, for now, I've made sure to stop the motors on reset, and
the BluetoothBee is configured to quickly automatically reconnect. It turns
out that connecting an additional external power supply, separate from the
power to the Arduino Duelimanove board, reduces the frequency of resets to a
manageable level. Now, I usually connect a 9v battery to the Duelimanove, and
the 4xAA battery pack is wired into the motor controller shield. I went and
bought a bunch of rechargable lithium AA batteries, because I can test using 
only these (without the 9v) and it still gives enough power to the Duelimanove
as well as the servos (albeit with less juice than if both power sources are
plugged in).

The command set that the motor control program implements is very simple; each
command is a single character:

'w' - set mode to move forward
's' - set mode to move backward
'a' - set mode to turn left
'd' - set mode to turn right
' ' - set mode to stop (saves speed to be restored on next mode change)
'x' - increase speed (by a hardcoded increment, caps at a maximum speed)
'z' - reduce speed (if > 0)
The program will send back the current speed value when the speed is changed.
Debugging and testing the motor control program for the Arduino
was another time consuming task, and is still sort of in progress, but it works
well enough to go on to more interesting things. On the phone side, I had
been testing all of this with BlueTerm, but I wanted a custom Android
application that I could use to programmatically send control commands to the
Arduino. So, I downloaded the Android SDK and development toolkit,
installed Eclipse, and configured the Android plugins for the IDE.

I found an example project for Eclipse that implements a simple Bluethooth
chat terminal, designed to be used to communicate between two Android devices.
I started working from the example Java source as a basis for an application 
that would allow me to establish a bluetooth connection to the Arduino and 
send data over the connection from the phone. My motivation was to be able to
forward data coming into the phone over an ethernet socket (e.g. from my
laptop) to the phone's bluetooth connection with the Arduino, thus remotely
controlling the motors over wifi from a remote location. The reason I wanted
this functionality is that I wanted to create a sort of ground-based "drone,"
that I could control while watching a video feed from a remote machine with an
Internet connection. The phone itself would be mounted on the robot and video
data collected by one of the phone's cameras.

My first idea was to use VNC to remotely control the phone, so I could load up
the BlueTerm application and not have to write my own custom app. The problem
was that no matter what video server app I used on the phone, it would not
continue to stream video if another view was active. When I would load the 
BlueTerm app over VNC, it would always stop the video feed, so I could only
use one or the other, but not both simultaneously. I figured programming
bluetooth would be easier than writing my own video server, so I chose to
focus on a background Android service that would open a TCP port, and upon 
connection, would forward all data from that port over the bluetooth
connection with the Arduino.

All of this shouldn't have been too difficult, but I hadn't used Eclipse for
years and had no experience with the Android SDK. Most of my problems were
related to Eclipse conventions for projects and Android xml configurations, so
this was definitely a learning experience. Also, I rarely use Java since most
of my experience is in low-level C and assembly language programming. It took
me a while to get the hang of the development environment, but I just recently
got this TCP to bluetooth socket program working. Now, I can power on my 
Arduino, load up the Android app, establish the bluetooth connection, and
telnet to a TCP port on the phone from my laptop. I can type the characters
from the command set I mentioned above directly into the telnet terminal on
my laptop, and they are forwarded to the Arduino to drive the robot around.
Since the forwarding logic is contained in a service running in the
background, I can load up the video server application on my phone, and watch
the video feed on my laptop as I'm also remotely controlling the motors.

The only other thing to complete this experiment was to physically mount the
phone on the robot. The kit had some strange looking metal bracket pieces that
just happened to be the right size to hold my phone steady. I spaced them in
such a way (and bent the metal a little bit) that I can seat the phone between
them without having to use ties, tape, or bolts. The video server I'm using
allows me to control some things, such as turning the bright LED on and off in
case the environment is too dark to see anything in the video feed. I can
view the video and access these controls over an http connection to the phone
from my laptop, while I also have the telnet connection open to control the
motors.

Next, I will try to connect this sonic range sensor I bought to the Arduino,
and figure out how to integrate it into the Arduino program. Its function
will be a failsafe stop mechanism to keep the robot from crashing into things,
in case either the TCP or bluetooth connection is lost and for some reason the
motors keep going. If it works well, I'll probably buy a few more to mount
around the perimeter of the robot, to increase safety. I'm amazed I haven't 
completely destroyed the thing yet, but I'd like for it to stay in one piece.
Another task is to learn about the camera API on the android, and integrate
the current tcp-to-bluetooth forwarding app with my own video streamer. I'm
stil not happy with the performance of the video server app I'm currently
using, and it's not convenient to have to load multiple apps on the phone to
initialize the connections and video stream. I will probably also write a 
client application for the laptop so I don't have to load a web browser and a
telnet terminal. 

Search

BlogListing