Go Down

### Topic: MotorKnob like Pot output to Stepper Driver (Read 4375 times)previous topic - next topic

#### lbjoum

##### Jul 28, 2011, 05:44 am
Hi,

I want to convert a Potentiometer Rotation into a discrete proportional number of pulses and a digital output for the direction that the Pot is turned, somewhat like MotorKnob.

I have a BiPolar Stepper Motor Driver that needs these inputs.

Can anyone suggest code?

cheers,
Joum

#1

#### lbjoum

#2
##### Jul 28, 2011, 10:17 am

http://arduino.cc/en/Tutorial/MotorKnob

Thanks,

I have been trying this method. Even thought of leaving the Stepper Driver out of the circuit and using the H-Bridge, but the Stepper Driver is well suited to the motor and I think it will provide more reliability.

The MotorKnob code has four outputs that pulse the number of steps (and they work in pairs and reverse their polarity).  MotorKnob has no output dedicated to direction. I would have to try and build an electronic circuit to combine the pulses into one output... and I'm not sure how I would get a direction output with it.

I did look at trying to tap into the direction integer in Stepper.cpp but it got too hard.  I think there will be a solution that doesn't need the Stepper.h Library.

Code: [Select]
`  // determine direction based on whether steps_to_mode is + or -:  if (steps_to_move > 0) {this->direction = 1;}  if (steps_to_move < 0) {this->direction = 0;}`

I've only been playing with Arduino for a few days and to create the code I need might take a while, so I was hoping someone knows an existing solution.

#### lbjoum

#3
##### Jul 28, 2011, 10:22 am
Just to clarify,

I only need two outputs:
1.  The number of steps to take.
2.  The direction in which the steps will be taken.

#### Grumpy_Mike

#4
##### Jul 28, 2011, 11:35 am
It is quite simple.
Take the reading from the pot.
Use the map() function to convert this into degrees.
Compare this to the current position (the position last time)
Subtract the current position from the required position.
The sign of this gives direction, the size is proportional to the number of steps.
Convert the number of degrees into the number of steps (you know how many steps you have in 360)
Do the motion.

Most of this is simple kindergarten maths.

#### lbjoum

#5
##### Jul 28, 2011, 12:09 pm
Easy if your mind is tuned to it. I am enjoying the learning curve, but I'm at the bottom.

I can see bits of what you have said in the examples of code I have found. I don't remember this math from school (20 years ago). Is it one field, like logic?

Thanks

#### lbjoum

#6
##### Jul 28, 2011, 12:14 pm

It is quite simple.
Take the reading from the pot.
Use the map() function to convert this into degrees.
Compare this to the current position (the position last time)
Subtract the current position from the required position.
The sign of this gives direction, the size is proportional to the number of steps.
Convert the number of degrees into the number of steps (you know how many steps you have in 360)
Do the motion.

Most of this is simple kindergarten maths.

As with "the size is proportional to the number of steps", what converts a number (I guess integer) into a number of pulses?

#### Grumpy_Mike

#7
##### Jul 28, 2011, 08:14 pm
Quote
As with "the size is proportional to the number of steps", what converts a number (I guess integer) into a number of pulses?

It's called division and multiplication, have you forgotten that?

if there are 200 steps in 360 degrees then there is 360 / 200 = 1.8 degrees per step. or 200 / 300 = 0.55555 steps per degree

if you want to move 20 degrees then you use 20 * 0.55555 = 11 steps

if you want to move 20 steps then you will move 20 * 1.8 = 36 degrees.

#### lbjoum

#8
##### Jul 28, 2011, 11:13 pm
I don't think you understood my last question, so I will put it another way.

If i want 10 (integer) pulses (digital output), what would be an example of Code that would achieve this?

Thanks.

#### Grumpy_Mike

#9
##### Jul 28, 2011, 11:21 pm
Quote
what would be an example of Code that would achieve this?

It depends on what driver you have.

If you have a step and direction driver the simply pulse the step 10 times
Code: [Select]
`for(int i=0; i<10; i++){digitalWrite(step,HIGH);delay(1);digitalWrite(step,LOW);delay(200); // or what ever speed you want it to pulse at}`

are you sure you are asking the right question again?

#### lbjoum

#10
##### Jul 28, 2011, 11:38 pm
Thanks,

No wonder you're Grumpy. You never sleep.

#### Grumpy_Mike

