Go Down

Topic: Help needed to move a stepper and ac motor simultaneously (Read 203 times) previous topic - next topic

Tallen_

Hi Guys

I need some help sorting code to make a stepper lift when the Arduino is turned on then when a button is pressed the stepper lowers the same distance then lifts the same distance and stops. Simultaneously an ac motor needs to spin up for a few seconds then stop. 


The actions are stated below;

1. Turn on the machine and the Arduino lifts the stepper 5 rotations (this will be a home code later). This lift only happens after power up.
2. Press a momentary button.
3. stepper drops 5 rotations then immediately lifts 5 rotations.
4. AC motor spins.
5. code stops and awaits the next button press

Points 3 and 4 start and end simultaneously

Im very new to this about 10hr in and I can get rough code working for the stepper or the motor but I can not figure out how to combine the codes to work simultaneously. I need help to do three things;

Combine the codes
Perform one action (lift 5 rotations on power up)
Stop the code repeating after completion.

Below is the stepper code I started using but it bounces and doesn't have the initial lift;



 Created 11 Mar. 2007
 Modified 30 Nov. 2009
 by Tom Igoe

 */

#include <Stepper.h>

const int stepsPerRevolution = 200;  // 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);

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

void loop() {
  // step one revolution  in one direction:
  Serial.println("clockwise");
  myStepper.step(5*stepsPerRevolution);
 

  // step one revolution in the other direction:
  Serial.println("counterclockwise");
  myStepper.step(-5*stepsPerRevolution);
 
}




Below is the code I have tried to use for the ac motor, I cant get the motor to stay on without using millis and a while command but that screws up the simultaneous function (I know while/delay are the wrong things to use). With this code the AC motor runs continuously if the momentary button is held in;

created 14 Mar 2012
  by Scott Fitzgerald

 
*/

void setup() {
  //start serial connection
  Serial.begin(9600);
  //configure pin 2 as an input and enable the internal pull-up resistor
  pinMode(2, INPUT_PULLUP);
  pinMode(8, OUTPUT);

}

void loop() {
  //read the pushbutton value into a variable
  int sensorVal = digitalRead(2);
  //print out the value of the pushbutton
  Serial.println(sensorVal);

  // Keep in mind the pull-up means the pushbutton's logic is inverted. It goes
  // HIGH when it's open, and LOW when it's pressed. Turn on pin 13 when the
  // button's pressed, and off when it's not:
  if (sensorVal == HIGH) {
    digitalWrite(8, LOW);
  } else {
    digitalWrite(8, HIGH);
  }
}




The stepper is a Nema 23 with 200 steps/rotation. The AC motor is powered via a solid state relay and is activated via pin 8.

I be grateful for any help anyone can give me. If i even had a basic working code that i could pick apart and see how why it works I could learn a lot.

Thanks in advance and sorry if I've done something wrong or left info out (first post on here)  :)  :)

Cheers

Tallen_

DrDiettrich

3. stepper drops 5 rotations then immediately lifts 5 rotations.
4. AC motor spins.

Points 3 and 4 start and end simultaneously
Start the AC motor before and stop it after the stepper has finished moving. It's sufficient to write a HIGH (or LOW) to the digital pin once, then the motor runs until the pin state is changed again.

Tallen_

Hi DrDiettrich

Thanks for the reply. Yes that had occurred to me, its not exactly what I need as I will want to adjust the AC motor duration in the future but its dam close!

Sadly while i can grasp the concept easily enough the code is still eluding me. However all is not lost, I have modified a Debounce code which is getting closer to my needs. This is what happens;

Power up, Spindle (AC motor) starts and stepper lowers then raises then spindle stops.

This is perfect so far.

Upon button press the spindle (AC motor) starts and will run for infinity.
Upon second button press the stepper lowers then rises and the spindle stops.

The above two lines result on any future button presses.

I could solve this crudely by using a reset button but this is not the solution I want.

If someone could help me finish this code correctly or near enough it would be great!

Below is the code that I have butchered and gaffertaped together;

/*
  Debounce

  Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
  press), the output pin is toggled from LOW to HIGH or HIGH to LOW. There's a
  minimum delay between toggles to debounce the circuit (i.e. to ignore noise).

  The circuit:
  - LED attached from pin 8
  - pushbutton attached from pin 2 to +5V
 
*/
#include <Stepper.h>


