HCMotor Arduino library for driving DC and stepper motors.

Useful guides, libraries, and example sketches to support our Arduino based products.
admin
Site Admin
Posts: 865
Joined: Sun Aug 05, 2012 4:02 pm

HCMotor Arduino library for driving DC and stepper motors.

Post by admin » Fri Jul 10, 2015 3:05 pm

Image


Image

This Arduino library (current only supports ATMega328p based Arduinos) will allow you to control one or more DC or stepper motors from you Arduino. The library makes use of the Arduinos hardware interrupt timer 2 to drive the motors in the background leaving your sketch totally free for you main program. It also allows you to mix motor types and connect them to any available digital pins (you are not limited to just PWM pins). You can simply add motors by using the libraries 'Attach' function and remove them using the 'Detach' command. You can also mix supported motor types. Current supported motor types are as follows:

DCMOTOR - A standard DC type motor driven via a transistor or driver module.

DCMOTOR_H_BRIDGE - A standard DC motor connected via a H-Bridge driver module allowing for forward and reverse directions.

STEPPER - A stepper motor connected via a standard stepper motor driver (Step/CLK & Direction)


You will need to download (please log in to download the library) and unzip this library to the Arduino development environments library area.

On Windows:
My Documents\Arduino\libraries\

On Mac:
Documents/Arduino/libraries/
or similarly for Linux.


Changing the maximum number or motors:

By default this library can drive up to 4 motors. However this can be increased by editing the following line in the libraries HCMotor.h file:

Code: Select all

#define MAXMOTORS 4


If you are using less than 4 motors and your sketch is processor intensive you may also want to reduce this value to match the number of motors you have attached as this will free up processing cycles for your main loop.



Using the library

To use the library just include the HCMotor.h header file and then create an instance of the library. E.g:

Code: Select all

#include <HCMotor.h>
HCMotor HCMotor;

To initialise the library place the following line in the Setup() loop at the top of the sketch:

Code: Select all

HCMotor.Init();

The following functions are available with this library:

Code: Select all

HCMotor.Attach(MotorNum, MotorType, Pin);
Attaches a PWM output for a standard DC motor where:
MotorNum is a value used to reference which motor you wish to attach. Valid values are between 0 and MAXMOTORS. Default maximum is 4.
MotorType is the type of motor being attached. Currently only one valid value (DCMOTOR see alternate version below for other motor types)
Pin is the digital pin to attach it to (this can be any digital pin, not just the hardware PWM pins)


Code: Select all

HCMotor.Attach(MotorNum, MotorType, PinA, PinB);
Attaches a PWM output for a standard DC motor with H-bridge driver or a stepper motor where:
MotorNum is a value used to reference which motor we wish to attach. Valid values are between 0 and MAXMOTORS. Default maximum is 4.
MotorType is the type of motor being attached. Valid values are DCMOTOR_H_BRIDGE or STEPPER
PinA PinB are the digital pins to attach it to. For a stepper motor PinA is the clock pin and PinB is the direction pin.


Code: Select all

HCMotor.detach(MotorNum);
Removes an attached motor from the list and sets its pin(s) to inputs where: MotorNum is a value used to reference which motor we wish to detach.


Code: Select all

HCMotor.OnTime(MotorNum, Time);
Sets the on part of the duty cycle for DC motors where:
MotorNum is a value used to reference which motor we wish to alter.
Time is the amount of the duty cycle the motor will be on for in 100uS increments.

Note that for steppe motors the function does nothing.


Code: Select all

HCMotor.DutyCycle(MotorNum, Time);
For DC motors sets the duty cycle length, for stepper motors the clock speed, where:
MotorNum is a value used to reference which motor we wish to alter.
Time is the duty cycle time in uS. For stepper motors this sets the clock speed.


Code: Select all

HCMotor.Direction(MotorNum, Direction);
Sets the direction of the motor for H-Bridge and stepper motors where:
MotorNum is a value used to reference which motor we wish to alter.
Direction is the direction of the motor. Valid values are FORWARD & REVERSE

For H-Bridge motors this will switch the pin the PWM is output to and the sets the opposite pin low.
For stepper motors the will set the direction pin (PinB) high or low.


Code: Select all

HCMotor.Steps(MotorNum, Steps);
Sets the number of steps (pulses) to step a stepper motor where:
MotorNum is a value used to reference which motor we wish to alter.
Steps is the number of steps to step the motor.

