Hi man thanks a lot for the reply , I added a print statement in the loop to print the ith iteration at which I press to button to see if the motor is moving in the opposite direction one full circle or not , and I can see 2-3 steps still being missed.
I you have a closer look in this image , you can see that I pressed the limit_switch at the iteration number 648 , so had the stepper moved an entire circle in the opposite direction , the motor should have displayed 152 instead of 150 , which it isn't , any ideas why this might be be the case ?
I doubt your motor can instantly go from standstill to 800 steps per second (240 RPM) without missing steps. You need to provide acceleration with a library like MobaTools that will ramp the step rate up and down gradually. It's in the IDE library manager. In the mean time, slow the motor down to 50 RPM (6000 microseconds per step) and try it.
int stepDelay = 6000; // Delay between steps in microseconds
What i meant was when i pressed the button it was iteration number 648 , had the stepper moved an entire circle in the opposite direction , the final step should have been 800-648=152 in the opposite direction , but from the image u can see its 150 steps , which implies 2 steps were missed and this is what I meant to ask ? why are the 2 steps being missed , how can I prevent this from happening.
Hi man , sorry for the delayed response , just wanted to know how to deal with my current situation . I am trying to build a string art machine in which I want to set the nail 0 as the 0th position for my setup so to help caliberate it using a limit switch . I have a series of nails in the form of (FROM NAIL NUMBER ) - (TO NAIL NUMBER ) and am required to move the stepper motor such that it rotates the entire assembly between the two nails , now my dilemma is that , say the current rotation involves the moving via the direction of hitting the limit switch , how do I ensure that the rotations are taking place accurately with the error as low as possible ?
My idea was that say the direction of rotation involves the limit switch being hit , then in that case I would first keep rotating the stepper until the limit switch is hit , and once it is hit , I know exactly how many step more I need to rotate the assembly further since I know the nail from which I am starting as well as the nail I need to reach however the problem with this approach is that , hitting the limit switch suddenly doesn't necessarily stop the stepper right then , it moves a little more because of the rate at which it de-accelerates.
This is what i want , say I am at pin 7 and need to move to pin 245 , at pin 0 would be a stick to hit the limit switch , I first want to keep moving the stepper till the limit switch is hit , and as soon as it is hit , I now know I am at pin 0 then I just need to move the distance from pin 0 to pin 245 . I want to do this since I belive the chances of error in this are lesser than directly moving from pin 7 to pin 245 cause in that case say there is a slight mis match in movement then the entire thing would break down .
The wokwi stepper doesn't always start with '0'. You can see that if you insert a delay(2000) at the very start of setup(). Then you see the initial step position.
Sometimes it's not zero but 2 steps off.
#include <AccelStepper.h>
#define STEP_PIN 2
#define DIR_PIN 3
#define LIMIT_SWITCH_PIN 7
AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
void setup() {
Serial.begin(9600);
pinMode(LIMIT_SWITCH_PIN, INPUT_PULLUP);
stepper.setMaxSpeed(400); // Set the maximum speed in steps per second
stepper.setAcceleration(400); // Set the acceleration in steps per second per second
stepper.setSpeed(40); // Set the speed in steps per second
}
void loop() {
stepper.move(200 * -8);
while (stepper.distanceToGo() != 0) {
if (digitalRead(LIMIT_SWITCH_PIN) == LOW) {
// Serial.println("Limit switch triggered");
stepper.stop();
stepper.move(200);
while (stepper.distanceToGo() != 0) {
stepper.run();
}
break;
}
stepper.run();
}
Serial.println("Stopped");
delay(3000);
}
I am using this code , the problem I am facing is that , often the speed of the stepper is so high and even when the limit switch is hit , it still moves some more distance before stopping and when I reduce the speed a lot , it isn't fast enough to fire the limit switch.
What do you think this will do? stepper.stop() does NOT stop the stepper immediately. It will only set a new target based on the actual acceleration. stepper.move does the same - setting a new target based on the actual position. So you overwrite the target set by stepper.stop immediately with a new one. That does not make sense. Because you use acceleration/deceleration with stepper.run() the stepper will never change direction instantly.
That sounds very strange. A limit switch should always 'fire' - even more so at low speeds.
For your motor, how many steps per revolution? For your machine, how many nails in the circle?
Once you "home" the motor at startup, ignore the limit switch unless you lose steps and need to home again.
How can you be absolutely SURE that it's not 1 or -1? What is the rotation speed in pins per second? Does it always turn in the same direction?
Post a detailed description of the limit switch and actuator mechanism.
This is how the attachment is joined to hit the limit switch , my idea is that as soon as the attachment hits the switch in clockwise direction , it would tell me that I am at pin 1 there by allowing me to caliberate the entire mechanism.
I am facing a dilema in coming up with the mechanism to help caliberate it because my idea is to always choose the shorter circumference when moving from one pin to another , say I am at pin 8 and want to move to pin 199 , now I would preferably be taking the shorter path along the circumference which goes from pin 8 to pin 1 and then from pin 1 to pin 199 , now the problem is that , say there is some sort of error induced in the motion , then I should have a mechanism in place which ensure that even if I miss some steps while moving from pin8 to pin 199 , my machine helps recaliberate it , my idea was to check if pin 1 would come in the direction in which I would move and if so , I would first move from my current pin to pin 1 and then from pin 1 to the pin I am required to go .
Now the problem with this approach is that , I can never say from surity as to how many steps would I need to take to hit pin 1 . On paper this is not true , since say I am at pin 8 and need to go to pin1 then that would be and angle of (8-1)*(angle between each nail) / my current step angle , but say because of some error I am actually at pin 9 instead of pin 8 , I have to take this scenario into account thus what I plan to do is to move the stepper until the limit switch is hit , and once it is hit , use the theoretical formula to specify the number of steps I need to move further .
what i want to do is that , I want to keep moving the stepper until the limit switch is hit , and then as soon as it is hit , I want to specify some fixed number of steps for it to move , any ideas how should I do that then ? say as soon as the limit switch is hit , I want it to move 200 steps.
This is how I was thinking of doing it :
stepper.setSpeed(200);
while (1) {
bool reached = false;
if (digitalRead(LIMIT_SWITCH_PIN) == LOW) {
Serial.println("HIT");
stepper.setCurrentPosition(0);
stepper.move(200);
while (stepper.distanceToGo() != 0) {
stepper.runSpeed();
}
reached = true;
break;
}
if (reached) break;
stepper.runSpeed();
}
String Art Machine
Have a look at this at timestamp : 4:13 , he mentions that he too uses a limit switch to find pin 0 , this is what I took inspiration from , what would you suggest then , how to go about caliberating it ?
I think one of the biggest problem is the mechanical design.
Placing the stepper in the centre of the disc and using the axis of the stepper directly as the axis of the disc is very problematic. Because of the large inertia of the disc, the stepper cannot control it precisely.
If you watch the video, you will see that there is a gear rim attached to the disc and the stepper uses a small gear wheel to engage with the gear rim to move the disc.
This allows for much more precise and rigid control of the disc position.
I think with your mechanics you will never get good results.
Thanks for the reply man , now that I have already got the nails engraved onto it , will give it a try this way , incase it doesn't work out , will switch to using 2 gears.
Any ideas how to caliberate the setup using a limit switch ?
I'd think that, depending on which way you approach pin 1, the trigger will happen at a different angle. I'd set the position once in a particular direction, and then measure the error each time you hit it from the same direction. If the error changes significantly, then you're skipping steps and need stronger mechanicals.
I'd also record and check the triggering in the opposite direction.
I'd also do my motion-planning in work units (pins? milli-pins? degrees? milli-degrees?) and make the program translate that into steps, including the measured CW or CCW errors from above.