Wheel encoders on Arduino Uno - half resolution [solved]

When I used your code with Arduino 1.0.2 and rotated the wheel 360 degrees, I got 48 counts. I suspect your encoder might be missing steps. Could you try speeding up your serial output rate and see how smoothly it counts as you rotate the wheel by hand? Could you try updating your Arduino to 1.0.2 or later and see if it works? Do you have access to an oscilloscope you could use to look at the encoder outputs?

Also, there are two potentiometers on the board that are calibrated during manufacturing. Have you adjusted these at all?

- Jeremy

I tried turning the trimmers and different versions of the arduino IDE (including 1.0.2), with no luck. I was able to verify that both encoders are pulsing properly by watching the serial monitor output, via digitalRead(), at high speeds. They both go high and low just fine. When I run CheckErrorM1(), it’s all zeros, even at slow speeds. Both encoders are very accurately measuring only half the ticks for some reason.

Now, when I installed the libraries, I simply copied the PololuWheelEncoder directory, along with all the Orangutan directories into /usr/share/arduino/libraries. I haven’t edited any of the files. Is there a problem with the way I’ve installed the libs? Do I need to set that I’m using an Arduino Uno R3 or the ATMega328p-pu?

When I get some more time, I will compile and upload some C/AVR code to see if I see the same problem.

I do not think there is a problem with the way you installed the libraries, but could you try reinstalling the Pololu Arduino Libraries? Is it possible that you originally downloaded the AVR version of the libraries for our products and the not the Arduino version?

When uploading your sketch to the Arduino, you should be selecting the Arduino Uno as the board.

If reinstalling the library does not work, could you post a video of you turning the wheel 360 degrees and not getting the correct counts?

By the way, we strongly suggest you not alter the pot settings as those are factory calibrated and changing them without proper test equipment can cause the encoder to stop functioning properly.

- Jeremy

Jeremy, that was exactly the problem: I have been using the AVR libraries within Arduino…

There are statements within the source code which enable compatibility with c++. So I assumed that the libraries were meant for both AVR and Arduino and I was unaware that there was a separate lib for Arduino.

For what it’s worth, here’s a youtube video of Arduino yielding half counts with AVR:
http://www.youtube.com/watch?v=yhY5B2wwf00&feature=youtu.be

Maybe the problem is that only one of the interrupt routines was working? Anyways, thanks so much for you help!

I read the quadrature encoder user guide and it says it uses 4 interrupts. The Arduino UNO only has 2 does this mean only one encoder can be used with it?

Hello.

The quadrature encoder uses pin change interrupts (as opposed to external interrupts), which exist on all of the Arduino’s digital I/O pins. You can find more information on the differences between external interrupts and pin change interrupts here.

- Jeremy

I am also trying to make the the same Pololu encoders noted above work and have a more basic question than dgalimeier. I have downloaded the Arduino library to

Desktop/Arduino/libraries/libpololu-arduino/PoluluWheelEncoders.h

but am not getting the code to compile. I get: ‘PololuWheelEncoders’ has not been declared. I am sure I’ve done something stupid. Can you help?


    #include <PololuWheelEncoders.h>

    void setup() {
      Serial.begin(9600);
      Serial.println("Hello World!");
     
      PololuWheelEncoders::init(2,3);
    }

    void loop() {
      //Serial.println(PololuWheelEncoders::getCountsM1());
      Serial.println(PololuWheelEncoders::getCountsM2());

      delay(1000);
    }

Hello.

That is a strange path. You should be copying the contents of the libpololu-arduino folder into your Arduino/libraries directory, so the path should be:

Desktop/Arduino/libraries/PololuWheelEncoders

And inside that folder should be three files:

  • keywords.txt
  • PololuWheelEncoders.cpp
  • PololuWheelEncoders.h

Also, make sure you are spelling “Pololu” correctly (you have it spelled “Polulu” in the path you gave).

By the way, this is a very different problem from the one this thread was originally about (the only common factor is that they both involve the same product). This kind of thing really should be in its own thread.

- Ben

Hi, I’m also having the same problem. Here’s a snapshot of it. I’ve setup the library just as you mentioned. But there’s no keywords.txt file… Please help.


Hello.

From your screenshot, it looks like that library was not installed properly, and since you are missing the keywords.txt file, it sounds like you did not install the whole library before. Can you try again?

As Ben mentioned, you will need to copy the contents of the library folder into your Arduino/libraries directory (e.g. you should copy the PololuWheelEncoders folder into the Arduino libraries folder). If you download our library from here, you should have all of the files you need, including the keywords.txt file.

-Jon

Hi,

