gin66 / FastAccelStepper

A high speed stepper library for Atmega 168/328p (nano), Atmega32u4, Atmega 2560, ESP32, ESP32S2, ESP32S3, ESP32C3 and Atmel SAM Due
MIT License
282 stars 67 forks source link

Two stepper realtime on Atmega328 #227

Closed Aeroexpert closed 5 months ago

Aeroexpert commented 5 months ago

Dear Jochen, Thank you for the Fastaccelstepper library. I am a mechanical engineer. trying to achieve a project with Atmega 328p.(I made my custom card like Arduino Uno) Beg my pardon for insufficient knowledge of electronics. because I am not an electronic engineer I tried very hard to understand but I got stuck on my project. I have two stepper motors in my project, which 1st motor: oscillates 2nd motor: continuously moves. I am using a potentiometer to control continuous movement speed. My problem is, that I cannot change the speed of the 2nd motor until the 1st motor finishes its cycles. (hence library uses timer1) I tried using timer interrupt with timer0 or timer3. But the system didn't work at all. I want to control both oscillating speed and continuous speed with potentiometers. If you have any advice I would be grateful. Thank you very much. with my best regards

gin66 commented 5 months ago

sounds like somewhere in the application is a blocking move.

Anyway, without a view onto your source code, there is not much to work with in order to come up with suggestions.

Aeroexpert commented 5 months ago

thank you for your answer:) The main code is a little long. I put the motor codes down. if needed Ican write the whole code here. `gen1 = analogRead(A0) / 3; hiz1 = map(analogRead(A1), 0, 1023, 100, 2000); solb = analogRead(A2) 1, 5; sagb = analogRead(A3) 1, 5; hiz2 = map(analogRead(A4), 0, 1023, 100, 12000);

if (mt1 == 1) { stepper1->setSpeedInHz(hiz1);
stepper1->setAcceleration(10000);
stepper1->moveTo(150, true); stepper1->moveTo(-150, true);

} else { stepper1->setSpeedInHz(2000);
stepper1->setAcceleration(10000);
stepper1->moveTo(kn3, true); }

if (mt2 == 2) { stepper2->setSpeedInHz(hiz2); stepper2->setAcceleration(5000); stepper2->runBackward(); } else { stepper2->stopMove(); }`

gin66 commented 5 months ago

as expected, there are blocking moves:

stepper1->moveTo(150, true);
stepper1->moveTo(-150, true);

The app will wait until stepper1 has completed its cycle. A more sophisticated scheme is needed to operate motors in parallel and stepper1->isRunning() will tell you, when the motor has completed a move and the next can be initiated

Aeroexpert commented 5 months ago

is there a way that I can move both motor and change their speeds while moving? If there is a command to read current position of motor, I think I may do the job with comparisons.

gin66 commented 5 months ago

yes. FastAccelStepper is primarily designed to drive the steppers in background without blocking and with the ability to change target position, speed and acceleration at any time.

Please check the API description

Aeroexpert commented 5 months ago

Thank you very much, I found the code. stepper->getCurrentPosition(); (https://github.com/gin66/FastAccelStepper/issues/52) helped me very much. If I can write the code and run it. I want to write it here.

Aeroexpert commented 5 months ago

I write the code as below. but while stopping I cannot make ramping. with stop move code ramping for stop but cannot control the stopping position. with force stop Program works fine. but I need ramping for stopping. I really need suggestion for my Issue.

` if (1 == 1 & gd == 0) { ad1 = 1; } if (ad1 == 1) { gd = 600; stepper1->setSpeedInHz(100); stepper1->setAcceleration(5000); stepper1->runForward(); } if (ad1 == 1 & stepper1->getCurrentPosition() > gn) { stepper1->forceStop(); ad1 = 0; ad2 = 1; } if (ad2 == 1) { delay(100); ad2 = 0; ad3 = 1; } if (ad3 == 1) { stepper1->setSpeedInHz(100); stepper1->setAcceleration(5000); stepper1->runBackward(); } if (ad3 == 1 & stepper1->getCurrentPosition() < -gn) { stepper1->forceStop(); ad3=0; ad4=1; } if (ad4 == 1) {

delay(100); ad4 = 0; ad1 = 1; }

/else { stepper1->setSpeedInHz(2000); // 500 steps/s stepper1->setAcceleration(10000); // 100 steps/s² stepper1->moveTo(kn3, true); } / if (2 == 2) { stepper2->setSpeedInHz(hiz1); stepper2->setAcceleration(15000); stepper2->runBackward(); } else { stepper2->stopMove(); }`

gin66 commented 5 months ago

so stepper 1 runs back and forth with the endpoints something >600 and <-600. While stepper2 is running continuously backwards.

Question: Why not just use moveTo(gn) and moveTo(-gn) ? This way, FastAccelStepper will precisely stop at your requested position with a nice deceleration.

Aeroexpert commented 5 months ago

exactly thats my problem. I am reading the second motor's speed with a potentiometer. If I use moveTo command system waits untill 1st motor finish its cycle. Until 1st motor finishes its cycle, I cannot read the value of 2nd motor's speed. I want to use moveTo command for 1st motor and read 2nd motor's potentiometer at the same time.

gin66 commented 5 months ago

can you show the source code with moveTo()

Aeroexpert commented 5 months ago

thank you very much for your help. ` if (mt1 == 1) { stepper1->setSpeedInHz(3000);
stepper1->setAcceleration(20000);
stepper1->moveTo(pz2, true); delay(20); stepper1->moveTo(-pz2, true); delay(20);

} else { stepper1->setSpeedInHz(2000);
stepper1->setAcceleration(10000);
stepper1->moveTo(kn3, true); }

if (mt2 == 2) { stepper2->setSpeedInHz(hiz1); stepper2->setAcceleration(5000); stepper2->runBackward(); } else { stepper2->stopMove(); }

yz = millis(); gen1 = analogRead(A3) / 3; hiz1 = map(analogRead(A1), 0, 1023, 100, 12000); solb = analogRead(A2) 1, 5; sagb = analogRead(A0) 1, 5; hiz2 = map(analogRead(A4), 0, 1023, 100, 12000); `

gin66 commented 5 months ago

Those moveTo() are still blocking and it is clear, that stepper1 needs to first finish its cycle. You need to remove the blocking and work with isRunning()

Aeroexpert commented 5 months ago

I read [API description] but I couldn't find which command blocks which dont. I don't understand which command I must use in order not to block the code. how can I use isRunning() command?

gin66 commented 5 months ago

The movement functions offer a boolean blocking parameter.

Aeroexpert commented 5 months ago

. I was reading this again and again but didn't understand. now the problem is solved. stepper1->moveTo(pz2, false); very good library. thank you for all your reply.