Potentiometer motor speed and direction

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

Potentiometer motor speed and direction

Post by Lokyi » Wed Jan 22, 2014 1:16 pm

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
Freetronics Staff
Posts: 853
Joined: Tue Apr 09, 2013 11:19 pm
Location: Melbourne, Australia
Contact:

Re: Potentiometer motor speed and direction

Post by angusgr » Wed Jan 22, 2014 11:24 pm

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

Post by Lokyi » Thu Jan 23, 2014 1:24 am

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  
      int analogValueA = analogRead(2);    // read the value from the sensor
      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
      int analogValueB = analogRead(4);    // read the value from the sensor
      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

Post by Lokyi » Thu Jan 23, 2014 2:23 am

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

Post by Lokyi » Thu Jan 23, 2014 11:03 am

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

Post by Lokyi » Fri Jan 24, 2014 4:17 am

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  
      int analogValueA = analogRead(potPinA);    // read the value from the sensor
      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
      int analogValueB = analogRead(potPinB);    // read the value from the sensor
      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);
}

Post Reply