Stepper motor judder whilst using millis

I only know basic programming so it would be greatly appreciated if any response is made as simple as possible.

The following (part) program is within the SETUP()

The program works fine but there is a slight glitch that I do not understand.
I wish to run a stepper motor constantly until a hall effect sensor has be activated, upon this time the stepper motor stops and the program continues to LOOP().
Whilst the stepper motor runs a series of LED’s flash in sequence.

The problem I have is the stepper motor judders every time the millis count (currentMillisled – previousMillisled) reaches the required interval (intervalled).

Can anyone help please

void setup()
{
 mcp1.begin(addr1);
 mcp2.begin(addr2);
 stepper.setMaxSpeed(75);
 stepper.setAcceleration(255);

 Serial.begin(9600);

// runs stepper motor

 while (digitalRead(sensor) == HIGH) {

   stepper.move(4000);
   stepper.run();

   currentMillisled = millis();
   if (currentMillisled - previousMillisled >= intervalled)
   {
     for (int ledrotate = 0; ledrotate < 16; ledrotate++)
     {
       mcp1.pinMode(ledpin[ledrotate], INPUT);
       mcp2.pinMode(ledpin[ledrotate], INPUT);

       // select the correct mcp chip

       if (((ledcount) < 2) ||
           (((ledcount) > 5) && ((ledcount) < 10)) ||
           ((ledcount) > 13)) {
         mcp1.pinMode(ledpin[x], OUTPUT);
         mcp1.digitalWrite(ledpin[x], LOW); 
       }
       else {
         mcp2.pinMode(ledpin[x], OUTPUT);
         mcp2.digitalWrite(ledpin[x], LOW)
       }
     }
     previousMillisled = currentMillisled;
     Serial.print ("led= ");
     Serial.println (x);
     Serial.print ("count= ");
     Serial.println (ledcount);
     x++;
     ledcount++;
     if (x >= 16) x = 0;
     if (ledcount >= 16) ledcount = 0;
   }

   if (digitalRead(sensor) == LOW) break;

 }
 {
   // switches all led’s off

   for (int ledoff = 0; ledoff < 8; ledoff++)
   {
     mcp1.pinMode (ledpinsetup[ledoff], INPUT);
     mcp2.pinMode (ledpinsetup[ledoff], INPUT);
   }
 }

  mcp1.pinMode(ledpin[0], OUTPUT);
 mcp1.digitalWrite(ledpin[0], HIGH);

 digitalWrite (ms1, HIGH);
 digitalWrite (ms2, HIGH);
 digitalWrite (ms3, HIGH);

 digitalWrite(sleep, LOW);

 stepper.setMaxSpeed(600);
 stepper.setAcceleration(80);
 }

Every time you go through your while() loop, you are asking your stepper to move 4000 more steps but there is no guarantee that it has finished doing so or is still in the middle of the move. When your timer expires, and you are doing other things, the stepper may finish before you get back to the beginning of the loop.

It is always best to post a complete sketch since what you posted can not be compiled.

16rdtt:
I wish to run a stepper motor constantly until a hall effect sensor has be activated,

For that you should use runSpeed() rather than run() - but that won't use acceleration so make sure the speed is slow.

If you really need acceleration then you should give a very large move() destination BEFORE the WHILE loop and also use stepper.stop() when it is appropriate to bring the motor to a decelerated halt. The move() value should not be updated inside the WHILE loop.

...R

Thank you for your replies

I will look into your suggestions.

I did spend a lot of time trying to resolve this myself, however I am a beginner and most articles I read I just found them rather baffling.

Thanks for you help

Hi,

I have done what you have suggested and changed the run() to runSpeed().

It work to a point. The stepper motor does run continuously without judder, however it runs too slowly.

I have tried experimenting with stepper.setSpeed(value), stepper.setMaxSpeed(value) and even

stepper.setAcceleration(value);.

these do work, but anything highter than the value 225 the judder comes back.

as requested I attached the complete code (minus the void loop() as this has not been wrote yet)

Any further suggestions on regulating the speed without judder would be greatly appreciated, as I am at a loss.

I have not added the stepper.stop() line as the stepper automatically stops when it exists the while statement

#include <Wire.h>
#include <AccelStepper.h>
#include <Adafruit_MCP23017.h>

#define dirPin 2
#define stepPin 3
#define motorInterfaceType 1
#define addr1 0
#define addr2 1

Adafruit_MCP23017 mcp1;
Adafruit_MCP23017 mcp2;