// constants won't change. They're used here to set pin numbers:
const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
const int buttonPin = 2;    // the number of the pushbutton pin
const int ledPin = 8;      // the number of the LED pin
// initialize the stepper library on pins 10, 11:
Stepper myStepper(stepsPerRevolution, 10, 11);

// Variables will change:
int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
 // set the speed at 60 rpm:
  myStepper.setSpeed(10000);
  // initialize the serial port:
  Serial.begin(9600);

  // set initial LED state
  digitalWrite(ledPin, ledState);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        ledState = !ledState;
        if (ledState == LOW)  {
          // step one revolution  in one direction:
  Serial.println("clockwise");
  myStepper.step(-150*stepsPerRevolution);
  delay(500);

  // step one revolution in the other direction:
  Serial.println("counterclockwise");
  myStepper.step(150*stepsPerRevolution);
  delay(500);
        }
       
      }
    }
  }

  // set the LED:
  digitalWrite(ledPin, ledState);

  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;
}

Here is also a pic of the project such as it is. Its a work in progress ;-)


JCA34F

Quote
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 10, 11);
How is your stepper wired exactly? Which stepper driver are you using?
Quote
- pushbutton attached from pin 2 to +5V
pinMode(buttonPin, INPUT_PULLUP);
How does it ever go LOW?
Quote
myStepper.step(-150*stepsPerRevolution);
-thirty thousand steps? How high is that machine?   :)
Quote
// set the speed at 60 rpm:
  myStepper.setSpeed(10000);
Ten thousand RPM? Where can I buy one of those?   :)

Please post a wiring diagram. A photographed pencil drawing is fine.
Oh, BTW, which Arduino?

DrDiettrich

Your code is very hard to read, please use Code Tags </>.

Whenever you found some step finished, clear the flag that started this step. No reset button is required for that, you only put the clear flag statement in the right place of your code.

TomGeorge

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html .
Then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

What model Arduino are you using?

Thanks.. Tom... :)
Everything runs on smoke, let the smoke out, it stops running....

Tallen_

Hi guys

Thanks for all the replies.

First off I'm a total newb. I'm butchering other peoples code and seeing what happens to get this far.

There are errors in the code and at the moment I'm only looking for "good enough" to get started and refinement will come later.

Completely correct about the steppers. I had them coded correctly for single stepping (I think) but they vibratted like crazy and sounded horrible but I noticed I could achieve the same speed and sound better while microstepping. Hence the crazy numbers on the code (they do function though).

I have no idea about the <\> tags but il check out the correct way to use them.

I will come back later  with the scroll function incorporated, a diagram and hopefully superior coding standards

Tallen_

Right, back to it!


The goal;

I want code that will do the following;

1. Upon power up the Arduino will home usually lift 100mm (20 rotations)
2. Upon button press spindle starts, stepper drops 100mm, stepper lifts 100mm and then spindle stops.
3. loop stops and awaits next button press. I have read that it may be prudent to reduce holding power on the stepper during this period but have no idea how to achieve this (it seems a needless complication at this juncture lets just get things rolling  ;D ).


The equipment;

I have an Arduino mega 2650 clone. See rough diagram attached.
Nema 23 stepper with 6 leads (using 4) driven by a 4A 9~40V Micro-Step CNC Single Axis TB6600 Stepper Motor Driver Controller.
24v PSU
Solid state relay switching a 240v AC 350W motor.


The current situation;

I will show the code that I am using below, this is a statement of where I am at atm. The code may be completely wrong for my needs, I don't know. However it is closer that it was 2 days ago hehe.

People have been very helpful and making good suggestions however this is another language to me. Telling me to do A, B and C whilst still helpful is trumped by an example of code that does what you suggest. I'm not looking for you to write my code, but a small example which I can fiddle with will help a lot.  I tried to use the "several things at once" code but it only had servo examples in it instead of steppers and working out what to keep/change was above my level at that stage.
     
I may return to that thread again soon since my knowledge has grown slightly since then.

Anyway here is the code with a few corrections;


Code: [Select]
/
*
  Debounce

  Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
  press), the output pin is toggled from LOW to HIGH or HIGH to LOW. There's a
  minimum delay between toggles to debounce the circuit (i.e. to ignore noise).

  The circuit:
  - LED attached from pin 8
  - pushbutton attached from pin 2 to GND
 
