Problem Step Indexer From Digital Machinist magazine

Results 1 to 8 of 8

Thread: Step Indexer From Digital Machinist magazine

  1. #1
    Registered wtxrcdog's Avatar
    Join Date
    Dec 2004
    Location
    USA
    Posts
    48
    Downloads
    1
    Uploads
    0

    Default Step Indexer From Digital Machinist magazine

    build a step indexer from Digital Machinist Winter 2013 issue. I have been working on this project for several weeks on & off. It uses an Arduino Uno and a Sain smart 1602 lcd display and a Sain smart TB6560 stepper driver. So far I can't even get the motor to turn. coming from the display I have do2 to step CLK- do3 to DIR CW- do11 to EN- 5 volts to CLK+ CW+ EN+ when I power it up I get hold torque then when I set it to turn a certain angle to the right it jumps once. when I try to turn it left it looses holding torque and does nothing.
    Here is the code provided. I omitted the temp sensors. I may not have the thing wired correcty but I think that is ok.

    Thanks Bruce

    /*
    Step Indexer v. 2.2

    This program controls the position of a stepper output shaft via
    manual input and displays the result. It also provides temperature
    information about the stepper motor and its driver board.

    The hardware assumes a bipolar stepper motor with a TB6065 driver board
    and the Sainsmart LCD/keypad sheild with two TMP36 temp sensors

    2.0 Created March 2013 by Gary Liming
    2.1 Frozen October 2013 by Gary Liming
    2.2 Frozen February 2014 by Gary Liming
    */

    //First, include some files for the LCD display, and its motor

    #include <Arduino.h>
    #include <LiquidCrystal.h>


    // Next define your parameters about your motor and gearing

    #define StepsPerRevolution 200 // Change this to represent the number of steps
    // it takes the motor to do one full revolution
    // 200 is the result of a 1.8 degree per step motor
    #define Microsteps 8 // Depending on your stepper driver, it may support
    // microstepping. Set this number to the number of microsteps
    // that is set on the driver board. For large ratios, you may want to
    // use no microstepping and set this to 1.
    #define GearRatio1 3 // Change these three values to reflect any front end gearing you
    #define GearRatio2 40 // are using for three different devices. If no gearing, then
    #define GearRatio3 90 // define this value to be 1. GearRatio1 is the default
    #define GearRatioMax 3 // number of gear ratios defined

    #define AngleIncrement 5 // Set how much a keypress changes the angle setting

    #define CW HIGH // Define direction of rotation -
    #define CCW LOW // If rotation needs to be reversed, swap HIGH and LOW here

    #define DefaultMotorSpeed 0 // zero here means fast, as in no delay

    // define menu screen ids
    #define mainmenu 0
    #define stepmode 1
    #define anglemode 2
    #define runmode 3
    #define jogmode 4
    #define ratiomode 5
    #define tempmode 6
    #define numModes 6 // number of above menu items to choose, not counting main menu

    #define moveangle 10
    #define movesteps 11

    // Define the pins that the driver is attached to.
    // Once set, this are normally not changed since they correspond to the wiring.

    #define motorSTEPpin 2 // output signal to step the motor
    #define motorDIRpin 3 // output siagnal to set direction
    #define motorENABLEpin 11 // output pin to power up the motor
    #define AnalogKeyPin 0 // keypad uses A0
    #define SinkTempPin 1 // temp sensor for heatsink is pin A1
    #define MotorTempPin 2 // temp sensor for motor is pin A2

    #define pulsewidth 2 // length of time for one step pulse
    #define ScreenPause 800 // pause after screen completion
    #define ADSettleTime 10 // ms delay to let AD converter "settle" i.e., discharge

    #define SpeedDelayIncrement 5 // change value of motor speed steps (delay amount)
    #define JogStepsIncrement 1 // initial value of number of steps per keypress in test mode
    #define TSampleSize 7 // size of temperature sampling to average

    // create lcd display construct

    LiquidCrystal lcd(8, 9, 4, 5, 6, 7); //Data Structure and Pin Numbers for the LCD/Keypad

    // define LCD/Keypad buttons
    #define NO_KEY 0
    #define SELECT_KEY 1
    #define LEFT_KEY 2
    #define UP_KEY 3
    #define DOWN_KEY 4
    #define RIGHT_KEY 5

    // create global variables

    int cur_mode = mainmenu;
    int mode_select = stepmode;
    int current_menu;
    float cur_angle = 0;
    int cur_key;
    int num_divisions = 0;
    int numjogsteps = JogStepsIncrement;
    unsigned long stepsperdiv;
    int cur_pos = 0;
    int cur_dir = CW;
    int motorspeeddelay = DefaultMotorSpeed;
    unsigned long motorSteps;
    int gear_ratio_array[GearRatioMax] = {GearRatio1,GearRatio2,GearRatio3};
    int gearratioindex = 0; // the first array element starts with 0

    void setup()
    {
    // Create some custom characters for the lcd display
    byte c_CW[8] = {0b01101,0b10011,0b10111,0b10000,0b10000,0b10000,0 b10001,0b01110}; //Clockwise
    byte c_CCW[8] = {0b10110,0b11001,0b11101,0b00001,0b00001,0b00001,0 b10001,0b01110}; // CounterClockWise
    byte c_DegreeF[8] = {0b01000,0b10100,0b01000,0b00111,0b00100,0b00110,0 b00100,0b00100}; // degreeF
    lcd.createChar(1,c_CW);
    lcd.createChar(2,c_CCW);
    lcd.createChar(3,c_DegreeF);

    // begin program

    motorSteps = gear_ratio_array[gearratioindex]*Microsteps*StepsPerRevolution;
    lcd.begin(16, 2);
    lcd.clear();
    lcd.setCursor(0,0); // display flash screen
    lcd.print("Step Indexer 2.2");
    lcd.setCursor(0,1);
    lcd.print("Ratio =");
    lcd.setCursor(8,1);
    lcd.print(gear_ratio_array[gearratioindex]);
    delay(1500); // wait a few secs
    lcd.clear();

    pinMode(motorSTEPpin, OUTPUT); // set pin 3 to output
    pinMode(motorDIRpin, OUTPUT); // set pin 2 to output
    pinMode(motorENABLEpin, OUTPUT); // set pin 11 to output
    digitalWrite(motorENABLEpin,HIGH); // power up the motor and leave it on

    displayscreen(cur_mode); // put up initial menu screen

    } // end of setup function

    void loop() // main loop services keystrokes
    {
    int exitflag;
    int numjogsteps;

    displayscreen(cur_mode); // display the screen
    cur_key = get_real_key(); // grab a keypress
    switch(cur_mode) // execute the keystroke
    {
    case mainmenu: // main menu
    switch(cur_key)
    {
    case UP_KEY:
    mode_select++;
    if (mode_select > numModes) // wrap around menu
    mode_select = 1;
    break;
    case DOWN_KEY:
    mode_select--;
    if (mode_select < 1) // wrap around menu
    mode_select = numModes;
    break;
    case LEFT_KEY: // left and right keys do nothing in main menu
    break;
    case RIGHT_KEY:
    break;
    case SELECT_KEY: // user has picked a menu item
    cur_mode = mode_select;
    break;
    }
    break;
    case tempmode: // call temps
    dotempmode(cur_key);
    cur_mode = mainmenu;
    break;
    case stepmode: // call steps
    dostepmode(cur_key);
    cur_mode = mainmenu;
    break;
    case anglemode: // call angles
    doanglemode(cur_key);
    cur_mode = mainmenu;
    break;
    case runmode: // call run
    dorunmode(cur_key);
    cur_mode = mainmenu;
    break;
    case jogmode: // call jog
    dojogmode(cur_key);
    cur_mode = mainmenu;
    break;
    case ratiomode: // call ratio
    doratiomode(cur_key);
    cur_mode = mainmenu;
    break;
    } // end of mode switch
    } // end of main loop
    void dostepmode(int tmp_key)
    {
    int breakflag = 0;
    displayscreen(stepmode);
    while (breakflag == 0)
    {
    switch(tmp_key)
    {
    case UP_KEY:
    num_divisions++;
    break;
    case DOWN_KEY:
    if (num_divisions > 0)
    num_divisions--;
    break;
    case LEFT_KEY:
    cur_dir = CCW;
    stepsperdiv = (motorSteps / num_divisions);
    move_motor(stepsperdiv, cur_dir, movesteps);
    delay(ScreenPause); //pause to inspect the screen
    cur_pos--;
    if (cur_pos == (-num_divisions))
    cur_pos = 0;
    break;
    case RIGHT_KEY:
    cur_dir = CW;
    stepsperdiv = (motorSteps / num_divisions);
    move_motor(stepsperdiv, cur_dir, movesteps);
    delay(ScreenPause); // pause to inspect the screen
    cur_pos++;
    if (cur_pos == num_divisions)
    cur_pos = 0;
    break;
    case SELECT_KEY:
    cur_pos = 0; // reset position
    num_divisions = 0; // reset number of divisions
    return;
    break;
    }
    displayscreen(stepmode);
    tmp_key = get_real_key();
    }
    return;
    }
    void doanglemode(int tmp_key)
    {
    int breakflag = 0;
    displayscreen(anglemode);
    while (breakflag == 0)
    {
    switch(tmp_key)
    {
    case UP_KEY:
    if ((cur_angle+AngleIncrement) < 361)
    cur_angle += AngleIncrement;
    break;
    case DOWN_KEY:
    if ((cur_angle-AngleIncrement) > -1)
    cur_angle -= AngleIncrement;
    break;
    case LEFT_KEY:
    cur_dir = CCW;
    stepsperdiv = ((motorSteps * cur_angle) / 360);
    move_motor(stepsperdiv, cur_dir,moveangle);
    delay(ScreenPause); //pause to inspect the screen
    break;
    case RIGHT_KEY:
    cur_dir = CW;
    stepsperdiv = ((motorSteps * cur_angle) / 360);
    move_motor(stepsperdiv, cur_dir,moveangle);
    delay(ScreenPause); //pause to inspect the screen
    break;
    case SELECT_KEY:
    cur_angle = 0; // reset angle to default of zero
    return;
    break;
    }
    displayscreen(anglemode);
    tmp_key = get_real_key();
    }
    return;
    }
    void dorunmode(int tmp_key)
    {
    int breakflag = 0;
    delay(100); // wait for keybounce from user's selection
    cur_dir = CW; // initially, clockwise
    displayscreen(runmode); // show the screen
    while (breakflag == 0) // cycle until Select Key sets flag
    {
    move_motor(1,cur_dir,0); // move motor 1 step
    if (analogRead(AnalogKeyPin) < 850 ) // if a keypress is present {
    {
    cur_key = get_real_key(); // then get it
    switch(cur_key) // and honor it
    {
    case UP_KEY: // bump up the speed
    if (motorspeeddelay >= SpeedDelayIncrement) {
    motorspeeddelay -= SpeedDelayIncrement;
    displayscreen(runmode);
    }
    break;
    case DOWN_KEY: // bump down the speed
    motorspeeddelay += SpeedDelayIncrement;
    displayscreen(runmode);
    break;
    case LEFT_KEY: // set direction
    cur_dir = CCW;
    displayscreen(runmode);
    break;
    case RIGHT_KEY: // set other direction
    cur_dir = CW;
    displayscreen(runmode);
    break;
    case SELECT_KEY: // user wants to stop
    motorspeeddelay = DefaultMotorSpeed; // reset speed
    breakflag = 1; // fall through to exit
    }
    }
    }
    }
    void dotempmode(int test_key)
    {
    while (1)
    {
    if (test_key == SELECT_KEY) return; // all we do here is wait for a select key
    test_key = get_real_key();
    }
    return; // to exit
    }

    void dojogmode(int tmp_key)
    {
    int breakflag = 0;

    numjogsteps = JogStepsIncrement;
    for (;breakflag==0
    {
    switch(tmp_key)
    {
    case UP_KEY: // bump the number of steps
    numjogsteps += JogStepsIncrement;
    break;
    case DOWN_KEY: // reduce the number of steps
    if (numjogsteps > JogStepsIncrement)
    numjogsteps -= JogStepsIncrement;
    break;
    case LEFT_KEY: // step the motor CCW
    move_motor(numjogsteps,CCW,0);
    break;
    case RIGHT_KEY: // step the motor CW
    move_motor(numjogsteps,CW,0);
    break;
    case SELECT_KEY: // user want to quit
    breakflag = 1;
    break;
    }
    if (breakflag == 0)
    {
    displayscreen(jogmode);
    tmp_key = get_real_key();
    }
    }
    numjogsteps = JogStepsIncrement;
    cur_mode = mainmenu; // go back to main menu
    return;
    }

    void doratiomode(int tmp_key)
    {
    int breakflag = 0;

    displayscreen(ratiomode);
    for (;breakflag==0
    {
    switch(tmp_key)
    {
    case UP_KEY: // bump the number of steps
    ++gearratioindex;
    if (gearratioindex > GearRatioMax-1) //wrap around if over the max
    gearratioindex = 0;
    motorSteps = gear_ratio_array[gearratioindex]*Microsteps*StepsPerRevolution;
    break;
    case DOWN_KEY: // reduce the number of steps
    --gearratioindex;
    if (gearratioindex < 0)
    gearratioindex = GearRatioMax-1; // wrap around if already at the bottom
    motorSteps = gear_ratio_array[gearratioindex]*Microsteps*StepsPerRevolution;
    break;
    case LEFT_KEY: // Left and Right keys do nothing in this mode
    break;
    case RIGHT_KEY:
    break;
    case SELECT_KEY: // user want to quit
    breakflag = 1;
    break;
    }
    if (breakflag == 0)
    {
    displayscreen(ratiomode);
    tmp_key = get_real_key();
    }
    }
    numjogsteps = JogStepsIncrement;
    cur_mode = mainmenu; // go back to main menu
    return;
    }

    void displayscreen(int menunum) // screen displays are here
    {
    lcd.clear();
    lcd.setCursor(0,0);
    switch (menunum)
    {
    case mainmenu:
    lcd.print("Select Mode");
    lcd.setCursor(0,1);
    lcd.print("Mode = ");
    lcd.setCursor(7,1);
    switch(mode_select)
    {
    case(stepmode):
    lcd.print("Step");
    break;
    case(tempmode):
    lcd.print("Temp");
    break;
    case(anglemode):
    lcd.print("Angle");
    break;
    case(runmode):
    lcd.print("Run");
    break;
    case(jogmode):
    lcd.print("Jog");
    break;
    case(ratiomode):
    lcd.print("Ratio");
    break;
    }
    break;
    case tempmode:
    lcd.setCursor(0,0);
    lcd.print(" Sink Temp:");
    lcd.setCursor(11,0);
    lcd.print(gettemp(SinkTempPin));
    lcd.setCursor(15,0);
    lcd.write(byte(3));
    lcd.setCursor(0,1);
    lcd.print("Motor Temp:");
    lcd.setCursor(11,1);
    lcd.print(gettemp(MotorTempPin));
    lcd.setCursor(15,1);
    lcd.write(byte(3));
    break;
    case stepmode:
    lcd.print("Divisions:");
    lcd.setCursor(10,0);
    lcd.print(num_divisions);
    lcd.setCursor(0,1);
    lcd.print(" Position:");
    lcd.setCursor(10,1);
    lcd.print(cur_pos);
    break;
    case movesteps:
    lcd.print("Steps/Div:");
    lcd.setCursor(10,0);
    lcd.print(stepsperdiv);
    lcd.setCursor(0,1);
    lcd.print("Move ");
    lcd.setCursor(5,1);
    if (cur_dir == CW)
    lcd.write(byte(1));
    else
    lcd.write(byte(2));
    lcd.setCursor(7,1);
    lcd.print("to:");
    lcd.setCursor(10,1);
    lcd.print(cur_pos);
    break;
    case anglemode:
    lcd.print("Move ");
    lcd.setCursor(5,0);
    lcd.print((int)cur_angle);
    lcd.setCursor(8,0);
    lcd.print(" degrees");
    break;
    case moveangle:
    lcd.print("Move ");
    lcd.setCursor(5,0);
    if (cur_dir == CW)
    lcd.write(byte(1));
    else
    lcd.write(byte(2));
    lcd.setCursor(12,0);
    lcd.print("steps");
    lcd.setCursor(0,1);
    lcd.print("to ");
    lcd.setCursor(3,1);
    lcd.print((int)cur_angle);
    lcd.setCursor(7,1);
    lcd.print("degrees");
    break;
    case runmode:
    lcd.print("Continuous");
    lcd.setCursor(11,0);
    if (cur_dir == CW)
    lcd.write(byte(1));
    else
    lcd.write(byte(2));
    lcd.setCursor(0,1);
    lcd.print("Speed = ");
    lcd.setCursor(8,1);
    lcd.print((int)motorspeeddelay);
    break;
    case jogmode:
    lcd.print("Jog ");
    lcd.setCursor(0,1);
    lcd.print("Steps/jog: ");
    lcd.setCursor(11,1);
    lcd.print(numjogsteps);
    break;
    case ratiomode:
    lcd.setCursor(0,0);
    lcd.print("Ratio =");
    lcd.setCursor(8,0);
    lcd.print(gear_ratio_array[gearratioindex]);
    break;
    }
    return;
    }

    void move_motor(unsigned long steps, int dir, int type)
    {
    unsigned long i;

    if (type == movesteps)
    displayscreen(movesteps);
    if (type == moveangle)
    displayscreen(moveangle);
    for (i=0;i<steps;i++)
    {
    digitalWrite(motorDIRpin,dir);
    digitalWrite(motorSTEPpin,HIGH); //pulse the motor
    delay(pulsewidth);
    digitalWrite(motorSTEPpin,LOW);
    if (type == movesteps) // in this mode display progress
    {
    lcd.setCursor(10,1);
    lcd.print(i);
    }
    if (type == moveangle) // in this mode display progress
    {
    lcd.setCursor(7,0);
    lcd.print(i);
    }
    delay(motorspeeddelay); // wait betweeen pulses
    }
    return;
    }

    int gettemp(int device)
    {
    int tfahrenheit=0;
    int i;
    analogRead(device); // first time to let adc settle down
    delay(50); // throw first reading away
    for (i=0;i<TSampleSize;++i) // take several readings
    {
    tfahrenheit += ((analogRead(device)* 4.88758)/10);
    delay(ADSettleTime);
    }
    return (int)(tfahrenheit/TSampleSize); // return the average
    }

    int get_real_key(void) // routine to return a valid keystroke
    {
    int trial_key = 0;
    while (trial_key < 1)
    {
    trial_key = read_LCD_button();
    }
    delay(200); // 200 millisec delay between user keys
    return trial_key;
    }

    int read_LCD_button() // routine to read the LCD's buttons
    {
    int key_in;
    delay(ADSettleTime); // wait to settle
    key_in = analogRead(0); // read ADC once
    delay(ADSettleTime); // wait to settle
    // average values for my board were: 0, 144, 324, 505, 742
    // add approx 100 to those values to set range
    if (key_in > 850) return NO_KEY;
    if (key_in < 70) return RIGHT_KEY;
    if (key_in < 250) return UP_KEY;
    if (key_in < 450) return DOWN_KEY;
    if (key_in < 650) return LEFT_KEY;
    if (key_in < 850) return SELECT_KEY;
    }

    Similar Threads:
    www.wtxrcdog.com
    http://wtxrcdog.blogspot.com/


  2. #2
    Gold Member doorknob's Avatar
    Join Date
    Jan 2010
    Location
    USA
    Posts
    2141
    Downloads
    0
    Uploads
    0

    Default Re: Step Indexer From Digital Machinist magazine

    Your best bet would be to use an oscilloscope to probe the step, dir, and enable lines to understand what is happening (if you don't have access to one, perhaps you have a friend who does).

    The loss of holding torque when you change direction could mean that you have the enable terminal of the driver incorrectly hooked up to the dir signal from the Arduino - rechecking your wiring might be a good idea - you could monitor the enable voltage with a multimeter to see whether that may be the case.



  3. #3
    Registered wtxrcdog's Avatar
    Join Date
    Dec 2004
    Location
    USA
    Posts
    48
    Downloads
    1
    Uploads
    0

    Default Re: Step Indexer From Digital Machinist magazine

    I just got an oscilloscope for a pc. I will try it out on this project. What is the enable pin responsible for does it just activate the driver board to send power to the steppers?

    Thanks for the help
    Bruce

    www.wtxrcdog.com
    http://wtxrcdog.blogspot.com/


  4. #4
    Gold Member doorknob's Avatar
    Join Date
    Jan 2010
    Location
    USA
    Posts
    2141
    Downloads
    0
    Uploads
    0

    Default Re: Step Indexer From Digital Machinist magazine

    Yes, that's usually what it does - you may not have holding torque if the driver is not enabled.



  5. #5
    Registered
    Join Date
    Aug 2006
    Location
    USA
    Posts
    21
    Downloads
    0
    Uploads
    0

    Default Re: Step Indexer From Digital Machinist magazine

    Hi Bruce,

    I was wondering if you were ever successful in getting this project to work properly. Just bought an Arduino Mega and want to use it to control a rotary table. I have the stepper driver and steppers (Slow-Syn) that I would like to use.

    Thanks,

    Dan



  6. #6
    Member revwarguy's Avatar
    Join Date
    Feb 2009
    Location
    USA
    Posts
    499
    Downloads
    0
    Uploads
    0

    Default Re: Step Indexer From Digital Machinist magazine

    I am the author of the code you posted as well as the author of the article. So far, many have had this run on first try.

    There was a bit of confusion about the pins on the display shield, and the latest version corrects the wiring mislabeling - even though it should have worked as labelled originally. You can simply omit the temp sensors if you don't want them. Based on your problem description, I am pretty sure you have something mis-wired. If you would please go to the magazine site where you got the code and download the latest version and print out the readme notes to compare your wiring with the diagram, I think you will find your problem.

    Please let the magazine site be the distributor of the code, because now you have posted code that is no longer the right stuff. You don't have to be a subscriber to get it.

    Also, the magazine forum has a long thread on this topic, and any support issues should be posted there.

    "72.6 per cent of all statistics are made up on the spot." - Steven Wright


  7. #7
    Registered
    Join Date
    Jun 2008
    Location
    USA
    Posts
    15
    Downloads
    0
    Uploads
    0

    Default Re: Step Indexer From Digital Machinist magazine

    Quote Originally Posted by revwarguy View Post
    \If you would please go to the magazine site where you got the code and download the latest version and print out the readme notes to compare your wiring with the diagram, I think you will find your problem.

    Please let the magazine site be the distributor of the code, because now you have posted code that is no longer the right stuff. You don't have to be a subscriber to get it.

    Also, the magazine forum has a long thread on this topic, and any support issues should be posted there.
    How about a link to the download? I am having problems with direction on your sketch, though the exact same hardware works with a sketch from another author.

    Chuck

    Last edited by chucketn; 04-15-2015 at 10:18 AM. Reason: speeling


  8. #8
    Member revwarguy's Avatar
    Join Date
    Feb 2009
    Location
    USA
    Posts
    499
    Downloads
    0
    Uploads
    0

    Default Re: Step Indexer From Digital Machinist magazine

    Go here:

    Digital Machinist

    and scroll down to the Winter 2013 issue and click the DM8.4Liming link to start the zip file download. All versions are included - use the 2.3 one.

    Then go to the forum area and create an account if you don't have one, and go to the Digital Machinist forum and select the "step indexer article" thread and post questions there.

    I don't check this thread very often.

    "72.6 per cent of all statistics are made up on the spot." - Steven Wright


Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


About CNCzone.com

    We are the largest and most active discussion forum for manufacturing industry. The site is 100% free to join and use, so join today!

Follow us on


Our Brands

Step Indexer From Digital Machinist magazine

Step Indexer From Digital Machinist magazine