Notifications
Clear all

Thoughts on motor encoders

Page 1 / 3

NewburyPi
(@dale)
Estimable Member
Joined: 2 years ago
Posts: 120
Topic starter  

Bill, 

I see that you are planning to use motors with integrated encoders. I've been using a much smaller motor, but with encoders to help me with waypoint navigation and speed regulation. Right now I'm using the Arduino PID controller library. It's quite easy to use and after a bit of tuning it was giving me reasonable results. 

I've recently made a modification to motor encoder circuit that has doubled the accuracy of my wheel encoders and given me even better performance. It's a simple mod, and think you may find it useful. 

The motor encoders (as you know) run with quadrature encoding. Allowing you to determine the direction of rotation. As I control the direction of rotation of my motors, this seemed to be of little use to me. Therefore I just ran one of the two encoder lines to the Nano's interrupt pin (one encoder line from each of the two motors to each of the Nano's two interrupts). 

Let's try to make this drag on much longer... The mod is to connect each of the two encoder lines from a motor to the inputs of an exclusive OR logic gate (74LS86)

image

This produces a pulse stream that is double the frequency, compared to just using the single line. 

image

Let me know if you have any questions. 

Dale

--
Dale


Quote
frogandtoad
(@frogandtoad)
Prominent Member
Joined: 2 years ago
Posts: 828
 

@dale

Not sure if you're interested, but a while back I purchased a couple of rotary encoders from eBay - They have 600 pulses / rev and only cost ~$17AUD each for me, and certainly much cheaper for the USD tinkerers!  Not sure of their exact cost these days, but might save you some screwing around with logic gates that won't even come close in the end 🙂

 


ReplyQuote
NewburyPi
(@dale)
Estimable Member
Joined: 2 years ago
Posts: 120
Topic starter  

Thanks @frogandtoad, but I'm now sure how I would attach the encoders to my motors. My current encoders are integral to the motor's frames. On the plus, I am getting 1400 pulses per revolution and all is working just fine. 

--
Dale


ReplyQuote
frogandtoad
(@frogandtoad)
Prominent Member
Joined: 2 years ago
Posts: 828
 

@dale

OK, no problem... looks like you have a higher resolution anyway 🙂


ReplyQuote
NewburyPi
(@dale)
Estimable Member
Joined: 2 years ago
Posts: 120
Topic starter  

Yes, I think I've got it covered. However, thank you for the suggestion.

--
Dale


ReplyQuote
huckOhio
(@huckohio)
Estimable Member
Joined: 2 years ago
Posts: 175
 
Posted by: @dale

Let's try to make this drag on much longer... The mod is to connect each of the two encoder lines from a motor to the inputs of an exclusive OR logic gate (74LS86)

image

This produces a pulse stream that is double the frequency, compared to just using the single line. 

image

Let me know if you have any questions. 

@dale

I am working on adding PID control to my robot and I saw your post.  I like the addition of 74LS86 to give you a higher frequency.  Are there any updates or advice you might have?

Thanks

Mike


ReplyQuote
NewburyPi
(@dale)
Estimable Member
Joined: 2 years ago
Posts: 120
Topic starter  

@huckohio not too much to add. Doubling the encoder frequency is still working well for me, on ARDVARC. The only thing you need to keep an eye on is overloading the interrupts. If your encoders are already fast, your processor may have difficulty keeping up. 

One recent change, I've made, is to use the remaining two gates to invert my "direction" signal. I connect two sets of encoders (one left and one right) to two of the XOR gates. Leaving two gates unused. Now... the H-bridge I'm using requires two signals that indicate direction. A FORWARD and a NOT_FORWARD. I feed my FORWARD signal to one of the spare XOR gate inputs and tie the other input high. This gives me the inverted signal at the gate's output. In my original robot, I used a pair of 2N2222s to perform the inversion. 

And a question  back to you... are you using a library for PID control? I was using Beaureguard (sp?) PID_v1 library. It worked well with my earlier robot but is giving me problems with the new one. I spent two days digging around without any joy. I'm at the point now of thinking I maybe I should try to write my own PID controller.

ttfn

Dale

--
Dale


ReplyQuote
huckOhio
(@huckohio)
Estimable Member
Joined: 2 years ago
Posts: 175
 
Posted by: @dale

