Need help with code for encoder

For the past few weeks, I have been trying to figure out how to make my encoder work but i can't seem to find a solution to the problem. The problem is that the encoder won't count or counts but doesn't send it back to the computer. Can you guys suggest what is wrong or even give me a new code.

Here is my code

int rawsensorValue = 0; // variable to store the value coming from the sensor
int sensorcount0 = 0;
int sensorcount1 = 0;
long count = 0;

int RightMotorSpeedPin = 5; //M1 Speed Control
int LeftMotorSpeedPin = 6; //M2 Speed Control
int RightMotorDirectionPin = 7; //M1 Direction Control
int LeftMotorDirectionPin = 8; //M2 Direction Control

void setup() {
int i;
for(i=5;i<=8;i++)
pinMode(i, OUTPUT);
Serial.begin(9600);
int leftspeed = 255; //255 is maximum speed
int rightspeed = 255;
}
void loop() {
analogWrite (10,255);
digitalWrite(12,LOW);
analogWrite (11,255);
digitalWrite(13,LOW);
delay(20);
rawsensorValue = analogRead(0);
if (rawsensorValue < 600){ //Min value is 400 and max value is 800, so state chance can be done at 600.
sensorcount1 = 1;
}
else {
sensorcount1 = 0;
}
if (sensorcount1 != sensorcount0){
count ++;
}
sensorcount0 = sensorcount1;
Serial.println(count);

int leftspeed = 255; //255 is maximum speed
int rightspeed = 255;
int wait_period = 15000;

forward(rightspeed,leftspeed);
delay(wait_period);
stop();
delay(500);

stop();
while(1) {};

}

void stop(void) //Stop
{
digitalWrite(RightMotorSpeedPin,LOW);
digitalWrite(LeftMotorSpeedPin,LOW);
}

void forward(char right_speed, char left_speed)
{
analogWrite (RightMotorSpeedPin,right_speed);
digitalWrite(RightMotorDirectionPin,LOW);
analogWrite (LeftMotorSpeedPin,left_speed);
digitalWrite(LeftMotorDirectionPin,LOW);
}

void reverse (char right_speed,char left_speed)
{
analogWrite (RightMotorSpeedPin,right_speed);
digitalWrite(RightMotorDirectionPin,HIGH);
analogWrite (LeftMotorSpeedPin,left_speed);
digitalWrite(LeftMotorDirectionPin,HIGH);
}

void left (char right_speed,char left_speed)
{
analogWrite (RightMotorSpeedPin,right_speed);
digitalWrite(RightMotorDirectionPin,HIGH);
analogWrite (LeftMotorSpeedPin,left_speed);
digitalWrite(LeftMotorDirectionPin,LOW);
}

void right (char right_speed,char left_speed)
{
analogWrite (RightMotorSpeedPin,right_speed);
digitalWrite(RightMotorDirectionPin,LOW);
analogWrite (LeftMotorSpeedPin,left_speed);
digitalWrite(LeftMotorDirectionPin,HIGH);
}

One reason you're not getting any responses is because you didn't read Nick Gammon's post at the top of the Forum on how to properly post code here. Also, before you post it, use Ctrl-T on the source code in the IDE to reformat it in a way that is easier for us to read.

Next, google "Arduino Rotary encoder" and find the rotary.h library files, download them, and try to run the sample programs in the Examples subdirectory for the library. If you get those working, at least you know the encoder's working properly. Also, I don't see anything in your code that activates the encoder.

  stop();
  delay(500);
  stop();
  while (1) {};

Why stop the motors twice ?
Why does the program come to a screeching halt in an infinite while loop at the end of the loop() function ?

econjack:
Next, google "Arduino Rotary encoder" and find the rotary.h library files, download them, and try to run the sample programs in the Examples subdirectory for the library. If you get those working, at least you know the encoder's working properly. Also, I don't see anything in your code that activates the encoder.

The Paul Stoffregen Encoder library is included in the Library Manager built into the IDE; amongst others.

Please explain more about the encoder. Is it a slotted wheel, or a quadrature encoder? How many counts/revolution? How fast is the encoder turning?

When you turn the motor/encoder by hand, can you get counts? Can you see the analogRead()value changing?

Thanks guys, my encoder has 8 whites and 8 blanks. I have changed the code so that it is easier for you to read. However, I still don't know the code to activate the encoder. Please can you suggest me some and where to put it.

