Matlab + AccelStepper Serial Control

607 views
Skip to first unread message

Holly E.

unread,
Nov 8, 2013, 10:56:35 AM11/8/13
to accels...@googlegroups.com
I am trying to control 4 motors using Matlab serial connection. 

The BED are in the simplest configurations right now. Motor wires, 12V power, Ground, Step, Enable, Ground.

The Arduino code compiles and uploads to a mega board, but when I send bytes from Matlab nothing happens. 

My main goal is to send 4 step values to the Arduino from Matlab in one array. Therefore the Arduino only needs to do a Serial.read() once, and then it parses the Array into individual values for each motor.

Does anyone have any ideas on what I am doing wrong or a different method of sending code from Matlab to the Big Easy Driver.


Here is the Arduino Code...
*Note: I used part of this code for a CNC machine that used MakerBot drivers/libraries and adapted it for AccelStepper/Big Easy Driver.

// Attach AccelStepper Library
#include <AccelStepper.h>

// Assign Stepper Motors motor(wiring,step, direction)
AccelStepper XMotor(1,4,5);
AccelStepper TopWheel(1,6,7);
AccelStepper BottomWheel(1,8,9);
AccelStepper ZMotor(1,10,11);

// Introduce variables
int gLineBuffIdx = 0;
char gLineBuffer[80];
boolean gValidDataReceived = false;
boolean gSendResponseWhenDone = false;

// Define Number of Motors in System
#define kMaxMotors      4

// Defines the length of array read into serial [0 0 0 0]
int      gMotorPosition[kMaxMotors];

// Set Up
void setup()
{
  
  
  int    ii;
  
  // Initialize Machine to not run the motors.
  gValidDataReceived = false;
  
  // Start serial connection
  Serial.begin(9600);
  delay(200);
  
  // Initialize Motor Speed, Max Speed. (steps/second)
  // Max Speed given: Imax=2A, L = 2.5H, V=3.6V, Steps/rev=3200steps
  //Maz Speed= .113 revs/second --> 361.6 steps/second
  XMotor.setMaxSpeed(315);
  TopWheel.setMaxSpeed(315);
  BottomWheel.setMaxSpeed(315);
  ZMotor.setMaxSpeed(315);
  XMotor.setSpeed(250);
  TopWheel.setSpeed(250);
  BottomWheel.setSpeed(250);
  ZMotor.setSpeed(250);
//  XMotor.setCurrentPosition();
}

void loop()
{
  // Run Function
  Run();
}


void    Run(void)
{
  //Define Motor Positions In the array 
  #define  XNextPosition        0
  #define  TopNextPosition      1
  #define  BottomNextPosition   2
  #define  ZNextPosition        3
  
      // Run Serial function
      CheckSerialInput();
      
      if (gValidDataReceived)
      {
        if (gMotorPosition[XNextPosition] == 1)
        {
          XMotor.moveTo(gMotorPosition[XNextPosition] );
        }
        else
        {
          XMotor.moveTo(gMotorPosition[XNextPosition] );
        }
        TopWheel.moveTo(gMotorPosition[TopNextPosition]);
        BottomWheel.moveTo(gMotorPosition[BottomNextPosition]);
        ZMotor.moveTo(gMotorPosition[ZNextPosition]);
        gValidDataReceived = false;
      }
      
}
//*******************************************************
// [12 36 50 100]
//*******************************************************
int ParseOneLine(char *lineBuffer)
{
int myStringLen;
int tt;
char theChar;
int valueCounter;
char valueString[16];
int valueCharIdx;

// Serial.print("ParseOneLine ");
// Serial.print(lineBuffer);
myStringLen = strlen(lineBuffer); //string length is equal to 9 
tt = 0;
valueCounter = 0;
valueCharIdx = 0;
        // Loop stores the step number in the motor location of array
        // gMotorPosition[counter]
while(tt <= myStringLen)
{
theChar = lineBuffer[tt];
if ((theChar == 0x20) || (theChar == 0x5d)) //0x20 is hex for space 0x5d=]
{
valueString[valueCharIdx] = 0; //* null terminate the string
if (valueCounter < kMaxMotors)
{
gMotorPosition[valueCounter] = atoi(valueString); //string to an integer (this is the vector of integers we are looking for)

// Serial.print("value = ");
// Serial.println(gMotorPosition[valueCounter]);

valueCounter += 1;
valueCharIdx = 0; // reset for next variable
gValidDataReceived = true;
}
}
else if (theChar == 0x5b) // hex for [
{
}
else // this will be when string character is a number
{
valueString[valueCharIdx] = theChar;
valueCharIdx += 1; 
}
tt += 1;
}
// for (tt=0; tt<3; tt++)
// {
// Serial.println(gMotorPosition[tt]);
// }
// Serial.println("ParseOneLine exit");
}