Note that for DC motors this function does nothing.



Image


DC Motor Example

Code: Select all

/* FILE:    HCMotor_DC_Motor_Example
   DATE:    09/07/15
   VERSION: 0.1
   AUTHOR:  Andrew Davies

   
This example uses the library to control a DC motor via a potentiometer connected
analogue pin A0. The motor should be connected to digital pin 7 on the Arduino 
via a suitable transistor/driver module. Do not connect the motor directly as you
may damage your Arduino.

You may copy, alter and reuse this code in any way you like, but please leave
reference to HobbyComponents.com in your comments if you redistribute this code.
This software may not be used directly for the purpose of selling products that
directly compete with Hobby Components Ltd's own range of products.

THIS SOFTWARE IS PROVIDED "AS IS". HOBBY COMPONENTS MAKES NO WARRANTIES, WHETHER
EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ACCURACY OR LACK OF NEGLIGENCE.
HOBBY COMPONENTS SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR ANY DAMAGES,
INCLUDING, BUT NOT LIMITED TO, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY
REASON WHATSOEVER.
*/


/* Include the library */
#include "HCMotor.h"

/* Set the pin that will control the motor. Note that it doesn't have to be a PWM pin - 
   any digital pin will do! */
#define MOTOR_PIN 7

/* Set the analogue pin the potentiometer will be connected to. */
#define POT_PIN A0

/* Create an instance of the library */
HCMotor HCMotor;


void setup() 
{
  /* Initialise the library */
  HCMotor.Init();

  /* Attach motor 0 to digital pin 7. The first parameter specifies the 
     motor number, the second is the motor type, and the third is the 
     digital pin that will control the motor */
  HCMotor.attach(0, DCMOTOR, MOTOR_PIN);

  /* Set the duty cycle of the PWM signal in 100uS increments. 
     Here 100 x 100uS = 1mS duty cycle. */
  HCMotor.DutyCycle(0, 100);
}



void loop() 
{
  int Speed;

  /* Read the analogue pin to determine the position of the pot. The map 
     function takes this value which could be anywhere between 0 - 1024 
     and reduces it down to match the duty cycle range of 0 - 100 */ 
  Speed = map(analogRead(POT_PIN), 0, 1024, 0, 100);
  
  /* Set the on time of the duty cycle to match the position of the pot. */
  HCMotor.OnTime(0, Speed);
}


DC Motor With H-Bridge Driver Example

Code: Select all

/* FILE:    HCMotor_DC_Motor_With H_Bridge_Example
   DATE:    09/07/15
   VERSION: 0.1
   AUTHOR:  Andrew Davies

   
This example uses the library to control a DC motor via a potentiometer connected
analogue pin A0. With this example the motor is connected to the Arduino via a standard 
H-Bridge driver module such as HCMODU0033 or HCARDU0013 to allow the motor to be driven in 
both forward and reverse directions. 

Do not connect the motor directly to your Arduino's digital pins as you may damage your 
Arduino.

You may copy, alter and reuse this code in any way you like, but please leave
reference to HobbyComponents.com in your comments if you redistribute this code.
This software may not be used directly for the purpose of selling products that
directly compete with Hobby Components Ltd's own range of products.

THIS SOFTWARE IS PROVIDED "AS IS". HOBBY COMPONENTS MAKES NO WARRANTIES, WHETHER
EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ACCURACY OR LACK OF NEGLIGENCE.
HOBBY COMPONENTS SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR ANY DAMAGES,
INCLUDING, BUT NOT LIMITED TO, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY
REASON WHATSOEVER.
*/


/* Include the library */
#include "HCMotor.h"

/* Pins used to drive the motors */
#define MOTOR_PINA 8 //For HCMODU0033 connect to A-IA, for HCARDU0013 connect to IN1
#define MOTOR_PINB 9 //For HCMODU0033 connect to A-IB, for HCARDU0013 connect to IN2

/* Set the analogue pin the potentiometer will be connected to. */
#define POT_PIN A0

/* Set a dead area at the centre of the pot where it crosses from forward to reverse */
#define DEADZONE 20 

/* The analogue pin will return values between 0 and 1024 so divide this up between 
   forward and reverse */