int rawsensorValue = 0; // variable to store the value coming from the sensor
  int sensorcount0 = 0;
  int sensorcount1 = 0;
  long count = 0;
  
  int RightMotorSpeedPin = 5; //M1 Speed Control
  int LeftMotorSpeedPin = 6; //M2 Speed Control
  int RightMotorDirectionPin = 7; //M1 Direction Control
  int LeftMotorDirectionPin = 8; //M2 Direction Control
  
  void setup() {
   int i;
   for(i=5;i<=8;i++)
   pinMode(i, OUTPUT);
   Serial.begin(9600);
   int leftspeed = 255; //255 is maximum speed
   int rightspeed = 255;
  }
  void loop() {
   analogWrite (10,255);
   digitalWrite(12,LOW);
   analogWrite (11,255);
   digitalWrite(13,LOW);
   delay(20);
   rawsensorValue = analogRead(0);
   if (rawsensorValue < 600){ //Min value is 400 and max value is 800, so state chance can be done at 600.
   sensorcount1 = 1;
   }
   else {
   sensorcount1 = 0;
   }
   if (sensorcount1 != sensorcount0){
   count ++;
   }
   sensorcount0 = sensorcount1;
   Serial.println(count);
  
   
   int leftspeed = 255; //255 is maximum speed
   int rightspeed = 255;
   int wait_period = 15000;
  
   forward(rightspeed,leftspeed);
     delay(wait_period);
     stop();
     while(1) {};
   
  }
  
  void stop(void) //Stop
  {
    digitalWrite(RightMotorSpeedPin,LOW);
    digitalWrite(LeftMotorSpeedPin,LOW);
  }
  
  void forward(char right_speed, char left_speed)
  {
    analogWrite (RightMotorSpeedPin,right_speed);
    digitalWrite(RightMotorDirectionPin,LOW);
    analogWrite (LeftMotorSpeedPin,left_speed);
    digitalWrite(LeftMotorDirectionPin,LOW);
  }
  
  void reverse (char right_speed,char left_speed)
  {
    analogWrite (RightMotorSpeedPin,right_speed);
    digitalWrite(RightMotorDirectionPin,HIGH);
    analogWrite (LeftMotorSpeedPin,left_speed);
    digitalWrite(LeftMotorDirectionPin,HIGH);
  }
  
  void left (char right_speed,char left_speed)
  {
    analogWrite (RightMotorSpeedPin,right_speed);
    digitalWrite(RightMotorDirectionPin,HIGH);
    analogWrite (LeftMotorSpeedPin,left_speed);
    digitalWrite(LeftMotorDirectionPin,LOW);
  }
  
  void right (char right_speed,char left_speed)
  {
    analogWrite (RightMotorSpeedPin,right_speed);
    digitalWrite(RightMotorDirectionPin,LOW);
    analogWrite (LeftMotorSpeedPin,left_speed);
    digitalWrite(LeftMotorDirectionPin,HIGH);
  }

I have also got another code that I adapted from the Reading Rotary Encoder.

int val;
  int encoder0PinA = 3;
  int encoder0PinB = 4;
  int encoder0Pos = 0;
  int encoder0PinALast = LOW;
  int n = LOW;
  
  int RightMotorSpeedPin = 5; //M1 Speed Control
  int LeftMotorSpeedPin = 6; //M2 Speed Control
  int RightMotorDirectionPin = 7; //M1 Direction Control
  int LeftMotorDirectionPin = 8; //M2 Direction Control
  
  void setup() 
  {
    pinMode (encoder0PinA, INPUT);
    pinMode (encoder0PinB, INPUT);
    Serial.begin (9600);
  }
  
  void loop() 
  {
    n = digitalRead(encoder0PinA);
    if ((encoder0PinALast == LOW) && (n == HIGH)) {
      if (digitalRead(encoder0PinB) == LOW) {
        encoder0Pos--;
      } else {
        encoder0Pos++;
      }
      Serial.print (encoder0Pos);
      Serial.print ("/");
    }
    encoder0PinALast = n;
    int rightspeed = 255;
    int leftspeed = 255;
    int wait_period = 15000;
  
    forward(rightspeed,leftspeed);
    delay(wait_period);
    stop();
    delay(500);
    while(1) {};
  }
  
  
  void stop(void) //Stop
  {
    digitalWrite(RightMotorSpeedPin,LOW);
    digitalWrite(LeftMotorSpeedPin,LOW);
  }
  
  void forward(char right_speed, char left_speed)
  {
    analogWrite (RightMotorSpeedPin,right_speed);
    digitalWrite(RightMotorDirectionPin,LOW);
    analogWrite (LeftMotorSpeedPin,left_speed);
    digitalWrite(LeftMotorDirectionPin,LOW);
  }

After reading the 2 codes, can you tell me which one is better and how I could improve. If they're both really bad, can you suggest to me a code that could work.

Thanks in advance.

The second code is for a quadrature encoder. You do not have one of those.

