Stepbotslast modified 27-APR-2000
Wouter van Ooijen (firstname.lastname@example.org)
I have build a number of stepbots: small PIC-controlled robot vehicles using stepper motors. The basic idea is to use two steppers which are directly connected to the front wheels, and a real wheel which can turn freely. The two steppers take care of the propulsion and steering. The steppers from old 5.25 disk drives are very practical, requiring 100 mA (per coil) at 12 Volt, which can be provided by 10 penlight NiCads. A 7805 regulator provides the 5 Volt required for the PIC 16f84 brain. A single ULN2803 interfaces the brain to the two stepper motors. I use either a 24 Volt wall wart to charge the NiCads and series resistor in the robot that selects the appropriate charge current, or a removeable NiCad pack.
5.25 inch diskdrives contain a number of different stepper motor types. You can find steppers with 4, 5 and 6 wires. The 4 wire types (often found in the more recent 5.25 drives) are bipolar and can not be used with the circuit described here. The 5 and 6 wire types are essentially the same. Use an multimeter to find the one (5 wire steppers) or two (6 wire steppers) common wire(s) that have a low resistance to other wires. For a 6 wire stepper connect the two commons together and you have a 5 wire stepper.
Now you must find out the stepping sequence. You can do this by hand, using a 12 V power supply (watch out for the spikes when you remove the power from a coil!), or by connecting the stepper to the robot circuit programmed for continous motion. In both cases you must find the correct sequence by trial and error, but you can keep one coil fixed, and from the remaining 8 possibilities two are OK (one for forward and one for backward motion).
The front wheels are taken from broken office chairs. These wheels are a bit difficult to take apart, but a combination of patience and some brute force will do the job. I drill a hole through the center of each half wheel which is a little bit smaller than the metal cylinder on the steppers' shaft and use some force to push it onto the shaft. A strip of self adhesive staircase grip paper around the wheels improves the grip on smooth undergrounds.
The real wheel is a swivel wheel, the kind used under office chairs and TV trolleys. It is important that the real wheel turns easily, which requires that it has a very small area of contact with the underground, and that this area is only a tiny bit (a few mm) behind its vertical axis. The wheel on the left picture is much better than the one on the right. An alternative real 'wheel' is a smooth sphere that simply sits beneath the real of the stepbot.
The brain of the robot is a Microchip PIC 16f84 microcontroller. This chip not very expensive, has enough horsepower for this simple control task and can be programmed quickly without removing it from its circuit. I use either a test clip directly on the chip, 2x3 pin header (one pin cut off as key) or a D15M connector as in-circuit programming interface. The electronics (16f84, crystal, 7805, ULN2803 and a few pin header connectors) can be build on a 2 x 3 cm breadboard.
Don't expect miracles from this simple hardware: it can crawl for an hour or so at its top speed of a few cm per second provided that the underground is smooth and level. The steppers deliver just enough power to move the vehicle, so it will not ride over any substantial obstacle. A toothpick in its path can be enough to block it.
The three stepbots shown below use essentially the same hardware. The first (left) one was build on a piece of wood using a solderless breadboard for easy modification. A battery pack can be put on its back. The middle one has its electronics (on a small PCB), the two steppers and a battery pack in a small gray case. Both use 12V steppers from 5.25 inch drives. The right one uses smaller 5V steppers from a small printer. It is not succesfull because the steppers do not deliver enough pull and I could not find a suitable rear wheel.
The essence of a simple Jal program to move the robot is shown below. The delay can be varied to find the minimal step interval which can start the robot. The library procedure stepper_motor_full_forward produces the sequence 0001, 0010, 0100, 1000. Similar procedures are available for half stepping and for stepping backward. The initial values can be changed to 0b_0011 to get a two coil sequence.
-- a robot that just rides at a constant speed include 16f84_10 -- define target include jlib -- standard libraries var byte left = 0b_0001 -- start of the stepper sequences var byte right = 0b_0001 -- " port_b_direction = all_output -- an input would not help us much forever loop -- stepper_motor_full_forward( left ) -- step both sides forward stepper_motor_full_forward( right ) -- " port_b_low = left -- output the new steps port_b_high = right -- " delay_1mS( 25 ) -- 25 mS delay between steps end loop
A more interesting but still very simple robot follows a line on a piece of paper. I use a black line on white paper. The line is approximately 5 mm wide. The robot is placed on the line before it is started. The main problem is to follow a line which bends abruptly. One sensor could be used, but this requires the robot to sweep left and right to keep locked onto the line. I used two (reflective) sensors.
-- a robot that follows a line using two sensors include 16f84_10 -- define target include jlib -- standard libraries var bit left dark at pin_a0 -- define IO pins var bit right_dark at pin_a1 -- " var byte left = 0b_0001 -- start of the stepper sequences var byte right = 0b_0001 -- " port_b_direction = all_output -- IO direction port_a_direction = all_input -- " forever loop -- if ! left_dark then -- when left sensor sees white stepper_motor_full_forward( left ) -- step left motor end if -- if ! right_dark then -- when right sensor sees white stepper_motor_full_forward( right ) -- step right motor end if -- port_b_low = left -- output the new steps port_b_high = right -- " delay_1mS( 25 ) -- 25 mS delay between steps end loop
Maze walking is more impressive than line following but also more difficult. (apart from the fact that you will also have to build a maze!). Any connected maze can be walked by following the wall with your left (or right) hand. Using switches to detect collision with a wall seems simple until you try it. A wall will always turn up at an unexpected angle, so a lot of switches are needed or a clever mechanism must allow a switch to be pushed from a wide range of angles. My robots do not have much power, so the switch must also be easy to push. I made a wide angle mechanism from a round piece of PCB material (I would have preferred a flippo but I could not find one). An obstacle in front or to the side of the robot will turn the circle around its axis, closing the switch. This works fine but the robot must keep close to the wall which makes a closed turn difficult and an irregular wall can lock the robot into a corner. A wire sensor like a cockroaches' antenna would probably not have these problems. The things on the picture below that look like Mickey Mouse ears are PCB pieces. The switches have been salvaged from an old VCR.
The most critical part of the software for my maze walker is the part which controls the turning, especially when it must turn left after it has hit its nose against a wall. The software uses feedback from the switches as often as possible to compensate for possible slip between the wheels and the surface. A turn right must not start too soon because the robot would get stuck against the edge of the maze (the sensor is in front of the turning axis of the robot). Apart from these two difficult turns the software just makes the robot follow the wall to its right side. When it senses the wall it steers away from the wall, when it does not sense the wall it steers (a little bit) to the right where it expects the wall. If the wall is lost for a significant time it turns to the right.
-- a maze-walking robot that follows the wall to its right side include 16f84_10 include jlib var volatile bit right_free is pin_a3 var volatile bit left_free is pin_a4 var volatile byte left_motor is port_b_low var volatile byte right_motor is port_b_high const byte stepper_initial = 0b_0011 var byte left_value = stepper_initial var byte right_value = stepper_initial port_b_direction = all_output port_a_direction = all_input procedure move( byte in left, byte in right ) is while ( left != 0 ) | ( right != 0 ) loop if ( left != 0 ) then if left < 128 then stepper_motor_full_forward( left_value ) left = left - 1 else stepper_motor_full_backward( left_value ) left = left + 1 end if end if if ( right != 0 ) then if right < 128 then stepper_motor_full_forward( right_value ) right = right - 1 else stepper_motor_full_backward( right_value ) right = right + 1 end if end if left_motor = left_value right_motor = right_value delay_1mS( 25 ) end loop end procedure var byte n = 0 forever loop -- frontal hit : turn left if ! left_free then -- move back to get free from the wall move( -100, -100 ) -- turn a little bit left move( 0, 30 ) for 3 loop -- forward until right sensor hits while right_free loop move( 1, 1 ) end loop -- a little bit back to get free from the wall move( -10, -10 ) -- turn right until left sensor hits while left_free loop move( 1, 0 ) move( 1, -1 ) move( 1, 0 ) end loop -- retreat to make toom for the turn left move( -90, -90 ) -- turn left move( -30, 30 ) end loop -- retreat to make toom for the turn left move( -15, -15 ) -- turn slowly left until right sensor hits for 75 loop move( 1, 3 ) end loop -- hit right wall elsif ! right_free then -- remember & steer away n = 0 move( 1, 2 ) -- free on both sides elsif ( n < 120 ) then -- turn a little to the right n = n + 1 if ( n & 3 ) == 0 then move( 1, 0 ) else move( 1, 1 ) end if -- definitely lost the wall else -- turn right sharply move( 1, -1 ) end if end loop
The Mickey Mouse robot can walk a maze by following the wall to its right side, but it has its problems. It can get stuck in a corner, it sometimes thinks it must turn right when it actually just wandered a little bit from the wall, and it must make some strange moves to make a left turn (when runs into a wall). This is largely due to the relatively large distance between the front wheels and the real wheel. But it works! Below you can see it crawling its way through a maze. The cloth is needed because the wheels do not get enough grip on my wooden floor. My cats don't know what to think of this oversized mouse.$LEGAL