rotary encoder and robot distance

i need help with my rotary encoder/distance program. i wrote a program that can count the number of pulses and calculated that for every pulse, the robot travels .25 inches. My question is how do i apply this pulse count and tell my servos to go a distance, turn, and go forward some more?

You turn the motor on, count the pulses until you have counted the required number, then turn the motor off.

i have already done something like that but its not working quite as i hoped. i was thinking someone could give me another approach.

Well, if you're driving a car from one stop sign to the next, you don't just floor it until you reach the second sign and then release the acclerator -- you slow down first. If you are overshooting, look into PID loops (or P loops or PI loops). However, they are very complicated and may be beyond the range of arduino.

What's not working about your current approach? And what IS your current approach?

i have researched the PID control last night. i think its a little to advanced for what i need it for. basically when i combine two functions in a row like forward(4); then forward(8); when my pulse count gets to 4 my servos start twitching and shuddering back and forth. i believe this because forward(4) is telling them to stop but they are still wanting to spin forward so it can complete forward(8). i THINK i need to reset the pulse count but every where i try to implement pulse_Count = 0; to reset it my serial monitor just outputs “number of pulses: 1” over and over when i push the button.

/*******************/
/* ROBOT CHALLENGE */
/*******************/
#include <Servo.h>
Servo L_servo;
Servo R_servo;

//buttons on breadboard to start challenges
#define button1 8;    // mission_group_1
#define button2 9;    // mission_group_2
#define button3 10;  // mission_group_3

// read photoresistor on digital pin 6
const int photo = 6;

// variables that will change
int photo_State = 0;
int last_photo_State = 0;
int pulse_Count = 0;

void setup() {

  // attach servos to digital pins 4 and 5
  L_servo.attach(4);
  R_servo.attach(5);

  // read photoresistor as ON/OFF
  pinMode(photo, INPUT);

  // initialize serial
  Serial.begin(9600);
}


void loop() {

/* ok everything is fine up to this point, if
   i were to put forward(4); by itself it would
   run perfectly but when i combine multiple
   functions, my servos twitch and shudder.
*/

forward(4);
forward(8);

}


int pulse_Counter() {
 
  photo_State = digitalRead(photo);

  if (photo_State != last_photo_State) {
    if (photo_State == HIGH) {
      pulse_Count++;
      Serial.print("number of pulsess:  ");
      Serial.println(pulse_Count, DEC);
  }
    else {
      pulse_Count++;
      Serial.print("number of pulsess:  ");
      Serial.println(pulse_Count, DEC);
  }

}

  last_photo_State = photo_State;
  
}


/* FORWARD */
// [distance = (pulses * .25)]

void forward(int pulses) {
   
 pulse_Counter();
 
  if (pulse_Count == pulses) {
    L_servo.writeMicroseconds(1500);
    R_servo.writeMicroseconds(1500);
  }
  
  else {
    L_servo.writeMicroseconds(1400);
    R_servo.writeMicroseconds(1600);
  }

}

I'm not sure if you're going to change this, but the "if" statement here is useless.

if (photo_State == HIGH) {
      pulse_Count++;
      Serial.print("number of pulsess:  ");
      Serial.println(pulse_Count, DEC);
  }
    else {
      pulse_Count++;
      Serial.print("number of pulsess:  ");
      Serial.println(pulse_Count, DEC);
  }

but that is pretty minor...

It appears that you only have one encoder for both motors. How does that work?

just wondering how is it useless? what could i change it to, is there another way to count the pulses? well yes i am only reading it on one wheel. i think it will be a lot easier this way.

ddronett:
just wondering how is it useless?

If it’s true, it increments pulse_count and prints some serial lines. If it’s false, it increments pulse_count and prints the same serial lines.

what could i change it to, is there another way to count the pulses? well yes i am only reading it on one wheel. i think it will be a lot easier this way.

Oh wait, I think I get it… Are you trying to go forward 4 steps, pause, and then go forward 8 steps? You’ll want to reset the pulse counter when it equals steps, but then it will just keep going 4 steps over and over. I just don’t think your current function will work. What you could do is something like this:

void loop() {
  for (byte i=0;i<2;i++){
    while(digitalRead(photo) == HIGH); //Wait until photo is LOW
    while(digitalRead(photo) == LOW); //Wait until photo is HIGH
  }
  delay(1000);
  for (byte i=0;i<4;i++){
    while(digitalRead(photo)==HIGH); //Wait until photo is LOW
    while(digitalRead(photo)==LOW); //Wait until photo is HIGH
  }
  delay(1000);
}

yes you are correct and i will be adding turns and also a backward function just by changing the "writeMicroseconds(....)". so where do i implement the sketch you have provided?

i think that is it!!! i just need to tweak it a little bit for every function thank you so much. i have spent weeks on this.

one tiny problem, it is reading one more button press then needed after the first one. it reads number of pulses: 5
here is the code.

for (byte i=0;i<3;i++){
    while(digitalRead(photo) == HIGH); //Wait until photo is LOW
    forward(4);
    while(digitalRead(photo) == LOW); //Wait until photo is HIGH
    forward(4);
}

pulse_Reset();

  for (byte i=0;i<4;i++){
    while(digitalRead(photo)==HIGH); //Wait until photo is LOW
     forward(8);
    while(digitalRead(photo)==LOW); //Wait until photo is HIGH
     forward(8);
  }

Serial Monior

number of pulsess: 1
number of pulsess: 2
number of pulsess: 3
number of pulsess: 4 // stops here perfectly
number of pulsess: 5 // next press it dose not start at zero??
number of pulsess: 1
number of pulsess: 2
number of pulsess: 3
number of pulsess: 4
number of pulsess: 5
number of pulsess: 6
number of pulsess: 7
number of pulsess: 8 //stops here as programed
number of pulsess: 9

but wait i use odd integers for my pulses and it is perfect!!!
i.e. forward(3);
forward(9);

I was thinking more along the lines of:

void loop() {
  servo1.writeMicroseconds(forward);
  Servo2.writeMicroseconds(forward);
  for (byte i=0;i<2;i++){
    while(digitalRead(photo) == HIGH); //Wait until photo is LOW
    while(digitalRead(photo) == LOW); //Wait until photo is HIGH
  }
  servo1.writeMicroseconds(stop);
  servo2.writeMicroseconds(stop);
  delay(1000);
  servo1.writeMicroseconds(forward);
  Servo2.writeMicroseconds(forward);
  for (byte i=0;i<4;i++){
    while(digitalRead(photo)==HIGH); //Wait until photo is LOW
    while(digitalRead(photo)==LOW); //Wait until photo is HIGH
  }
  servo1.writeMicroseconds(stop);
  servo2.writeMicroseconds(stop);
  delay(1000);
}

But, if it works for you and makes sense, great!