my encoder has 8 whites and 8 blanks.

It looks like you have a colored(or slotted) disc being read with a photo sensor with analog output. Your first code is more appropriate for this type of device. Do you have a link to the photo sensor you are using to read the disc?

This routine from the first code looks like it should be counting the transitions. What do you see when you turn the motor by hand?

 rawsensorValue = analogRead(0);
   if (rawsensorValue < 600){ //Min value is 400 and max value is 800, so state chance can be done at 600.
   sensorcount1 = 1;
   }
   else {
   sensorcount1 = 0;
   }
   if (sensorcount1 != sensorcount0){
   count ++;
   }
   sensorcount0 = sensorcount1;
   Serial.println(count);

Hi,
Can you post a picture of your encoder and your project please?

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom... :slight_smile:

If I turn the wheel by hand with just the code for the encoder, the encoder counts properly but I don't know how and where to put the instructions to make my Rover go forward then stop.

By the way, I am using the encoder with a DFRobotShop Rover (No bluetooth).

but I don't know how and where to put the instructions to make my Rover go forward then stop.

You are evidently just starting up the learning curve for robotics, and the Rover is a good place to start. I think you are going to need more assistance than you will get from this forum.

Can you find a class or a hacker space or some resource in your community which can help you learn?

My dad knows arduino and helps me but I want to be more independent so I'm doing the code for the encoder on my own.

I have looked at the dfrobot user manual and see where your code is coming from.
http://www.robotshop.com/media/files/pdf/dfrobotshop-rover-user-guide.pdf

It's important as you proceed with your projects, that you never use delay() in your code, and you run the encoder routine as often as possible. You will also have to duplicate code for a second encoder so as to read for both sides. The motors will not be exactly the same speed, and you may need to manage the motors differently in order to go straight ahead.

I have created a function getCount() for calling the analogRead() and updating the encoder counts. You should be able to use it in the future. I've changed some data types from int to byte as you should get in the habit of using the smallest size possible.

byte E1 = 6; //M1 Speed Control
byte E2 = 5; //M2 Speed Control
byte M1 = 8; //M1 Direction Control
byte M2 = 7; //M2 Direction Control

void setup()
{
  byte i;
  for (i = 5; i <= 8; i++)
    pinMode(i, OUTPUT);

  //Serial.begin(9600);
}

void loop()
{
  const int targetCount = 16;
  if (getCount() >= targetCount)
  {
    stop();
  }
  else
  {
    forward(127, 127);//forward half speed
  }
}

void forward(byte leftspeed, byte rightspeed)
{
  analogWrite (E1, leftspeed);
  digitalWrite(M1, LOW);
  analogWrite (E2, rightspeed);
  digitalWrite(M2, LOW);
}

void stop(void) 
{
  digitalWrite(E1, LOW);
  digitalWrite(E2, LOW);
}

int getCount(void)
{
  static byte sensorCount0 = 0;
  static byte sensorCount1 = 0;
  static int count;
  int rawSensorValue = analogRead(A0);
  if (rawSensorValue < 600) { //Min value is 400 and max value is 800, so state chance can be done at 600.
    sensorCount1 = 1;
  }
  else {
    sensorCount1 = 0;
  }
  if (sensorCount1 != sensorCount0) {
    count ++;
    //Serial.print("Encoder Count =  ");
    //Serial.println(count);
  }
  sensorCount0 = sensorCount1;
  return count;
}

I have found a code that counts both encoders at the same time (I have an encoder on the two back wheels of my rover). Here is my code:

int rawsensorValue = 0;// variable to store the value coming from the sensor
int rawsensorValue2 = 0;
int sensorcount0_right = 0;
int sensorcount1_right = 0;
int sensorcount0_left = 0;
int sensorcount1_left = 0;
long right_count = 0;
long left_count = 0;
void setup() {
 int i;
 for(i=5;i<=8;i++)
 pinMode(i, OUTPUT);
 Serial.begin(9600);
 int leftspeed = 255; //255 is maximum speed
 int rightspeed = 255;
}


void loop() {  
 analogWrite (10,255);
 digitalWrite(12,LOW);
 analogWrite (11,255);
 digitalWrite(13,LOW);
 delay(20);
 if (analogRead(1) < 600){ //Min value is 400 and max value is 800, so state chance can be done at 600.
 sensorcount1_left = 1;
 }
 else {
 sensorcount1_left = 0;
 }
 if (sensorcount1_left != sensorcount0_left){
 left_count ++;
 }
 sensorcount0_left = sensorcount1_left;
 Serial.print(left_count);

 analogWrite (10,255);
 digitalWrite(12,LOW);
 analogWrite (11,255);
 digitalWrite(13,LOW);
 delay(20);
 if (analogRead(0) < 600){ //Min value is 400 and max value is 800, so state chance can be done at 600.
 sensorcount1_right = 1;
 }
 else {
 sensorcount1_right = 0;
 }
 if (sensorcount1_right != sensorcount0_right){
 right_count ++;
 }
 sensorcount0_right = sensorcount1_right;
 Serial.print("  ");
 Serial.println(right_count);
 
}

