Stepper Motor - OSC - Forward & Backward (SOLVED)

Hi guys,

Here is what I'm trying to achieve, basically I want to move objects up & down at a long distance.
So, I'm using an Arduino Uno with a Stepper Motor and communicate through OSC.

For now, it's working OK forward.
I send OSC values between 0 to 10.24 and the stepper motor goes from 0 to 2048 steps.
It even works with value from 0 to 20.48 for 2 full rotations for example.

But, I'm struggling for days with the Backward movement.
The stepper motor interprets each additional step in the backward direction as a forward movement, which is the expected behaviour I guess. (values sent from 10.24 to 0 is interpreted as a new full rotation forward)

Here is the OSC track I'm trying to achieve :
2 full rotations forward and then 2 full rotations backward.
For now, this track is interpreted as 4 full rotations forward.

How could I indicate for example that after a full cycle up to 2048 steps, a step to 2047 is a backward step not an additional step forward ?

Could anyone point me in the right direction ? I'm completely out of my depth there...

Thanks a lot

Here is the code I use :

#include <SPI.h>
#include <Ethernet.h>
#include <ArdOSC.h>
#include <AccelStepper.h>

byte myMac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte myIp[]  = { 192, 168, 0, 100 };
int serverPort  = 8000;
int destPort= 9000;

OSCServer server;
OSCClient client;
AccelStepper stepper1(4,6,7,8,9);

// initialize the stepper library on pins 6 through 9:

long val1 = 0;

void setup(){ 
 
Serial.begin(9600);

Ethernet.begin(myMac ,myIp); 
server.begin(serverPort);

//set callback function & oscaddress
server.addCallback("/Fader/Value",&func1);


stepper1.setMaxSpeed(300.0);
stepper1.setAcceleration(20.0);


}
 
void loop(){
 
 if(server.availableCheck()>0){
//    Serial.println("alive! "); 
 }
 stepper1.moveTo(val1);
 stepper1.run();
 
}


void func1(OSCMessage *_mes){
 float value = _mes->getArgFloat(0);
 val1 = (long)(value*200);
 Serial.println(val1);
}

amy_bl:
Could anyone point me in the right direction ? I'm completely out of my depth there...

You need to provide some examples of the data that is sent to the Arduino and how you want those values to be interpreted.

...R

Thanks for your answer Robin2,

The stepper motor receives integral values (val1) from 0 to "whatever positive int", and a full rotation moves from 0 to 2048. I don't know yet how many full rotations I will use, but it already seems to work ok with multiples rotations forward (int 4096 and up), as, I guess, the OSC track is constantly broadcasting the current position the stepper motor should be at.

My problem, I guess, is to code "when val1 is < the current position, speed has to be negative" & the opposite "when val1 is > the current position, speed has to be positive"
And I failed miserably at that, because speed can't be <0 for one, and secondly the stepper motor doesn't know what its current position is...

One case example would be :

  • move forward from 0 to (val1)100
  • move backward from 100 to (val1)80
  • move forward from 80 to (val1)100

for now it is interpreted as :

  • move forward 100 steps
  • move forward 20 steps
  • move forward 20 steps

even if the data received by the arduino is:

  • int from 0 to 100
  • int from 100 to 80
  • int from 80 to 100

Does that help ? Let me know, thanks.

What stepper motor and what stepper motor driver are you using?

...R

For now, I'm trying to get the right code with basics :

  • Stepper Motor 28BYJ-48
  • Driver SBT0811

