I created a setup in which a potentiometer controls a dc motor, with current flow through the dc motor controlled by an H-bridge. The principle is as follows: With the potentiometer dial set to the mid-point, the motor is off. Rotating the potentiometer clockwise would cause the motor to rotate in one direction, with speed dictated by the displacement of the potentiometer from the mid-point: the greater the displacement from mid-point, the greater the speed of rotation of the motor. If the potentiometer is rotated anti-clockwise, away from mid-point, the motor would rotate in the opposite direction from before; again, with speed dictated by the extent of displacement of the potentiometer from mid-point.
The loop has three functions, where HB_12EN is to enable the drivers, HB_1A is the first driver input, and HB_2A is the second driver input (H-Bridge pins 1, 2 and 7, respectively) as per this datasheet: http://www.ti.com/lit/ds/symlink/sn754410.pdf
To summarise their functions: HB_12EN allows voltage to be applied to the the device controlled by the H-Bridge (in this case a motor), and is pulse-wave-modulated. HB_1A and HB_2A control the flow of current through the motor, setting its angular velocity. HB_1A set HIGH and HB_2A set LOW directs current one way through the motor, and HB1A set LOW and HB_2A set HIGH directs current the other way through the motor.
The loop is:
//OUTPUTS
int const HB_12EN = 9; //pwm pin
int const HB_1A = 2;
int const HB_2A = 3;
//INPUTS
int const POT_MOT = 0; //A0, analog 0
//GLOBAL VARIABLES
unsigned int pot_val = 0; //ADC value from potentiometer
unsigned int grp_num = 1;
pot_val = analogRead(POT_MOT);
grp_num = setMotSwitch(HB_12EN, HB_1A, HB_2A, pot_val, grp_num);
setMotSpeed(HB_12EN, pot_val, grp_num);
The two (non-library) functions are:
unsigned int setMotSwitch(int const motor_reg, int const first_motor, int const sec_motor, unsigned int pot_value, unsigned int group_num) //grp 0: 0-383; grp 1: 384-639; grp 2: 640-1023
{
if (pot_value >= 0 && pot_value < 384)
{
if (group_num != 0)
{
digitalWrite(motor_reg, LOW);
digitalWrite(first_motor, HIGH);
digitalWrite(sec_motor, LOW);
group_num = 0;
}
}
else if (pot_value > 383 && pot_value < 640)
{
if (group_num != 1)
{
digitalWrite(motor_reg, LOW);
digitalWrite(first_motor, LOW);
digitalWrite(sec_motor, LOW);
group_num = 1;
}
}
else if (pot_value > 639 && pot_value <= 1023)
{
if (group_num != 2)
{
digitalWrite(motor_reg, LOW);
digitalWrite(first_motor, LOW);
digitalWrite(sec_motor, HIGH);
group_num = 2;
}
}
else
{
digitalWrite(motor_reg, LOW);
digitalWrite(first_motor, LOW);
digitalWrite(sec_motor, LOW);
group_num = 0;
}
return group_num;
}
void setMotSpeed(int const motor_reg, unsigned int pot_value, unsigned int group_num)
{
unsigned int mot_speed = 0;
if (group_num == 0)
{
mot_speed = map(pot_value, 0, 383, 255, 0);
mot_speed = constrain(mot_speed, 0, 255);
analogWrite(motor_reg, mot_speed);
}
else if (group_num == 1)
{
if (pot_value > 500 && pot_value < 523)
{
digitalWrite(motor_reg, HIGH); //braking
}
else
{
digitalWrite(motor_reg, LOW);
}
}
else if (group_num == 2)
{
mot_speed = map(pot_value, 640, 1023, 0, 255);
mot_speed = constrain(mot_speed, 0, 255);
analogWrite(motor_reg, mot_speed);
}
}
I tried to proceed as follows: As the potentiometer would produce an ADC input with 1024 states, I divided those 1024 states in to 8 groups, the first three groups, covering the first 384 states (0-383) correspond to a dc motor direction (let's say anticlockwise), representing different speeds of rotation (ignoring issues of many-to-one mapping). The middle 2 groups, 256 states (384-639), correspond to a stationary motor. The last three groups, 384 states (640-1023), correspond to motor rotation in the other direction (in this example, clockwise). The ADC inputs have to be translated in to analog outputs with 256 possible states (0-255), so I map each range as appropriate; for 0-383, the mapping has to be reversed, so an input of 383 corresponds to an input of 0. The middle range (384-639) is stationary, but I tried to make a small "sub"-range in the middle a "braking range", I believed this is achieved by setting both H-bridge inputs to LOW. The 640-1023 range mapping is 640 to 0 and 1023 to 255.
Hopefully that makes sense. It seems to work, the issue I am having is that the motor seems to achieve a greater speed in one direction compared to the other: the maximum rotation speed produced in the motor is greater when the potentiometer is at its maximum in one direction compared to the other. I am pretty sure the code above gives an "even" mapping from the potentiometer to the motor for both directions. Is this, then, something to do with hardware?, and is it something to be anticipated in these kinds of setups?
Any help would be appreciated. If anyone has any advice on the best way to combine a potentiometer -or similar- input with a motor output let me know. The "braking" functionality is also a little confusing.