I have been working on this for a few hours and I am quite lost. I have a stepper and encoder. I have used the encoder counts and pulse to create an error when the motor has missed steps. I would like the arduino to reset the stepper back to its original 0 when it has an error larger than a full step. the snippet below is my attempt. the entire code is below.
Check this part of code. Without any test condition how it can move inside the loop. you share me snap shot of serial monitor , Since i dont have encoder here to test it,
You can't mix integers and floats in maths like this
int correctedActualPosition=(actualPosition)*.801;
All the variables must be floats - if you really need that precision. You could also approximate the fraction with integers - actualPosition * 10 / 8 (edited to correct stupid typo - I had a 2 where the 8 is now)
All these WHILEs
while (digitalRead(buttonRT) == LOW)
should probably be IFs
If you have lost the stepper position you will need a move sequence that can restore it. Normally this is done by moving until a limit switch is triggered.
In this case if you know the actual position from the encoder why not just use that to update the current position and carry on.
buttonBK pushed once then rotated out of phase to show the error on the right.the error is the result of *.801 by encoder counts on the left.
-10 0 0 -8
-10 0 0 -8
Robin2,
All valid points I have not thought of fractions, but it does seem to work. The las serial reading shows the error correctly.
I changed the Whiles for IFs. Is this because the whiles are more expensive?
using limit switch, I am trying to keep as few of components as I can My plan is to use a Z channel of an encoder to rezero, but they are weeks out.
I actually was making an attempt to reset zero with this bit of code.
if (error<-25 || error> 25){
target.move(Zero);
target.setSpeed(4000);
Zero is a corrected value of error to move to the original 0. That even sound complicated to me now that I have read it back. so much for k.i.s.s.
Tom, I have a standard 200 step motor micro-stepping at 1/8. My encoder is a 500 steps per rev.
Thanks everyone for the input, I am looking forward to hearing how to simplify my code and make it actually work. I have tried many things and have been close but no cigar.
I did include the entire sketch showing the libraries and I did fix the while statements like Robbin2 suggested. I included snap shots of the serial monitor of different scenarios to show you how the program was reacting. I am still not sure what the
As mentioned there is no entry condition???
is all about. I still am new to the arduino I guess I need to have my hand held from time to time. I am not sure what the print statement that you have added does for me either.
entry condition means, you used improper bracket without condition statement. Seems even you new to C. For previous program it not even printing data because you used while loop.
Check condition
{
//Do this process
}
i have highlighted it my post where you made mistake.
you have used where loop gets early as before your test condition. use autoformat option from tool or press ctrl+T
Ok, I have my motor behaving as it should. If there is a deviation from where it suppose to be and where it is, it moves back to the encoder zero. Now I am trying to increment a score every time I have an error larger than twelve micro steps. unfortunately it is giving me more than one increment. I need some type of debounce for the increment. can anyone point me in the right direction.
#include <AccelStepper.h>
#include <Encoder.h>
Encoder myEnc(2, 3);
AccelStepper target(1, 6, 8); // pin 6 = pulse, pin 8 = direction
const int buttonRT = 11;
const int buttonBK = 10;
const int buttonLT = 9;
const int disableMotor = 7;
int Desired_position = 0;
int RightScore =0;
int LeftScore =0;
void setup() {
target.setMaxSpeed(4000);
target.setSpeed(3000);
target.setMinPulseWidth(50);
//target.setAcceleration(10);
pinMode(buttonRT, INPUT_PULLUP);
pinMode(buttonBK, INPUT_PULLUP);
pinMode(buttonLT, INPUT_PULLUP);
pinMode(disableMotor, OUTPUT);
Serial.begin(9600);
}
void loop(){
// encoder and error collection section.
int actualPosition = myEnc.read();
int StepsToZero=(actualPosition)*8/10;
int error = (StepsToZero - target.currentPosition());
int Zero= error/8;
// count and return to zero
// position control
if (digitalRead(buttonRT) == LOW) {//wired N.O.
Desired_position = -400;
}
if (digitalRead(buttonBK) == HIGH) {//wired N.C.
Desired_position = 0;
}
//wired N.C.
if (digitalRead(buttonLT) == LOW) {//wired N.O.
Desired_position = 400;
}
/*
if ((error<-15) && (Desired_position = -400)){
}
*/
if (error<-15){
delay (1000);
target.setCurrentPosition(StepsToZero);
Desired_position = 0;
RightScore++;
}
/*
if ((error>12) && (Desired_position = -400)){
LeftScore++;
}
*/
if (error>12){
delay (1000);
target.setCurrentPosition(StepsToZero);
Desired_position = 0;
LeftScore++;
}
{
// controls motor moves
target.moveTo(Desired_position);
target.setSpeed(3000);
target.runSpeedToPosition();
//print only while there are no pulses to the motor.
if (target.distanceToGo()==0){
Serial.print("LeftScore");
Serial.print (" ");
Serial.print (LeftScore);
Serial.print (" ");
Serial.print ("RightScore");
Serial.print (" ");
Serial.println (RightScore);
/*
//digitalWrite(disableMotor, HIGH);
Serial.print(actualPosition);
Serial.print (" ");
Serial.print (Desired_position);
Serial.print (" ");
Serial.print (target.currentPosition());
Serial.print (" ");
Serial.print (error,DEC);
Serial.print (" ");
Serial.print (StepsToZero);
Serial.println (" ");
*/
}
}}
Can you put datasheet of the Encoder.
Have you checked output W.r.t voltage you getting proper angle. If not calibrate using first order or second order software filtering program.
The encoder is working fine. I can stop the motor in a move or simply turn the motor to a position and it will always find zero. My issue is counting each time it is out of sequence. It is a 500ppr Quadrature encoder (actual 2000ppr) from us digital. but the hardware is working fine. It is my brain that is not. I am looking into adapting the debounce sketch to keep from incrementing more than one per event. Is there some simple way to implement this?
Please share serial output of below code!!! replace loop statement
void loop(){
// encoder and error collection section.
int actualPosition = myEnc.read();
Serial.print("actualPosition:"); Serial.println(actualPosition);
int StepsToZero=(actualPosition)*8/10;
Serial.print("StepsToZero:"); Serial.println(StepsToZero);
int error = (StepsToZero - target.currentPosition());
Serial.print("error:"); Serial.println(error);
int Zero= error/8;
Serial.print("Zero:"); Serial.println(Zero);
// count and return to zero
// position control
if (digitalRead(buttonRT) == LOW) {//wired N.O.
Desired_position = -400;
}
if (digitalRead(buttonBK) == HIGH) {//wired N.C.
Desired_position = 0;
}
//wired N.C.
if (digitalRead(buttonLT) == LOW) {//wired N.O.
Desired_position = 400;
}
/*
if ((error<-15) && (Desired_position = -400)){
}
*/
Serial.print("error value before check condition:"); Serial.println(error);
if (error<-15){
delay (1000);
target.setCurrentPosition(StepsToZero);
Desired_position = 0;
RightScore++;
}
/*
if ((error>12) && (Desired_position = -400)){
LeftScore++;
}
*/
if (error>12){
delay (1000);
target.setCurrentPosition(StepsToZero);
Desired_position = 0;
LeftScore++;
}
//No entry condition Here???
{
// controls motor moves
target.moveTo(Desired_position);
target.setSpeed(3000);
target.runSpeedToPosition();
//print only while there are no pulses to the motor.
if (target.distanceToGo()==0){
Serial.print("LeftScore");
Serial.print (" ");
Serial.print (LeftScore);
Serial.print (" ");
Serial.print ("RightScore");
Serial.print (" ");
Serial.println (RightScore);
}
}
}
In your code posted above what does this part will do??. dont post code blindly. just check what you sharing. use autoformat option. check braces, brackets,entry conditions are valid or not???
//No entry condition Here???
{
// controls motor moves
target.moveTo(Desired_position);
target.setSpeed(3000);
target.runSpeedToPosition();
//print only while there are no pulses to the motor.
if (target.distanceToGo()==0){
Serial.print("LeftScore");
Serial.print (" ");
Serial.print (LeftScore);
Serial.print (" ");
Serial.print ("RightScore");
Serial.print (" ");
Serial.println (RightScore);
}
}
in the accelstepper library you need to call the stepper to run. It does not need an entry statement here. when I push the right botton and change desired position it needs a moveTo command.
I told to share screen shot like this Not like below.
Dont give oversmart asnwers. If you dont know things try to learn it. All people helping to solve your issue , if giving over smart answer like you know everything none will help here…
For your reference i attached screen shot of serial monitor.We dont have actual setup here. Depend on your valid answer only we can give suggestions. Since you have device connected it wont be Zero in your case.
Try this code in your device. Send me screen shot of serial monitor.
#include <AccelStepper.h>
#include <Encoder.h>
Encoder myEnc(2, 3);
AccelStepper target(1, 6, 8); // pin 6 = pulse, pin 8 = direction
const int buttonRT = 11;
const int buttonBK = 10;
const int buttonLT = 9;
const int disableMotor = 7;
int Desired_position = 0;
int RightScore =0;
int LeftScore =0;
void setup() {
target.setMaxSpeed(4000);
target.setSpeed(3000);
// target.setMinPulseWidth(50);
//target.setAcceleration(10);
pinMode(buttonRT, INPUT_PULLUP);
pinMode(buttonBK, INPUT_PULLUP);
pinMode(buttonLT, INPUT_PULLUP);
pinMode(disableMotor, OUTPUT);
Serial.begin(9600);
}
void loop(){
// encoder and error collection section.
int actualPosition = myEnc.read();
Serial.print("actualPosition:"); Serial.println(actualPosition);
int StepsToZero=(actualPosition)*8/10;
Serial.print("StepsToZero:"); Serial.println(StepsToZero);
int error = (StepsToZero - target.currentPosition());
Serial.print("error:"); Serial.println(error);
int Zero= error/8;
Serial.print("Zero:"); Serial.println(Zero);
// count and return to zero
// position control
if (digitalRead(buttonRT) == LOW) {//wired N.O.
Desired_position = -400;
}
if (digitalRead(buttonBK) == HIGH) {//wired N.C.
Desired_position = 0;
}
//wired N.C.
if (digitalRead(buttonLT) == LOW) {//wired N.O.
Desired_position = 400;
}
/*
if ((error<-15) && (Desired_position = -400)){
}
*/
Serial.print("error value before check condition:"); Serial.println(error);
if (error<-15){
delay (1000);
target.setCurrentPosition(StepsToZero);
Desired_position = 0;
RightScore++;
}
/*
if ((error>12) && (Desired_position = -400)){
LeftScore++;
}
*/
if (error>12){
delay (1000);
target.setCurrentPosition(StepsToZero);
Desired_position = 0;
LeftScore++;
}
// controls motor moves
target.moveTo(Desired_position);
target.setSpeed(3000);
target.runSpeedToPosition();
//print only while there are no pulses to the motor.
if (target.distanceToGo()==0){
Serial.print("LeftScore");
Serial.print (" ");
Serial.print (LeftScore);
Serial.print (" ");
Serial.print ("RightScore");
Serial.print (" ");
Serial.println (RightScore);
}
Serial.println(".......................................");
delay(1000);
}
AMPS, I do apologize if it Sounded to Smart. I was simply trying to clarify. I was not trying to rub anyone the wrong way. I am in no way trying to boast my knowledge,I am aware that I know very little of the C programming world. I appreciate all of the time you guys put in.
I was unsuccessful in attaching the screen shot on to this post, I am not sure how to get it from paint to here? if you would let me in on the secret, I will do so. In the mean time I will post your debug as I know how.
I have captured where it gives first gives the error where I grabbed the shaft and it lost one full step.
I no longer use Zero in the code I just forgot to take it out. The StepsToZero never referred to Zero anyway it was referring to the original programmed zero. (The reset position when you reset the arduino.)
Thanks again for taking a look.
actualPosition:0
StepsToZero:0
error:0
Zero:0
error value before check condition:0
LeftScore 0 RightScore 0
.......................................
actualPosition:41
StepsToZero:32
error:32
Zero:4
error value before check condition:32
.......................................
actualPosition:38
StepsToZero:30
error:-1
Zero:0
error value before check condition:-1
.......................................
actualPosition:37
StepsToZero:29
error:-1
Zero:0
error value before check condition:-1
.......................................
OK I also added the debug portion where the motor is approaching zero again and then it shows the score. I did this several times and it scored only one like I would like it to do. but with all of this printing it has slowed the program and motor to a slow crawl.
.......................................
actualPosition:-9
StepsToZero:-7
error:-2
Zero:0
error value before check condition:-2
.......................................
actualPosition:-7
StepsToZero:-5
error:-1
Zero:0
error value before check condition:-1
.......................................
actualPosition:-6
StepsToZero:-4
error:-1
Zero:0
error value before check condition:-1
.......................................
actualPosition:-4
StepsToZero:-3
error:-1
Zero:0
error value before check condition:-1
.......................................
actualPosition:-3
StepsToZero:-2
error:-1
Zero:0
error value before check condition:-1
LeftScore 0 RightScore 1