I am using Arduino UNO, NEMA34 stepper motor, CL86T driver and nRF24L01 for communication from remote. I am using Accel library. This motor is being used to operate a oscillating arm. I am facing following problems.
a. I want to stop the arm at center position when off signal is received. It starts properly as per code but doesn't stop at center position.
b. When off signal is passed, it doesn't stops after completing a single cycle but it stops after four cycles.
Please find my code and guide me.
#include <AccelStepper.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); // CE, CSN
int x , i , m, ang , arm_sp , AC; // ang = Angle, arm_sp = Arm Speed, AC = Arm On/Off Control,
int n = 12;
int a[12] ;
int A[12] ;
AccelStepper stepper(1, 7, 6);
const byte address[6] = {'1' , 'S' , '0' , '1', '1'};
void setup()
{
// Serial.begin(9600);
radio.begin();
radio.openReadingPipe(0, address);
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_LOW);
radio.startListening();
for (int i = 0; i < n; i++)
{
a[i] = 0;
}
}
void loop()
{
Data_recieve(a, n);
arm();
}
void Data_recieve(int x[], int n)
{
int c = 0;
while (c < n)
{
if (radio.available())
{
radio.read( A, sizeof(A));
for (int i = 0; i < 1; i++)
{
x[i] = A[i];
}
break;
}
}
}
void arm()
{
{
AC = A[5];
if ( AC == 1)
{
ang = A[2];
arm_sp = A[7];
ang = map( ang , 0 , 860 , 70 , 140 ); // mapping angle with Pot value. Pot max value is 860.
arm_sp = map(arm_sp, 0, 860, 100, 10000); // mapping arm speed with Pot value. Pot max value is 860.
int ang1 = ang * 20; // to include gear ratio
stepper.setMaxSpeed(arm_sp); // change of speed by pot setting.
stepper.setAcceleration(arm_sp); // Set Acceleration
stepper.currentPosition();
stepper.setMaxSpeed(arm_sp); // change the speed by pot setting.
stepper.setAcceleration(arm_sp); // Set Acceleration
stepper.moveTo(ang1/2); // Run in CCW to half angle value with set speed and acceleration/deceleration:
while (stepper.currentPosition() != (ang1/2)) // Full speed up to half of angle
stepper.run();
stepper.runToPosition();
Serial.println(stepper.currentPosition());
delay(1000);
stepper.moveTo(-ang1); // Reverse direction to CW and run full angle value
while (stepper.currentPosition() != (-ang1)) // Full speed up to angle in reverse direction
stepper.run();
stepper.runToPosition();
Serial.println(stepper.currentPosition());
delay(2000);
stepper.moveTo(ang1/2); // Reverse direction to CCW and run to half angle value
while (stepper.currentPosition() != (ang1/2)) // Full speed up to half of angle
stepper.run();
stepper.runToPosition();
Serial.println(stepper.currentPosition());
delay(2000);
AC = A[5];
Serial.println(AC);
if ( AC == 0) {
stepper.stop();
}
}
}
}
stepper.moveTo(ang1/2); // Run in CCW to half angle value with set speed and acceleration/deceleration:
while (stepper.currentPosition() != (ang1/2)) // Full speed up to half of angle
stepper.run();
stepper.runToPosition();
Serial.println(stepper.currentPosition());
delay(1000);
stepper.moveTo(-ang1); // Reverse direction to CW and run full angle value
while (stepper.currentPosition() != (-ang1)) // Full speed up to angle in reverse direction
stepper.run();
stepper.runToPosition();
Serial.println(stepper.currentPosition());
delay(2000);
stepper.moveTo(ang1/2); // Reverse direction to CCW and run to half angle value
while (stepper.currentPosition() != (ang1/2)) // Full speed up to half of angle
stepper.run();
stepper.runToPosition();
Serial.println(stepper.currentPosition());
delay(2000);
AC = A[5];
Serial.println(AC);
if ( AC == 0) {
stepper.stop();
}
No, It didn't. When you switch on power, it starts with mid and goes to extreme end (half angle) and then after completion of cycle, it stops at extreme end. Now, if I again start it, it starts from extreme end and goes to another extreme end.
rather than duplicate code to run the stepper, i suggest writing a sub-function to run the stepper to a position specified as an argument. that function can be used to move the stepper from side to side, as well as position it in the middle ... as well as do other things
... maybe that function is simply runToPosition()
i'm not familiar with AccelStepper and the functions, but do you need to invoke both run() and runToPosition()?
also, suggest to test the motor function using the Serial monitor and only add the radio part after motor stuff works properly
finally, why is arm_sp passed to both setMaxSpeed() and setAcceleration()?
Sets the arm_sp to a number between 100 and 10000. Then sets the stepper max speed to that value. The default max speed is 1. The values you are using are huge. Can the stepper actually produce that speed?
Thanks for your guidance and sorry for delayed responce.
I changed code. Now it works as desired but as per your above guidance motor runs quite slow if I map 860 to 1000. With 860 to 10000, I am getting the required speed. I would like to have your comments on it. What is wrong? Changed code is given below. I also want to run it on constant speed then accelarating and deaccelarating it.
void arm()
{
{
AC = A[5];
if ( AC == 1)
{
ang = A[2];
arm_sp = A[7];
stepper.setCurrentPosition(0);
ang = map( ang , 0 , 860 , 80 , 140 ); // mapping angle with Pot value. Pot max value is 860.
arm_sp = map(arm_sp, 0, 860, 0, 10000); // mapping arm speed with Pot value. Pot max value is 860.
int ang1 = ang * 20; // to include gear ratio
stepper.setSpeed(arm_sp); // change the speed by pot setting.
stepper.setAcceleration(arm_sp); // Set Acceleration
stepper.moveTo(ang1); // Run in CCW to half angle value with set speed and acceleration/deceleration:
while (stepper.currentPosition() != (ang1))
stepper.run();
stepper.moveTo(-ang1); // Reverse direction to CW and run full angle value
while (stepper.currentPosition() != (-ang1))
stepper.run();
stepper.moveTo(0);
while (stepper.currentPosition() != 0)
{
stepper.run();
}
}
}
}
If your motor really can handle 10,000 steps per second then that's fine. The step angle of your motor is 1.8 degree so it does 1 full turn in 200 steps.
200 steps for a full turn and 10,000 steps per second means 50 full turns per second. That's 3000rpm. I can't see a max speed in the spec for the motor but that seems high to me.
You can't set the acceleration and speed to the same value if you're using the max speed.
If your motor is already at the max speed then it can't accelerate.