#define POT_REV_MIN 0
#define POT_REV_MAX (512 - DEADZONE)
#define POT_FWD_MIN (512 + DEADZONE)
#define POT_FWD_MAX 1204


/* Create an instance of the library */
HCMotor HCMotor;


void setup() 
{

  /* Initialise the library */
  HCMotor.Init();

  /* Attach motor 0 to digital pins 8 & 9. The first parameter specifies the 
     motor number, the second is the motor type, and the third and forth are the 
     digital pins that will control the motor */
  HCMotor.attach(0, DCMOTOR_H_BRIDGE, MOTOR_PINA, MOTOR_PINB);

  /* Set the duty cycle of the PWM signal in 100uS increments. 
     Here 100 x 100uS = 1mS duty cycle. */
  HCMotor.DutyCycle(0, 100);

}

void loop() 
{
  int Speed, Pot;

  /* Read the analogue pin to determine the position of the pot. */ 
  Pot = analogRead(POT_PIN);

  /* Is the pot in the reverse position ? */
  if (Pot >= POT_REV_MIN && Pot <= POT_REV_MAX)
  {
    HCMotor.Direction(0, REVERSE);
    Speed = map(Pot, POT_REV_MIN, POT_REV_MAX, 100, 0);

  /* Is the pot in the forward position ? */
  }else if (Pot >= POT_FWD_MIN && Pot <= POT_FWD_MAX)
  {
    HCMotor.Direction(0, FORWARD);
    Speed = map(Pot, POT_FWD_MIN, POT_FWD_MAX, 0, 100);

  /* Is the pot in the dead zone ? */
  }else
  {
    Speed = 0;
  }

  /* Set the on time of the duty cycle to match the position of the pot. */
  HCMotor.OnTime(0, Speed);

}


Stepper Motor Example

Code: Select all

/* FILE:    HCMotor_Stepper_Example
   DATE:    09/07/15
   VERSION: 0.1
   AUTHOR:  Andrew Davies

   
This example uses the library to control a stepper motor via a standard stepper driver 
module (with step/clock & direction inputs) using a potentiometer connected to
analogue pin A0. For suitable driver modules see items HCMODU0022 & HCMODU0068.

Do not connect the motor directly to your Arduino's digital pins as you may damage your 
Arduino.

Note about driving more than one motor:
By default this library can drive up to 4 motors. However this can be increased by 
editing the following line in the libraries HCMotor.h file:

#define MAXMOTORS 4 <-- change to match the number of motors you require.

If you are using less than 4 motors and your sketch is processor intensive you may 
also want to reduce this value to match the number of motors you have attached as this 
will free up processing cycles for your main loop.

You may copy, alter and reuse this code in any way you like, but please leave
reference to HobbyComponents.com in your comments if you redistribute this code.
This software may not be used directly for the purpose of selling products that
directly compete with Hobby Components Ltd's own range of products.

THIS SOFTWARE IS PROVIDED "AS IS". HOBBY COMPONENTS MAKES NO WARRANTIES, WHETHER
EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ACCURACY OR LACK OF NEGLIGENCE.
HOBBY COMPONENTS SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR ANY DAMAGES,
INCLUDING, BUT NOT LIMITED TO, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY
REASON WHATSOEVER.
*/



/* Include the library */
#include "HCMotor.h"

/* Pins used to drive the motors */
#define DIR_PIN 8 //Connect to drive modules 'direction' input.
#define CLK_PIN 9 //Connect to drive modules 'step' or 'CLK' input.

/* Set the analogue pin the potentiometer will be connected to. */
#define POT_PIN A0

/* Set a dead area at the centre of the pot where it crosses from forward to reverse */
#define DEADZONE 20 

/* The analogue pin will return values between 0 and 1024 so divide this up between 
   forward and reverse */
#define POT_REV_MIN 0
#define POT_REV_MAX (512 - DEADZONE)
#define POT_FWD_MIN (512 + DEADZONE)
#define POT_FWD_MAX 1024


/* Create an instance of the library */
HCMotor HCMotor;



void setup() 
{
  //Serial.begin(9600);
  /* Initialise the library */
  HCMotor.Init();

  /* Attach motor 0 to digital pins 8 & 9. The first parameter specifies the 
     motor number, the second is the motor type, and the third and forth are the 
     digital pins that will control the motor */
  HCMotor.attach(0, STEPPER, CLK_PIN, DIR_PIN);

  /* Set the number of steps to continuous so the the motor is always turning whilst 
     not int he dead zone*/
  HCMotor.Steps(0,CONTINUOUS);
}