I am using shaft encoder, (pololu.com/product/2590 ) . In this case how shall I count the rotation. I am new to arduino programming and encoder. I am trying to make exact 90 degree rotation in the robot.

  1. How can I achieve this?

  2. Shall I use same library and same program listed above?

pls help me.

Hello.

You could write a sketch that interprets the encoder outputs as counts and stops after enough counts for a 90 degree rotation. The library in my post above is an Arduino example for basic processing of encoder signals, so you would have to add code to make it stop after a certain number of counts.

By the way, that library should work similarly to the examples on the Arduino web page Amanda linked you to in the other thread you started.

-Jon

Hi,

Thanks for your reply. I am using “Pololu Wheel Encoder” library and trying to make wheel rotation for certain count after that stop for 1 second , this has to be done continuously .But , how shall I make encoder value set to zero ? So, it will be going back to first condition and execute the sequences .

Hi ,

Thanks for your reply,

I am using your code above. I am trying to make rotate the wheel for certain counts and stop for 1 second and again starts rotation for certain counts and go on. By using your code I can get a rotation and stop it. How can I reset the “count” value here? If I could reset the value then I can achieve my objective.

You might consider using the getCountsAndResetM1() and getCountsAndResetM2() functions. You can learn more about those and other functions of our encoder library under the “Wheel Encoders” section of the Pololu AVR Library Command Reference.

-Jon

Thank you for your kind reply.

I tried it,but only one motor do that operation ,other one keep on rotating. after sometime both keep on rotating .
I post my code here,pls let me know if you find any mistake.

Code:

#include <PololuWheelEncoders.h>

int motorRightEnable_pin =12;
int motorRightPositive = 6; 
int motorRightNegative = 5; 

int motorLeftPositive = 9; 
int motorLeftNegative = 10;
int motorLeftEnable_pin=13;

    void setup() {
      Serial.begin(115200);
      pinMode (motorRightPositive, OUTPUT); 
     pinMode (motorRightNegative ,OUTPUT); 
     pinMode(motorRightEnable_pin, OUTPUT);
     pinMode (motorLeftPositive, OUTPUT);
     pinMode(motorLeftNegative, OUTPUT);
     pinMode(motorLeftEnable_pin, OUTPUT);
      
     
     
      PololuWheelEncoders::init(3,4,7,8);
    }

    void loop() {
      Serial.println(PololuWheelEncoders::getCountsM1());
      Serial.println(PololuWheelEncoders::getCountsM2());
 digitalWrite(motorLeftEnable_pin, HIGH);
     analogWrite (motorLeftPositive, 50);
     analogWrite (motorLeftNegative, 0);
      //Serial.println("Hello World!");
     
     digitalWrite(motorRightEnable_pin, HIGH);
     analogWrite (motorRightPositive, 50);
     analogWrite (motorRightNegative, 0);  
     
if(PololuWheelEncoders::getCountsM2()==3420)
{
  digitalWrite(motorRightEnable_pin, LOW);
     analogWrite (motorRightPositive, 50);
     analogWrite (motorRightNegative, 50); 
     delay(1000);
    PololuWheelEncoders::getCountsAndResetM2();
    
}


  
  

if(PololuWheelEncoders::getCountsM1()==-3420)
{
  digitalWrite(motorLeftEnable_pin, LOW);
     analogWrite (motorLeftPositive, 50);
     analogWrite (motorLeftNegative, 50); 
     delay(1000);
     PololuWheelEncoders::getCountsAndResetM1();
}

     
    }

I am not entire sure, but it looks like as soon as getCountsM1 reaches 3420, then your code delays for a full second and during that time the getCountsM2() value grows larger than -3420 and the condition is never met for it to reset. You could probably get around that by using “greater than or equal to” (">=").

By the way, you should double check that the sign on 3420 makes sense with your last two conditionals (e.g. when your motor drives forward, does getCountsM1() get more positive as getCountsM2() gets more negative?).

-Jon

Yes Jon, you are right when I looked the serial monitor the values doesn’t match. But if I use greater than or equal to in that condition ,how could I get an exact 90 degree?

Is there any alternate solution to stop both motors individually for 1 second or can you please modify the program which satisfies the both left and right motor condition?

You could probably get both your motors to stop at the right time if you remove delay(1000) from the last two conditionals. If you expect your motors to rotate to 90 degrees at almost the same time, you could just add code to wait for one second after both conditionals occur. Otherwise, if you need more specific timing, you might need to use more advanced programming techniques like using state variables and the millis() function.

-Jon

A post was split to a new topic: Help with encoder on Pololu gearmotor