Shop OBEX P1 Docs P2 Docs Learn Events
sending pulse width signals to an HB-25 in Propeller C — Parallax Forums

sending pulse width signals to an HB-25 in Propeller C

doug.taylordoug.taylor Posts: 31
edited 2014-02-25 16:58 in Learn with BlocklyProp
I haven't found in the forums an example of sending pulse width signals to an HB-25 in Propeller C.

Doug

Comments

  • SRLMSRLM Posts: 5,045
    edited 2014-02-24 09:41
    Well, since nobody else has replied I'll respond with my slightly off-topic solution. libpropeller has two C++ PWM solutions. The first, PWM2, runs in the background of a cog using the cog counters. PWM2 can control up to two PWM channels. The second, PWM32, runs in it's own cog and can control up to 32 channels. These are written in C++, but with some effort you could convert them to C. I hesitate to mention this solution only because it's C++ and not C like you had asked for.

    Another option is to use spin2cpp to convert a Spin PWM object to C.

    You may also want to browse the learn libraries. You can find some servo control code here that might work.
  • edited 2014-02-24 09:42
    The HB25 is designed to take servo signals, so you can use the servo library. It has a feature for continuous rotation servos that controls speed. Here is an example that sends servo signals to an HB25 connected to P14. The current servo library incarnation launches servo code into another cog that can control up to 14 servos. So, if you have another one connected to P15, you can start adding servo_speed(15, speed) calls, no problem.
    #include "simpletools.h"   // Library includes
    #include "servo.h"
    
    int main()
    {
      servo_speed(14, 250);    // Full speed one direction
      pause(3000);             // ...for 3 seconds
      servo_speed(14, 0);      // Stop
      pause(1000);             // ...for 1 second
      servo_speed(14, -250);   // Full speed other direction
      pause(3000);             // ...for 3 seconds
      servo_speed(14, 0);      // Stop
    }
    
  • Ken GraceyKen Gracey Posts: 7,387
    edited 2014-02-24 09:48
  • doug.taylordoug.taylor Posts: 31
    edited 2014-02-25 09:01
    SRLM wrote: »
    Well, since nobody else has replied I'll respond with my slightly off-topic solution..

    SLRM, thanks for the reply. I appreciate ANY reply so don't be shy. Your approach using the C++ solutions looks promising, but I'd like to try the path that Andy suggested first since it is more out-of-the-box. If it doesn't work, I'll revisit this.
    The HB25 is designed to take servo signals, so you can use the servo library. It has a feature for continuous rotation servos that controls speed. Here is an example that sends servo signals to an HB25 connected to P14. The current servo library incarnation launches servo code into another cog that can control up to 14 servos. So, if you have another one connected to P15, you can start adding servo_speed(15, speed) calls, no problem.]

    Andy, Thanks for the reply. I had gone down this path and could not get it to work. One of my test programs looked just like your sample but when I ran it the HB-25 never put any voltage out of the motor leads. Then out of desperation I copied your code over mine and behold, it worked. Now I can't go back to mine to see what I was doing wrong. It must have been something stupid.

    By the way, I could never get servo_setramp() or servo_get() to do anything. Should these work in continuously rotating servos like that which the HB-25 emulates?

    Thanks,
    Doug
  • edited 2014-02-25 16:58
    Doug,

    Thanks for the update, that's great news.

    I usually let my program run for a few seconds to make sure the servo pulses are present before turning on the HB25 power. If the HB25 wakes up and sees control pulses immediately, it will work. If it does not see control pulses, it has a built-in safety feature that makes it unresponsive until you restart with control pulses applied.

    Not sure, but maybe the HB25 was already not responding by the time you tried out the program that matched mine. Maybe the power-up sequence was more favorable the second time around.

    The servo_setramp function is a way to set the largest change in angle/speed per 20 ms. It defaults to 2000 (no limit). If you reduce it and then set your servo for a significant speed, change, the resulting change should be slow instead of sudden. You only need to set it once.

    The servo_get function should tell you the current setting, in pulse width microseconds. So, int pulse = servo_get(14) should give you the pulse width of the servo signal going to P14. That should be 1500 + speed.

    Here is a program that sets the ramp step to 1 us/20 ms, then very slowly goes from 0 to +500. It uses servo_get to get the current pulse width, and displays it with print. The pulse width should run from 1500 to 2000 in steps of 1 per 20 ms. The samples are taken every 100 ms (plus serial communication time, so slightly slower), so they should increase by about 4 or 5 per measurement. Your motor speed may stay at 0 and then suddenly start turning because DC motors will stay still up to a point, and then start turning.

    After the loop gets to 2000, another setramp call changes the ramp step to 10 us/20 ms, and so the speed change will be a little quicker, but still comparatively gradual.

    Andy
    #include "simpletools.h"        // Library includes
    #include "servo.h"
    
    int main()
    {
      servo_speed(14, 0);           // Get servo running
      servo_setramp(14, 1);         // Ramp step -> 1us/20ms
      servo_speed(14, 500);         // Full speed one direction
    
      int pulse = 1500;             // Var for pulse width
      while(pulse < 2000)           // While pulse < 2000
      {
        pulse = servo_get(14);      // Get the current pulse
        print("%c pulse = %4d ",    // Display it
               HOME,      pulse);
        pause(100);                 // Wait 1/10 s to repeat
      }
      servo_setramp(14, 10);        // Ramp step -> 10us/20ms
    
      servo_speed(14, 0);           // Stop
      pause(1000);                  // ...for 1 second
      servo_speed(14, -500);        // Full speed other direction
      pause(3000);                  // ...for 3 seconds
      servo_speed(14, 0);           // Stop
    }
    
Sign In or Register to comment.