The circuit that this report describes allows the NXT to control two additional motors. Like the NXT itself, it can power both the NXT servo motors and other 9V Lego motors (using converter cables). The controller allows the NXT to turn the motors on and off, in both direction, but it does not provide speed control in hardware and it does not use the feedback from the NXT's servo motors. The power to the motors can, however, be adjusted in software by turning them on and off quickly. With this circuit, the NXT can control up to five motors. But its batteries do not have enough power for five motors. Also, the sensor ports do not have enough power for even one motor. Therefore, a separate 9v battery box provids power to the extra motors. NXT motors can be connected to this board with the The same board also houses my pressure sensor.
The picture on the right shows how the board is used. You connect it to a sensor port of the NXT; this allow the next to control the extra motors (and to read the pneumatic pressure sensor). You connect a 9v battery box to another socket on the board, and you turn it on. If the red LED on the board lights, the battery box is connected correctly. If not, you press the other botton on the battery box to flip its polarity and then the LED lights. The two motors are also connected to NXT sockets, either using a standard NXT cable or via a converter cable.
The circuit is built on a printed-circuit board (PCB) that I designed and ordered from a manufacturer that produces low-cost custom PCB's. But like the other NXT-related circuits that I built, I first constructed it on a solderless breadboard. So it is certainly possible to build it in a low-tech fashion without a custom PCB, as shown in the picture on the right.
The schematics below shows the circuit, drawn in sections. The top section shows the NXT socket (on the left), the two pull-up resistors for the I2C bus, and the 5v regulator for the pressure sensor. I connected the pull-up resistors to the positive supply through jumpers, which allows me to take them out of the circuit if the I2C bus already has pull-up resistors somewhere else. The 5v regulator uses a 100mA low-drop regulator, LP2950. It works even if the voltage on the ANA line is only 5.5v or even a bit lower. This regulator requires a 1µF or larger capacitor on sides; I used 3.3µF tantalum capacitors. There are many other 5v and adjustable low-drop regulators that would do the job here. (In the prototype I used a more common regulator, 78L05, but it is guaranteed to work only if the ANA line carries 7v or higher, which is not always the case.)
The rest of the pressure sensor is the PCF8591 analog-to-digital converter and the MPX4250A pressure sensor. The unused digital inputs of the PCF8591 and its digital-to-analog line are available on the PCB and can be connected to small sockets. This allows the circuit to measure additional voltages and to produce an analog signal.
The motor controller itself consists of four sections. The lower section in the schematic, the one with the L272M, is the one that actually controls the motor. There are two identical copies of it on the board, but the schematics only show one copy. The chip that contols the motors, L272, consists of two power operational amplifiers (opamps). They are configured in this circuit not as amplifiers, but as comperators. Each opamp compares its non-inverting input (marked with a plus sign) with its inverting input (marked with a minus sign). If the non-inverting input is higher, it drives the opamp's output as high as possible (close to the positive supply of the opamp). If the non-inverting input is lower, it drives the ouput close to ground. By driving one opamp high and the other low, we generate a large voltage drop across the motor's terminals, turning it on. By choosing which opamp's output is high and which is low, we control the polarity of the motor's terminals and hence the motor's direction. When the output of both opamps is low, no power is provided to the motor; the same happens if both outputs are high. This power-control configuration is called an H-bridge.
The inverting inputs of both opamps are connected to the middle of a voltage divider (the two 100K resistors), so they are always at 4.3/2v. Since we will drive the non-inverting inputs to either ground or 4.3v, the non-inverting input is always either much higher or much lower than the inverting one. This causes the opamps to act as a comparator or a switch, with its output always going all the way up or all the way down.
The four diodes and the 0.1µF capacitor are there to protect the circuit from the motor. A motor can generate current (if you turn it), and the resulting voltages can damage the L272 unless we protect it. The L272, like most chips, can be damaged if the voltage in any of its pins goes more than a few tenth of a volt above the positive supply or lower than the ground (or negative supply, if any). In this circuit, if the motor causes voltage in one of its terminals to go below ground or above the 9v supply, the a diode will start to conduct and will clamp that terminal to ground or to the 9v supply.
The L272 chips that I used are made by STMicroelectronics. They can each supply 1A continuous and 1.5A peak current. The same chip is also made by oher manufacturers, but some of them rate their chips for lower currents (e.g., 0.7A continuous and 1A peak for Fairchild's version). I used the chip in an 8-pin package (called L272M); the same chip also comes in bigger 16-pin packages. The bigger packages dissipate heat better, so they can probably provide somewhat more power to motors.
The 9v power to the H-bridges should be provided by a battery box, which is connected to the circuit through a NXT-style connector and a converter cable. The 9v lego connectors are not polarized; when you connect a cable to a battery box, you never know whether which terminal on the other side of the cable will be positive and which will be negative. It depends on how you connected the cable and on which button is pressed on the battery box. This causes a problem in our circuit, because if we supply negative 9v to the H-bridge, it will destroy the L272. A simple solution is to connect a diode in series with the 9v battery, but this will cause a voltage drop across the diode and less power to the motors. I used a more sophisticated scheme that uses a P-channel MOSFET transsistor. In this configuration, the transistor behaves like a conductor when its drain is connected to a positive supply. But when the drain is connected to a negative supply, the transistor shuts off and prevents the negative voltage from reaching its source (and the sensitive chips beyond). I used a somewhat expensive MOSFET with a very low resistance when it is turned on (0.02Ω); low-cost MOSFETs have a larger resistance when they are on (so they deliver less power to the H-bridge), but they are still better than a diode. It's also fine to use a diode, especially a Schotky diode. But don't operate chips from a Lego battery pack without some polarity protection.
To give the user of the circuit a visual indication as to whether the battery is connected with the correct polarity, I included a LED. If the battery is connected properly, the LED lights. If not, no damage is caused, but the LED remains off so the user changes the polarity of the battery box (by pressing the other button on the box or by reversing the Lego 9v connector).
The inputs to the H-bridges are provided by a PCF8574, which is an I2C chip with 8 bidirectional digital ports. Each H-bridge is controlled by two digital outputs, so four input-output pins of the PCF8574 remain available. I connected each one of them to a 33K pull-up resistors and to a terminal on the PCB. These terminals can be fitted with a connector (an IDC connector or a header connector) and receive input from up to 6 switches (touch sensors).
As I mentioned above, I first built the motor controller (and the pressure sensor) on a solderless breadboard. So it is definitely possible to build it that way. It is also possible to solder the circuit on a prototyping board.
But I decided to build it on a PCB, to make it really usable in a Lego robot. I designed the PCB using Eagle CAD, a PCB-layout program that is free for non-commercial use (with some restrictions). It took me about 2 days to learn to use the software and to design the circuit. On the right you can see a printout of the design together with the resulting boards. The actual design file is available for download. I actually made a small mistake in the design; the ouputs of the opamp on the right side is connected incorrectly to pins 5 and 6 of the socket, not to pins 1 and 2. I will patch my board, but if you use the design file, you should fix this problem.
I decided to connect the motor controller to Lego parts using Lego-Technic compatible holes, a series of 6mm holes whose centers are 8mm apart. The whole board is exactly 72-by-72mm, or exactly 9 Lego units on each side. I borrowed this idea from the Lego Mindstorms add-ons produced by Mindsensors. Some people house their electronic circuits and sensors inside original Lego bricks; the resulting devices integrate well with Lego parts both mechanically and visually. I felt that (1) it will be difficult for me to build good Lego-like enclosures, (2) the Mindsensors method is mechanically sound, and (3) my devices integrate with Lego but they are not Lego, so it's fine if they don't look like Lego.
The company that produced my boards accepts Eagle files so I did not need to produce any production files; I just sent them the file that I created with Eagle. The boards, which are double-sided and have a solder mask (the green coating the covers everything except areas where you need to solder components), cost $50 to produce plus a small shipping fee. I ordered two boards (in case I ruined one; I didn't) but got four. It took about 3 weeks for them to arrive (about 1 week for production and 2 more in the mail).
When the boards arrived, I soldered the component onto one of them. I actually did this in phases, making sure that each circuit section worked as expected before continuing. For example, I first built the pressure-sensor section, then the MOSFET polarity protection, and so on.
I ordered the boards without a silkscreen (printing on the board, usually in white, to help identify components and connections) so I wrote some useful indentification information on the board with a fine permanent marker (actually, my wife did; she has a neater handwriting than me).
The main determinant of performance in this circuit is how low and how high the opamps' outputs can go. With a battery box supplying 7v, I measured the low-level and high-level ouputs of the opamps at 0.15v and 6.9v when a motor is not connected. When the opamps where driving the NXT motor, their outputs were 0.18v and 5.75v. So we are loosing almost 1.5v out of 7v on the opamps, thereby significantly reducing the power to the motors.
There are several alternatives to the L272, such as the SN754410. This chip is a quad half-H bridge, so one such chip can drive two motors (each half H-bridge is a bit like one of our opamps, except that it designed with a binary output and not as an amplifier). It is also rated at 1A, so it can provide similar power to the motors. It's ouputs, however, stay even further from the supply voltages, up to 2v from each rail. So it is not necessarily better than the L272 for battery-operated motors.
I am pretty sure that it is possible to build an H-bridge with very small voltage drops from discrete MOSFETs. I don't know if there are single-chip H-bridges whose ouputs can swing almost rail to rail. In fact, many motor controller chips are designed to drive MOSFETs, not to provide power to motors directly.
How can you provide a specific level of power to a motor? The usual way, which both the NXT and the RCX use, is to use pulse-width modulation (PWM). Software or a hardware circuit turns a motor on and off rapidely at a fixed rate. By changing the length of time that the motor is on within each period (the pulse width), we control the amount of power provided to the motor.
The circuit presented here cannot do this directly. We can use software to turn the motor on and off rapidely, which will give about 50% power (if we turn it on and off as fast as possible). It is also possible to build a circuit that will accept a power level from the NXT via I2C commands and will generate the appropriate PWM pulses for the H-bridges. One way to do this is to use a small microcontroller, and the second is to use a specialized PWM chip. Philo suggested using an I2C chip designed to dim LED's using PWM; this should be possible, but I have not tried it.
Processing and using the data coming back from the NXT servo motors to count rotations and to adjust power levels is possible (the NXT does it), but pretty difficult. Doing this in a useful way almost certainly requires a microcontroller. The circuit will not necessarily be much more complex than the circuit here (the microcontroller can essentially replace the PCF8574 and also process the tacho inputs), but the microcontroller would need to be programmed appropriately.
I am grateful for the assistance of several people in this project.
Thanks to Philo (Philippe Hurbain) and to Ezra Shaked for circuit ideas and critique.
Thanks to Nitin Patil of Mindsensors for providing the Eagle template for the NXT sockets.
Thanks to Adi Shmorak of Robotec Technologies (my local Lego Education distributor) for providing the converter cables.
The MOSFET polarity protection circuit was taken from a web page by R.G. Keen (the idea to use MOSFET for protection was suggested by Philo).
© 2007, Sivan Toledo