Notifications
Clear all

Trying to get a stepper motor to rotate a wheel code problem

22 Posts
5 Users
0 Reactions
3,969 Views
(@greendragon)
Member
Joined: 3 years ago
Posts: 42
Topic starter  

My Goal:

A script that will allow me to do the following -

1. choose the number of full rotations of a wheel and then the stepper stops

   example  1 = 1 full rotation, 2 = 2 full rotations, 3 = 3 full rotations 

2. control forwards or backwards

3. control the speed of the wheel

I am using a nema 17 motor 8HS11-0204S ( 200 steps for a full revolution - I think)

 

Below is the code I have so far and it does not work! Note I am new to coding so if you could just keep it simple it would be greatly appreciated. Thanks

// defines pins
const int dirPin = 10;
const int stepPin = 11;

int numberOfSteps = 200;
int millisbetweenSteps = 250;  // milliseconds - or try 1000 for slower steps

void setup() {
  pinMode(dirPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
}

void loop() {
  digitalWrite(dirPin, LOW);
  for (int n = 0; n < numberOfSteps; n++) {
    digitalWrite(stepPin, HIGH);
    delay(2);
    digitalWrite(stepPin, LOW);
    delay(millisbetweenSteps);
  }
}


   
Quote
robotBuilder
(@robotbuilder)
Member
Joined: 7 years ago
Posts: 2429
 

@greendragon

Below is the code I have so far and it does not work!

Where did the code come from. What is your hardware setup?

Any Arduino c++ programmer here can give you an exact solution and explanation if enough detail is given.

Probably worth while getting up to speed on using stepper motors and how they work? Plenty of examples online.

https://dronebotworkshop.com/big-stepper-motors/



   
ReplyQuote
(@davee)
Member
Joined: 5 years ago
Posts: 2037
 

Hi @greendragon,

  To supplement the wise advice provided by @robotbuilder, including the reference to one of Bill (@dronebot-workshop)'s excellent tutorials, I offer a few comments which I hope may be helpful.

You say it 'does not work', but please also remember to say both what you expected it to do, and what actually happened. I appreciate your programme is short, so that the reader can quickly guess what you might have expected, but such assumptions are often wrong, leading everyone down the wrong paths.

-------

In the interest of trying to move forward, I'll guess you were expecting the motor shaft to make a single 360 degree rotation over a period of 7.5 minutes. I'll also guess, the shaft stayed stationary or maybe moved a small angle over the same period of time. The motion might have been so small, say a few degrees, that you didn't even notice it.

-------------

I haven't tried to compile and run your programme, so there might be an error I missed when glancing at it, but I think it is important to check the hardware first.

Simple wiring errors/faults are a common problem. Sometimes this is due to unexpected faults, like a loose connection, whilst others are due to a misunderstanding of how the system should be connected. Posting a circuit diagram and some photos of the set up might enable others to make suggestions as to what to look for, etc. Include details of your power supply arrangement, as a motor of this size will need a suitable source.

In addition, you do not say which motor driver/controller you are using. Many such devices support 'micro-stepping' which is an electrical trick to increase the effective number of steps per revolution, sometimes by a factor as large as 128. In this case, 200 'steps' sent to the controller would only move the shaft by about 4 degrees!

-------------

So, sorry I cannot offer an immediate solution, but if you supply a little more information, someone may be able to offer a useful suggestion.

Best wishes and good luck, Dave



   
ReplyQuote
(@aliarifat)
Member
Joined: 2 years ago
Posts: 119
 

Posted by: @davee

Hi @greendragon,

  To supplement the wise advice provided by @robotbuilder, including the reference to one of Bill (@dronebot-workshop)'s excellent tutorials, I offer a few comments which I hope may be helpful.

You say it 'does not work', but please also remember to say both what you expected it to do, and what actually happened. I appreciate your programme is short, so that the reader can quickly guess what you might have expected, but such assumptions are often wrong, leading everyone down the wrong paths.

-------

In the interest of trying to move forward, I'll guess you were expecting the motor shaft to make a single 360 degree rotation over a period of 7.5 minutes. I'll also guess, the shaft stayed stationary or maybe moved a small angle over the same period of time. The motion might have been so small, say a few degrees, that you didn't even notice it.

-------------

I haven't tried to compile and run your programme, so there might be an error I missed when glancing at it, but I think it is important to check the hardware first.

Simple wiring errors/faults are a common problem. Sometimes this is due to unexpected faults, like a loose connection, whilst others are due to a misunderstanding of how the system should be connected. Posting a circuit diagram and some photos of the set up might enable others to make suggestions as to what to look for, etc. Include details of your power supply arrangement, as a motor of this size will need a suitable source.

In addition, you do not say which motor driver/controller you are using. Many such devices support 'micro-stepping' which is an electrical trick to increase the effective number of steps per revolution, sometimes by a factor as large as 128. In this case, 200 'steps' sent to the controller would only move the shaft by about 4 degrees!

-------------

So, sorry I cannot offer an immediate solution, but if you supply a little more information, someone may be able to offer a useful suggestion.

Best wishes and good luck, Dave

Please check if your stepper driver is getting sufficient power.

 



   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 7 years ago
Posts: 2429
 

@greendragon

The code I wrote for another poster to control a model train turn table used this little stepper but I suspect the control logic would be similar for the NEMA. 

stepperAndController

 

It used 8 push buttons to rotate the table to 8 positions.

 

#define IN1 8 
#define IN2 9 
#define IN3 10 
#define IN4 11 

int oldAngle = 0;
int newAngle = 0;

int shedPos[] = {0,512,1024,1536,2048,2560,3072,3584};

void setup() { 
  // stepper motor
  pinMode(IN1, OUTPUT); 
  pinMode(IN2, OUTPUT); 
  pinMode(IN3, OUTPUT); 
  pinMode(IN4, OUTPUT);
  // input buttons
  pinMode(22,INPUT);
  pinMode(23,INPUT);
  pinMode(24,INPUT);
  pinMode(25,INPUT);
  pinMode(26,INPUT);
  pinMode(27,INPUT);
  pinMode(28,INPUT);
  pinMode(29,INPUT);
  // LEDS
  pinMode(32,OUTPUT);
  pinMode(33,OUTPUT);
  pinMode(34,OUTPUT);
  pinMode(35,OUTPUT);
  pinMode(36,OUTPUT);
  pinMode(37,OUTPUT);
  pinMode(38,OUTPUT);
  pinMode(39,OUTPUT);
  Serial.begin(9600);  
  delay(1000); 
} 

int GET_NUMBER(){
  int num;
    num = -1;
    if (digitalRead(22) == LOW) num = 0;
    if (digitalRead(23) == LOW) num = 1;
    if (digitalRead(24) == LOW) num = 2;
    if (digitalRead(25) == LOW) num = 3;
    if (digitalRead(26) == LOW) num = 4;
    if (digitalRead(27) == LOW) num = 5;
    if (digitalRead(28) == LOW) num = 6;
    if (digitalRead(29) == LOW) num = 7;

    return num;
}

void moveStepper(int steps_left,int Direction) { 

  int Steps = 0; 
  unsigned long last_time; 
  unsigned long currentMillis ; 
  long time;
   
  while(steps_left>0){ 
    currentMillis = micros(); 
    if(currentMillis-last_time>=1000){ 

      for (int x=0;x<1;x++){ 
        switch(Steps){ 
          case 0: 
          digitalWrite(IN1, LOW);
          digitalWrite(IN2, LOW); 
          digitalWrite(IN3, LOW); 
          digitalWrite(IN4, HIGH); 
          break; 
          case 1:
          digitalWrite(IN1, LOW); 
          digitalWrite(IN2, LOW); 
          digitalWrite(IN3, HIGH); 
          digitalWrite(IN4, HIGH); 
          break; 
          case 2: 
          digitalWrite(IN1, LOW); 
          digitalWrite(IN2, LOW); 
          digitalWrite(IN3, HIGH); 
          digitalWrite(IN4, LOW); 
          break; 
          case 3: 
          digitalWrite(IN1, LOW); 
          digitalWrite(IN2, HIGH); 
          digitalWrite(IN3, HIGH); 
          digitalWrite(IN4, LOW); 
          break; 
          case 4: 
          digitalWrite(IN1, LOW); 
          digitalWrite(IN2, HIGH); 
          digitalWrite(IN3, LOW); 
          digitalWrite(IN4, LOW); 
          break; 
          case 5: 
          digitalWrite(IN1, HIGH); 
          digitalWrite(IN2, HIGH); 
          digitalWrite(IN3, LOW); 
          digitalWrite(IN4, LOW); 
          break; 
          case 6: 
          digitalWrite(IN1, HIGH); 
          digitalWrite(IN2, LOW); 
          digitalWrite(IN3, LOW); 
          digitalWrite(IN4, LOW); 
          break; 
          case 7: 
          digitalWrite(IN1, HIGH); 
          digitalWrite(IN2, LOW); 
          digitalWrite(IN3, LOW); 
          digitalWrite(IN4, HIGH); 
          break; 
          default: 
          digitalWrite(IN1, LOW); 
          digitalWrite(IN2, LOW); 
          digitalWrite(IN3, LOW); 
          digitalWrite(IN4, LOW);  
          break; 
        } 
        if(Direction==1){ 
          Steps++;
        } 
        if(Direction==0){ 
          Steps--; 
        } 
        if(Steps>7){
          Steps=0;
        } 
        if(Steps<0){
          Steps=7; 
        }  
      } 

      time=time+micros()-last_time; 
      last_time=micros(); 
      steps_left--; 
    } 
  } 
}

int tool;
int Direction2;
int stepCount;

void MOVE_DISC(){
  stepCount = abs(newAngle-oldAngle);
    
  if (newAngle < oldAngle){
    Direction2 = 0;
  }else{
    Direction2 = 1;
  }
  
  if (abs(newAngle-oldAngle)>2047){
    stepCount = 4096 - stepCount;
    if (Direction2==0){
      Direction2 = 1;
    }else{
      Direction2 = 0;
    }
  }

  moveStepper(stepCount,Direction2);

  oldAngle = newAngle;  // update current position
}

int btnID;

void loop(){
  
  btnID = GET_NUMBER();
  
  if (btnID != -1){          // returns -1 if no tool on
    Serial.print(btnID);
    newAngle = shedPos[btnID];
    MOVE_DISC();
  }
  
  
}

 



   
ReplyQuote
TFMcCarthy
(@tfmccarthy)
Member
Joined: 2 years ago
Posts: 452
 

Posted by: @greendragon

Below is the code I have so far and it does not work!

I'll repeat the request for the schematic. Otherwise, we're just guessing.

The code appears to be similar to Bill's code for the Bipolar stepper. A difference I see is the missing Stepper library include file. If that was the intent, then the direction pin is using a motor control PWM pin (pin 10). That won't work.

But we really need more info on the circuit.


The one who has the most fun, wins!


   
ReplyQuote
(@greendragon)
Member
Joined: 3 years ago
Posts: 42
Topic starter  

The layout is the following -

Arduino Mega 2560 R3 that is connected to a adafruit TMC2209 Stepper Motor Driver Breakout Board (No kidding that its the full name - From now on I will be calling it the TMC2209 Board)

Pin D 10 is connected to the Dir on the TMC2209 Board

Pin D 11 is connected to the STEP on the TMC2209 Board

The +5 on the Mega is connected to the VDD on the TMC2209 Board

The GND right above Pin D13 on the Mega is connected to the GND on the TMC2209 Board.

The + & - on the TMC2209 Board is connected to my HM310 power supply which is supplying 12V and 1.5 Amps.

2B, 2A, 1A, 1B on the TMC2209 Board are connected to a nema 17 motor 8HS11-0204S

 



   
ReplyQuote
(@greendragon)
Member
Joined: 3 years ago
Posts: 42
Topic starter  

The code below is the new code I have been working on.

It does work (the wheel does one full rotation pauses and then rotates 5 more times in a row - no pause). I want the wheel to do 5 full rotations.

there is a flaw in the logic that I don't get.

 

#include <Stepper.h>

const int stepsPerRevolution = 6400;  // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 10, 11);

boolean running = true;  // Global variable

void setup() {
  // set the speed at 60 rpm:
  myStepper.setSpeed(60);
  // initialize the serial port:
  Serial.begin(9600);
}
int i = 0;

void loop() {
  if (!running) {
    return;  // Exit loop() if running is false
  }

  // Your main loop logic here
  myStepper.step(-stepsPerRevolution);
  delay(2);
  i++;
  Serial.println(i);

  // Example condition to stop the loop
  if (i == 5) {
    running = false;
  }
}


   
ReplyQuote
TFMcCarthy
(@tfmccarthy)
Member
Joined: 2 years ago
Posts: 452
 

Posted by: @greendragon

The layout is the following -

Thank you for this. With this information I was able to find the Adafruit learning page for the board. (Hats off to Adafruit for a complete reference page! They really do a fine job. I'm really just recapping what they present.)

I put together a schematic image to match your description

schematic

Adafruit provides a sample sketch

// SPDX-FileCopyrightText: 2025 Liz Clark for Adafruit Industries
//
// SPDX-License-Identifier: MIT

const int DIR = 5;  // change to your dir pin
const int STEP = 6; // change to your step pin
const int microMode = 8; // microstep mode, default is 1/8 so 8; ex: 1/16 would be 16
// full rotation * microstep divider
const int steps = 200 * microMode;

void setup()
{
  // setup step and dir pins as outputs
  pinMode(STEP, OUTPUT);
  pinMode(DIR, OUTPUT);
}

void loop()
{
  // change direction every loop
  digitalWrite(DIR, !digitalRead(DIR));
  // toggle STEP to move
  for(int x = 0; x < steps; x++)
  {
    digitalWrite(STEP, HIGH);
    delay(2);
    digitalWrite(STEP, LOW);
    delay(2);
  }
  delay(1000); // 1 second delay
}

You need to change the DIR and STEP pins to 10 and 11

With this driver board you don't need the Stepper library as the board controls the motor signals.

The behavior is that for each iteration of the loop function the motor rotates one full revolution, alternating directions for each iteration.


The one who has the most fun, wins!


   
ReplyQuote
(@greendragon)
Member
Joined: 3 years ago
Posts: 42
Topic starter  

Adafruit Script Does not work and yes I did change the pins...



   
ReplyQuote
(@greendragon)
Member
Joined: 3 years ago
Posts: 42
Topic starter  

Please take a look at the last script I posted. 

It does work (the wheel does one full rotation pauses and then rotates 5 more times in a row - no pause). I want the wheel to do 5 full rotations.

there is a flaw in the logic that I don't get.



   
ReplyQuote
TFMcCarthy
(@tfmccarthy)
Member
Joined: 2 years ago
Posts: 452
 

Posted by: @greendragon

Please take a look at the last script I posted. 

OK.

On a quick visual inspection, the loop should run 6 times (0-5) before early termination. However, the stepper library code is troublesome. It uses the operational pins (DIR and STEP) as motor control pins. Calling myStepper.step() will cause the library to set the STEP pin repeatedly which should cause the driver board to try to change the motor pins as well.  The DIR pin is changed in a similar manner. This is chaos and I'm surprised the motor turns at all. I don't doubt you but I'm at a loss to explain it.

Hence, I need to scare up some components to test. I don't have the same driver board but do have a ULN2003 driver chip and a 28BYJ-48 stepper motor. (I never thought I'd have a use for them.) I want to verify that the basic sketch functions before diving into why the Adafruit sketch has issues.


The one who has the most fun, wins!


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 7 years ago
Posts: 2429
 

The code provided by @greendragon includes returning from the Arduino C++ loop but to where? Apparently back to itself according to what I found online. And apparently an exit() in the loop stops everything. It is strange code. The delay(2) seems pointless and is perhaps a remnant of code that doesn't use the library as given by the code posted by @tfmccarthy . I couldn't figure out why it would do a full rotation and pause and then do the five desired rotations. I would just forget about it and use the Adafruit provided sample sketch posted by @tfmccarthy then you can tackle the desired behaviors you wrote about earlier.

Unfortunately I don't have the particular hardware to test but would still be interested in why it runs once and pauses before it performs the five full rotations.



   
ReplyQuote
(@greendragon)
Member
Joined: 3 years ago
Posts: 42
Topic starter  

@robotbuilder I have the feeling it's something to do with the library, but that level of skill to understand that is way beyond me. Also that Adafruit provided sample sketch does not work as advertised. that's why I have been trying other codes and searching out help. I was led to believe that running a stepper motor was no problem, but this is turning out to be not so simple. 



   
ReplyQuote
(@greendragon)
Member
Joined: 3 years ago
Posts: 42
Topic starter  

Just on intuition I uninstalled the Stepper library 1.1.3 and installed a older version and run a semi working script and the motor did not move. I then uninstalled and  installed a even older version and lets just say the motor did not like it. 

My conclusion is that some code I am using that is only for the stepper library is messed up in the current version.

 

  



   
ReplyQuote
Page 1 / 2