HB-25 Motor Controller - how to slow down motor?

Hello all,

Does anyone have any experience using the HB-25 motor controller? I can't seem to figure this thing out. I need to slow my DC motor down considerably, but not limit the torque.

HB-25 Documentation

I've tried two methods of programming my arduino. The documentation suggests pulse width modulation w/ pulsewidth between .8 and 2.2 ms. If I use the digitalWrite function to set the output pin to high and then low, I can get the motor to turn at full speed one direction and then full speed the other direction. If I recall correctly, it changes direction when I make the pulsewidth greater than 1.9ms. Overall, this operation is thoroughly confusing and doesn't give me the desired speed control.

I've also tried using the servo library. I can use the myservo.Write command (like in the servo sweep example) to change the speed and direction. That being said, it doesn't work for the full range from write(0) to write(180). If I use values around 70 and 110, I can slow the motor down -- but it seems to suffer a severe drop in torque.

Any suggestions or input would be much appreciated.

Thanks,
Scott

I need to slow my DC motor down considerably, but not limit the torque.

Maximum torque for a DC motor is at 0 rpm.

The documentation suggests pulse width modulation w/ pulsewidth between .8 and 2.2 ms.

Without knowing the PWM frequency, it is difficult to calculate the duty cycle. Without knowing the duty cycle, hard to say what the motor might be doing.

You haven't said what sort of motor it is, but I'm dreading that you're talking about an ex-servo.

I'm familiar with the torque/rpm curves for DC motors, but i'm certain that the output torque is considerably lower when I use the servo Write function to slow the motor down. I haven't measured it or anything, but it takes very little effort to stall the motor (using my hand) at this speed. Perhaps this is just an inherent result of how the write function operates... I'm not sure.

I can get a specific model number later this evening, but I do know that it's a DC 1/30 hp gearhead motor.

The pwm frequency would be dictated by the delay between pulses, correct? From what I've experimented with, changing the delay either has no affect on the speed or causes it to not work at all.

Thanks for the help so far.

-Scott

when I use the servo Write function to slow the motor down.

Are you sure you're not using a modded servo?

Using a PWM controller at the sort of mark/space ratios used for R/C servos for an ordinary DC motor means that the motor isn't powered for about 90% of the time - it isn't surprising it hasn't got much torque.

The motor is a Dayton 1l475, 12V 3.5A 1/30hp DC motor. Link.

It's probably worth clarifying that the drop in torque occurs only when I use the servo Write function. This is the only method I have found to slow the motor down.

If I use the digitalWrite functions... which is probably closer to how the HB25 is supposed to operate... I get full speed one direction, and full speed the other direction. In this case, even though it's running at a higher rpm, the motor seems to be putting out a much larger torque.

If anyone has ever used the HB25 to change the direction and speed of a DC motor, I'd love to see some sample code.

Thanks,
Scott

It's probably worth clarifying that the drop in torque occurs only when I use the servo Write function

Now I'm really confused - why are you using servo functions for a DC motor?
Why aren't you using analogWrite?

If I use the digitalWrite functions... which is probably closer to how the HB25 is supposed to operate... I get full speed one direction, and full speed the other direction

Well, no surprise there.

Everything I read elsewhere says the HB25 behaves like a servo. I couldn't get the PWM code to give me any sort of speed control, so I gave the servo library a try. I'll play around with analogWrite once I get a chance.

Sorry for my ignorance on these topics. I have very little experience with electronics, this is all a learning process for me.

Edit:
Also, I haven't tried analogWrite because the sample code I started with used the digitalWrite function.
My initial attempts were based off of this topic.
I'll try analogWrite shortly.

Thanks,
Scott

Everything I read elsewhere says the HB25 behaves like a servo. I couldn't get the PWM code to give me any sort of speed control, so I gave the servo library a try.

Really confused now.
If you thought it behaved like a servo (50Hz PPM), why write PWM (490 Hz PWM) to it?

Let's forget the stupid things I've already tried. I didn't just want to make a post saying "hey, how do I make the hb25 work, thanks, bye!" so I shared some of my attempts thus far.

From the HB25 documentation, Mode 1 Communication:

"In this mode, a single pulse value sent to the HB-25 can control the HB-25; no “refreshing” is necessary,
as is the case with a servo. For compatibility however, you may send the HB-25 pulses every 20 ms just
like a servo and it will function the same.
There is a hold-off time of 5 ms where the HB-25 will ignore incoming pulses. As a result, the unit should
not be refreshed more frequently than about 5.25 ms + pulse time. Pulse time can be anywhere from
0.8 ms to 2.2 ms. If the HB-25 receives a pulse outside of this range, it will temporarily shut off the
motor until it receives a valid pulse."

Here's what I know:
-Previous posts in the old Arduino forum show people using digitalWrite for time intervals in the .5 to 2 ms range. These same individuals were complaining of less than ideal functionality.
-Posts in other forums always say the HB25 behaves like a servo. To quote the parallax forums: "And the HB-25's input pulse is 1-2ms, just like a servo. 1.5 ms is center. The only difference between managing an HB-25 and a servo is that the HB-25 doesn't need continual pulses every 15-30 ms - only when you want to change the motor speed: set it and forget it."

Also: "As mentioned in your other thread, the speed is set by the width of the control pulse. The stop position is a pulse width of 1500us. The further away the pulse width is from 1500us, the faster the motor will go (up to about 1000us or 2000us). The fastest movement in one direction is with a pulse width of 1000us and in the other direction with a pulse width of 2000us. With the BS2, this corresponds to a "PULSOUT ,500" or a "PULSOUT ,1000" respectively. "

I'm not getting any sort of speed change when I vary the input pulsewidth, and I'm pretty sure my direction change wasn't occurring at 1.5ms. It sure seems like I picked the wrong motor controller to work with...

Thanks,
Scott

Well, I actually have RTFM and it clearly states the HB-25 motor controller operates just as if it is a continous rotation servo. :roll_eyes: That being said, I suggest the servo library be used to control it. Below is some servo test code that should allow the motor setup to be checked out. As to the torque issue, with this type of motor setup the motor rotation speed is load dependent. If more torque is needed at a low speed, the on duration of the pulse to the h-bridge in the motor controller needs to lengthened. With this motor controller this would be accomplished by sending servo control pulses (PPM) that are increasingly distant from the neutral 1500us servo control value.

// zoomkat 10-4-10 serial servo test
// type servo position 0 to 180 in serial monitor
// for writeMicroseconds, use a value like 1500
// for IDE 0019 and later
// Powering a servo from the arduino usually DOES NOT WORK.

String readString;
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);
  myservo.writeMicroseconds(2000); //set initial servo position if desired
  myservo.attach(7);  //the pin for the servo control 
  Serial.println("servo-test-21"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(1);  
    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
    } 
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string 
    int n;
    char carray[6]; //converting string to number
    readString.toCharArray(carray, sizeof(carray));
    n = atoi(carray); 
    myservo.writeMicroseconds(n); // for microseconds
    //myservo.write(n); //for degees 0-180
    readString="";
  } 
}

Stebes did you solve your problem?
I need some advice please.
Thanks

Stebes did you solve your problem?

Stebes didn't even clearly DEFINE the problem.

I need some advice please.

Wear a hat when it is cold out.
Wear sunscreen when it is sunny.

If you narrow your request a little, the advice you get might even come somewhere close to being useful.

NVM
Better stop here and solve the problem by my self... as usual.