#11
##### Jul 28, 2011, 11:42 pm
Ah .... I wondered why that was.

Yes I was up in the night last night, sleep is not my friend sometimes.

#### lbjoum

#12
##### Jul 30, 2011, 01:55 pm
I got the two outputs I was after. Number of Steps and Direction.  Some fairly blunt hacking.

Pins are 8 (number of steps) and 10 (direction)

The Post is too long so must spread it out.  Just join it back together.  I know it is the full stepper.h & stepper.cpp with an adapted MotorKnob at the end, but putting it all in one set of code was the only way i could put the direction cod into it.

Code: [Select]
`/*  Stepper.h - - Stepper library for Wiring/Arduino - Version 0.4    Original library     (0.1) by Tom Igoe.  Two-wire modifications   (0.2) by Sebastian Gassner  Combination version   (0.3) by Tom Igoe and David Mellis  Bug fix for four-wire   (0.4) by Tom Igoe, bug fix from Noah Shibley  Drives a unipolar or bipolar stepper motor using  2 wires or 4 wires  When wiring multiple stepper motors to a microcontroller,  you quickly run out of output pins, with each motor requiring 4 connections.  By making use of the fact that at any time two of the four motor  coils are the inverse  of the other two, the number of  control connections can be reduced from 4 to 2.  A slightly modified circuit around a Darlington transistor array or an L293 H-bridge  connects to only 2 microcontroler pins, inverts the signals received,  and delivers the 4 (2 plus 2 inverted ones) output signals required  for driving a stepper motor.  The sequence of control signals for 4 control wires is as follows:  Step C0 C1 C2 C3     1  1  0  1  0     2  0  1  1  0     3  0  1  0  1     4  1  0  0  1  The sequence of controls signals for 2 control wires is as follows  (columns C1 and C2 from above):  Step C0 C1     1  0  1     2  1  1     3  1  0     4  0  0  The circuits can be found at  http://www.arduino.cc/en/Tutorial/Stepper*/// ensure this library description is only included once#ifndef Stepper_h#define Stepper_h// library interface descriptionclass Stepper {  public:    // constructors:    // ** One motor_pin and one direction_pin    Stepper(int number_of_steps, int motor_pin_1/*, int motor_pin_2*/, int direction_pin);    //Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4);    // speed setter method:    void setSpeed(long whatSpeed);    // mover method:    void step(int number_of_steps);    int version(void);  private:    void stepMotor(int this_step);        int direction;        // Direction of rotation    int speed;          // Speed in RPMs    unsigned long step_delay;    // delay between steps, in ms, based on speed    int number_of_steps;      // total number of steps this motor can take    int pin_count;        // whether you're driving the motor with 2 or 4 pins    int step_number;        // which step the motor is on        // motor pin numbers:    int motor_pin_1;    int motor_pin_2;    int motor_pin_3;    int motor_pin_4;        // Direction Pin    int direction_pin;        long last_step_time;      // time stamp in ms of when the last step was taken};#endif`

#### lbjoum

