Yet another slow stepper motor

Hi.

OK so I have an issue with a very short bit of code… its really annoying me at the moment but then again im not soley focussed on this and have multiple things going on in life.

Any way here is the the problem.
I have a stepper connected to a tb6600 Driver on 24v (stepper specs unknown but this is not currently casuing an issue). THe driver is connected to a controllino MAXI

This code below runs perfectly. speed is ok and motor sounds good.

#include <AccelStepper.h>
#define motorInterfaceType 1
#define stepPin 2

AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin);

void setup()
{  
   stepper.setMaxSpeed(1000);
   stepper.setSpeed(800);	
}

void loop()
{  
   stepper.runSpeed();
}

And this code works but the stepper is very slow.

#include <AccelStepper.h>
#include <Controllino.h>
#define stepPin 2
#define motorInterfaceType 1

AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin);

int flagstate = 0;
int flag = 0;

void setup() {
  pinMode(CONTROLLINO_D0, OUTPUT);
  pinMode(CONTROLLINO_A8, INPUT);
  stepper.setMaxSpeed(1000);
  stepper.setSpeed(800);
}
void loop()
{
  stepperflag();
  if (flag == 0) {
    stepper.runSpeed();
  } else  {
    stepper.stop();
  }

}

void stepperflag(void)
{
  flagstate = analogRead(CONTROLLINO_A8);

  if (flagstate >= 1)
  {
    flag = 0;
  }
  else
  {
    flag = 1;
  }

}

On the back of the stepper is a disc with a slot in it for the optical slot detector. to initiate the motor for now I am moving the slot round so it changes state and starts the stepper turning.
eventually the motor will turn when a target weight is reached.
Thanks

craskie1805:
And this code works but the stepper is very slow.

In that program what happens if you comment out the line

stepperflag();

…R

Hi Robin,

When I uncomment stepperflag(); it runs at the correct speed.

Thanks

The result of a call to analogRead() will have noise, you cannot test it for being 0 or not
and expect useful behaviour as that will be mainly determined by noise in the system.

What is the source of the analog voltage in question? What values are you expecting it
to have?

craskie1805:
When I uncomment stepperflag(); it runs at the correct speed.

That tells you that it is the code in the function stepperflag() that is causing loop() to repeat more slowly and thus reduce the frequency of calls to stepper.runSpeed().

There is no need to check the analogue pin so often. Try checking the analogue value 4 times per second and see what happens. Something like this

void stepperFlag() {
   static unsigned long previousAnalogTestTime = 0;
   if (millis() - previousAnalogTestTime >= 250) {
        previousAnalogTestTime = millis();
        // other code from stepperFlag()
   }
}

…R

MarkT:
The result of a call to analogRead() will have noise, you cannot test it for being 0 or not
and expect useful behaviour as that will be mainly determined by noise in the system.

What is the source of the analog voltage in question? What values are you expecting it
to have?

Hello MarkT
I will breifly explain how it seems to work.
The controllino people have also added boards you can add to the board manager so you can call thier "input/output" names.
The 5v opto is in A8 of the Controllino but Physical pin 2 of the mega inside. It uses a voltage comparator when doing the read and anything over say 3v is classed as a 1 and below is 0.
Not 100% on all the ins and outs yet but they are awesome biys of kit.

Robin2:
That tells you that it is the code in the function stepperflag() that is causing loop() to repeat more slowly and thus reduce the frequency of calls to stepper.runSpeed().

There is no need to check the analogue pin so often. Try checking the analogue value 4 times per second and see what happens. Something like this

void stepperFlag() {

static unsigned long previousAnalogTestTime = 0;
  if (millis() - previousAnalogTestTime >= 250) {
       previousAnalogTestTime = millis();
       // other code from stepperFlag()
  }
}




...R

Thanks Robin2
I will give it a go and let you know how it goes,.
P. S what happened to Robin1

P. S what happened to Robin1

This is what happened to Robin1:

;D :o

aarg:
This is what happened to Robin1:

https://youtu.be/M6lOpuI7rQI

aarg:
This is what happened to Robin1:

LOL

...R

OK so ive added the code suggestion, It makes sense to only check 4 times a second etc etc.

but its still not working, would I be better writing the stepper.runSpeed into the void stepperflag()?

updated code still not working correctly