*/
#include <Stepper.h>


// constants won't change. They're used here to set pin numbers:
const int stepsPerRevolution = 800;  // change this to fit the number of steps per revolution
const int buttonPin = 2;    // the number of the pushbutton pin
const int ledPin = 8;      // the number of the LED pin
// initialize the stepper library on pins 10, 11:
Stepper myStepper(stepsPerRevolution, 10, 11);

// Variables will change:
int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
 // set the speed at 80 rpm:
  myStepper.setSpeed(80);
  // initialize the serial port:
  Serial.begin(9600);

  // set initial LED state
  digitalWrite(ledPin, ledState);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        ledState = !ledState;
        if (ledState == LOW)  {
          // step one revolution  in one direction:
  Serial.println("clockwise");
  myStepper.step(-2*stepsPerRevolution);
 
  // step one revolution in the other direction:
  Serial.println("counterclockwise");
  myStepper.step(2*stepsPerRevolution);
 
        }
       
      }
    }
  }

  // set the LED:
  digitalWrite(ledPin, ledState);

  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;
}


There are a number of problems with this;

1. Upon power up it executes, spindle starts, stepper drops 100mm then rises 100mm then spindle stops (this is bad). Someone could get hurt. The machine needs to either home (rise 100mm) or do nothing. I will add endstops for homing in the near future.
2. Upon button press the spindle starts.
3. Upon next button press stepper lowers 100mm then rises 100mm then the spindle finally stops.
Further presses of the buttons repeat steps 2-3.

I realize a lot of contradicting info was in my previous posts hopefully it is fixed or at least improved.

Again thanks for your help guys!

Cheers

Tallen_



DrDiettrich


Tallen_

Well that's been a long week!

Finally I have something that is close to acceptable.

1. Upon power up the Arduino will home usually lift 10mm (2 rotations)
2. Upon button press spindle starts, stepper drops 10mm, stepper lifts 10mm and then spindle stops.
3. loop stops and awaits next button press.

The code;

Code: [Select]

/*
  Debounce

  Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
  press), the output pin is toggled from LOW to HIGH or HIGH to LOW. There's a
  minimum delay between toggles to debounce the circuit (i.e. to ignore noise).

  The circuit:
  - LED attached from pin 8
  - pushbutton attached from pin 2 to GND
 
*/
#include <Stepper.h>


// constants won't change. They're used here to set pin numbers:
const int stepsPerRevolution = 800;  // change this to fit the number of steps per revolution
const int buttonPin = 2;    // the number of the pushbutton pin
const int spindlePin = 8;      // the number of the LED pin
// initialize the stepper library on pins 10, 11:
Stepper myStepper(stepsPerRevolution, 10, 11);

// Variables will change:
int spindleState = LOW;         // the current state of the output pin
int buttonState = HIGH;          // the current reading from the input pin
int lastButtonState = HIGH;   // the previous reading from the input pin

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(spindlePin, OUTPUT);
 // set the speed at 80 rpm:
  myStepper.setSpeed(80);
  // initialize the serial port:
  Serial.begin(9600);

  // set initial spindlestate
  digitalWrite(spindlePin, spindleState);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

       {
        spindleState = !spindleState;
        while (spindleState == LOW)  {
          // step one revolution  in one direction:
  Serial.println("clockwise");
  myStepper.step(-2*stepsPerRevolution);
 
  // step one revolution in the other direction:
  Serial.println("counterclockwise");
  myStepper.step(2*stepsPerRevolution);
  break;
  (buttonState == HIGH);
 
 
        }
       
      }
    }
  }

  // set the LED:
  digitalWrite(spindlePin, spindleState);

  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;
}


Hopefully this might be of help to someone having the same problems as me.

Next problem is I would like acceleration control but I get the feeling this is not compatible with the stepper_oneRevolution example code?

Thanks for the help guys, I had hoped to be finished this earlier but I'm grateful for the guidance. 8)

Tallen




Paul_KD7HB

If what ever your button press initiates will last for longer then, say, 1/4 second, there is no need for "debounce".

Paul

TomGeorge

Everything runs on smoke, let the smoke out, it stops running....

Go Up