Hello, I'm Sebastian and this is my first time posting on the forum.
I need some help to solve a problem I'm currently facing while trying to develop my project.
My problem:
Can't find the proper way to disable the stepper Driver after a set period of time since the moving tray activated the rear sensor.
More specific: Rear sensor is activated - tray is stopped - wait 30 seconds - if between this 30 seconds the operator doesn't push a button to move the stepper - Driver should disable power to the motor.
Power enables automatically when the operator press a button that starts the motor in the needed direction CW or CCW
My project relates to the following:
I have build an X axis moving platform that is driven by this setup:
- Arduino UNO R3
- Hybrid Bipolar Stepper Motor (200 steps ;1.8 degrees; 1.4 Nm; 3.0Amp )
- DM542A stepper Driver
- 24V Power suply.
- 2 HIWIN liniar guides with 4 cariages
- ballscrew
- pulleys and belt for the motor and ballscrew.
Attached picture of my build:
https://drive.google.com/open?id=0BwN-RXLbjBc_dDlNeExWSzJqWUE
To better understand my code here are some clarifications:
FrontSwitch - represents the Push Button that commands the tray to move to the Front Sensor
BackSwitch - represent the Push Button that returns the tray to the home position.
FrontSensor- is actually a normal Limit switch that is also used to set a flag.
RearSensor - is actually a normal Limit Switch also used for homing the tray (stepper) when the device is powered in case there was a power failure and the moving tray is not currently in it's place.
running is a boolean var that is set to true or false if motor is moving or not.
If FrontSensor is activated this also sets a flag allowing a third parity device to control the motor.
The whole thing should work by the following rule:
.Power on
-
Check the tray to see if it is in the home position (BackSensorWasActivated = true or not).
If not step the stepper until BackSensor activates. -
If BackSensor is activated (tray is in home position) begin to count for 30 seconds.
if the operator doens't push the FrontSwitch button is this amount of 30 seconds - Arduino should disable the Driver for the stepper. -
If Driver is disabled and operator pushes the FrontSwitch button - Arduino enables the driver - stepper steps in the set direct direction moving the tray.
-
Once the tray returns to the home position (BackSensor activated) driven by the third party device or by direct instruction of the operator by pushing the BackSwitch button, the counter begins to count again for 30 seconds and disable the driver.
By using the code bellow it works good only when the tray it's in home position at power on.
once the tray travels to the FrontSensor and then returns to the BackSensor - once the BackSensor gets activated the driver disables instantly. It does not wait 30 seconds.
#include <SimpleTimer.h>
// variables declared here
const byte SensorActivated = LOW;
void setup() {
pinMode (FrontSwitch, INPUT_PULLUP);
pinMode (BackSwitch, INPUT_PULLUP);
pinMode (BackSensor, INPUT_PULLUP);
pinMode (FrontSensor, INPUT_PULLUP);
pinMode (StepPin, OUTPUT);
pinMode (DirPin, OUTPUT);
pinMode (EnablePin, OUTPUT);
digitalWrite (EnablePin, LOW);
timer1.enable(1);
}
void disableDriver(){
digitalWrite(EnablePin, HIGH);
}
void loop() {
timer1.disable(1);
BackSensorReading = digitalRead(BackSensor);
if (BackSensorReading == SensorActivated)
{
timer1.enable(1);
BackSensorWasActivated=true;
FrontSensorWasActivated=false;
TrayStopped=true;
encoder=0;
if (TrayStopped)if (!running){
timer1.setTimeout(30000, disableDriver); // wait 30 seconds to disable timer
timer1.run(); //start the thread.
}
}
FrontSensorReading = digitalRead(FrontSensor);
if (FrontSensorReading == SensorActivated)
{
FrontSensorWasActivated=true;
BackSensorWasActivated=false;
}
if (FrontSensorWasActivated){
motor_position=0;
// here is the function that allows the third party device to take over control
}
int FrontSwitchReading = digitalRead(FrontSwitch);
// check to see if you just pressed the FrontSwitch button
// (i.e. the input went from HIGH to LOW), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (FrontSwitchReading != LastFrontSwitchState) {
// 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 (FrontSwitchReading != FrontSwitchState) {
FrontSwitchState = FrontSwitchReading;
if (FrontSwitchState == LOW){// if Front Push button was pushed and we waited long enough.
timer1.disable(1); // stop counting, we only need to count when the moving tray stops at the back sensor
digitalWrite(EnablePin, LOW);
if (!FrontSensorWasActivated)
if(running == false) {
// digitalWrite(EnablePin, LOW);
digitalWrite(DirPin, HIGH); // choose the right direction for the stepper to turn CW
driveStepper (nSteps);
}
}
else return;
}
}
// save the reading. Next time through the loop,
// it'll be the LastSwitchButtonState:
LastFrontSwitchState = FrontSwitchReading;
int BackSwitchReading = digitalRead(BackSwitch);
// check to see if you just pressed the FrontSwitch button
// (i.e. the input went from HIGH to LOW), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (BackSwitchReading != LastBackSwitchState) {
// 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 (BackSwitchReading != BackSwitchState) {
BackSwitchState = BackSwitchReading;
// only start moving the motor if the state is LOW
if (BackSwitchState == LOW){
if (!BackSensorWasActivated)
if(running==false) {
digitalWrite(DirPin, LOW);
driveStepper(nSteps);
}
}
}
}
// save the reading. Next time through the loop,
// it'll be the LastSwitchButtonState:
LastBackSwitchState = BackSwitchReading;
// }
}
void driveStepper(long lnSteps){
// function to drive the stepper here
TrayStopped=false;
}
As you can see currently I'm trying to make this work by using the SimpleTimer.h library yet it doesn't works as I wanted since. It looks to me like the counter timer1 doens;t stop counting at all.
For example if I remove if (! running) in this part of code:
if (TrayStopped)if (!running){
timer1.setTimeout(30000, disableDriver); // wait 30 seconds to disable timer
timer1.run(); //start the thread.
}
and make it like this:
if (TrayStopped){
timer1.setTimeout(30000, disableDriver); // wait 30 seconds to disable timer
timer1.run(); //start the thread.
}
the driver disable after 30 seconds even though the motor is still moving.
I have tried using milis() function comparing it to a set interval inside a while loop with no success also.
something likein this online found example:
unsigned long previousMillis = 0; // last time update
long interval = 30000; // interval at which to do something (milliseconds)
void setup(){
}
void loop(){
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
// do something
}
}
my version looked something like this
if (TrayStopped){
while(currentMillis - previousMillis < interval) return;// do nothing
else disableDriver();
Yet this somehow freezes the microcontroller I think, as it won't take input from pushed buttons.
So if you can please help me solve this.
Regards!