Forum Update - Announcement about May 10th, 2018 update and your password.

Question About Continuous Rotation Servos

Hello,

I am working on a balancing ActivityBot using the continuous rotation servos (not the new 360 feedback servos). Whenever the servos change direction they seem to pause for a brief time (this can also be seen in the output stream in the terminal). I think this pause is enough to cause problems tuning the controller and the robot falls over. Is this pause something that can be eliminated? By the way, I'm using the abdrive.h library. I don't know if the library could have something to do with it. Thank you.

Regards,
David

Comments

  • 19 Comments sorted by Date Added Votes
  • Sounds like a problem with your program as the servos slow then change direction. You'll need to post your source code. It's probably not the library, but can't tell without seeing how you call it.
  • Hi Mike,

    Here is the code I am using to call the servos:
    print("%f\n",phi*180/PI);
        
        //PI w/ rate feedback
        float Error=phi*180/PI-(-67);
        float Error_int=Error_int+Ts*Error;
        float servo=kp*Error+ki*Error_int-kd*gy;
        drive_speed(-servo,-servo);
    

    Please let me know what you think.

    David
  • Since the balancing is done outside any encoder loop do you even need to use the 360 servos for this? Typically you'd use a compact gearmotor with PWM drive, which is faster and more controllable. Servos are only updated at 50 Hz as it is (though you can change this in sofrware), which is considered on the low end for such a system.

    I realize you're using what you have, but it seems like you have a good idea hampered by a second choice for hardware. Mind you, I like these servos but what makes them special has little/no use in a balance robot.
  • I agree with Gordon. Just ignore the encoder feedback for this app.

    -Phil
    “Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away. -Antoine de Saint-Exupery
  • Hi Gordon and Phil,

    Thanks for your replies. I am using the continuous rotation servos with external optical encoders. How would I ignore the encoder information in the
    drive_speed(-servo,-servo);
    
    command?

    I am interested in trying the gear motors as Gordon suggests. What would be the best way to drive a PWM command in C?

    Thank you again.

    David
  • Use a different library, i.e. the one for the old-style CR servos.

    -Phil
    “Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away. -Antoine de Saint-Exupery
  • Hi Phil,

    I believe I am using the old library. I am using the abdrive.h library rather than the abdrive360.h library. Please correct me if I am wrong. I should be able to use the gear motors with the abdrive.h library to drive the PWM signal. Are there specific gear motors you would recommend for this application?

    Thanks,
    David
  • Instead of using abdrive, use the servo module. In it, there's a routine called servo_speed.

    -Phil
    “Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away. -Antoine de Saint-Exupery
  • Thank you. I will try the servo module.

    Regards,
    David
  • For a self-balancing robot you use inertial data -- typically an accelerometer and gyroscope -- to obtain the instantaneous vertical orientation and motion of your bot. Encoders can't provide any information related to "balance." These days, you can get very inexpensive multi-inertial sensors (IMU) for under $20. Most connect via I2C, and can very difficult to use without a library. They're commonly used in quadcopters, so Parallax likely has libraries for their versions for C.

    I haven't looked at the Prop BOE libraries in a while, but to control a PWM motor you send it pulses of a specific duty cycle and frequency. The basic servo drive is sorta kinda like PWM, but the frequency is much, much slower (50 Hz). Most DC motors want a frequency in the 1-5 kHz range, sometimes higher. Also, in PWM it's the amount of on-time versus off-time that's important. In a servo, the length of the pulse -- from 1 to 2 ms -- is all that matters.

    So, I don't think you can rely on the servo library unless you rewrite it. If you've got some spare cash, a motor driver with PWM control is a lot easier! It gives you PWM and provides an output stage for driving the motor from a microcontroller.

    I'm not sure if Parallax carries any of these, but Pololu, Sparkfun, and Adafruit do. They';re about $5 to $10. You're looking for a basic DC controller for two motors with I2C control. Something with a max 1-1.5 amp current output should about do it. The DRV8833 module is popular, and used on a number of boards. You'll find it on lots of cheap boards from eBay China (a couple bucks each).
  • Has anyone else on the forum built a balancing ActivityBot before? If so, I'm curious to read about it.
  • I purchased this motor controller:

    https://www.pololu.com/product/2135

    and two micro gear motors to drive my robot's wheels. Can the Parallax servo library be used with the motor controller to drive the motors or is there other code that is required?
  • So, I don't think you can rely on the servo library unless you rewrite it. If you've got some spare cash, a motor driver with PWM control is a lot easier! It gives you PWM and provides an output stage for driving the motor from a microcontroller.

    Would you be able to explain what the code would look like to run the motor driver?

    Respectfully,
    David
  • I don't use those libraries, so I don't know what's in them. I think there are more objects for the Propeller in Obex that use Spin -- the Prop has been out for over 10 years, so much of the user- contributed code is for that language. Maybe you could switch gears and do this as a Spin-based project?

    You may also find some examples in the BlocklyProp community site. You don't have to stick with blocks if you don't want to (though it's a robust environment in its own right). BlocklyProp creates PropC code in the background.

    I'm sure you're aware that a self-balancing robot is one of the most difficult projects to take on, even for experienced builders. Pololu sells a kit for a small balancing robot and they spend a long time writing the support libraries. I doubt they have libraries for the Propeller, but you could look at the C code for the Arduino version and see if you could port it over. It would be a tall job in any case.
  • Thanks Gordon. I've been able to get the motor to spin in one direction (when the values I'm sending are positive) but not the other. Here is my set up and code. Any ideas why it wouldn't be working in both directions?
    float Error=phi*180/PI;//-(-65);
        float Error_int=Error_int+Ts*Error;
        float servo=kp*Error+ki*Error_int-kd*gy*180/PI;
        
        // Add PWM control for motors
        pwm_start(100);
        
        if(servo < 0){
          pwm_set(3,1,servo);
        }
        else if(servo > 0){
          pwm_set(4,0,servo);
        }
    
  • [img][/img]
  • For some reason I cannot upload an image of my bread board setup.
  • It seems to be working now. All I had to do was add a negative sign when the input values are negative, since the PWM function can't take a negative value. I really hope I can get my robot balancing now with these motors.
    float Error=phi*180/PI;//-(-65);
        float Error_int=Error_int+Ts*Error;
        float servo=kp*Error+ki*Error_int-kd*gy*180/PI;
        
        // Add PWM control for motors
        pwm_start(100);
        
        if(servo < 0){
          pwm_set(3,1,-servo);
        }
        else if(servo > 0){
          pwm_set(4,0,servo);
        }
    
  • One other question I have though is what is the value between the pin number and the value you are sending in pwm_set(3,1,-servo)? In this case the value I am talking about is 1. What is that for and what does it mean?

    Thanks for all your help.

    David
Sign In or Register to comment.