//*******************************************************
//Read from matlab
void CheckSerialInput()
{
char theChar;

// send data only when you receive data:
if (Serial.available() > 0) 
{
// read the incoming byte:
                // 0x0d, 0x0a, 0x20 are ASCII code for Carriage REturn, New Line, and Space respectively
theChar = Serial.read();
                Serial.println(theChar);
if ((theChar == 0x0d) || (theChar == 0x0a)) //* is it a Carriage Return wait until you get the whole line to put in array
{
//* we have the END OF LINE (CR = 0x0d = Carriage Return) (/n = 0x0a = newline
gLineBuffer[gLineBuffIdx] = 0; //* null terminate the line
// Serial.println(gLineBuffer);
ParseOneLine(gLineBuffer);
gLineBuffIdx = 0; //* reset index back to 0 (start of line)
}
else if (theChar >= 0x20) //* 0x20 is the HEX value for the CHAR SPACE
{
//* its a regular character, store it in the line buffer
                        // Store output from matlab as gLineBuffer
gLineBuffer[gLineBuffIdx] = theChar;
gLineBuffIdx += 1;
}
}
}




Matlab Output:

global obj1
obj1 = instrfind('Type', 'serial', 'Port', 'COM3', 'Tag', '');
% Create the serial port object if it does not exist
% otherwise use the object that was found.
if isempty(obj1)
    obj1 = serial('COM3');
else
    fclose(obj1);
    obj1 = obj1(1);
end
fopen(obj1);


go_X = 500;
go_Top = 500;
go_Bottom = 500;
go_Z = 500;

fprintf(obj1, sprintf('[%f %f %f %f]',go_X, go_Top, go_Bottom, go_Z));


If you need any other infromation let me know. Any help is GREATLY appreciated.
sketch_nov07a (3).zip
TestMotors.m

Brian Schmalz

unread,
Nov 8, 2013, 11:06:35 AM11/8/13
to accels...@googlegroups.com

Holly,

 

Can you confirm that, with your exact same hardware configuration, a simple sketch on the Arduino can step the motors fine on its own? (Trying to see if it’s the hardware or your sketch/Matlab that’s the problem).

 

*Brian

 

Brian Schmalz  //  Principal Embedded Systems Engineer | product development services

Logic PD
T // 612.436.5134

NOTICE: Important disclaimers and limitations apply to this email.

Please see this web page for our disclaimers and limitations:

http://logicpd.com/email-disclaimer/

--
You received this message because you are subscribed to the Google Groups "accelstepper" group.
To unsubscribe from this group and stop receiving emails from it, send an email to accelstepper...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Holly E.

unread,
Nov 8, 2013, 12:56:50 PM11/8/13
to accels...@googlegroups.com
Brian, 

Yes. I have run the motors by defining the step, direction pins in pinMode. And a digitalWrite command with a microseconddelay.

The motors spin, but not in a fluid manner. They tend to jerk to the correct position. As far as I can tell the Motor Coils are correctly configured based on the wantai spec sheets.

I'm not sure what could be the issue. 

Brian Schmalz

unread,
Nov 8, 2013, 1:10:38 PM11/8/13
to accels...@googlegroups.com

OK, so it sounds like there are problems in your hardware setup or low-level (i.e. simple) control.

 

I’d start with doing a simple timed loop, just setting and clearing one of the step pins of one of the drivers at about 10Hz rate. (100ms between rising edges.) Then slowly adjust the current limit pot on the BED to achieve the smoothest possible stepping. You can feel  if each of the microsteps has the same ‘size’ or ‘torque’ by squeezing the motor shaft with your fingers as it is rotating. You want to try and achieve perfectly smooth motion at a rate where you can feel each individual microstep.

 

If that doesn’t work, you may not have a high enough input voltage for your coil resistance, and so the BED can’t create equal sized microsteps.

Isa Rao

unread,
Oct 20, 2014, 6:15:25 AM10/20/14
to accels...@googlegroups.com
hi there, I am having a similar problem at the moment. I am using a BigEasyDriver+Arduino UNO+ Stepper motor set up and want to make the stepper move when I send a command variable from Matlab. Now, I know the serial communication between Matlab and Arduino works because I can get the LED on the Arduino to switch on and off according to what command variable I send through matlab. I also know that my hardware setup in itself should be ok because I can make the steppers run if I remove the serial communication bit out of my code. If I try to make the stepper move via my Matlab command variable ( or even the Arduinos own serial monitor) the motor doesnt move. Is there anything particular I have to take care off when running the BED or AccelStepper via serial communication input? any help is appreciated!
Heres is my code:


#include <AccelStepper.h>


// Define a stepper and the pins itwill use
AccelStepper stepper1(1, 9, 8);






void setup()
{  


 
 
 
Serial.begin(9600);
  stepper1
.setMaxSpeed(3200);
}
void loop()
{    
 
if(Serial.available() > 0)
 
{
   
char letter =  Serial.read();
   
if (letter=='1')
   
{
     
       stepper1
.moveTo(10000);
  stepper1
.setSpeed(3200);
  stepper1
.runSpeedToPosition();
   
}
else if (letter=='2')
 
{
  stepper1
.moveTo(10000);
  stepper1
.setSpeed(3200);
  stepper1
.runSpeedToPosition();
   
}
}
}




                        else // this will be when string character is a number</o:

...
Reply all
Reply to author
Forward
0 new messages