void loop() 
{
  int Speed, Pot;

  /* Read the analogue pin to determine the position of the pot. */ 
  Pot = analogRead(POT_PIN);

  /* Is the pot in the reverse position ? */
  if (Pot >= POT_REV_MIN && Pot <= POT_REV_MAX)
  {
    HCMotor.Direction(0, REVERSE);
    Speed = map(Pot, POT_REV_MIN, POT_REV_MAX, 10, 1024);

  /* Is the pot in the forward position ? */
  }else if (Pot >= POT_FWD_MIN && Pot <= POT_FWD_MAX)
  {
    HCMotor.Direction(0, FORWARD);
    Speed = map(Pot, POT_FWD_MIN, POT_FWD_MAX, 1024, 10);

  /* Is the pot in the dead zone ? */
  }else
  {
    Speed = 0;
  }

  /* Set the duty cycle of the clock signal in 100uS increments */
  HCMotor.DutyCycle(0, Speed);

}



Image

The library files can be downloaded from github here:

https://github.com/HobbyComponents/HCMotor

Or directly from this forum:
HCMotor.zip
You do not have the required permissions to view the files attached to this post.

rzamora06
Posts: 3
Joined: Wed Jun 29, 2016 7:01 am

Re: HCMotor Arduino library for driving DC and stepper motor

Post by rzamora06 » Wed Jun 29, 2016 7:07 am

I have a couple of questions on your HCMotors library. Without manipulating the library, is there a way to create a sketch that will cause the stepper motor to travel a limited number of steps?

andrew
Site Admin
Posts: 1374
Joined: Sun Aug 05, 2012 4:15 pm

Re: HCMotor Arduino library for driving DC and stepper motor

Post by andrew » Wed Jun 29, 2016 2:39 pm

You should be able to use the HCMotor.Steps() function to do this. For example, to step the first stepper motor (motor 0) by 15 steps:

Code: Select all

HCMotor.Steps(0, 15);
Comments made by this poster do not necessarily reflect the views of Hobby Components Ltd.

rzamora06
Posts: 3
Joined: Wed Jun 29, 2016 7:01 am

Re: HCMotor Arduino library for driving DC and stepper motor

Post by rzamora06 » Fri Jan 27, 2017 10:12 pm

Hi Andrew,

This snippet from the HCMotor.cpp file:

void HCMotor::Init(void)
{
HCMotor::_MotorTimer2Init(T2_CLK_DIV_32, 49);
}

Has multiple values from which the prescaller can be set to: T2_CLK_DIV_0 = 1, T2_CLK_DIV_8 = 2, T2_CLK_DIV_32 = 3, T2_CLK_DIV_64 = 4, T2_CLK_DIV_128 = 5, T2_CLK_DIV_256 = 6, and T2_CLK_DIV_1024 = 7.

Using a stepper motor, if I were to set the clock speed to 1000, would the clock speed be divided by three (scaled down by T2_CLK_DIV_32 = 3) effectively resulting in a clock speed of 333.3? Also why would you divide by 49?

Lastly, the stepper moter clock speed is determined by the void HCMotor::DutyCycle(byte MotorNum, unsigned int Time) class. For an input time of 2000 what are the units (Hz, MHz) and what is the default duty cycle?

andrew
Site Admin
Posts: 1374
Joined: Sun Aug 05, 2012 4:15 pm

Re: HCMotor Arduino library for driving DC and stepper motor

Post by andrew » Sat Jan 28, 2017 10:47 am

If you've not already worked it out these two values set the prescaller (TCCR2B) and compare (OCR2A) registers for the hardware interrupt timer 2. This hardware timer is then used to run the library code at regular intervals allowing it to PWM pins at precise intervals. The timer 2 code is actually borrowed from the HCTimer2 library (http://forum.hobbycomponents.com/viewto ... =58&t=1336) and there is an explanation of how it works and what these registers do on our blog site here:

http://blog.hobbycomponents.com/?p=235

I recommend having a read of it as it will help make the following answers a bit clearer.

