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

Inserting code which still doesn't work though:

#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
C3 = 20     #LED for testing only...

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


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


def setPosition(position):
    pwm1.stop()
    pwm2.stop()

    if position == -7:
        pwm1.start(100)
    elif position == -6:
        pwm1.start(88.2)
    elif position == -5:
        pwm1.start(76)
    elif position == -4:
        pwm1.start(63.5)
    elif position == -3:
        pwm1.start(50.1)
    elif position == -2:
        pwm1.start(38)
    elif position == -1:
        pwm1.start(25.8)
    elif position == 0:
        pwm1.start(0)
    elif position == 1:
        pwm2.start(25.8)
    elif position == 2:
        pwm2.start(38)
    elif position == 3:
        pwm2.start(50.1)
    elif position == 4:
        pwm2.start(63.5)
    elif position == 5:
        pwm2.start(76)
    elif position == 6:
        pwm2.start(88.2)
    elif position == 7:
        pwm2.start(100)

#Moving the Servo through its 15 positions
for i in range(-7, 8, 1):
    print 'Position: ' + str(i)
    setPosition(i)
    sleep(2)

#Testing the commands with a LED
try:
    pwm3.start(0)
    while True:
        for i in range(100):
            pwm3.ChangeDutyCycle(i)
            sleep(0.02)
        for i in range(100):
            pwm3.ChangeDutyCycle(100-i)
            sleep(0.02)
except:
    pass


pwm1.stop()
pwm2.stop()
pwm3.stop()
GPIO.cleanup()
  • Have you a link to the specs for the servo you are using? Given that it has an extra (control?) wire it is not standard so speculation without details is pretty pointless. – joan Dec 29 '14 at 10:00
4

Assuming https://www.youtube.com/watch?v=ArEt9RWPbhE is correct the servo is not controlled as a servo with 50Hz updates and 1-2 ms pulses.

Apply PWM to C1. C2 should be 0 for counterclockwise and 1 for clockwise.

The Arduino standard PWM (from memory) is about 400 Hz with 0 being off and 255 being fully on.

Try that with the software you have.

Power Functions Servo Motor turn through the 15 positions corresponding to the duty cycle of Arduino PWM signal:

Position -7 Duty Cycle: 100%, analogWrite(): 255, C1: +, C2: - (90 degrees counter-clockwise)
Position -6 Duty Cycle: 88.2%, analogWrite(): 225, C1: +, C2: -
Position -5 Duty Cycle: 76.0%, analogWrite(): 194, C1: +, C2: -
Position -4 Duty Cycle: 63.5%, analogWrite(): 162, C1: +, C2: -
Position -3 Duty Cycle: 50.1%, analogWrite(): 128, C1: +, C2: -
Position -2 Duty Cycle: 38.0%, analogWrite(): 97, C1: +, C2: -
Position -1 Duty Cycle: 25.8%, analogWrite(): 66, C1: +, C2: -
Position 0 Duty Cycle: 0%, analogWrite(): 0 (center)
Position 1 Duty Cycle: 25.8%, analogWrite(): 66, C1: -, C2: +
Position 2 Duty Cycle: 38.0%, analogWrite(): 97, C1: -, C2: +
Position 3 Duty Cycle: 50.1%, analogWrite(): 128, C1: -, C2: +
Position 4 Duty Cycle: 63.5%, analogWrite(): 162, C1: -, C2: +
Position 5 Duty Cycle: 76.0%, analogWrite(): 194, C1: -, C2: +
Position 6 Duty Cycle: 88.2%, analogWrite(): 225, C1: -, C2: +
Position 7 Duty Cycle: 100%, analogWrite(): 255, C1: -, C2: + (90 degrees clockwise)

EDITED TO ADD

I think I have misinterpreted what the table above was saying.

I now think it may mean

C2=0, PWM on C1 for counterclockwise.
C1=0, PWM on C2 for clockwise.

Suck it and see.

  • Cheers, if you get a chance add the details to your post if you got it to work. – joan Dec 29 '14 at 17:51
  • Hi Joan. I have just created to code but unfortunately it is not working. :-( Would you mind taking a look to check what I am missing? (I have edited my question with the code) Thanks! – user22948 Dec 30 '14 at 21:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy