Go Down

Topic: Accelstepper (Read 322 times) previous topic - next topic

GF1021

Hi everybody
So i,m working on another project and I need some help. I have build a automatic syringe filler that uses three different sized syringes. I,m using a UNO, three push button, a rotary switch with five settings, an end stop switch, a nema 23 stepper and I use accelstepper and eeprom library. Now the idea behind it is ... I hit the home button and the stepper goes  CW to bring the sled into the home position, then I insert one of the syringes and depending on the rotary switch (which select the size) I hit the start button and the stepper turns CCW. Once the filling is done I hit the home button and it (and here is the problem) turns 2-3 more times in the CCW direction before it reverses and goes CW. That is my first problem. The other one is ... I want to be able to overwrite the fill to maximum setting and save the value to eeprom. The problem is the value goes into the 10000 and I have no idea how to do that.

Please somebody help

Code: [Select]


#include <EEPROM.h>
#include <AccelStepper.h>
//#include <EEPROMAnything.h>

AccelStepper stepper (1, 8, 9);
const int progButton = 2;
const int rotoS = 3;
const int rotoM = 4;
const int rotoL = 5;
const int rotoO = 6;
const int rotoP = 7;
const int endStop = 10;
const int startButton = 12;
const int homeButton = 11;
byte endStopState = 0;
byte startButtonState = 0;
byte homeButtonState = 0;
byte progButtonState = 0;
byte rotoSState = 0;
byte rotoMState = 0 ;
byte rotoLState = 0;
byte rotoOState = 0;
byte rotoPState = 0;
int long i = 0;
int long p = 0;
int k = 0;

void setup() {
  pinMode(progButton, INPUT);
  pinMode(endStop, INPUT);
  pinMode(startButton, INPUT);
  pinMode(homeButton, INPUT);
  pinMode(rotoS, INPUT);
  pinMode(rotoM, INPUT);
  pinMode(rotoL, INPUT);
  pinMode(rotoO, INPUT);
  pinMode(rotoP, INPUT);
}

void loop() { 
  homeButtonState = digitalRead(homeButton);
    if (homeButtonState == HIGH) {
      Home();
}
 
  rotoSState = digitalRead(rotoS);
  startButtonState = digitalRead(startButton);
    if ((startButtonState == HIGH) && (rotoSState == HIGH)) {
      Small();
}
 
  rotoMState = digitalRead(rotoM);
  startButtonState = digitalRead(startButton);
    if ((rotoMState == HIGH) && (startButtonState == HIGH)) {
      Mid();
}
  rotoLState = digitalRead(rotoL);
  startButtonState = digitalRead(startButton);
    if ((rotoLState == HIGH) && (startButtonState == HIGH)) {
      Large();
}
  rotoOState = digitalRead(rotoO);
  startButtonState = digitalRead(startButton);
    if ((rotoOState == HIGH) && (startButtonState == HIGH)) {
   stepper.setMaxSpeed(4000);
   stepper.setAcceleration(500);
   stepper.moveTo(p);
   p = p + 1;
   stepper.run();  // Start moving the stepper
   rotoPState = digitalRead(rotoP);
   progButtonState = digitalRead(progButton);
    if ((rotoPState == HIGH) && (progButtonState == HIGH)) {
     
    }
  }
  rotoPState = digitalRead(rotoP);
  startButtonState = digitalRead(startButton);
    if ((rotoPState == HIGH) && (startButtonState == HIGH)) {
      Prog();
}
}
/////////////////// Function to bring the sled in to the home position. //////////////////
    void Home() {
  while (digitalRead(homeButtonState)) {
    endStopState = digitalRead(endStop);
      if (endStopState == LOW) {
    stepper.setMaxSpeed(5000);
    stepper.setAcceleration(800);
    stepper.moveTo(-5000);
    stepper.run();  // Start moving the stepper
    } else {
    stepper.setMaxSpeed(0);
    stepper.setCurrentPosition(0);
    homeButtonState = 0;
    break;
    }
  }
}
//////////////////// Function to fill the small syringe to it's maximum. ////////////////////
    void Small() {
      for (i = 0; i <= 7600; i++) {
    stepper.setMaxSpeed(4000);
    stepper.setAcceleration(500);
    stepper.moveTo(i); //Number for small syringe 24500
    stepper.run();  // Start moving the stepper
  }
}
//////////////////// Function to fill the medium syringe to it's maximum. /////////////////
  void Mid() {
      for (i = 0; i <= 7500; i++) {
    stepper.setMaxSpeed(5000);
    stepper.setAcceleration(800);
    stepper.moveTo(i); //34500
    stepper.run();  // Start moving the stepper
  }
}
///////////////////// Function to fill the large syringe to it's maximum. ///////////////////
   void Large() {
      for (i = 0; i <= 8900; i++) {
    stepper.setMaxSpeed(5000);
    stepper.setAcceleration(800);
    stepper.move(i); //42250
    stepper.run();  // Start moving the stepper
  }
}
///////////////// Function to read from eeprom. ///////////////////////
  void Prog()  {
   
  }

 

UKHeliBob

The EEPROM bit is easy.  Just use EEPROM.put() and EEPROM.get() and you can save and load data of any type,  An int would be fine for values up to 10000
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

pert

Please always do a Tools > Auto Format on your code before posting it. This will make it easier for you to spot bugs and make it easier for us to read. If you're using the Arduino Web Editor you will not have access to this useful tool. I recommend you to use the standard IDE instead.
CCing @232 on this:

Robin2

#3
May 17, 2018, 09:33 am Last Edit: May 17, 2018, 09:38 am by Robin2
Once the filling is done I hit the home button and it (and here is the problem) turns 2-3 more times in the CCW direction before it reverses and goes CW.
I find that confusing.

Do you want it do do 2 or 3 more turns but it is not doing them?

OR

Is it doing 2 or 3 turns that you don't want it to do?



You should NOT have
Code: [Select]
stepper.run();
inside any functions. That line is only needed once and it should be in loop().

It may also be useful to use stepper.distanceToGo() to check that a movement has completed.

Or, if a movement has intentionally completed prematurely you might want to use stepper.setCurrentPosition() to update the library's position data.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

GF1021

Hi again
First of all thanks to everybody for jumping in and help.

OK ...UKHeliBob ...
I'm not sure how to use your idea about eeprom.put and .get but I certainly will try it..

To pert ...
Thanks for pointing out my mistake .. was the first thing I changed in my sketch.

and to pert ...
I don't want the stepper to do the additional turns. If I take "stepper.run()" out of my functions the stepper will not turn at all and I tried inserting "stepper.setCurrentPosition()" ... it had no effect.

Thanks..

UKHeliBob

Quote
OK ...UKHeliBob ...
I'm not sure how to use your idea about eeprom.put and .get but I certainly will try it..
https://www.arduino.cc/en/Reference/EEPROMPut

https://www.arduino.cc/en/Reference/EEPROMGet
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

MarkT

Call setMaxSpeed() and setAcceleration once only, in setup(), they are setup calls.