Has multiple values from which the prescaller can be set to: T2_CLK_DIV_0 = 1, T2_CLK_DIV_8 = 2, T2_CLK_DIV_32 = 3, T2_CLK_DIV_64 = 4, T2_CLK_DIV_128 = 5, T2_CLK_DIV_256 = 6, and T2_CLK_DIV_1024 = 7
They actually represent the values 0, 8, 32, 64, 128, 256, 1024 respectively and are used to divide down the 16MHz clock so that longer interrupt timer internals can be achieved. So for example if you where to set the prescaller to T2_CLK_DIV_32 you would be scaling down the internal clock by 32. I.e. From 16MHz to 0.5MHz.

Using a stepper motor, if I were to set the clock speed to 1000, would the clock speed be divided by three (scaled down by T2_CLK_DIV_32 = 3) effectively resulting in a clock speed of 333.3? Also why would you divide by 49?

No, with reference to the explanation in the blog post, the two values are used to set the amount of time before the timer interrupt will trigger. The equation for this is as follows:

Time in seconds = ((compare + 1) * prescaler) / 16MHz

So for the values set by the HCMotor library the library code will get executed once every ((49 + 1) * 32) / 16MHz seconds = 0.0001 seconds or 100 microseconds.

You can of course alter these values to speed up or slow down the PWM signals (I should point out of course that to use the library there is no need to change these values unless for some reason you want to modify the internal workings of the library). So for example changing the compare value from 49 to 99 would half the speed but there are a couple of things to keep in mind when doing this...

Firstly you can only set the prescaller to one of the previously mentioned fixed values and the compare register can only be set between 0 and 255. Secondly, each time the timer interrupt is triggered the library code needs a certain amount of time to run. If you set interrupt interval too low the code wont have enough time to run before the next interrupt is due to trigger and so the timings will be off.
Lastly, the stepper moter clock speed is determined by the void HCMotor::DutyCycle(byte MotorNum, unsigned int Time) class. For an input time of 2000 what are the units (Hz, MHz)
When used with a stepper motor Time sets the stpeer motors clock frequency in 100us increments. So for a value of 2000 this would give a clock period of 200ms or 1/0.2 = 5Hz.
and what is the default duty cycle?
The default value for Time should be 0. This stops the motor from turning until a valid value is specified.
Comments made by this poster do not necessarily reflect the views of Hobby Components Ltd.

rzamora06
Posts: 3
Joined: Wed Jun 29, 2016 7:01 am

Re: HCMotor Arduino library for driving DC and stepper motor

Post by rzamora06 » Sat Jan 28, 2017 11:18 am

Last question (hopefully):
When used with a stepper motor Time sets the stpeer motors clock frequency in 100us increments. So for a value of 2000 this would give a clock period of 200ms or 1/0.2 = 5Hz.
For a speed of 2000 (clock period of 5Hz), would 5Hz then be considered my stepper motor pps?

andrew
Site Admin
Posts: 1374
Joined: Sun Aug 05, 2012 4:15 pm

Re: HCMotor Arduino library for driving DC and stepper motor

Post by andrew » Mon Jan 30, 2017 10:00 am

Yes that's correct.
Comments made by this poster do not necessarily reflect the views of Hobby Components Ltd.

darryltan
Posts: 1
Joined: Mon Apr 24, 2017 5:39 am

Re: HCMotor Arduino library for driving DC and stepper motor

Post by darryltan » Fri Apr 28, 2017 8:13 am

how to set clockwise and anti clockwise?? the code only run 1 way only

andrew
Site Admin
Posts: 1374
Joined: Sun Aug 05, 2012 4:15 pm

Re: HCMotor Arduino library for driving DC and stepper motor

Post by andrew » Fri Apr 28, 2017 10:16 am

You can use the following library function to set the direction:

Code: Select all

HCMotor.Direction(MotorNum, Direction);
Sets the direction of the motor for H-Bridge and stepper motors where:
MotorNum is a value used to reference which motor we wish to alter.
Direction is the direction of the motor. Valid values are FORWARD & REVERSE
Comments made by this poster do not necessarily reflect the views of Hobby Components Ltd.

azherajju
Posts: 1
Joined: Sun Jan 28, 2018 2:15 pm

Re: HCMotor Arduino library for driving DC and stepper motor

Post by azherajju » Sun Jan 28, 2018 2:26 pm

hi andrew please tell me how can i divide 1.8deg/step to 0.225/step using arduino and TB 6560

Post Reply

Return to “Arduino”