In order to try to drive my 2wd robot on a straight line I buy some motors with encoders.
I’m using the arduino pid controller lib.
When I try the sample with one encoder/motor the pid setpoint is reached quickly and motor stay on setpoint, or very close without a lot of errors.
The problem is with 2 pids
When I double the pid controller instances, duplicate all the required variables, and control code to have the arduino running each motor with its own pid controller, the results are bad, the speed up and down, and neither pid produce a good job.
I try to optimize it changing the p, I and d factors and the sampling time, and I manage to get better results, but they are far from the single pid results.
If you want I can post the code.
So the questions are:
do you have the same problem?
Any reason to have this issue?
And my main question is anyone have a sample code of arduino running 2 pid controllers on setpoint ?
The pid input is the Encoder pulses, the output are speed motor changes, the setpoint are 60 pulses per sampling time, the error are +- 8 pulses, more than 10%.
Do you know any sample of 2 pid engine controller?
I can post the code for sure. But it also contains i2c code, and external commands parsing code, because it’s used as a program for a nano168 that should only control the motors as a i2c slave. It is a nice sample for working i2c control messages, but a example of a bad combination of pid controllers.
As soon as I got in my desk I will post the full code. It’s not big because I need to fit small nano168 memory.
@inaciose, nobody is going to study all that code the way you have posted it in Replies #4, 5 and 6. You have not used the code button </> and it is too easy to introduce errors when trying to join pieces together.
The best thing to do is to delete those Replies and add your .ino file as an attachment in a new Reply. See How to use the Forum
inaciose:
The pid input is the Encoder pulses, the output are speed motor changes, the setpoint are 60 pulses per sampling time, the error are +- 8 pulses, more than 10%.
Do you know any sample of 2 pid engine controller?
I think you don't have a stable setup there - 60 pulses per sampling time implies a long sampling time,
meaning the PID loop isn't running at a suitably high rate for stability.
The pid loop time needs to be pretty small for tight control, you need to calculate your speed error from
the instanteous rate of encoder ticks, you cannot wait and count them, input to a PID loop should be
about the present state, not some time in the past.
maybe you are right, but then i suppose that the 1 pid versions should have same problems to, and it dont.
Maybe im not understant the pid implementation.
put it simply:
using a encoder with: 20 holes (so 1 rotation are 20 pulses)
setting up a pid with: encoderPIDLeft.SetSampleTime(100);//Set PID sampling frequency is 100ms
setting up a setpoint to: 60
reads as follows?
the pid controller should try to get 60 pulses (3 rotations) on input on every 100 ms (the SampleTime set above?)
on PID.compute(), if read lower, should raise the output, if higher should lower the output.
My assumptions is: if raise the the sampleTime, there are more time to generate pulses and the PID.compute() take more time to change the output.
Im right?
what do you mean with this?
"you need to calculate your speed error from the instanteous rate of encoder ticks, you cannot wait and count them, input to a PID loop should be about the present state, not some time in the past."
Its the current count, that are reset on every PID.compute().
what is a setpoint in a dc motor? i belive that are pulses per time (speed). so you need to count pulses on each time cycle. and the pid job is set the output to reach and mantain smothly the number of pulses per cycle on the setpoint we desire.
Can you supply a working sample of 2 pid controllers for 2 dc engines?
If this was my problem I would be measuring the time between pulses (using micros() ) and using that as the input for PID.
I control the speed of a small DC motor that way - calling the PID function every time a pulse is detected. It works fine for a wide range of speeds from about 30,000 µsecs down to 4,000 µsecs per revolution (1 pulse per rev).