Hi Guys, I had a PLC malfunction on site this morning (Sunday!) and all I have is an Arduino which has been in the drawer for years which I'm sure will do the job if only I knew how!
I need to run a stepper (Via a DM556 driver) 3450 steps, stop then return back the same number with an operating frequency of 1000millisec. I need that to be triggered by an input pin with no other input. Outputs to the driver are DIR and PUL.
Thanks to Youtube and this forum I have figured out how to run the motor at the correct speed but how to compile the above action is beyond me, especially given my timeframe is asap.
Any help would be most appreciated.
Please read the topic "How to get the best out of this forum" for more correct and useful replies.
Start by testing the stepper example code in the IDE.
I’m sure we’ll be happy to help, maybe a quick (clear) napkin sketch of what’s wired to what. Power supply etc.
If you’ve got any code already, you already understand that - then put that in code tags, and post here.
It’s a bit daunting in a rush like this, but stay focussed and calm… it just might work!
I need to run a stepper (Via a DM556 driver) 3450 steps, stop then return back the same number with an operating frequency of 1000millisec.
I have figured out how to run the motor at the correct speed
3450 steps/second is quite fast and if you have the hardware running at this speed you have accomplished a lot.
I need that to be triggered by an input pin
What actually drives the trigger input pin?
The trigger pin is started by a Tempus master clock which triggers it every 60 seconds. At the risk of sounding patronising the further we go in that direction the more confusing things will get. This is an actuator which drives a (public) clock as part of a large water sculpture, best we stick to first principles as there's a world of pain to be had elsewhere in the installation.
What voltage is the high and low of the Tempus clock signal?
How long is the pulse?
Do you know how to write the code for the Arduino to read that pin and detect the trigger signal?
The Tempus is simply the contacts of a relay so feeds voltage from the Arduino back to the pin when it closes. the signal is 9 seconds long.
I don't know how to write the code to read the pin, my Arduino career spans about 6 hours.
If you are using a library like AccelStepper or MobaTools, the stepper.moveTo(position);
function will move the stepper to an absolute position away from the reference position (home) and stepper.moveTo(0);
will move it back to home. The reference position is established at startup.
Does the one second stepper movement need to be on the starting or ending of the 9 second contact closure.
If the stepper does not start exactly at the start or end of the trigger how important is that error for what the stepper is driving?
What is the broken PLC controlling which you now want to control with the Arduino. What model of Arduino do you have?
I'll write it out in point form which might explain it more precisely than I can.
-Input pin goes high for 9 seconds
-output pin 2 pulses 3450 times then stops
-wait (nominal period, less than a second)
then
-output pin 3 goes high to trigger DIR for duration of return travel
-output pin 2 pulses 3450 times to run motor back
-Stop awaiting next trigger (must stop within the 9 second window)
I may have almost written my own program there but I just don't have the know how to make it work.
Sounds like you're onto something there, I'll have a look. Thank you.
The broken PLC was just running the driver for the stepper motor - nothing else. Kinda like going to the shops in a jumbo jet it was way overkill but we use them elsewhere on bigger projects so they are our go to building blocks.
The Arduino is a duinotech MEGA. again, overkill as far as I can tell.
As a new user I can't upload attachments which is unfortunate. At the suggestion of groundFungus I found a sketch from MobaTools which does exactly what I want EXCEPT it does it in a continuous loop. I need it to start a cycle when triggered then stop when one cycle is complete.
You can post the code. Please read the forum guidelines to see how to properly post code and some information on making a good post.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.
To post images etc you need trust level 1, you can get there by:
- Entering at least 5 topics
- Reading at least 30 posts
- Spend a total of 10 minutes reading posts
Users at trust level 1 can…
- Use all core Discourse functions; all new user restrictions are removed
- Send PMs
- Upload images and attachments
Thank you,
We're making steady progress in the right direction, I'll be onsite elsewhere for the next 12 hours but will pick this up again when I get back.
type or paste code here
``````cpp
/* Example for MobaTools
Moving a stepper back and forth
*/
#include <MobaTools.h>
// Adjust pins, steps and time as needed
const byte stepPin = 9;
const byte dirPin = 8;
const int stepsPerRev = 800; // Steps per Revolution ( example with 1/4 microsteps )
const long targetPos = 3450; // stepper moves between 0 and targetpos
long nextPos;
MoToStepper myStepper ( stepsPerRev, STEPDIR );
MoToTimer pause; // Pause between stepper moves
bool stepperRunning;
void setup() {
myStepper.attach( stepPin, dirPin );
myStepper.setSpeed( 1000 ); // 60 Rev/Min ( if stepsPerRev is set correctly )
myStepper.setRampLen( 200 );
stepperRunning = true;
}
void loop() {
if ( stepperRunning ) {
// Wait till stepper has reached target, then set pause time
if ( !myStepper.moving() ) {
// stepper has reached target, start pause
pause.setTime( 1000 );
stepperRunning = false;
}
} else {
// stepper doesn't move, wait till pause time expires
if ( pause.expired() ) {
// pause time expired. Start stepper in opposite direction
if ( nextPos == 0 ) {
nextPos = targetPos;
} else {
nextPos = 0;
}
myStepper.moveTo( nextPos );
stepperRunning = true;
}
}
// The sketch is not blocked while the stepper is moving nor while it is stopped.
// Other nonblocking tasks can be added here
}
Sketch posted previously is close to what I want. I've tweaked speed and number of steps to what I want but no idea how to start a single cycle from an input pin, then have it wait for the next impulse. Any help most appreciated.
You can try this. It's a simple finite state machine.
Maybe you don't need a ( nearly ) not blocking design, but learning about a FSM is always a good idea. It can solve many problems.
The code is untested ( but it compiles ), because I don't have any testing possibilities at the moment.
/* Example for MobaTools
Moving a stepper back and forth
*/
#include <MobaTools.h>
// Adjust pins, steps and time as needed
const byte stepPin = 9;
const byte dirPin = 8;
const byte triggerPin = 10; // adjust pinnumber to your needs, connect relay contact between pin and gnd
const int stepsPerRev = 800; // Steps per Revolution ( example with 1/4 microsteps )
const long targetPos = 3450; // stepper moves between 0 and targetpos
enum states_t { TRIGGERWAIT, FORWARD, WAITING, BACKWARD };
states_t stepperState = TRIGGERWAIT;
long nextPos;
MoToStepper myStepper ( stepsPerRev, STEPDIR );
MoToTimer pause; // Pause between stepper moves
void setup() {
myStepper.attach( stepPin, dirPin );
myStepper.setSpeed( 1000 ); // 60 Rev/Min ( if stepsPerRev is set correctly )
myStepper.setRampLen( 200 );
pinMode( triggerPin, INPUT_PULLUP );
}
void loop() {
switch ( stepperState ) {
case TRIGGERWAIT:
// waiting for trigger
if ( digitalRead( triggerPin ) == LOW ) {
// trigger active, start stepper movement
myStepper.moveTo( targetPos );
stepperState = FORWARD;
}
break;
case FORWARD:
// stepper is moving forward, wait till it reaches its target position
if ( !myStepper.moving() ) {
// stepper has reached target, start pause
pause.setTime( 1000 );
stepperState = WAITING;
}
break;
case WAITING:
// stepper is at target position, wait until pause time exceeded
if ( pause.expired() ) {
// pause time has expired. Move stepper back to 0
myStepper.moveTo( 0 );
stepperState = BACKWARD;
}
break;
case BACKWARD:
// stepper is moving backwards. Wait till it reaches 0 position
// and trigger pulse has ended ( is HIGH again )
if ( !myStepper.moving() && digitalRead( triggerPin ) == HIGH ) {
stepperState = TRIGGERWAIT;
}
break;
}
delay(20); // simple debouncing of relay contact
}
That's fantastic, Thank you! If I get chance I'll put together a video of what this actually does.