Figure 1. LEGO NXT servo motor.
Photo courtesy of The LEGO Group.
beginning. I won’t give source examples of an I2C slave
implementation here; this has been done many times and if
you Google for it on the Internet, you can choose your own
favorite or easiest to understand implementation from a
wide selection of examples!
Your second question is one that is not isolated to the
PIC. Everyone who develops a device that must not have
spurious signals sent out their I/O lines has to consider this
problem. The issue does not just occur because of an
intermittent battery connection. It will also occur every time
the device is programmed. When all of a PIC’s I/O lines are
turned High-Z (High Impedance), it is because they have
been set to be inputs. In this case, the state of the I/O line
is unknown because it is floating; you need to preload
these I/O lines to safe states with either pull-up or
Figure 2. LEGO servo motor testbed; everything we need.
14 SERVO 07.2009
pull-down resistors. You select the values of those resistors
based on two things: the amount of drive required to
change state (in a PIC, each I/O line can drive 20 mA,
so pretty much any resistor is fine there); and how much
current you want to waste (a higher value resistor takes less
current to change state.)
If you are designing a low power device, you’ll want
those resistors to be 100K or larger to cut down on the
current that you need to use to change state. Because the
PIC specifications state that after a POR the internal value
of the PORT bits is undefined, you will need to initialize
your PORT values before you set up your TRIS registers, and
broadcast those bit values to the rest of your board. The
lesson? Always initialize your PORT registers before you
initialize your TRIS registers. Fortunately, after a reset every
microcontroller that I’ve used defaults the data direction
registers (TRIS registers in a PIC) to be inputs. This gives you
the time to make sure everything is correct before you
enable an output.
Q. I read your answer about interfacing a
LEGO NXT motor with an ATMEGA168
(SERVO March ‘09). I am also playing with
these motors and an ATMEGA8. Did you have some sample
code available for the encoders?
— Stephan
A. The LEGO NXT motor in Figure 1 is indeed a
cool motor. Remember that LEGO calls this a
servo because it isn’t just a motor and gearbox;
it also has an integrated quadrature encoder. This encoder
allows us to know how fast the motor is turning and in
what direction! I’ll generate some avr-gcc code for the
ATMEGA168 to show how you can use this in your
projects. This code is completely compatible with the
ATMEGA8.
Because it isn’t much fun to just turn a motor, I put a
LEGO NXT servo motor in a small custom testbed car and
attached one of my Bot50 robot boards that has an
ATMEGA168 processor and a 754410 motor driver. Sure,
it can only go forward and back since it only has a single
motor, but heck, it looks like a robot, right? See Figure 2
for my motor testbed vehicle.
Some of what you are looking at in Figure 2 no
doubt begs to be explained further, so I will. My little
car consists of a bunch of LEGO Technic rails that are
mounted to the LEGO NXT servo motor. I used typical
LEGO Technic axles and a set of spiffy tires that I found in
one of my many LEGO parts bins. I held my robot board
on the robot with two rubber bands. The power for my
project is a 2S1P 7.4V lithium polymer pack that I built
from two 740 mAh cells. I didn’t gear anything down; I’m
running the wheels straight off of the motor output. There
was one special bit of work that needed to be done to get
everything to work together: I needed a cable to run from
my robot board to the LEGO motor. The next section details
that process.