#13
##### Jul 30, 2011, 01:56 pm
Code: [Select]
`/*  Stepper.cpp - - Stepper library for Wiring/Arduino - Version 0.4    Original library     (0.1) by Tom Igoe.  Two-wire modifications   (0.2) by Sebastian Gassner  Combination version   (0.3) by Tom Igoe and David Mellis  Bug fix for four-wire   (0.4) by Tom Igoe, bug fix from Noah Shibley    Drives a unipolar or bipolar stepper motor using  2 wires or 4 wires  When wiring multiple stepper motors to a microcontroller,  you quickly run out of output pins, with each motor requiring 4 connections.   By making use of the fact that at any time two of the four motor  coils are the inverse  of the other two, the number of  control connections can be reduced from 4 to 2.   A slightly modified circuit around a Darlington transistor array or an L293 H-bridge  connects to only 2 microcontroler pins, inverts the signals received,  and delivers the 4 (2 plus 2 inverted ones) output signals required  for driving a stepper motor.  The sequence of control signals for 4 control wires is as follows:  Step C0 C1 C2 C3     1  1  0  1  0     2  0  1  1  0     3  0  1  0  1     4  1  0  0  1  The sequence of controls signals for 2 control wires is as follows  (columns C1 and C2 from above):  Step C0 C1     1  0  1     2  1  1     3  1  0     4  0  0  The circuits can be found at http://www.arduino.cc/en/Tutorial/Stepper */// set pin numbers:const int dirPin =  10;      // the number of the LED pin// Variables will change:int dirState = LOW;             // ledState used to set the LEDlong previousMillis = 0;        // will store last time LED was updated// the follow variables is a long because the time, measured in miliseconds,// will quickly become a bigger number than can be stored in an int.long interval = 0;           // interval at which to blink (milliseconds)#include "WProgram.h"//#include "Stepper.h"/* * two-wire constructor. * Sets which wires should control the motor. */// ** One motor_Pin and direction_pinStepper::Stepper(int number_of_steps, int motor_pin_1/*, int motor_pin_2*/, int direction_pin){  this->step_number = 0;      // which step the motor is on  this->speed = 0;        // the motor speed, in revolutions per minute  this->direction = 0;      // motor direction  this->last_step_time = 0;    // time stamp in ms of the last step taken  this->number_of_steps = number_of_steps;    // total number of steps for this motor    // Arduino pins for the motor control connection:  this->motor_pin_1 = motor_pin_1;  this->motor_pin_2 = motor_pin_2;  // setup the pins on the microcontroller:  pinMode(this->motor_pin_1, OUTPUT);  //pinMode(this->motor_pin_2, OUTPUT);  // Direction Pin  pinMode(this->direction_pin, OUTPUT);  this->direction_pin = dirPin;    // When there are only 2 pins, set the other two to 0:  // Only 1 motor_pin  this->motor_pin_2 = 0;  this->motor_pin_3 = 0;  this->motor_pin_4 = 0;  // pin_count is used by the stepMotor() method:  //this->pin_count = 2;  this->pin_count = 1;}/* *   constructor for four-pin version *   Sets which wires should control the motor. *//*Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4){  this->step_number = 0;      // which step the motor is on  this->speed = 0;        // the motor speed, in revolutions per minute  this->direction = 0;      // motor direction  this->last_step_time = 0;    // time stamp in ms of the last step taken  this->number_of_steps = number_of_steps;    // total number of steps for this motor    // Arduino pins for the motor control connection:  this->motor_pin_1 = motor_pin_1;  this->motor_pin_2 = motor_pin_2;  this->motor_pin_3 = motor_pin_3;  this->motor_pin_4 = motor_pin_4;  // setup the pins on the microcontroller:  pinMode(this->motor_pin_1, OUTPUT);  pinMode(this->motor_pin_2, OUTPUT);  pinMode(this->motor_pin_3, OUTPUT);  pinMode(this->motor_pin_4, OUTPUT);  // pin_count is used by the stepMotor() method:    this->pin_count = 4;  } *//*  Sets the speed in revs per minute*/void Stepper::setSpeed(long whatSpeed){  this->step_delay = 60L * 1000L / this->number_of_steps / whatSpeed;}/*  Moves the motor steps_to_move steps.  If the number is negative,    the motor moves in the reverse direction. */void Stepper::step(int steps_to_move){    int steps_left = abs(steps_to_move);  // how many steps to take    // determine direction based on whether steps_to_mode is + or -:  if (steps_to_move > 0) {this->direction = 1;}  if (steps_to_move < 0) {this->direction = 0;}      // Attempt to write Direction  // set the dir digital pin as output:  pinMode(dirPin, OUTPUT);      unsigned long currentMillis = millis();   if(currentMillis - previousMillis > interval) {    // save the last time you blinked the LED     previousMillis = currentMillis;       // if the dirPin is off turn it on and vice-versa:    if (this->direction == 1)      dirState = HIGH;    else      dirState = LOW;    // set the LED with the ledState of the variable:    digitalWrite(dirPin, dirState);  }/*// Attempt to write Direction  if (this->direction == 1) {        digitalWrite(direction_pin, HIGH);         delay(1000);              // wait for a second  }          else        {        digitalWrite(direction_pin, LOW);         delay(1000);              // wait for a second}*/  // decrement the number of steps, moving one step each time:  while(steps_left > 0) {  // move only if the appropriate delay has passed:  if (millis() - this->last_step_time >= this->step_delay) {      // get the timeStamp of when you stepped:      this->last_step_time = millis();      // increment or decrement the step number,      // depending on direction:      if (this->direction == 1) {        this->step_number++;        if (this->step_number == this->number_of_steps) {          this->step_number = 0;        }      }       else {         if (this->step_number == 0) {          this->step_number = this->number_of_steps;        }        this->step_number--;      }      // decrement the steps left:      steps_left--;      // step the motor to step number 0, 1, 2, or 3:      stepMotor(this->step_number % 4);    }  }}/* * Moves the motor forward or backwards. */void Stepper::stepMotor(int thisStep){  if (this->pin_count == 1) {    // I think "switch" sets up a walk through each case.    switch (thisStep) {      case 0: /* 01 */      digitalWrite(motor_pin_1, LOW);            break;      case 1: /* 11 */      digitalWrite(motor_pin_1, HIGH);            break;          }   }  if (this->pin_count == 2) {    switch (thisStep) {      case 0: /* 01 */      digitalWrite(motor_pin_1, LOW);      digitalWrite(motor_pin_2, HIGH);      break;      case 1: /* 11 */      digitalWrite(motor_pin_1, HIGH);      digitalWrite(motor_pin_2, HIGH);      break;      case 2: /* 10 */      digitalWrite(motor_pin_1, HIGH);      digitalWrite(motor_pin_2, LOW);      break;      case 3: /* 00 */      digitalWrite(motor_pin_1, LOW);      digitalWrite(motor_pin_2, LOW);      break;    }   }  if (this->pin_count == 4) {    switch (thisStep) {      case 0:    // 1010      digitalWrite(motor_pin_1, HIGH);      digitalWrite(motor_pin_2, LOW);      digitalWrite(motor_pin_3, HIGH);      digitalWrite(motor_pin_4, LOW);      break;      case 1:    // 0110      digitalWrite(motor_pin_1, LOW);      digitalWrite(motor_pin_2, HIGH);      digitalWrite(motor_pin_3, HIGH);      digitalWrite(motor_pin_4, LOW);      break;      case 2:    //0101      digitalWrite(motor_pin_1, LOW);      digitalWrite(motor_pin_2, HIGH);      digitalWrite(motor_pin_3, LOW);      digitalWrite(motor_pin_4, HIGH);      break;      case 3:    //1001      digitalWrite(motor_pin_1, HIGH);      digitalWrite(motor_pin_2, LOW);      digitalWrite(motor_pin_3, LOW);      digitalWrite(motor_pin_4, HIGH);      break;    }   }}  /*  version() returns the version of the library:*/int Stepper::version(void){  return 4;}/* * MotorKnob * * A stepper motor follows the turns of a potentiometer * (or other sensor) on analog input 0. * * http://www.arduino.cc/en/Reference/Stepper * This example code is in the public domain. *///#include <Stepper.h>// change this to the number of steps on your motor#define STEPS 100// create an instance of the stepper class, specifying// the number of steps of the motor and the pins it's// attached to// Pin 8 Steps and 10 DirectionStepper stepper(STEPS, 8, 10);// the previous reading from the analog inputint previous = 0;void setup(){  // set the speed of the motor to 30 RPMs  stepper.setSpeed(30);}void loop(){  // get the sensor value  //int val = analogRead(0);  //Read analog 0 (pot) and map it to the range of the motor   int val = map(analogRead(0), 0, 1023, 400, 0);    // move a number of steps equal to the change in the  // sensor reading  stepper.step(val - previous);  // remember the previous value of the sensor  previous = val;};`