AccelStepper stepper(1, 3, 2);

int automaticswitch = A0;
int fallshort = A1;
int overrun = A2;

int currentRead = A3;
int currentValue;

int relay1a = 10;
int relay1b = 11;
int relay2a = 8;
int relay2b = 9;

int sensor = 13;
int sleep = 4;

int ms1 = 5;
int ms2 = 6;
int ms3 = 7;

int MCP1_input1 = 0;
int MCP1_input2 = 1;
int MCP1_input3 = 2;
int MCP1_input4 = 3;
int MCP1_input5 = 15;
int MCP1_input6 = 14;
int MCP1_input7 = 13;
int MCP1_input8 = 12;

int MCP_led1 = 11;
int MCP_led2 = 10;
int MCP_led3 = 9;
int MCP_led4 = 8;
int MCP_led5 = 7;
int MCP_led6 = 6;
int MCP_led7 = 5;
int MCP_led8 = 4;

int MCP2_input1 = 0;
int MCP2_input2 = 1;
int MCP2_input3 = 2;
int MCP2_input4 = 3;
int MCP2_input5 = 15;
int MCP2_input6 = 14;
int MCP2_input7 = 13;
int MCP2_input8 = 12;


int ledState = LOW;
int prevled = MCP_led7;
int led;
int chipSelect;
int prevchipSelect = 1;
int automaticcount = 0;

int ledpin[] {
 MCP_led7, MCP_led4, MCP_led2, MCP_led4, MCP_led1, MCP_led3, MCP_led1, MCP_led3,
 MCP_led2, MCP_led5, MCP_led7, MCP_led5, MCP_led8, MCP_led6, MCP_led8, MCP_led6,
};

int ledpinsetup[] {
 MCP_led1, MCP_led2, MCP_led3, MCP_led4, MCP_led5, MCP_led6, MCP_led7, MCP_led8,

};
int ledcount = 0;

unsigned long currentMillisled;
unsigned long previousMillisled = 0;
unsigned long intervalled = 600;

unsigned long currentMillisanalog;
unsigned long previousMillisanalog = 0;
unsigned long intervalanalog = 1000;

int x = 0 ;

int r1 = 0;
int r2 = 2160;
int r3 = 4320;
int r4 = 6480;
int r5 = 8640;
int r6 = 10800;
int r7 = 12960;
int r8 = 15120;
int r9 = 17280;
int r10 = 19440;
int r11 = 22160;
int r12 = 23760;
int r13 = 25920;
int r14 = 28080;
int r15 = 30240;
int r16 = 32400;

int moveto;
int currentrotation = 0;
int locate;
int pause = 0;
int wait = 1000;
int randNumber;