then I'll switch to :

  • Nema 17
  • A4988 driver
    (I don't have a 12V power supply on hand yet)

Thx

amy_bl:
For now, I'm trying to get the right code with basics :

  • Stepper Motor 28BYJ-48
  • Driver SBT0811

I'm not familiar with the SBT0811 but I presume it behaves like a ULN2003.

I would STRONGLY advise against changing to a different motor and driver before you get this problem solved.

Try this simplified program and tell us what happens

#include <AccelStepper.h>

AccelStepper stepper1(4,6,7,8,9);


void setup(){ 
 
    Serial.begin(9600);

    stepper1.setMaxSpeed(300.0);
    stepper1.setAcceleration(20.0);

    stepper1.moveTo(160);
    Serial.println("Moving forward to 160");
    while (stepper1.distanceToGo > 0) {
        stepper1.run;
    }
    delay(1000);
    stepper1.moveTo(80);
    Serial.println("Moving back to 80");
    while (stepper1.distanceToGo > 0) {
        stepper1.run;
    }
    delay(1000);
    stepper1.moveTo(160);
    Serial.println("Moving forward to 160");
    while (stepper1.distanceToGo > 0) {
        stepper1.run;
    }

}
 
void loop(){

}

...R

Thanks Robin2,
I had to add a few "()" to make it run

#include <AccelStepper.h>

AccelStepper stepper1(4,6,7,8,9);


void setup(){ 
 
    Serial.begin(9600);

    stepper1.setMaxSpeed(300.0);
    stepper1.setAcceleration(20.0);

    stepper1.moveTo(160);
    Serial.println("Moving forward to 160");
    while (stepper1.distanceToGo() > 0) {
        stepper1.run();
    }
    delay(1000);
    stepper1.moveTo(80);
    Serial.println("Moving back to 80");
    while (stepper1.distanceToGo() > 0) {
        stepper1.run();
    }
    delay(1000);
    stepper1.moveTo(160);
    Serial.println("Moving forward to 160");
    while (stepper1.distanceToGo() > 0) {
        stepper1.run();
    }

}
 
void loop(){

}

Here is what happens : it moves 160 steps forward and then stops. (no more activity on the driver's leds)

If I just modify a > for a < on the second movement :
It moves 160 steps forward, then 80 steps forward, then 160 steps forward.

#include <AccelStepper.h>

AccelStepper stepper1(4,6,7,8,9);


void setup(){ 
 
    Serial.begin(9600);

    stepper1.setMaxSpeed(300.0);
    stepper1.setAcceleration(20.0);

    stepper1.moveTo(160);
    Serial.println("Moving forward to 160");
    while (stepper1.distanceToGo() > 0) {
        stepper1.run();
    }
    delay(1000);
    stepper1.moveTo(80);
    Serial.println("Moving back to 80");
    while (stepper1.distanceToGo() < 0) {
        stepper1.run();
    }
    delay(1000);
    stepper1.moveTo(160);
    Serial.println("Moving forward to 160");
    while (stepper1.distanceToGo() > 0) {
        stepper1.run();
    }

}
 
void loop(){

}

Hope it clarifies something.
Thanks

Hi,
Can I suggest you forget about OSC etc and write some code JUST to control the stepper.
Get it working in both directions then integrate it into your OSC code.

Look at the examples for AccelStepper library in the IDE to see how to change direction.

Tom... :slight_smile:

Hi Tom,
Yes, I totally agree, I went back to the "bounce example" which works ok.

But I can't figure out how to code something like that :
"when val1 is < the current position, speed has to be negative" & the opposite "when val1 is > the current position, speed has to be positive"

Any idea ?
Thanks

amy_bl:
I had to add a few "()" to make it run

Apologies for that.

Here is what happens : it moves 160 steps forward and then stops. (no more activity on the driver's leds)

I don't have a way to test it with a stepper motor but when I try the corrected code it goes through all 3 stages.

If I just modify a > for a < on the second movement :

I had not realised that distanceToGo() uses negative numbers.

When I add the line

Serial.println(stepper1.currentPosition());

after each WHILE loop it prints the expected values

It seems that your stepper driver is not doing what AccelStepper assumes. Can you post a link to the datasheet for the driver?

...R

Hi,
A circuit diagram including power supply would help a lot at this stage.

Thanks.. Tom... :slight_smile:

Sorry Robin, I'm stupid.
I wasn't checking the "bounce code" with the same pin configuration... (the switch between 7&8 I forgot about)
Sorry about that.
Anyway, now I've managed to obtain the expected behaviour, but I had to modify the second ">" otherwise it stops after the first movement.

I've checked with "Serial.println(stepper1.currentPosition());" this code sends the right values.
So, this works : 160 forward, 80 backward, 160 forward.

#include <AccelStepper.h>

AccelStepper stepper1(4,6,8,7,9);


void setup(){ 
 
    Serial.begin(9600);

    stepper1.setMaxSpeed(300.0);
    stepper1.setAcceleration(20.0);

    stepper1.moveTo(160);
    Serial.println("Moving forward to 160");
    while (stepper1.distanceToGo() > 0) {
        stepper1.run();
    }
    delay(1000);
    stepper1.moveTo(80);
    Serial.println("Moving back to 80");
    while (stepper1.distanceToGo() < 0) {
        stepper1.run();
    }
    delay(1000);
    stepper1.moveTo(160);
    Serial.println("Moving forward to 160");
    while (stepper1.distanceToGo() > 0) {
        stepper1.run();
    }

}
 
void loop(){

}

Without "<0", it doesn't print any values after the first movement:

159
159
159
160
Moving back to 80
Moving forward to 160

What do you think would be next ? [edit] I’m stupid again, that should work fine now with the OSC, as values were correct. (I’m on a train without an RJ45 cable...) I’ll let you know tomorrow..

Thanks a lot !

@TomGeorge
it is pretty straight forward :

  • Arduino Uno Pin 6 to 9 connected to Stepper Driver Pin 1 to 4
  • Power Supply is USB port for now.
    I could provide a circuit diagram if you think there's still something fishy there. (beyond my previous pin misconfiguration :wink: )

Thanks

amy_bl:
, but I had to modify the second ">" otherwise it stops after the first movement.

I acknowledged that I had that mistake.

I've checked with "Serial.println(stepper1.currentPosition());" this code sends the right values.
So, this works : 160 forward, 80 backward, 160 forward.

Does that mean everything is now working properly?

...R

Yes, I believe so.
I have to wait until tomorrow to check with the OSC part.
I hope it is just my pin misconfiguration... :’(
Thanks a lot, I’ll let you know

And it works flawlessly with the OSC code, forward & backward. :smiley:
Thanks a lot guys for pointing me in the right direction !

(Now I will switch for the nema 17 and will discover some new issues :stuck_out_tongue: )
Thanks again

1 Like

Good to hear you have it working.

...R