Pages: [1]   Go Down
Author Topic: stepper motor turns too far (about 3 full rotations)  (Read 500 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
I'm trying to control a stepper motor with Arduino Uno and the MotorShield. But when I move it fast - doesn't matter if I use Stepper.h or do it 'manually' with short delay times - it moves for about 3 full rotations.
So even if I do something like myStepper.step(1) I get 3 rotations. With
Code:
const int stepsPerRevolution = 200;
 Stepper myStepper(stepsPerRevolution,12,13);   
this should only turn the motor 1/200 of one rotation. Any hints?
Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 50
Posts: 3429
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In a situation like this, the only way to get any meaningful help is to post the entire sketch.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes I know. It took me a while to clean it up a bit.
Basically it's a simple firmata version with a stepper motor control. I use it with an openframeworks application. The application sets 2 pins. One to activate the motor, one for the direction.
My last version started delayed and ended delayed. This one starts instantly - when I activate the motor from the of application it starts turning instantly. But I still have the problem that the motor keeps turning for a while after i deactivate it from my application.
Anyway, here's my arduino sketch:

Code:
#include <Stepper.h>
#include <Firmata.h>

/*==============================================================================
 * GLOBAL VARIABLES
 *============================================================================*/

 const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
                          // for your motor
 
 // initialize the stepper library on the motor shield
 Stepper myStepper(stepsPerRevolution,12,13);     
 
 // give the motor control pins names:
 const int pwmA = 3;
 const int pwmB = 11;
 const int brakeA = 9;
 const int brakeB = 8;
 
 const int activateMotorPin = 5;
 const int directionPin = 6;

/* analog inputs */
int analogInputsToReport = 0; // bitwise array to store pin reporting
int analogPin = 0; // counter for reading analog pins
/* timer variables */
unsigned long currentMillis;     // store the current value from millis()
unsigned long previousMillis;    // for comparison with currentMillis

byte previousPIN[TOTAL_PORTS];  // PIN means PORT for input
byte previousPORT[TOTAL_PORTS];


/*==============================================================================
 * FUNCTIONS                                                               
 *============================================================================*/

void outputPort(byte portNumber, byte portValue)
{
    // only send the data when it changes, otherwise you get too many messages!
    if (previousPIN[portNumber] != portValue) {
        Firmata.sendDigitalPort(portNumber, portValue);
        previousPIN[portNumber] = portValue;
    }
}

void setPinModeCallback(byte pin, int mode) {
    if (IS_PIN_DIGITAL(pin)) {
        pinMode(PIN_TO_DIGITAL(pin), mode);
    }
}

void digitalWriteCallback(byte port, int value)
{
    byte i;
    byte currentPinValue, previousPinValue;

    if (port < TOTAL_PORTS && value != previousPORT[port]) {
        for(i=0; i<8; i++) {
            currentPinValue = (byte) value & (1 << i);
            previousPinValue = previousPORT[port] & (1 << i);
            if(currentPinValue != previousPinValue) {
                digitalWrite(i + (port*8), currentPinValue);
            }
        }
        previousPORT[port] = value;
    }
}

void analogWriteCallback(byte pin, int value)
{
    switch(pin) {
    case 3:
    case 5:
    case 6:
    case 11: // PWM pins
        analogWrite(pin, value);
        break;
    }
}
// -----------------------------------------------------------------------------
// sets bits in a bit array (int) to toggle the reporting of the analogIns
void reportAnalogCallback(byte pin, int value)
{
    if(value == 0) {
        analogInputsToReport = analogInputsToReport &~ (1 << pin);
    }
    else { // everything but 0 enables reporting of that pin
        analogInputsToReport = analogInputsToReport | (1 << pin);
    }
    // TODO: save status to EEPROM here, if changed
}

/*==============================================================================
 * SETUP()
 *============================================================================*/
void setup()
{
     // set the PWM and brake pins so that the direction pins  // can be used to control the motor:
 pinMode(pwmA, OUTPUT);
 pinMode(pwmB, OUTPUT);
 pinMode(brakeA, OUTPUT);
 pinMode(brakeB, OUTPUT);
 digitalWrite(pwmA, HIGH);
 digitalWrite(pwmB, HIGH);
 digitalWrite(brakeA, LOW);
 digitalWrite(brakeB, LOW);
 
 // set the motor speed (for multiple steps only):
 myStepper.setSpeed(120);
 
    Firmata.setFirmwareVersion(0, 2);
    Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
    Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
    Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
    Firmata.attach(SET_PIN_MODE, setPinModeCallback);

    Firmata.begin(57600);
}

/*==============================================================================
 * LOOP()
 *============================================================================*/
void loop()
{
    byte i;

    for (i=0; i<TOTAL_PORTS; i++) {
        outputPort(i, readPort(i, 0xff));
    }
 
    while(Firmata.available())
        Firmata.processInput();
    currentMillis = millis();
    if(currentMillis - previousMillis > 20) { 
        previousMillis += 20;                   // run this every 20ms
        for(analogPin=0;analogPin<TOTAL_ANALOG_PINS;analogPin++) {
            if( analogInputsToReport & (1 << analogPin) )
                Firmata.sendAnalog(analogPin, analogRead(analogPin));
        }
   
  }
 
      if(digitalRead(activateMotorPin) == HIGH) {
      if(digitalRead(directionPin) == HIGH) {
         myStepper.step(5);
      }
      else if(digitalRead(directionPin) == LOW) {
         myStepper.step(-5);
      }
    }


}
Logged

0
Offline Offline
Shannon Member
****
Karma: 162
Posts: 10496
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How are pins 5 and 6 configured and controlled?
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah.. I had the pins configured like this:
Code:
    ard.sendDigitalPinMode(activePin, ARD_INPUT);
    ard.sendDigitalPinMode(directionPin, ARD_INPUT);

Changing it to
Code:
    ard.sendDigitalPinMode(activePin, ARD_OUTPUT);
    ard.sendDigitalPinMode(directionPin, ARD_OUTPUT);
did the trick. Now everything works.

I still have one question though: now I'm able to turn the motor on/off. If I also want to change its speed from my openframeworks app how would I do it? Use an analog pin to send a speed value to the arduino board? Or are there any other options?
Logged

0
Offline Offline
Shannon Member
****
Karma: 162
Posts: 10496
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well it certainly sounded like a floating pin problem...
Logged

[ I won't respond to messages, use the forum please ]

Pages: [1]   Go Up
Jump to: