stepper motor control

hello.
im trying to make a sliding table controlled by a stepper motor. i want to be able to move the motor through matlab but at the moment i am doing it through the serial monitor on the arduino software(i know how to do it through matlab). below is my code. i adapted the serial communication part from a code i found for a serial controlled moodlight (red green and blue leds, pwm).

// Include stepper controller function library
#include <Stepper.h>

// Define number of steps
#define motorSteps 200

// Define the Arduino Pins
#define motorPin1 5
#define motorPin2 7
#define motorPin3 8
#define motorPin4 10
#define ledPin 13

// Define variables for serial communication from matlab
char buffer[8];

// Call up the Stepper library
Stepper stepperMotor(motorSteps, motorPin1, motorPin2, motorPin3, motorPin4);

void setup()
{
  // Set rotation speed (rpm)
  stepperMotor.setSpeed(3);

  // Open serial port for communication
  Serial.begin(9600);
  Serial.flush();
  
  // Set up LED pin
  pinMode(ledPin, OUTPUT);
  // Blink the LED
  blink(3);
}

void loop()
{
  if (Serial.available() > 0) 
  {
    int index=0;
    // let the buffer fill up
    delay(100); 
    int numChar = Serial.available();
    if (numChar>5)
    {
      numChar=5;
    }
    while (numChar--)
    {
    buffer[index++] = Serial.read();
    }
    splitString(buffer);
  }
}

// Blink the reset LED:
void blink(int howManyTimes) 
{
  int i;
  for (i=0; i< howManyTimes; i++) 
  {
    digitalWrite(ledPin, HIGH);
    delay(200);
    digitalWrite(ledPin, LOW);
    delay(200);
  }
}

void splitString(char* data)
{
  Serial.print("Data entered: ");
  Serial.println(data);
  char* parameter;
  parameter = strtok (data, " ,");
  while (parameter != NULL) 
  {
    moveTable(parameter);
    parameter = strtok (NULL, " ,");
  }
  // Clear the text and serial buffers
  for (int x=0; x<16; x++) 
  {
    buffer[x]='\0';
  }
  Serial.flush();
}

void moveTable(char* data)
{
  if ((data[0] == 'f') || (data[0] == 'F'))
  {
    int Ans = strtol(data+1, NULL, 10);
    stepperMotor.step(Ans);
    //stepperMotor.motorOff();
    Serial.print("Forward steps: ");
    Serial.println(Ans);
  }
  if ((data[0] == 'b') || (data[0] == 'B'))
  {
    int Ans = strtol(data+1, NULL, 10);
    stepperMotor.step(-Ans);
    //stepperMotor.motorOff();
    Serial.print("Backward steps: ");
    Serial.println(Ans);
  }
}

instead of a motor atm i just have some leds (im still waiting for the motor to be delivered). the problem i have is that the first instruction i send to the arduino (for example 'F500' for five hundred forward steps) will be executed just fine, but when i try to tell it something else (fex. 'B200'), it seems to skip out every step and finish on the last one( instantly). for example, if the leds are on in the following order ON ON OFF OFF and i send '25', the leds change to OFF ON ON OFF rather than cycling through the combinations to get to that state. what is going on?! :cry:

also, does the motorOff() command have any effects other than saving power (the motor will be run intermittantly - maybe some 10-20 revolutions once every other week of=r so)?

thank you!

btw the motorOff() command is in another version of the Stepper.h library i found somewhere on the forums.

One problem is that buffer is an array of characters, NOT a string. For it to ba a string, it needs to be NULL terminated.

Change this:

    buffer[index++] = Serial.read();

to this:

    buffer[index++] = Serial.read();
[glow]    buffer[index] = '\0';[/glow]

You have a good number of Serial.print statements. How about showing us the serial monitor data?

i want the motor to do 100 steps forward. here is the serial monitor:

Data entered: f100
Forward steps: 100

the first line shows up as soon as i send the command, and the second line comes up when its done.

then i want it to do 200 steps backwards:

