Shop OBEX P1 Docs P2 Docs Learn Events
Where the *BLEEP* is that extra blip coming from? — Parallax Forums

Where the *BLEEP* is that extra blip coming from?

John KauffmanJohn Kauffman Posts: 653
edited 2014-01-31 10:34 in Propeller 1
I'm experimenting with control of servo by pulse_out instead of servo.h
As check of hardware, program first tests circuit with three uses of servo.h - no problem
Then real test: while() loop sending centering pulse to servo - but servo chatters.

#include "servo.h"
#include "simpletools.h"
int main(void)
{
servo_angle(14, 0); // for 0 degrees (far CCW)
pause(1000);
servo_angle(14, 900); // for 90 degrees (middle)
pause(1000);
servo_angle(14, 1800); // for 180 degrees (far CW)
pause(1000);

while(1){ //loop is creating two pulses. why ???
pulse_out(14,1500);
pause(20);
}
return 0;
}

I ran the propscope on the servo pin and I'm getting attached shot during while() loop.
Servo Pulse_Out makes 2 pulses.jpg

When goes into loop I'm getting *two* pulses per cycle. First is as expected, 1.5 mSec.
Then there is a .5 mSec low and a .5 mSec high again.

Where is that second pulse coming from?

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-01-31 08:22
    My guess if because both the servo_angle function and the pulse_out function are pulsing the pin. The two pulses are interfering with each other?

    Doesn't the servo_angle continue to pulse unless turned off?

    Edit: I probably typed too soon. I don't know enough about these functions to be much help.
  • John KauffmanJohn Kauffman Posts: 653
    edited 2014-01-31 08:36
    Duane:
    Sounds perfectly logical, thanks.
    Adding this worked: servo_stop();
    Adding this caused compile error of to many args: servo_stop(14); so I'll have to figure out how to stop each servo if several are running
    Again, thanks for seeing what I missed.
  • JonnyMacJonnyMac Posts: 9,107
    edited 2014-01-31 08:42
    The first part of your program is registering pin 14 with the servo driver that is running in one cog while you're accessing the same pin with pulse_out in another.

    Add this before the loop:
    servo_set(14, 0);
      pause(20);
    


    The value 0 disconnects the servo pin from the background driver; the pause(20) allows the servo driver to refresh and disconnect the pin.

    Edit: the servo_stop() function shuts down the driver -- all running servos would be affected. Use servo_set() with 0 if you want to do something else with a pin while other servos continue to run in the servo driver.
  • John KauffmanJohn Kauffman Posts: 653
    edited 2014-01-31 09:10
    Got it, thanks Jon
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-01-31 10:34
    I'm not familiar with the servo driver, but I looked at servo.c in SimpleIDE\Learn\Simple Libraries\Motor\libservo, and it contains the following routine:
    void servo(void *par)                         // Servo process in other cog
    {
      ...
      while(1)                                    // Servo control loop
      {
        while(lockset(lockID));                   // Set the lock 
        for(i = 0; i < s; i++)                    // Go through all possible servos
        {
        ...
          if(p[i] != -1)                          // If servo entry in pin array
          {
            int tPulse =  t[i];                   // Copy requested position to var
            ...
            pulse_out(p[i], tPulse);               // Send pulse to servo
            tp[i] = tPulse;                       // Remember pulse for next time
          }
        }
        lockclr(lockID);                          // Clear the lock
        wait(20000);
      }
    }
    
    I edited out some of the code to highlight the important parts. The first time you call servo_angle it starts up a cog running the servo function. The servo function runs in an infinite loop calling pulse_out for each pin that has been specified by calls to servo_angle. Once you call servo_angle you don't have to call it again unless you are changing the angle. So after you call servo_angle(14, 1800) the servo driver will continue to pulse pin 14 every 20 msec. When you call pulse_out(14,1500) in the loop in your main routine you are generating a second pulse.
Sign In or Register to comment.