Stepper motor + driver RMP LCD help

Hi,

I’m new to arduino programming and I’m looking for a bit of help.

I have a project which requires a stepper motor to turn at approximately 1-15RPM with high torque and variable speed. It also must print the speed on an LCD after. The display does not have to be particularly fast/responsive- it is purely so that i can replicate the speed.

My hardware is a TB6600 microstep driver (set at 32 microsteps or 6400 pulses/rev), a NEMA 17 stepper motor, arduino UNO, benchtop power supply, a 2*16 LCD display and an appropriate resistor and potentiometers.

I would be grateful for any help with my code as i cannot get it to do what i want - feel free to modify!

Cheers, Matty

NEMA17_RPM_LCD.ino (707 Bytes)

m-forbes-1:
I would be grateful for any help with my code as i cannot get it to do what i want - feel free to modify!

You have not told us what it actually does do and what you want it to do that is different.

And there does not seem to be any LCD code in your program.

For the future please include short programs in your Post - like this

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);


const int stepsPerRevolution = 6400;

int sPin = 9;
int dirpin = 8;
float stepdelay;
int stepCount = 6400;
int minute = 60;
int steps;

void setup() {
  pinMode(sPin, OUTPUT);
  pinMode(dirpin, OUTPUT);
  digitalWrite(dirpin, HIGH);

  lcd.print ("RPM;");



  Serial.begin(9600);
}





void loop() {
  int val = analogRead(A4);
  stepdelay = map (val, 0,1023, 0, 6400);
  digitalWrite(sPin, HIGH);
  delayMicroseconds(stepdelay);
  digitalWrite(sPin, LOW);
  delayMicroseconds(stepdelay);



  
  Serial.println(minute*( steps /stepsPerRevolution));
  steps = (stepCount++);
  delay(val);  
}

…R
Stepper Motor Basics
Simple Stepper Code

It also must print the speed on an LCD after.

After the next full moon? After noon every Tuesday?

There is no reason for attaching code when it can be posted inline:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);


const int stepsPerRevolution = 6400;

int sPin = 9;
int dirpin = 8;
float stepdelay;
int stepCount = 6400;
int minute = 60;
int steps;

void setup() {
  pinMode(sPin, OUTPUT);
  pinMode(dirpin, OUTPUT);
  digitalWrite(dirpin, HIGH);

  lcd.print ("RPM;");



  Serial.begin(9600);
}





void loop() {
  int val = analogRead(A4);
  stepdelay = map (val, 0,1023, 0, 6400);
  digitalWrite(sPin, HIGH);
  delayMicroseconds(stepdelay);
  digitalWrite(sPin, LOW);
  delayMicroseconds(stepdelay);



  
  Serial.println(minute*( steps /stepsPerRevolution));
  steps = (stepCount++);
  delay(val);  
}

There is no excuse for all the useless white space.

 Serial.println(minute*( steps /stepsPerRevolution));

Anonymous printing sucks. What is that value supposed to be? Do you REALLY need to print that value after EVERY step?

i cannot get it to do what i want - feel free to modify!

You failed to explain what you want the code to do that it does not do. So how can we modify it to do what you want?

Hi all,

Apologies for the confusion- I am new to programming and to this forum.

At the moment;
-the stepper motor turns-however it is too slow and I am unsure of the correct way to speed it up.
-the LCD prints "RPM;" but no value for it.

-everything else appears to work as it should.

-i would like an updated speed to be printed after, say every second? It does not have to be precise at all- just so that i can record a value in in order to replicate speed/conditions.

Apologies again for the crummy code. I thought it may be best to consult the professionals and try to understand what I'm doing before proceeding.

Cheers, Matty.

-the LCD prints "RPM;"

So, you know how to print something to the LCD.

but no value for it.

Because you never tell it to show a value for it (whatever it is).

-the stepper motor turns-however it is too slow

Maybe you are waiting too long between steps. Do you REALLY need to be able to take 6400 discrete steps to make one complete revolution?

I am unsure of how to print the actual value for speed- could you give me an example of how I could do this?

I have the driver set to make 6400 steps in order to produce a smoother rotation. However this can easily be changed if you think it would simply things.

Any help appreciated.

Cheers.

I am unsure of how to print the actual value for speed- could you give me an example of how I could do this?

Sure.

   lcd.print(theActualkValueForSpeed);

Since I have no idea what you think the Serial.print() statement you do have is printing, and you don't appear to, either (or you would have answered my question), I can only assume that you don't KNOW the value to print.

BEFORE you hit reply again, go through all of the previous replies, and make sure you have answered ALL of the questions.