[code]
#include <AccelStepper.h>
#include <Controllino.h>
#define stepPin 2
#define motorInterfaceType 1

AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin);

int flagstate = 0;
int flag = 0;

void setup() {
  pinMode(CONTROLLINO_D0, OUTPUT);
  pinMode(CONTROLLINO_A8, INPUT);
  stepper.setMaxSpeed(4000);
  stepper.setSpeed(2000);
}
void loop()
{
  stepperflag();
  if (flag == 0) {
    stepper.runSpeed();
  } else  {
    stepper.stop();
  }

}

void stepperflag(void)
{
  static unsigned long previousAnalogTestTime = 0;
  if (millis() - previousAnalogTestTime >= 900) {
    flagstate = analogRead(CONTROLLINO_A8);
  }
  if (flagstate >= 1) {
    flag = 0;
    stepper.runSpeed();
  } else {
    flag = 1;
    stepper.stop();
  }

}

Thanks
Andy

You never set previousAnalogTestTime, so after 900mS, stepperFlag is back to its old tricks.

craskie1805:
updated code still not working correctly

You have omitted this critically important line from your program

previousAnalogTestTime = millis();

Read Reply #4 again.

...R

Hi Robin2

Damn it snow blind sorry ok so done that and it now rotates once at the correct speed and when it gets to “home” it stops as it should.
Then if i jog the wheel to make it rotate again its still slow.

#include <AccelStepper.h>
#include <Controllino.h>
#define stepPin 2
#define motorInterfaceType 1

AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin);

int flagstate = 0;
int flag = 0;

void setup() {
  pinMode(CONTROLLINO_D0, OUTPUT);
  pinMode(CONTROLLINO_A8, INPUT);
  stepper.setMaxSpeed(2500);
  stepper.setSpeed(2000);
}
void loop()
{
  stepperflag();
  if (flag == 0) {
    stepper.runSpeed();
  } else  {
    stepper.stop();
  }

}

void stepperflag(void)
{
  unsigned long previousAnalogTestTime = 0;
  if (millis() - previousAnalogTestTime >= 500) {
    previousAnalogTestTime = millis();
    flagstate = analogRead(CONTROLLINO_A8); 
      if (flagstate >= 1)
      {
        flag = 0;
      }
      else
      {
        flag = 1;
      }
    
  }
}

Probably missed something else obvious :frowning:

craskie1805:
Probably missed something else obvious :frowning:

I suspect the answer lies in Reply #3

…R

Okie dokie

I will see if digitalread works instead. Also would using an interrupt pin work better?

craskie1805:
I will see if digitalread works instead. Also would using an interrupt pin work better?

An interrupt would not be any better and it would just make the code more complex.

Based on what you said in Reply #5 digitalRead() should work. But if it does not you need to find the highest value from analogRead() that corresponds to a ZERO. Then, supposing it is 600, your test should be something like

analogValue = analogRead(analogPin);
if (analogValue < 590 ) {
   // we definitely have a zero
}
else if (analogValue > 610) {
   // we definitely have a 1
}

…R

Woo hoo.

It works!!

Went back to basics and started again and low and behold it worked.

one revolution when its jogged and then stops in the home position. Had to reduce the interval as occasionally it would miss and go round twice.
now ive got to add it into the main working code…

working code below if anyone is interested.

#include <Controllino.h>
#include <AccelStepper.h>

#define stepPin 2
#define motorInterfaceType 1


AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin);

  unsigned long previousMillis = 0;
  const long interval = 10;


int flag = 0;
int flagstate = 0;

void setup() {
  // initialize necessary pin as input pin
  pinMode(CONTROLLINO_A8, INPUT);
  pinMode(CONTROLLINO_D0, OUTPUT);
  stepper.setMaxSpeed(3000);
  stepper.setSpeed(2000);


  Serial.begin(9600);
}


void loop()
  {
  
    readflag();

  }





void readflag(void)
{

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) 
    {
    previousMillis = currentMillis;
    flagstate = analogRead(CONTROLLINO_A8);
    }
    if (flagstate >= 1)
    {
      flag = 0;
      stepper.runSpeed();
    }
    else  {
      flag = 1;
    }
}

Thanks for your help Robin2 :smiley: Karma coming your way, not that you need it :stuck_out_tongue: