6

I am able to control a simple servo motor such as SG90 by using pulse-width modulation. However when it comes to controlling a 88004 LEGO Servo Motor it is simply a nightmare.

By using PWM all I managed was bringing it to its normal position. It seems the pulse length doesn't play a role at all - I've tried several ones...

Another difference between a SG90 and a 88004 is that the first has only three wires (PWR, GND and Control) whereas the LEGO servo has 4 (PWR, C1, C2 and GND).

  • Which of those wires (C1 and C2) should be used with the PWM?
  • How long should the pulses be to move the motor through its 15 positions?
  • Is there another way to control a 88004 directly from the Raspberry Pi such as I2C?
EDITED

It works!

#Importing the necessary library
import RPi.GPIO as GPIO
from time import sleep

#Reference by GPIOs IDs
GPIO.setmode(GPIO.BCM)

#Assigning the GPIOs to the Lego's command wires
C1 = 21
C2 = 26
moveFactor = 14.285714286

#Setting up the necessary GPIOs
GPIO.setup(C1, GPIO.OUT)
GPIO.setup(C2, GPIO.OUT)

#Setting up the PWMs - (GPIO ID, Frequency)
pwm1 = GPIO.PWM(C1, 1200)
pwm2 = GPIO.PWM(C2, 1200)


def setPosition(position):
    pwm1.stop()
    pwm2.stop()
    i = round(position * moveFactor, 2)

    if position >= 0:
        print 'Position: ' + str(position) + ' at a Duty Cycle of ' + str(i)
        pwm1.start(i)
    else:
        print 'Position: ' + str(position) + ' at a Duty Cycle of ' + str(i*-1)
        pwm2.start(i*-1)

#Testing the commands with a LED
try:
    setPosition(-7)   #180 Degrees
    sleep(2)
    setPosition(7)    #0 Degree
    sleep(1)
except:
    pass

pwm1.stop()     # Back to the normal position (90 degrees)
pwm2.stop()
GPIO.cleanup()
1
  • Did you need to raise the voltage levels to 5v or 9v, or were you able to control it via 3v3 directly from the pi? Commented Jul 16, 2015 at 22:32

1 Answer 1

9

LEGO "Servo Motor" has little to do with a RC servomotor. To drive it, you need to:

  • Power it at 9V (probably works at 5 volts, but with less torque) through PWR/GND terminals
  • To move in one direction, send a PWM signal (1200 Hz, 0 to 100% duty cycle) on C1 and keep C2 at GND level. As duty cycle varies, servo motor will move along 7 positions on one side. See this video.
  • To move in the other direction and reach the 7 other positions, send PWM to C2 and keep C1 at ground level.
5
  • Thank you very much Philo. Just another question from someone who has very limited physics knowledge. What exactly do you mean by "0 to 100% duty cycle"? Would you be so kind and write a very simple algorithm? Thank you!
    – user4343
    Commented Dec 29, 2014 at 17:27
  • The duty cycle percentage is the ratio between powered time over cycle period. Eg. here, a 30% duty cycle at 1200 Hz means 250µs on / 583µs off.
    – Philo
    Commented Dec 30, 2014 at 15:20
  • Hi Philo. Thanks for your replay. I just created a code in Phyton based on your explanation (see the edited question) but unfortunately it still does not work. Would you help me by reviewing it and making the necessary adjustments? I would be very thankful for that.
    – user4343
    Commented Dec 30, 2014 at 20:11
  • Problem is that I am not Python savvy... Might be a physical interface problem too?
    – Philo
    Commented Jan 1, 2015 at 18:05
  • As best I can tell the above instructions are correct, but I couldn't get my servo to go to any position other than -90/0/90, no matter what PWM duty cycles I used. It turns out that my cheap 88004 clone motor for aliexpress only has 3 positions, so it's not 100% compatible. A bit disappointing but it was cheap & does work for some applications...
    – Tom
    Commented Feb 3 at 11:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.