Data entered: b200
Backward steps: 200

both lines come up at the same time as it skips all the steps inbetween. :-[ any ideas?

Skips all of what steps in between?

The first statement is printed in splitString. The 2nd is printed in moveTable.

It appears as though the code is working exactly like it's supposed to.

Does the motor not move in the reverse direction? What happens if you send b200 first, then f100?

what ever i send as the first command after resetting the arduino (f1, b4, f5839, whatever), the arduino will do it. with a 200 step motor and 1 rpm, it takes 1 min to do f200 or b200. all subsequent commands, however, will skip all of the steps. for example, if i send f200 as the first and f201 as the second command, it will do the first command, but only seems to do one change for the second command.

the led flashing order is

0 0 x x
x 0 0 x
x x 0 0
0 x x 0

leds after first command say f20

0 0 x x

leds after second command say f50

x x 0 0

im guessing this is the same as doing f2 (50/4=12 remainder 2)

if the leds are 0 0 x x after the first command, f801 would result in:

x 0 0 x

and it does f801 command instantly where it should take just over 4 min with the above stated settings :-/

How about posting an updated version of your code?

// Include stepper controller function library
#include <Stepper.h>

// Define number of steps
#define motorSteps 200

// Define the Arduino Pins
#define motorPin1 5
#define motorPin2 8
#define motorPin3 7
#define motorPin4 10
#define ledPin 13

// Define variables for serial communication from matlab
char buffer[8];

// Call up the Stepper library
Stepper stepperMotor(motorSteps, motorPin1, motorPin2, motorPin3, motorPin4);

void setup()
{
  // Set rotation speed (rpm)
  stepperMotor.setSpeed(1);

  // Open serial port for communication
  Serial.begin(38400);
  Serial.flush();
  
  // Set up LED pin
  pinMode(ledPin, OUTPUT);
  // Blink the LED
  blink(3);
}

void loop()
{
  if (Serial.available() > 0) 
  {
    int index=0;
    // let the buffer fill up
    delay(100); 
    int numChar = Serial.available();
    if (numChar>5)
    {
      numChar=5;
    }
    while (numChar--)
    {
    buffer[index++] = Serial.read();
    buffer[index] = '\0';
    }
    splitString(buffer);
  }
}

// Blink the reset LED:
void blink(int howManyTimes) 
{
  int i;
  for (i=0; i< howManyTimes; i++) 
  {
    digitalWrite(ledPin, HIGH);
    delay(200);
    digitalWrite(ledPin, LOW);
    delay(200);
  }
}

void splitString(char* data)
{
  Serial.print("Data entered: ");
  Serial.println(data);
  char* parameter;
  parameter = strtok (data, " ,");
  while (parameter != NULL) 
  {
    moveTable(parameter);
    parameter = strtok (NULL, " ,");
  }
  // Clear the text and serial buffers
  for (int x=0; x<16; x++) 
  {
    buffer[x]='\0';
  }
  Serial.flush();
}

void moveTable(char* data)
{
  if ((data[0] == 'f') || (data[0] == 'F'))
  {
    int Ans = strtol(data+1, NULL, 10);
    stepperMotor.step(Ans);
    //stepperMotor.motorOff();
    Serial.print("Forward steps: ");
    Serial.println(Ans);
  }
  if ((data[0] == 'b') || (data[0] == 'B'))
  {
    int Ans = strtol(data+1, NULL, 10);
    stepperMotor.step(-Ans);
    //stepperMotor.motorOff();
    Serial.print("Backward steps: ");
    Serial.println(Ans);
  }
}
char buffer[8];
  // Clear the text and serial buffers
  for (int x=0; x<16; x++)
  {
    buffer[x]='\0';
  }

What do you suppose is being overwritten when you write to buffer[8] through buffer[15]? Buffer isn't that big, so something is getting overwritten.

hmm i copied the code from another source (im not still sure what it all means) and i forgot to change that... i changed the first buffer to 8. anywhooo it works now!!!!! I LOVE YOU! :smiley: thanks!