run() should be called every time through loop(), whatever else is going on, and you need
to ensure loop() runs fast (no delays, no other loops that take control away from loop() function.

To stop a current motion unilaterally just call stop().
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Robin2

If I take "stepper.run()" out of my functions the stepper will not turn at all
Where did you put it?

You need to post the revised code so we can see what exactly you did.

Quote
and I tried inserting "stepper.setCurrentPosition()" ... it had no effect.
Likewise - we need to see your code.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

GF1021

ok thanks again for the reply's

 UKHeliBob ... I tried the eeprom.put and get ... no luck...I installed the serial print to check what I get and it's "2046820361" as a result...go figure.

 MarkT ... Don't I have to have "stepper.run" in every of my sub-functions? Don't they act as loops? And when I try to use "stepper.stop()" I get "class Accelstepper has no member named stop".

 Robin2 ... Sorry .. If I take the "stepper.run" out of my functions and put one into my "void loop" stepper does not turn at all.

Here is the update code
Code: [Select]
#include <EEPROM.h>
#include <AccelStepper.h>
//#include <EEPROMAnything.h>

AccelStepper stepper (1, 8, 9);
const int progButton = 2;
const int rotoS = 3;
const int rotoM = 4;
const int rotoL = 5;
const int rotoO = 6;
const int rotoP = 7;
const int endStop = 10;
const int startButton = 12;
const int homeButton = 11;
byte endStopState = 0;
byte startButtonState = 0;
byte homeButtonState = 0;
byte progButtonState = 0;
byte rotoSState = 0;
byte rotoMState = 0 ;
byte rotoLState = 0;
byte rotoOState = 0;
byte rotoPState = 0;
int long i = 0;
int long p = 0;
int k = 0;
int addr = 0;

void setup() {
  pinMode(progButton, INPUT);
  pinMode(endStop, INPUT);
  pinMode(startButton, INPUT);
  pinMode(homeButton, INPUT);
  pinMode(rotoS, INPUT);
  pinMode(rotoM, INPUT);
  pinMode(rotoL, INPUT);
  pinMode(rotoO, INPUT);
  pinMode(rotoP, INPUT);
  EEPROM.begin();
  Serial.begin(115200);
  stepper.setMaxSpeed(5000);
  stepper.setAcceleration(800);
}

void loop() {
  homeButtonState = digitalRead(homeButton);
  if (homeButtonState == HIGH) {
    Home();
  }

  rotoSState = digitalRead(rotoS);
  startButtonState = digitalRead(startButton);
  if ((startButtonState == HIGH) && (rotoSState == HIGH)) {
    Small();
  }

  rotoMState = digitalRead(rotoM);
  startButtonState = digitalRead(startButton);
  if ((rotoMState == HIGH) && (startButtonState == HIGH)) {
    Mid();
  }
  rotoLState = digitalRead(rotoL);
  startButtonState = digitalRead(startButton);
  if ((rotoLState == HIGH) && (startButtonState == HIGH)) {
    Large();
  }
  rotoOState = digitalRead(rotoO);
  startButtonState = digitalRead(startButton);
  if ((rotoOState == HIGH) && (startButtonState == HIGH)) {
    stepper.setMaxSpeed(4000);
    stepper.setAcceleration(500);
    stepper.moveTo(p);
    p = p + 1;
    stepper.run();  // Start moving the stepper
    rotoPState = digitalRead(rotoP);
    progButtonState = digitalRead(progButton);
    if ((rotoPState == HIGH) && (progButtonState == HIGH)) {
      EEPROM.put(addr, p);
    }
  }
  rotoPState = digitalRead(rotoP);
  startButtonState = digitalRead(startButton);
  if ((rotoPState == HIGH) && (startButtonState == HIGH)) {
    Prog();
  }
}
/////////////////// Function to bring the sled in to the home position. //////////////////
void Home() {
  while (digitalRead(homeButtonState)) {
    endStopState = digitalRead(endStop);
    if (endStopState == LOW) {
      stepper.moveTo(-5000);
      stepper.run();  // Start moving the stepper
    } else {
      stepper.setMaxSpeed(0);
      stepper.setCurrentPosition(0);
      homeButtonState = 0;
      break;
    }
  }
}
//////////////////// Function to fill the small syringe to it's maximum. ////////////////////
void Small() {
  for (i = 0; i <= 7600; i++) {
    stepper.setMaxSpeed(4000);
    stepper.setAcceleration(500);
    stepper.moveTo(i); //Number for small syringe 24500
    /*  if (i == 7600) {
        stepper.stop();
      }  */
    stepper.setCurrentPosition(0);
    stepper.run();  // Start moving the stepper
  }
}
//////////////////// Function to fill the medium syringe to it's maximum. /////////////////
void Mid() {
  for (i = 0; i <= 7500; i++) {
    stepper.setMaxSpeed(5000);
    stepper.setAcceleration(800);
    stepper.moveTo(i);
    stepper.setCurrentPosition(0);
    stepper.run();  // Start moving the stepper
  }
}
///////////////////// Function to fill the large syringe to it's maximum. ///////////////////
void Large() {
  for (i = 0; i <= 8900; i++) {
    stepper.setMaxSpeed(5000);
    stepper.setAcceleration(800);
    stepper.move(i);
    stepper.setCurrentPosition(0);
    stepper.run();  // Start moving the stepper
  }
}
///////////////// Function to read from eeprom. ///////////////////////
void Prog() {
  EEPROM.get(addr, p);
  stepper.setMaxSpeed(5000);
  stepper.setAcceleration(800);
  stepper.move(p);
  Serial.println(p);
  stepper.run();  // Start moving the stepper

}

MarkT

#9
May 17, 2018, 03:36 pm Last Edit: May 17, 2018, 03:36 pm by MarkT
MarkT ... Don't I have to have "stepper.run" in every of my sub-functions? Don't they act as loops? And when I try to use "stepper.stop()" I get "class Accelstepper has no member named stop".
C doesn't allow subfunctions(*).  You mean functions called from loop. 

Yes, run() should be called often,
No, that doesn't mean you need to call run() from every function.

If a function has its own loop that takes any length of time, you are implementing a delay - that's
not how to write code for AccelStepper.  The loop() function should be the only event loop.

(*) subfunction has a technical meaning here.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Robin2

Here is the update code
That program still has stepper.run() in the functions. I asked you to post the version in which you have taken it out of the functions - so that I can see what the problem is.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

GF1021

Robin2  ... here is the code with steeper.run removed.
Code: [Select]
#include <EEPROM.h>
#include <AccelStepper.h>

AccelStepper stepper (1, 8, 9);
const int progButton = 2;
const int rotoS = 3;
const int rotoM = 4;
const int rotoL = 5;
const int rotoO = 6;
const int rotoP = 7;
const int endStop = 10;
const int startButton = 12;
const int homeButton = 11;
byte endStopState = 0;
byte startButtonState = 0;
byte homeButtonState = 0;
byte progButtonState = 0;
byte rotoSState = 0;
byte rotoMState = 0 ;
byte rotoLState = 0;
byte rotoOState = 0;
byte rotoPState = 0;
int long i = 0;
int long p = 0;
int k = 0;
int addr = 0;

void setup() {
  pinMode(progButton, INPUT);
  pinMode(endStop, INPUT);
  pinMode(startButton, INPUT);
  pinMode(homeButton, INPUT);
  pinMode(rotoS, INPUT);
  pinMode(rotoM, INPUT);
  pinMode(rotoL, INPUT);
  pinMode(rotoO, INPUT);
  pinMode(rotoP, INPUT);
  EEPROM.begin();
  Serial.begin(115200);
  stepper.setMaxSpeed(5000);
  stepper.setAcceleration(800);
}

void loop() {
  homeButtonState = digitalRead(homeButton);
  if (homeButtonState == HIGH) {
    Home();
  }

  rotoSState = digitalRead(rotoS);
  startButtonState = digitalRead(startButton);
  if ((startButtonState == HIGH) && (rotoSState == HIGH)) {
    Small();
  }

  rotoMState = digitalRead(rotoM);
  startButtonState = digitalRead(startButton);
  if ((rotoMState == HIGH) && (startButtonState == HIGH)) {
    Mid();
  }
  rotoLState = digitalRead(rotoL);
  startButtonState = digitalRead(startButton);
  if ((rotoLState == HIGH) && (startButtonState == HIGH)) {
    Large();
  }
  rotoOState = digitalRead(rotoO);
  startButtonState = digitalRead(startButton);
  if ((rotoOState == HIGH) && (startButtonState == HIGH)) {
    stepper.setMaxSpeed(4000);
    stepper.setAcceleration(500);
    stepper.moveTo(p);
    p = p + 1;
    stepper.run();  // Start moving the stepper
    rotoPState = digitalRead(rotoP);
    progButtonState = digitalRead(progButton);
    if ((rotoPState == HIGH) && (progButtonState == HIGH)) {
      EEPROM.put(addr, p);
    }
  }
  rotoPState = digitalRead(rotoP);
  startButtonState = digitalRead(startButton);
  if ((rotoPState == HIGH) && (startButtonState == HIGH)) {
    Prog();
  }
  stepper.run();
}
/////////////////// Function to bring the sled in to the home position. //////////////////
void Home() {
  while (digitalRead(homeButtonState)) {
    endStopState = digitalRead(endStop);
    if (endStopState == LOW) {
      stepper.moveTo(-5000);
      //stepper.run();  // Start moving the stepper
    } else {
      stepper.setMaxSpeed(0);
      stepper.setCurrentPosition(0);
      homeButtonState = 0;
      break;
    }
  }
}
//////////////////// Function to fill the small syringe to it's maximum. ////////////////////
void Small() {
  for (i = 0; i <= 7600; i++) {
    stepper.setMaxSpeed(4000);
    stepper.setAcceleration(500);
    stepper.moveTo(i); //Number for small syringe 24500
    /*  if (i == 7600) {
        stepper.stop();
      }  */
    stepper.setCurrentPosition(0);
    //stepper.run();  // Start moving the stepper
  }
}
//////////////////// Function to fill the medium syringe to it's maximum. /////////////////
void Mid() {
  for (i = 0; i <= 7500; i++) {
    stepper.setMaxSpeed(5000);
    stepper.setAcceleration(800);
    stepper.moveTo(i);
    stepper.setCurrentPosition(0);
    // stepper.run();  // Start moving the stepper
  }
}
///////////////////// Function to fill the large syringe to it's maximum. ///////////////////
void Large() {
  for (i = 0; i <= 8900; i++) {
    stepper.setMaxSpeed(5000);
    stepper.setAcceleration(800);
    stepper.move(i);
    stepper.setCurrentPosition(0);
    // stepper.run();  // Start moving the stepper
  }
}
///////////////// Function to read from eeprom. ///////////////////////
void Prog() {
  EEPROM.get(addr, p);
  stepper.setMaxSpeed(5000);
  stepper.setAcceleration(800);
  stepper.move(p);
  Serial.println(p);
  //stepper.run();  // Start moving the stepper

}

UKHeliBob

Quote
UKHeliBob ... I tried the eeprom.put and get ... no luck...I installed the serial print to check what I get and it's "2046820361" as a result...go figure.
There is no element of luck either way.

The put() and get() functions work so why don't they work in your program ?

1.  Are you actually writing anything to the EEPROM ?
    Does the program ever call the put() function and, if so, what value is written to the EEPROM ?
    Print it to find out before put()

2.  Is the data being written to and read from the same address ?
    Your program look OK but temporarily substitute an explicit address for the addr variable

3.  The EEPROM is, to use a technical term, shagged.  Either one address, many or the whole EEPROM may be affected
    Run a separate diagnostic program to write to every EEPROM address and read back the values.  Are they correct ?

4.  You are using the EEPROM in a different way to everyone else.
    What does EEPROM.begin() do in your program ?
    When used with an ESP8266 it allows you to specify the number of bytes of EEPROM to be available but you are using a Uno.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Qwertyqwq

if you want to use a professional encoder(which are 2000-5000 pulses) , you can find it on old printers. there are 2 encoder disks and 1 encoder slider. they are professional encoder disks and if you want you can use that with your arduino's interrupt pins. im gonna share my codes here ;



Code: [Select]
/*This sketch counts the pulses of the simple encoder.
Every time the encoder sends a pulse the interrupt is activated at the rising edge of the pulse.
The function count() is called and increments the counter.
The counter variable must be declared as volatile, see the arduino reference.
Otherwise you could miss some of the pulses. The datatype unsigned int gives you a maximum of 65535 pulses.
If this is not enough you can take e. g. unsigned long (4,294,967,295 pulses max.).
When you have more pulses your counter will overflow.

*/
// The pin the encoder is connected
int encoder_in = 2;
int encoder_light = 13;
// Initialize the counter
volatile unsigned int pulses = 0;

void count() {
  // This function is called by the interrupt
  pulses++;
 
}

void setup() {
  pinMode(encoder_in, INPUT);
  pinMode(encoder_light, OUTPUT);
  attachInterrupt(0, count, RISING);
  Serial.begin(9600);
 
 
}

void loop() {
  // Here you can output your counter value e. g. once a second
  //
  //
 if (digitalRead(2)==HIGH) {
 Serial.println("1");

 }
   delay(100);
}
NO RESISTANCE CAN DROP MY POTENTIAL.

Robin2

#14
May 17, 2018, 06:20 pm Last Edit: May 17, 2018, 06:21 pm by Robin2
Robin2  ... here is the code with steeper.run removed.
This style of using AccelStepper is all wrong - and is more complicated than is needed.
Code: [Select]
void Mid() {
  for (i = 0; i <= 7500; i++) {
    stepper.setMaxSpeed(5000);
    stepper.setAcceleration(800);
    stepper.moveTo(i);
    stepper.setCurrentPosition(0);
    // stepper.run();  // Start moving the stepper
  }
}


Try this style and let the library do all the hard work
Code: [Select]
void Mid() {
    stepper.setMaxSpeed(5000);
    stepper.setAcceleration(800);
    stepper.moveTo(7500); // or maybe this should be stepper.move(7500);

}


and you could probably move the first two lines to setup() if they are always the same.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up