## Potentiometer motor speed and direction

Drive a 4-wire bipolar stepper motor or a pair of DC motors from your Arduino. [Product page]
Lokyi
Posts: 5
Joined: Wed Jan 22, 2014 12:56 pm

### Potentiometer motor speed and direction

Theoretical question, I haven't tried starting to code this one yet, but is it technically possible to use a single pot to control motor speed and direction on a single channel by using the analogue input values to set certain "states"?
I did notice in the example and a couple of other places, it says to use 0-255 values for the HBRIDGE, so does that mean you need to limit the pot somehow? or could you somehow "convert" values in the sketch? so say 0-100 on the pot = 0-25 on the HBRIDGE, 104-200 = 26-50 (only used those examples as they're round numbers).

So what I was thinking (using the pot analogue values) was:
0-250 motor turns left at full speed
251-499 motor turns left half speed
500-528 would give you a motor stop condition (and maybe pause a few second to stop too)
529-779 motor turns right half speed
780-1023 motor turns right full speed

angusgr
Freetronics Staff Posts: 853
Joined: Tue Apr 09, 2013 11:19 pm
Location: Melbourne, Australia
Contact:

### Re: Potentiometer motor speed and direction

Hi Lokyi,

That should work.

A useful function to look into is the map() function for mapping one range of numbers onto another, easily:
http://www.arduino.cc/en/Reference/Map

Let us know if you get stuck once you start coding.

- Angus

Lokyi
Posts: 5
Joined: Wed Jan 22, 2014 12:56 pm

### Re: Potentiometer motor speed and direction

Here's where I'm starting from:

Code: Select all

``````const int channel_a_enable  = 6;
const int channel_a_input_1 = 4;
const int channel_a_input_2 = 7;
const int channel_b_enable  = 5;
const int channel_b_input_3 = 3;
const int channel_b_input_4 = 2;

int analogValueA = 0;
int analogValueB = 0;

void setup()
{
pinMode(2, INPUT);
pinMode(4, INPUT);

pinMode( channel_a_enable, OUTPUT );  // Channel A enable
pinMode( channel_a_input_1, OUTPUT ); // Channel A input 1
pinMode( channel_a_input_2, OUTPUT ); // Channel A input 2

pinMode( channel_b_enable, OUTPUT );  // Channel B enable
pinMode( channel_b_input_3, OUTPUT ); // Channel B input 3
pinMode( channel_b_input_4, OUTPUT ); // Channel B input 4

Serial.begin( 9600 );
Serial.println("Starting up");
}

void loop()
{
// CHANNEL A
Serial.print("Channel A: ");
Serial.println(analogValueA);
analogValueA = map(analogValueA, 0, 1023, 0, 255);
analogWrite( channel_a_enable, analogValueA);
digitalWrite( channel_a_input_1, LOW);
digitalWrite( channel_a_input_2, HIGH);

// CHANNEL B
Serial.print("Channel B: ");
Serial.println(analogValueB);
analogValueB = map(analogValueB, 0, 1023, 0, 255);
analogWrite( channel_b_enable, analogValueB);
digitalWrite( channel_b_input_3, LOW);
digitalWrite( channel_b_input_4, HIGH);

// delay ms before the next reading:
delay(300);
}
``````
Only issue I've found so far is that I'm using 10k turn pots, which were *supposed* to be linear, however I'm finding that it's returning 1023 by around half way around... does that mean they could be log instead of linear?

Ultimately I want to use sliding pots for these two motors, but what would be the best resistance to use, 10k or 100k?

Lokyi
Posts: 5
Joined: Wed Jan 22, 2014 12:56 pm

### Re: Potentiometer motor speed and direction

I tried a 5k multi-turn pot, but that hardly worked as the motor just ended up on or off, so I'm assuming if I go upwards to 100k I may end up with better control?
I wouldn't have thought overall resistance would have a huge effect on an analogue/pwm port though, it's always going to be somewhere in between full off and full on.

Lokyi
Posts: 5
Joined: Wed Jan 22, 2014 12:56 pm

### Re: Potentiometer motor speed and direction

Hah just talked through it with a mate, because I was running the +ve and -ve of the pots on the 12v rails I had setup on the breadboard connected to the hbridge supply, of course the third leg was hitting 5v just under halfway round... dumbarse lol.

Lokyi
Posts: 5
Joined: Wed Jan 22, 2014 12:56 pm

### Re: Potentiometer motor speed and direction

Muahahahaha happy I got this working after a bit of mucking around.
Edit: Fixed for both channels, modified the deadzone for the stop phase to narrow it down a bit and give more resolution for left and right instead.

Code: Select all

``````const int channel_a_enable  = 6;
const int channel_a_input_1 = 4;
const int channel_a_input_2 = 7;
const int channel_b_enable  = 5;
const int channel_b_input_3 = 3;
const int channel_b_input_4 = 2;

const int potPinA = A2;
const int potPinB = A4;

int analogValueA = 0;
int analogValueAL = 0;
int analogValueAR = 0;
int analogValueB = 0;
int analogValueBL = 0;
int analogValueBR = 0;

void setup()
{
pinMode(potPinA, INPUT);
pinMode(potPinB, INPUT);

pinMode( channel_a_enable, OUTPUT );  // Channel A enable
pinMode( channel_a_input_1, OUTPUT ); // Channel A input 1
pinMode( channel_a_input_2, OUTPUT ); // Channel A input 2

pinMode( channel_b_enable, OUTPUT );  // Channel B enable
pinMode( channel_b_input_3, OUTPUT ); // Channel B input 3
pinMode( channel_b_input_4, OUTPUT ); // Channel B input 4

Serial.begin( 9600 );
Serial.println("Starting up");
}

void loop()
{
// CHANNEL A
Serial.print("Channel A: ");
Serial.println(analogValueA);
analogValueAR = map(analogValueA, 450, 0, 0, 255);
analogValueAL = map(analogValueA, 575, 1023, 0, 255);
if (analogValueA <= 450)
{
analogWrite( channel_a_enable, analogValueAR);
digitalWrite( channel_a_input_1, HIGH);
digitalWrite( channel_a_input_2, LOW);
}
else if (analogValueA >=451 && analogValueA <=574)
{
analogWrite( channel_a_enable, 0);
digitalWrite( channel_a_input_1, LOW);
digitalWrite( channel_a_input_2, LOW);
delay(100);
}
else if (analogValueA >=575)
{
analogWrite( channel_a_enable, analogValueAL);
digitalWrite( channel_a_input_1, LOW);
digitalWrite( channel_a_input_2, HIGH);
}

// CHANNEL B
Serial.print("Channel B: ");
Serial.println(analogValueB);
analogValueBR = map(analogValueB, 450, 0, 0, 255);
analogValueBL = map(analogValueB, 575, 1023, 0, 255);
if (analogValueB <= 450)
{
analogWrite( channel_b_enable, analogValueBR);
digitalWrite( channel_b_input_3, HIGH);
digitalWrite( channel_b_input_4, LOW);
}
else if (analogValueB >=451 && analogValueB <=574)
{
analogWrite( channel_b_enable, 0);
digitalWrite( channel_b_input_3, LOW);
digitalWrite( channel_b_input_4, LOW);
delay(100);
}
else if (analogValueB >=575)
{
analogWrite( channel_b_enable, analogValueBL);
digitalWrite( channel_b_input_3, LOW);
digitalWrite( channel_b_input_4, HIGH);
}

// delay in milliseconds before the next reading:
delay(100);
}``````