Maybe I should rephrase my question,

How do I take count the number of steps that are taken every second, multiply them by 60 (to find rotations per MINUTE) and then display this number on an LCD?

You are correct, i do not know the exact value to print- because it will change as the potentiometer is adjusted. However, as i mentiontioned previously- this number will be betweeen 1 and 15 RPM.

Thanks for the help- I Hope this makes more sense!

How do I take count the number of steps that are taken every second, multiply them by 60 (to find rotations per MINUTE) and then display this number on an LCD?

You are hiking in the woods. You take a step. You take a step. You take a step.

You want to know how many steps are taken to get to the end of the trail. How would you know that?

Obviously, counting the steps is trivial. Knowing how many steps per unit of time requires knowing when the steps are taken. If you count the number of steps in one second, then reset the count, you can calculate the number of steps per minute. If you count the number of steps in one minute, no calculation is needed.

Use the Blink Without Delay philosophy to know when to do the calculation (if needed) and to reset the number of steps.

Do not mistake number of steps for RPM.

Curious to know if this approach has any merit:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

//#define DEBUG       1   //uncomment to stop time-consuming serial printing 

//microseconds per half-pulse lookup table
const unsigned long uSPerHalfPulse[141] = 
{
    4687, 4261, 3906, 3605, 3348, 3125, 2929, 2757, 2604, 2467, 2343, 2232, 2130, 2038,
    1953, 1875, 1802, 1736, 1674, 1616, 1562, 1512, 1464, 1420, 1378, 1339, 1302, 1266,
    1233, 1201, 1171, 1143, 1116, 1090, 1065, 1041, 1019,                               
    997, 976, 956, 937, 919, 901, 884, 868, 852, 837, 822, 808, 794, 781, 768, 756, 744, 
    732, 721, 710, 699, 689, 679, 669, 660, 651, 642, 633, 625, 616, 608, 600, 593, 585,
    578, 571, 564, 558, 551, 545, 538, 532, 526, 520, 515, 509, 504, 498, 493, 488, 483,
    478, 473, 468, 464, 459, 455, 450, 446, 442, 438, 434, 430, 426, 422, 418, 414, 411,
    407, 404, 400, 397, 393, 390, 387, 384, 381, 378, 375, 372, 369, 366, 363, 360, 357,
    355, 352, 349, 347, 344, 342, 339, 337, 334, 332, 330, 327, 325, 323, 321, 318, 316,
    314, 312                                                                            
};

const int stepsPerRevolution = 6400;

const int sPin = 9;
const int dirpin = 8;
const int pinPot = A4;

//use globals to avoid time-consuming stack accesses
unsigned long
    timeNow,
    timeMotor = 0,
    uSecDelay = 0;
int
    potVal = 0,
    lastidx = -1,
    whole,          //whole part of RPM figure
    frac,           //tenths part of RPM figure
    idx;
bool
    bpinLevel = 0;

    
void setup() 
{
    pinMode( pinPot, INPUT );
    pinMode( sPin, OUTPUT );
    pinMode( dirpin, OUTPUT );
    digitalWrite( dirpin, HIGH );
    lcd.setCursor( 0,0 );
    lcd.print( "RPM:" );
    
    Serial.begin(9600);
    
}//setup

void StepControl( void )
{        
    timeNow = micros();
    if( (timeNow - timeMotor) < uSecDelay )
        return;
    timeMotor = timeNow;
    
    bpinLevel ^= 1;
    digitalWrite( sPin, (bpinLevel)?HIGH:LOW );

    //time-consuming analog is read is placed where we think/know it will
    //do no harm (right at the beginning of a pulse half-period period...)
    potVal = analogRead(pinPot);
    
}//StepControl

void loop() 
{
    //call step control to keep tight control on pin timing    
    StepControl();
    idx = map( potVal, 0, 1023, 0, 140 );
    StepControl();
    if( idx != lastidx )
    {
        //update things only if different from last update
        uSecDelay = uSPerHalfPulse[idx];
        whole = (idx+10)/10;
        frac = idx - ((whole-1)*10);
        StepControl();
        lcd.setCursor(0,5);
        StepControl();
        lcd.print(whole);
        StepControl();
        lcd.print(".");
        StepControl();
        lcd.print(frac);
        StepControl();
        lcd.print( "  " );
        StepControl();
#ifdef DEBUG
        //debug
        StepControl();
        Serial.println( uSecDelay );
        StepControl();
#endif
        lastidx = idx;
        
    }//if
            
}//loop

Blackfin and PaulS,

Thanks for the help. The example code works perfectly.