Help with determining motor steps

Hi guys, Clon here. I am doing a project which involves the use of a stepper motor (28BYJ-48 to be exact) to turn a thumb screw attached to a shock absorber. I am using Arduino UNO and a bluetooth module (HC-06). The problem that I have now is with the coding, I am not so sure where to start or even how to start.

The thumb screw can be to rotated 22 times/clicks (clockwise to tighten and anticlockwise to loosen), and each click is about 50 degree or it's motor step is approximately 284 steps. Let's say if I want to turn all the way to the 22nd click from origin, its 284*22 = 6248. But if afterwards I wanted to turn to the 17th click for example, how do I let the program know for sure how much steps to go back (cause the program doesn't really know it is at the 22nd click, right?).

Imagine you are in the elevator at ground floor (1), and you want to get to the 2nd floor which requires 284 motor steps. Once you reached 2nd floor, you want to go to the 3rd floor, that's another additional 284 steps. What if when you are at the ground floor, you want to go to the third floor directly? I can't just program ( if( x == '3' );, step(284); or even step(568); that would be make it go incremental. I want to make it absolute (with ground floor as reference point (0 steps)).

I hope you guys have some insight on this and please do ask if you can't understand it, I'm not a good descriptive writer. I understand that you guys are trying your best to help so here is the code that I previously modified from adafruit tutorial.

#include <Stepper.h>

int pin1 = 12;
int pin2 = 11;
int pin3 = 10;
int pin4 = 9;
int bluetooth;
 
Stepper motor(512, pin1, pin2, pin3, pin4);  
 
void setup()
{
  pinMode(pin1, OUTPUT);
  pinMode(pin2, OUTPUT);
  pinMode(pin3, OUTPUT);
  pinMode(pin4, OUTPUT);
 
  while (!Serial);
  
  Serial.begin(9600);
  motor.setSpeed(30);
}

void loop()
{
  if (Serial.available()){
    Serial.println("\n");
      Serial.println("Press 1 for medium stiffness and press 2 to return to normal stiffness. \n Press 3 for high stiffness and press 4 to normal stiffness.\n");
  bluetooth = Serial.read();
  if(bluetooth == '1')
  motor.step(2048);
  if(bluetooth == '2')
  motor.step(-2048);
  if(bluetooth == '3')
  motor.step(4096);
  if(bluetooth == '4')
  motor.step(-4096);
  delay(500);
  }
}

Current coding is when I input 1, the motor will turn 360 degree and 2 will turn -360 degree back to initial position. 3 will turn 720 degree and 4 will turn -720 degrees.

I think what I wanted to do is to make the steps system similar to an elevator system where you can choose the floor you want to go (the nth click you want) and I don't think this can be achieved with just numbers alone...

Here is the image of the thumb screw

I am not so sure where to start or even how to start.

With small steps. Learn to control the stepper motor.
Learn to connect to the bluetooth module.
Learn to get data from the bluetooth module.

Then, start making the individual items work in concert.

But if afterwards I wanted to turn to the 17th click for example, how do I let the program know for sure how much steps to go back (cause the program doesn't really know it is at the 22nd click, right?).

Count the number of clicks you've asked the stepper motor to step n times for.

I can't just program ( if( x == '3' );, step(284); or even step(568); that would be make it go incremental. I want to make it absolute (with ground floor as reference point (0 steps)).

I give up. Why can't you? If x is the number of floors to go up. then stepping 568 steps seems appropriate.

If x is the floor to go to, then you need to know where you are going FROM.

HI, before you get any further, can you edit the subject of your post to show what it is you actually want.
Most forum members do not even look twice at "Need help with programming."
Please edit the subject to something like

"Help please, Bluetooth control of stepper with Arduino UNO "

Then you will get some help.

Tom..... :slight_smile:

cause the program doesn't really know it is at the 22nd click, right?)

You're going to have to ensure that it does.

Keep a variable with the current position (in steps or clicks). Whenever you command the motor, adjust the position too. You just need a way to tell where you are at startup; one solution would be to have a limit switch at one end and adjust when you start until you hit the limit switch.

PaulS:

I am not so sure where to start or even how to start.

With small steps. Learn to control the stepper motor.
Learn to connect to the bluetooth module.
Learn to get data from the bluetooth module.

Then, start making the individual items work in concert.

But if afterwards I wanted to turn to the 17th click for example, how do I let the program know for sure how much steps to go back (cause the program doesn't really know it is at the 22nd click, right?).

Count the number of clicks you've asked the stepper motor to step n times for.

I can't just program ( if( x == '3' );, step(284); or even step(568); that would be make it go incremental. I want to make it absolute (with ground floor as reference point (0 steps)).

I give up. Why can't you? If x is the number of floors to go up. then stepping 568 steps seems appropriate.

If x is the floor to go to, then you need to know where you are going FROM.

Sorry, I forgot to mention that I am already able to control the stepper motor and get the bluetooth working already. Only problem now is determining the steps required.

Sure, it will definitely be viable to just put if(x==2); steps(284) if I am from 2nd floor, but if I want to go to 2nd floor directly from ground floor, I can't just use back if(x==2); steps(284) right? It will only go up to first floor, and I can't just change the program on the spot.

Or is it possible to determine that the first click is 0 steps and the 2nd click is 284 steps and 3rd click is 568 steps and so on, so if I input 2 from 1st click position, it will turn 284 and if I input 3 from 2nd click position, it will turn another 284 steps instead of 568 (which means it isn't incremental)?

TomGeorge:
HI, before you get any further, can you edit the subject of your post to show what it is you actually want.
Most forum members do not even look twice at "Need help with programming."
Please edit the subject to something like

"Help please, Bluetooth control of stepper with Arduino UNO "

Then you will get some help.

Tom..... :slight_smile:

Thanks Tom, I've edited the title. :slight_smile:

wildbill:

cause the program doesn't really know it is at the 22nd click, right?)

You're going to have to ensure that it does.

Keep a variable with the current position (in steps or clicks). Whenever you command the motor, adjust the position too. You just need a way to tell where you are at startup; one solution would be to have a limit switch at one end and adjust when you start until you hit the limit switch.

which means I have to add another limit switch electronic into my circuit?

Assuming you have a limit switch so there is some way for the Arduino to "know" that the device is at the zero position then you could have an array (let's call it floorSteps[]) with an element for each floor holding the number of steps from the 0 position to that floor. Separately you have a variable (curFloor) storing the current floor the device is at. Suppose it is at floor 3 and wants to go to floor 5. Then the number of steps would be calculated like this

reqdSteps = floorSteps[5] - floorSteps[curFloor];

...R

Robin2:
Assuming you have a limit switch so there is some way for the Arduino to "know" that the device is at the zero position then you could have an array (let's call it floorSteps[]) with an element for each floor holding the number of steps from the 0 position to that floor. Separately you have a variable (curFloor) storing the current floor the device is at. Suppose it is at floor 3 and wants to go to floor 5. Then the number of steps would be calculated like this

reqdSteps = floorSteps[5] - floorSteps[curFloor];

...R

Hi Robin,

in that case the Arduino would know exactly where it is located if a limit switch is installed, am i right? But then in my case I am trying to rotate the thumb screw attached to the shock absorber so there isn't any applicable way to install the limit switch in it...

Are there anyway else to do this without the use of a limit switch?

I have come up with an equation that probably will help in the problem,

say that (x-1)*(284) - y
where x is the input number and y is the previous step data. (however this is only true for 2nd attempt, 1st attempt has no previous value so I will just use (x-1)*284).

Is there any way to retrieve previous value to substitute in the y value?

For example first attempt I input 7 (7th click) which means (7-1)*(284) = 1704 steps. From 1st click to 7th click.
second attempt i input 1 (1st click) which means (1-0)*284 - 1704 = -1704 steps. From 7th click back to 1st click.

This will probably solve the problem I am facing, provided that I am able to retrieve previous data and put into that equation, any insight on this? :~

The math is fairly trivial:

Steps=(DesiredClicks - CurrentClicks) * 284;

The issue is setting CurrentClicks when you start - you need a way to measure it. I assume you would have mechanical problems if you tried to step 6248 steps at startup irrespective of what click you were at?

wildbill:
The math is fairly trivial:

Steps=(DesiredClicks - CurrentClicks) * 284;

The issue is setting CurrentClicks when you start - you need a way to measure it. I assume you would have mechanical problems if you tried to step 6248 steps at startup irrespective of what click you were at?

There won't be much mechanical problem as once it reaches the maximum click it will only become stagnant or rather come "into a dead end" and the stepper motor would be losing steps there. Assuming we are at initial position, 6248 steps would mean going to the the maximum tightness (22 clicks).

Even with the equation I came up with in the last post, it will not be able to rectify the problem if we cannot determine the current click? :~

I have included a photo of the thumb screw of the shock absorber for reference.

Even with the equation I came up with in the last post, it will not be able to rectify the problem if we cannot determine the current click?

No. You're undoing the prior move before you make the next one, but you have no idea of your absolute position.

As far as I know every machine that needs to know the absolute position of a stepper motor needs a limit switch or equivalent. An equivalent might be a potentiometer that is turned by the motor (perhaps a multi-turn pot) from which the Arduino could read the variable voltage and thus estimate the position. However that would not be nearly as accurate as individual motor steps.

Also (to the best of my knowledge) most rotary encoders just give a relative position. I don't know if you can buy ones that give an absolute position.

The limit switch would probably only need to be used once when the Arduino is powered up. After that it would remember where the motor is.

Of course another option might be to manually move the motor accurately to the zero position before starting the Arduino - but you might forget.

...R

I don't know if you can buy ones that give an absolute position.

You can, but they are much more expensive.

Robin2:
As far as I know every machine that needs to know the absolute position of a stepper motor needs a limit switch or equivalent. An equivalent might be a potentiometer that is turned by the motor (perhaps a multi-turn pot) from which the Arduino could read the variable voltage and thus estimate the position. However that would not be nearly as accurate as individual motor steps.

Also (to the best of my knowledge) most rotary encoders just give a relative position. I don't know if you can buy ones that give an absolute position.

The limit switch would probably only need to be used once when the Arduino is powered up. After that it would remember where the motor is.

Of course another option might be to manually move the motor accurately to the zero position before starting the Arduino - but you might forget.

...R

I see, thanks for the info. Guess that I can't do it from the coding side alone then.

But how about the retrieving previous data and put in the new equation? Is there such command present in the Arduino coding? Like what I posted earlier.

But how about the retrieving previous data

What previous data? From where?

PaulS:

I don't know if you can buy ones that give an absolute position.

You can, but they are much more expensive.

Not only are they much more expensive (the encoding wheel uses grey code and needs many internal sensors to read all the bits of the grey code, where a relative encoder just needs two sensors), they can only tell you where you are in a single 360 degree rotation not multiple rotations. Combining with a multi-turn pot for an estimate of which rotation one is within (pot would be coarse location and encoder fine location) might work, but is probably way more complicated and expensive (in parts) than what is acceptable for the OP.

@clon12
I don't know any way except some sort of sensor (like a limit switch) to find a zero (or reference) point. Your application in theory is exactly like moving a carriage with a helical drive. You need to make sure that it is acceptable to move the carriage (this would be the part of the shock absorber that engages with the threads of the set-screw or the exposed end of the set screw) to a known position that would change the state of a limit switch. This point can either be at full-travel in or out, or even somewhere in between (as long as the limit switch isn't damaged by being over engaged). In the setup one would look at the switch and move 1 step (not "click" as defined in your application) at a time checking the limit switch to see if it changes state in between steps. Don't forget to debounce that limit switch at the same time. Once you find your zero point then it is trivial to move x number of steps for each click, and has already been discussed in this thread.

PaulS:

But how about the retrieving previous data

What previous data? From where?

Say that I run a loop from the code below

void loop()
{
if(1<x<23);
motor.step((x-1)*(284)-y );
}
where x is the nth click I want to go and y is the previous step data.

How do I first make the y value is equals to 0 at first loop (considering the first attempt has no previous value)?
How do I make the y value is equals to the answer from the first loop (assuming first attempt is to go to the 3th click, (3-1)*284 = 568, therefore y=568 in second loop)?

Sembazuru:

PaulS:

I don't know if you can buy ones that give an absolute position.

You can, but they are much more expensive.

Not only are they much more expensive (the encoding wheel uses grey code and needs many internal sensors to read all the bits of the grey code, where a relative encoder just needs two sensors), they can only tell you where you are in a single 360 degree rotation not multiple rotations. Combining with a multi-turn pot for an estimate of which rotation one is within (pot would be coarse location and encoder fine location) might work, but is probably way more complicated and expensive (in parts) than what is acceptable for the OP.

@clon12
I don't know any way except some sort of sensor (like a limit switch) to find a zero (or reference) point. Your application in theory is exactly like moving a carriage with a helical drive. You need to make sure that it is acceptable to move the carriage (this would be the part of the shock absorber that engages with the threads of the set-screw or the exposed end of the set screw) to a known position that would change the state of a limit switch. This point can either be at full-travel in or out, or even somewhere in between (as long as the limit switch isn't damaged by being over engaged). In the setup one would look at the switch and move 1 step (not "click" as defined in your application) at a time checking the limit switch to see if it changes state in between steps. Don't forget to debounce that limit switch at the same time. Once you find your zero point then it is trivial to move x number of steps for each click, and has already been discussed in this thread.

It seems that things are much more complicated that I thought here. :~ I'm not sure I understand fully of your statement but I believe that you are referring that what I wanted to do is not achievable without the use of a limit switch as suggested by previous forumers too.

clon12:

Sembazuru:
@clon12
I don't know any way except some sort of sensor (like a limit switch) to find a zero (or reference) point. Your application in theory is exactly like moving a carriage with a helical drive. You need to make sure that it is acceptable to move the carriage (this would be the part of the shock absorber that engages with the threads of the set-screw or the exposed end of the set screw) to a known position that would change the state of a limit switch. This point can either be at full-travel in or out, or even somewhere in between (as long as the limit switch isn't damaged by being over engaged). In the setup one would look at the switch and move 1 step (not "click" as defined in your application) at a time checking the limit switch to see if it changes state in between steps. Don't forget to debounce that limit switch at the same time. Once you find your zero point then it is trivial to move x number of steps for each click, and has already been discussed in this thread.

It seems that things are much more complicated that I thought here. :~ I'm not sure I understand fully of your statement but I believe that you are referring that what I wanted to do is not achievable without the use of a limit switch as suggested by previous forumers too.

Basically, when you power on your control circuit, how is it supposed to know where it is? Ever watch when you turn on a printer that has a moveable head (like the standard, run-of-the mill ink jet)? The print head moves around a bit. One of the things happening in this initialization part is the printer is moving the head to trigger some sort of fixed location sensor so the printer knows where the head is. Turn the printer off and move the head to the middle of the print-area and then turn it back on. The head will move back to "home" as the printer is trying to locate it. That is a demonstration of what I was describing.

The sensor doesn't have to be a physical limit switch, it just needs to act as one. It could be an optical sensor. I.e. it changes state when the device that is being moved reaches (or crosses) a known, fixed point in it's allowed travel range. This point is usually known as a "zero" point. If the zero point is in the middle of the travel range then the device can move in both positive and negative directions. Usually for simplicity the zero point is defined by the designer as at one of the two extremes of the travel range.

Sembazuru:

clon12:

Sembazuru:
@clon12
I don't know any way except some sort of sensor (like a limit switch) to find a zero (or reference) point. Your application in theory is exactly like moving a carriage with a helical drive. You need to make sure that it is acceptable to move the carriage (this would be the part of the shock absorber that engages with the threads of the set-screw or the exposed end of the set screw) to a known position that would change the state of a limit switch. This point can either be at full-travel in or out, or even somewhere in between (as long as the limit switch isn't damaged by being over engaged). In the setup one would look at the switch and move 1 step (not "click" as defined in your application) at a time checking the limit switch to see if it changes state in between steps. Don't forget to debounce that limit switch at the same time. Once you find your zero point then it is trivial to move x number of steps for each click, and has already been discussed in this thread.

It seems that things are much more complicated that I thought here. :~ I'm not sure I understand fully of your statement but I believe that you are referring that what I wanted to do is not achievable without the use of a limit switch as suggested by previous forumers too.

Basically, when you power on your control circuit, how is it supposed to know where it is? Ever watch when you turn on a printer that has a moveable head (like the standard, run-of-the mill ink jet)? The print head moves around a bit. One of the things happening in this initialization part is the printer is moving the head to trigger some sort of fixed location sensor so the printer knows where the head is. Turn the printer off and move the head to the middle of the print-area and then turn it back on. The head will move back to "home" as the printer is trying to locate it. That is a demonstration of what I was describing.

The sensor doesn't have to be a physical limit switch, it just needs to act as one. It could be an optical sensor. I.e. it changes state when the device that is being moved reaches (or crosses) a known, fixed point in it's allowed travel range. This point is usually known as a "zero" point. If the zero point is in the middle of the travel range then the device can move in both positive and negative directions. Usually for simplicity the zero point is defined by the designer as at one of the two extremes of the travel range.

I see.. well that explains just right. Now I understand. But the printer head only moves horizontally, compared to the thumb screw of the shock absorber which has a rotary movement. I assume that optical sensors would not be applicable in this case, right?

If turning the screw causes it to move in and out that is linear movement that could, perhaps, be detected with a microswitch.

...R