Automatic Gearbox

A while back I was making some large LEGO vehicle of sorts, and I was faced with the choice of gearing down my motor or dedicating a whole extra motor to controlling a gearbox.

I chose to do neither, and build an automatic one. The ones I found where to big and relied on friction and differentials. After a few email exchanges and iterations, I arrived at this compact 2-gear automatic gearbox.

The gear has 2 sides, one with a 1:1 ratio, the other with a 12:20 slowdown.

When no torque is applied, the front lever is pressed onto the 1:1 chain by a rubber band, causing it to turn faster than the 12:20 side, and thus pushing the rear lever up.

When torque is applied, the front lever is pushed up by the force, and starts to slip, making the 12:20 chain turn faster, causing the rear lever to fall back into position.

Automatic Gearbox Building Instructions

LEGO TECHNIC Design School

I found some lost and forgotten Lego building lessons. I think you’ll love them.

Over at Lugnet, in an old thread, someone asked for tips and tricks about studless building(using smooth beams rather than the classic Lego bricks). Someone linked him to the “LEGO TECHNIC Design School”, which sounded really good, but unfortunately, the links where dead.

I searched, and searched, but LEGO just seems to have removed them. Are they to good for this world? Finally, I found them using the Wayback Machine. Enjoy!

Unfortunately, a few images are missing, but it’s still interesting to read.

Diagonal Connections

One thing they teach that I have not seen “in the wild” much are all sorts of diagonal connections, like this 1:2 gear ratio and right-angle connection.

It is possible to build all integer Pythagorean triangles, although few of them are practical.

It might at first be confusing to build a triangle with sides of 3, 4 and 5 in length using beams of 4, 5 and 6 of length, but think of it like this:

What would be the length of a dot? Zero, right? So when talking about LEGO units, a beam with one hole also has a length of zero. Start counting at zero, and it’ll all make sense.

Gamepad remote control

I had this pincer bot that I had not yet programmed, but using software remotes proved disappointing. With a few lines of code, I was able to use any gamepad or joystick to control the robot.

To use this code, you need to know how to execute commands on your computer. Then, do the following.

  1. Install Python if you don’t already have it.
  2. Install PyGame for interfacing with the gamepad.
  3. Install NXT-python for interfacing with the NXT.
  4. Make sure your NXT and gamepad are connected and working.
  5. Run
    python nxtjoy.py

    in the directory where you’ve downloaded the code below.

The code assumes you have the pincer bot in the video, for which I’ll give you instructions later. Moving around should work with most tank-steered robots.
import pygame
from nxt import locator, motor
from time import sleep

# edit this to reflect your joystick axis and buttons
axis = {'x':0, 'y':1}

b = locator.find_one_brick()

left = motor.Motor(b, motor.PORT_B)
right = motor.Motor(b, motor.PORT_A)
action = motor.Motor(b, motor.PORT_C)

closed = False

def limit(nr):
    if nr > 50 or nr < -50:
        return min(127, max(-128, nr))
    else:
        return 0

def move(fwd=0, turn=0):
    lp = int((fwd - turn) * -100)
    rp = int((fwd + turn) * -100)
    left.run(limit(lp))
    right.run(limit(rp))

def pincer(button):
    global closed
    try:
        if button and not closed:
            closed = True
            action.turn(-40, 70, emulate=False)
        elif not button and closed:
            closed = False
            action.turn(30, 70, emulate=False, brake=False)
    except motor.BlockedException:
        print action.get_tacho()

pygame.init()
j = pygame.joystick.Joystick(0) # first joystick
j.init()
print 'Initialized Joystick : %s' % j.get_name()
try:
    while True:
        pygame.event.pump()
        sleep(0.1)

        # get_axis returns a value between -1 and 1
        move(j.get_axis(axis['y']), j.get_axis(axis['x']))
        pincer(j.get_button(0))

except KeyboardInterrupt:
    j.quit()