And a question  back to you... are you using a library for PID control? I was using Beaureguard (sp?) PID_v1 library. It worked well with my earlier robot but is giving me problems with the new one. I spent two days digging around without any joy. I'm at the point now of thinking I maybe I should try to write my own PID controller.

@dale

Not that far along yet.  I saw there is an Arduino PID library, but most of the videos I am watching are not using a library.


ReplyQuote
byron
(@byron)
Honorable Member
Joined: 2 years ago
Posts: 678
 
Posted by: @dale

The only thing you need to keep an eye on is overloading the interrupts. If your encoders are already fast, your processor may have difficulty keeping up. 

+ FYI @huckohio

You may be interested in this video on using External encoder Counter chip LS7366R. It seems useful for when the processor cannot keep up

 


ReplyQuote
NewburyPi
(@dale)
Estimable Member
Joined: 2 years ago
Posts: 120
Topic starter  

@huckohio there seems to be a number of libraries available. I'll try to put a list together, a little later. I'll also be looking at the match between my math(s) skills and the code for PID controlling 🙂 First off however, I need to get to Costco.

--
Dale


huckOhio liked
ReplyQuote
NewburyPi
(@dale)
Estimable Member
Joined: 2 years ago
Posts: 120
Topic starter  

@byron very interesting. Many thanks. I'll be looking closer at that chip. 

--
Dale


ReplyQuote
huckOhio
(@huckohio)
Estimable Member
Joined: 2 years ago
Posts: 175
 

@dale 

I did see that there is a V2 for the PID library you mentioned.  

Right now my focus is getting the robot to drive in a straight line.


ReplyQuote
NewburyPi
(@dale)
Estimable Member
Joined: 2 years ago
Posts: 120
Topic starter  

@huckohio straight lines is the reason I went to PID. I was originally planning to "orient" ARDVARC by running a straight line (a la line following) and having it learn how much power to feed each of the two motors to keep them in sync. After a night's sleep I thought better of it. 

I'll take a closer look at which revision I'm using. I'm loading the .h file for the earlier one, but not shore which link files are being used. I'm using platformio/vscode to develop my code and am certainly not full skilled in it yet. 

--
Dale


ReplyQuote
THRandell
(@thrandell)
Eminent Member
Joined: 5 months ago
Posts: 45
 

@dale

Dale,

Regarding your original post I have a question.  Your wave forms make it clear how you are doubling your clicks per revolution.  Nice.  I’m wondering how you are able to measure the distance covered if you are moving backwards?  Do you have a clever way of decrementing your counters?  This is the code that I’ve plagiarized, but only encoder A is connected to an interrupt pin.

 

#define LH_ENCODER_A 1  
#define LH_ENCODER_B 5 
#define RH_ENCODER_A 0  
#define RH_ENCODER_B 4

void setup() {
  pinMode(LH_ENCODER_A, INPUT);
  pinMode(LH_ENCODER_B, INPUT);
  pinMode(RH_ENCODER_A, INPUT);
  pinMode(RH_ENCODER_B, INPUT);
   // initialize hardware interrupts
  attachInterrupt(digitalPinToInterrupt(1), leftEncoderEvent, CHANGE);
  attachInterrupt(digitalPinToInterrupt(0), rightEncoderEvent, CHANGE);
}

void leftEncoderEvent() {
  if (digitalRead(LH_ENCODER_A) == HIGH)
    if (digitalRead(LH_ENCODER_B) == LOW)
      leftClicks++;
    else 
      leftClicks--;
  else
    if (digitalRead(LH_ENCODER_B) == LOW)
      leftClicks--;
    else
      leftClicks++;
}

 

 

Thanks  Tom


ReplyQuote
NewburyPi
(@dale)
Estimable Member
Joined: 2 years ago
Posts: 120
Topic starter  

@thrandell I took the cheap and dirty road. I assume that the only way for the robot to move is under power. I know which way the wheels are turning, as I am the cause of any movement. This is not a solution for travel on uneven ground, unless you have brakes.

You could change your current code to only check direction when A is high. Just store the direction in a variable. When A is low, increment or decrement according to the stored direction variable. Any error should be limited to one tick.

At least I think that would work <insert a shoulder shrug>.

 

Dale

--
Dale


ReplyQuote
Page 1 / 3