Every time I see a PID control for a motor, it involves an Encoder, so the algorithm knows the real position of the motor or wheel. But with the robot I have, I cannot use an encoder. I only have ONE optocoupler per wheel which can count how many degrees the wheel has moved. I can use it to increment a counter, but the counter ALWAYS increment (if the wheel moves forward or if the wheel moves backward).

The first moment I saw it as an inconvenient was when I studied the Arduino PID Autotune Library. In the first figure, I would not see decrements on the INPUT.

My objective is to move a little two-wheels robot small segments driven by simple trajectories separated over time by a complete stop (straight 10 cm, stop, move right 90 degrees, stop, straight until detect obstacle...)

Could you suggest me some kind of ideas? The first idea I have is to transform the PID position control to a speed control (which is more convenient for the feedback loop I have) and keep a counter of the traveled distance to inform the speed control when to stop.

  • $\begingroup$ Technically that's a photo-interrupter. You have the right idea, you can do closed loop control with this setup (both velocity and position). The only area of "fuzzyness" is around very low speeds which you'll need some way of dealing with (e.g. cube's answer). $\endgroup$ – Guy Sirton Apr 28 '14 at 5:14
  • $\begingroup$ Yes Guy. I have seen some people calling it a simple encoder or encoder in contrast to the better "quadrature encoder" which is the one that provides exact position information (with two optocouplers). I think I will have an error when I wanted to stop and the motor had an inertia, but it's the best I can achieve. Thanks. $\endgroup$ – Chirrin Dul Apr 28 '14 at 6:28

I'm no guru (building a robot, learning as I go :) ), but I was facing similar problem (not with arduino, though).

For the one encoder only part: I'm counting ticks using a single reflective sensor. I assumed that motor + gearing are strong enough that they will never turn when I'm not sending commands. Then I keep track of the direction of rotation and when there is a request to change it, I force several milliseconds wait with the motor stopped to ensure that it's not turning in a wrong direction. This adds some complications and state keeping to the code, but seems to work OK.

For the PID: I'm putting in speed difference (encoder ticks / timer interval) and using the output for PWM (actually I'm feeding it to a RC car ESC). This works really nice, it's fairly stable even when the motor has almost no torque during start up.

If some code will help you, here is my implementation for AVR: https://github.com/bluecube/robomower2/blob/master/src_avr/drive/main.c

| improve this answer | |
  • $\begingroup$ Thank you very much @cube. Not only you have confirmed the idea I was considering is feasible, but you also has been so kind to share your work. I will see it and get ideas for my vehicle. $\endgroup$ – Chirrin Dul Apr 28 '14 at 6:26

I have the same kind of system. It is a wheel encoder with just one sensor. I get just 20 counts per wheel revolution. It is easy to use. The software that sets the motor direction also sets a global variable to either +1 or -1. Then when the interrupt handler gets the signal "tick" it ADDS the global variable to the current count.

In short with one encoder you have to just remember the direction you told the wheel to go. This only works if the motor is strong or if there is a lot of friction in the system. It fails if there can be uncommanded wheel motion.

| improve this answer | |
  • $\begingroup$ Thank you very much, user3150208. I had a baby and I don't have enough time. I have done an speed control and there is a bit difference between the two wheels and sometimes peaks on the speed. For that reason, I am going to greed to the PID controller the average of the last 4 values of the speed. The drawback is that I have to adjust one more time the P, I and D values, as the response time is now different. I had to make some modifications on the Arduino code, for I need two counters for the two wheels. The third counter is for the PID timing. $\endgroup$ – Chirrin Dul Jan 6 '15 at 12:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.