#### lbjoum

#14
##### Jul 31, 2011, 01:01 pm
Update:
I cleaned up the code.  Even though the input is re-mapped the pot is to sensitive.  When the Pot is Stationary the outputs both jitter. Any ideas how to stabilize?
Code: [Select]
`// JoumStepDir2/*    Original library     (0.1) by Tom Igoe.  Two-wire modifications   (0.2) by Sebastian Gassner  Combination version   (0.3) by Tom Igoe and David Mellis*/// library interface descriptionclass Stepper {  public:    // constructors:    // ** One motor_pin and one direction_pin    Stepper(int number_of_steps, int motor_pin_1, int direction_pin);    // speed setter method:    void setSpeed(long whatSpeed);    // mover method:    void step(int number_of_steps);    int version(void);    void stepMotor(int this_step);        int direction;        // Direction of rotation    int speed;          // Speed in RPMs    unsigned long step_delay;    // delay between steps, in ms, based on speed    int number_of_steps;      // total number of steps this motor can take    int pin_count;        // whether you're driving the motor with 2 or 4 pins    int step_number;        // which step the motor is on        // motor pin number:    int motor_pin_1;    // direction pin number    int direction_pin;        long last_step_time;      // time stamp in ms of when the last step was taken};//-------------------------end stepper.h// Variables will change:int dirState = LOW;             // dirState used to set the direction_pinlong previousMillis = 0;        // will store last time direction_pin was updated// the follow variables is a long because the time, measured in miliseconds,// will quickly become a bigger number than can be stored in an int.long interval = 0;           // interval at which to blink (milliseconds)#include "WProgram.h"/* * two-wire constructor. * Sets which wires should control the motor. */// ** One motor_Pin and direction_pinStepper::Stepper(int number_of_steps, int motor_pin_1, int direction_pin){  this->step_number = 0;      // which step the motor is on  this->speed = 0;        // the motor speed, in revolutions per minute  this->direction = 0;      // motor direction  this->last_step_time = 0;    // time stamp in ms of the last step taken  this->number_of_steps = number_of_steps;    // total number of steps for this motor    // Arduino pins for the motor control connection:  this->motor_pin_1 = motor_pin_1;  // setup the pins on the microcontroller:  pinMode(this->motor_pin_1, OUTPUT);  // Direction Pinthis->direction_pin = direction_pin;    // pin_count is used by the stepMotor() method:this->pin_count = 1;}   // mover method:    void step(int number_of_steps);    int version(void);/*  Sets the speed in revs per minute*/void Stepper::setSpeed(long whatSpeed){  this->step_delay = 60L * 1000L / this->number_of_steps / whatSpeed;}/*  Moves the motor steps_to_move steps.  If the number is negative,    the motor moves in the reverse direction. */void Stepper::step(int steps_to_move){    int steps_left = abs(steps_to_move);  // how many steps to take    // determine direction based on whether steps_to_mode is + or -:  if (steps_to_move > 0) {this->direction = 1;}  if (steps_to_move < 0) {this->direction = 0;}      // Attempt to write Direction  // set the dir digital pin as output:  pinMode(direction_pin, OUTPUT);      unsigned long currentMillis = millis();   if(currentMillis - previousMillis > interval) {    // save the last time you blinked the direction_pin     previousMillis = currentMillis;       // if the direction_pin is off turn it on and vice-versa:    if (this->direction == 1)      dirState = HIGH;    else      dirState = LOW;    // set the direction_pin with the dirState of the variable:    digitalWrite(direction_pin, dirState);  }  // decrement the number of steps, moving one step each time:  while(steps_left > 0) {  // move only if the appropriate delay has passed:  if (millis() - this->last_step_time >= this->step_delay) {      // get the timeStamp of when you stepped:      this->last_step_time = millis();      // increment or decrement the step number,      // depending on direction:      if (this->direction == 1) {        this->step_number++;        if (this->step_number == this->number_of_steps) {          this->step_number = 0;        }      }       else {         if (this->step_number == 0) {          this->step_number = this->number_of_steps;        }        this->step_number--;      }      // decrement the steps left:      steps_left--;      // step the motor to step number 0, 1, 2, or 3:      stepMotor(this->step_number % 4);    }  }}/* * Moves the motor forward or backwards. */void Stepper::stepMotor(int thisStep){  if (this->pin_count == 1) {    // I think "switch" sets up a walk through each case.    switch (thisStep) {      case 0: /* 01 */      digitalWrite(motor_pin_1, LOW);            break;      case 1: /* 11 */      digitalWrite(motor_pin_1, HIGH);            break;          }   }}/*  version() returns the version of the library:*/int Stepper::version(void){  return 4;}/* * MotorKnob * * A stepper motor follows the turns of a potentiometer * (or other sensor) on analog input 0. * * http://www.arduino.cc/en/Reference/Stepper * This example code is in the public domain. */// change this to the number of steps on your motor#define STEPS 100// create an instance of the stepper class, specifying// the number of steps of the motor and the pins it's// attached to// Pin 8 Steps and 10 DirectionStepper stepper(STEPS, 6, 7);// the previous reading from the analog inputint previous = 0;void setup(){  // set the speed of the motor to 30 RPMs  stepper.setSpeed(30);}void loop(){  // get the sensor value  //int val = analogRead(0);  //Read analog 0 (pot) and map it to the range of the motor   int val = map(analogRead(0), 0, 1023, 48, 0);    // move a number of steps equal to the change in the  // sensor reading  stepper.step(val - previous);  // remember the previous value of the sensor  previous = val;}`

Go Up