However, I can't figure out how to add a code to make the rover go forward while the encoders count.

When I try to add a forward command, the rover either goes forward but the encoders doesn't count or neither works and there is a high-pitched buzzing noise. I don't know what that buzzing noise is. Can you guys suggest a way to add a code to the original code that makes the rover go forward but the encoder still counts. I am currently doing different tests to see how and where to add the code.

int rawsensorValue = 0;// variable to store the value coming from the sensor
int rawsensorValue2 = 0;

These are useless names. What sensor? Do you count "Uh-huh, two, three"? Or do you count "one, two, three"? It makes no sense to number one of the values in a set but not the other one.

Number both of them.

int rawsensorValue5 = 0;
int rawsensorValue2 = 0;

Now, you can see that the numbers are meaningless. Use an array when you have a collection of related variables.

 int leftspeed = 255; //255 is maximum speed
 int rightspeed = 255;

These variables immediately go out of scope. There are, therefore, useless.

 if (analogRead(1) < 600){ //Min value is 400 and max value is 800, so state chance can be done at 600.

What, exactly, is connected to analog pin 1? Using a name in place of the 1 might provide a clue.

What, exactly, is connected to analog pin 0? Using a name in place of the 1 might provide a clue.

However, I can't figure out how to add a code to make the rover go forward while the encoders count.

This implies that you have encoders connected to analog pins. That is highly unusual, to say the least.

Adding code to turn the motor on is trivial. That will NOT interfere with reading the encoders. So, you need to show us what you have tried.

When I try to add a forward command, the rover either goes forward but the encoders doesn't count or neither works and there is a high-pitched buzzing noise.

Please post the code that you tried.

Here is my code:

int rawsensorValue = 0; // variable to store the value coming from the sensor
int sensorcount0 = 0;
int sensorcount1 = 0;
long count = 0;
void setup() {
 int i;
 for(i=5;i<=8;i++)
 pinMode(i, OUTPUT);
 Serial.begin(9600);
 int leftspeed = 255; //255 is maximum speed
 int rightspeed = 255;
}
void loop() {
 analogWrite (10,255);
 digitalWrite(12,LOW);
 analogWrite (11,255);
 digitalWrite(13,LOW);
 delay(20);
 rawsensorValue = analogRead(0);
 if (rawsensorValue < 600){ //Min value is 400 and max value is 800, so state chance can be done at 600.
 sensorcount1 = 1;
 }
 else {
 sensorcount1 = 0;
 }
 if (sensorcount1 != sensorcount0){
 count ++;
 }
 sensorcount0 = sensorcount1;
 Serial.println(count); 

 int leftspeed = 255;
 int rightspeed = 255;
 analogWrite (E1,255);
 digitalWrite (M1,LOW);
 analogWrite (E2,255);
 digitalWrite (M2,LOW);
 delay(100);
 
}

However, I just did this one and I think it works:

int rawsensorValue = 0; // variable to store the value coming from the sensor
int sensorcount0 = 0;
int sensorcount1 = 0;
long count = 0;

int E1 = 6; //M1 Speed Control
int E2 = 5; //M2 Speed Control
int M1 = 8; //M1 Direction Control
int M2 = 7; //M2 Direction Control
 

void setup() {
 int i;
 for(i=5;i<=8;i++)
 pinMode(i, OUTPUT);
 Serial.begin(9600);
 int leftspeed = 255; //255 is maximum speed
 int rightspeed = 255;
}
void loop() {
 analogWrite (10,255);
 digitalWrite(12,LOW);
 analogWrite (11,255);
 digitalWrite(13,LOW);
 delay(20);
 rawsensorValue = analogRead(0);
 if (rawsensorValue < 600){ //Min value is 400 and max value is 800, so state chance can be done at 600.
 sensorcount1 = 1;
 }
 else {
 sensorcount1 = 0;
 }
 if (sensorcount1 != sensorcount0){
 count ++;
 }
 sensorcount0 = sensorcount1;
 Serial.println(count); 

 if (count >= 0){
  analogWrite (E1,255);
  digitalWrite (M1,LOW);
  analogWrite (E2,255);
  digitalWrite (M2,LOW);
 }
 else {
  digitalWrite (E1,LOW);
  digitalWrite (E2,LOW);
 }
 }