void setup()
{
 mcp1.begin(addr1);
 mcp2.begin(addr2);

 stepper.setMaxSpeed(255);
 //stepper setSpeed(225);
 stepper.setAcceleration(255);

 Serial.begin(9600);
 

 mcp1.pinMode (MCP1_input1, INPUT);
 mcp1.pinMode (MCP1_input2, INPUT);
 mcp1.pinMode (MCP1_input3, INPUT);
 mcp1.pinMode (MCP1_input4, INPUT);
 mcp1.pinMode (MCP1_input5, INPUT);
 mcp1.pinMode (MCP1_input6, INPUT);
 mcp1.pinMode (MCP1_input7, INPUT);
 mcp1.pinMode (MCP1_input8, INPUT);

 mcp1.pullUp(MCP1_input1, HIGH);
 mcp1.pullUp(MCP1_input2, HIGH);
 mcp1.pullUp(MCP1_input3, HIGH);
 mcp1.pullUp(MCP1_input4, HIGH);
 mcp1.pullUp(MCP1_input5, HIGH);
 mcp1.pullUp(MCP1_input6, HIGH);
 mcp1.pullUp(MCP1_input7, HIGH);
 mcp1.pullUp(MCP1_input8, HIGH);

 mcp2.pinMode (MCP2_input1, INPUT);
 mcp2.pinMode (MCP2_input2, INPUT);
 mcp2.pinMode (MCP2_input3, INPUT);
 mcp2.pinMode (MCP2_input4, INPUT);
 mcp2.pinMode (MCP2_input5, INPUT);
 mcp2.pinMode (MCP2_input6, INPUT);
 mcp2.pinMode (MCP2_input7, INPUT);
 mcp2.pinMode (MCP2_input8, INPUT);

 mcp2.pullUp(MCP2_input1, HIGH);
 mcp2.pullUp(MCP2_input2, HIGH);
 mcp2.pullUp(MCP2_input3, HIGH);
 mcp2.pullUp(MCP2_input4, HIGH);
 mcp2.pullUp(MCP2_input5, HIGH);
 mcp2.pullUp(MCP2_input6, HIGH);
 mcp2.pullUp(MCP2_input7, HIGH);
 mcp2.pullUp(MCP2_input8, HIGH);

 pinMode (sensor, INPUT);
 pinMode (automaticswitch, INPUT);
 pinMode (fallshort, INPUT);
 pinMode (overrun, INPUT);
 pinMode (currentRead, INPUT);

 pinMode (ms1, OUTPUT);
 pinMode (ms2, OUTPUT);
 pinMode (ms3, OUTPUT);

 pinMode (relay1a, OUTPUT);
 pinMode (relay1b, OUTPUT);
 pinMode (relay2a, OUTPUT);
 pinMode (relay2b, OUTPUT);

 digitalWrite (relay1a, LOW);
 digitalWrite (relay1b, LOW);
 digitalWrite (relay2a, LOW);
 digitalWrite (relay2b, LOW);

 digitalWrite (ms1, LOW);
 digitalWrite (ms2, LOW);
 digitalWrite (ms2, LOW);

 digitalWrite(dirPin, HIGH);

 pinMode (sleep, OUTPUT);
 digitalWrite(sleep, HIGH);


 stepper.moveSpeed(4000);
 while (digitalRead(sensor) == HIGH) {

  
   stepper.run();


   currentMillisled = millis();
   if (currentMillisled - previousMillisled >= intervalled)
   {
     for (int ledrotate = 0; ledrotate < 16; ledrotate++)
     {
       mcp1.pinMode(ledpin[ledrotate], INPUT);
       mcp2.pinMode(ledpin[ledrotate], INPUT);

       if (((ledcount) < 2) ||
           (((ledcount) > 5) && ((ledcount) < 10)) ||
           ((ledcount) > 13)) {
         mcp1.pinMode(ledpin[x], OUTPUT);
         mcp1.digitalWrite(ledpin[x], LOW);
         //Serial.println ("if");
       }
       else {
         mcp2.pinMode(ledpin[x], OUTPUT);
         mcp2.digitalWrite(ledpin[x], LOW);
         //Serial.println ("else");
       }
     }
     previousMillisled = currentMillisled;
     x++;
     ledcount++;
     if (x >= 16) x = 0;
     if (ledcount >= 16) ledcount = 0;
   }

   

 }
 {
   for (int ledoff = 0; ledoff < 8; ledoff++)
   {
     mcp1.pinMode (ledpinsetup[ledoff], INPUT);
     mcp2.pinMode (ledpinsetup[ledoff], INPUT);
   }

 }

 mcp1.pinMode(ledpin[0], OUTPUT);
 mcp1.digitalWrite(ledpin[0], HIGH);

 digitalWrite (ms1, HIGH);
 digitalWrite (ms2, HIGH);
 digitalWrite (ms3, HIGH);

 digitalWrite(sleep, LOW);

 stepper.setMaxSpeed(600);
 stepper.setAcceleration(80);
 }
void setup()
{
}

[PLEASE use the Code tags button, </> on the Menu - Thanks, Moderator)

Yes the suggestion is to re-edit your posting.
code should always be inserted as a code-section.

Easiest way to do this is
bring Arduino-IDE with the code you like to post to front
press Ctrl-T to re-format your code to the right indentions
do a right-click with the mouse inside Arduino-IDE
choose "copy for forum"

change to your browser
go to the posting that shall be edited
in the bottom right corner move mouse to "more"
a popup shows up - choose edit
delete the code
press Ctrl-V to paste the clipboard-content

Voila code inserted as code-section

best regards Stefan

Why does your posted code have two setup() functions, and no loop() function?

My apologies

The second setup() should read loop() which is not wrote yet as I am concentrating on the setup()

16rdtt:
I have done what you have suggested and changed the run() to runSpeed().

It work to a point. The stepper motor does run continuously without judder, however it runs too slowly.

I have tried experimenting with stepper.setSpeed(value), stepper.setMaxSpeed(value) and even

stepper.setAcceleration(value);.

these do work, but anything highter than the value 225 the judder comes back.

Start with a short program that does nothing but control the stepper motor. It will make it much easier to help you.

...R