![]() |
PID algorithm using Arduino
I am fairly new to the microcontroller/robotics world. I am currently trying to write/understand the basics of the PID algorithm and notice that I could get by with using only the 'P' algorithm. I understand the basics of it, I am now just trying to write the code for it.
Onto the actual questions. I have a wireless cart(go cart). I have a target pot(attached to steering wheel) and a feedback pot(current position pot) that is attached to the wiper motor. http://img703.imageshack.us/img703/9...lfrontpots.jpg What I am trying to do is write my own 'P' algorithm for this to send to the motor controller I have for the wiper motor. I understand the basic equations for the 'P' algorithm and finding the value to send to the motor controller which will interpret it and turn left/right and how fast to turn. What my main concern is what is all involved besides the basic equations. I have just started learning the PID algorithm and have picked up on it well but as a beginner I am still trying to learn more. Any available information on this topic is great, or examples. I have wrote out a detailed explanation of what I am trying to do involving the pots with equations(error, Turn, etc) and can post that if it helps. Thanks in advance. |
Re: PID algorithm using Arduino
For just P, it's not bad at all.
If you have the equations, then you know this: Output = Kp * (Target Value - Process Value). What this does is findes the error (TV - PV), then applies a gain Kp to make the motor actually do something, or to calm it down some. So with the Arduino, I'm assuming you're using a pre-made motor controller, such as a Victor or Jaguar, but since I don't see a team number, I might also assume you're using a different brand. Even so, the likelihood of it taking a PWM value is still high. In the Arduino library, there's examples on how to run a servo. Most motor controllers that I have ever seen emulate a servo. There's actually an example on how to use a knob (read potentiometer) to control a servo. All you need to do is add in the feedback to the system using that equation above and you'll have yourself a simple P controller. The I & D parts aren't hard to add either. The hardest part that you'll have is tuning it correctly. Seeing that you're driving a motor for steering, it will be extremely important to have a highly responsive system that does not overshoot or oscillate, as you can lose control. Oh, by the way. Cool project! I always wanted to do something like that, but never had the time or money to do it in high school, and now I'm more broke than ever being in college. Maybe it can be a fun project for my wife and I do to once we're all finished and have our degrees in Electrical Engineering and Computer Engineering. |
Re: PID algorithm using Arduino
Gulfport, MS...I am originally from Jackson.
Anyway, I am fairly new to the microcontroller/PID scene as this is a first for me. To answer some questions, I am using a Roboclaw 2x5A with the arduino uno. I am using two arduinos with xbee's to communicate wirelessly. I have the inputs(steering, the 'target') going into one arduino and sending to the second arduino(I have this code written for both). I have the pot at the wheels sent to the second arduino also so now the second arduino has the 'target' and 'curent' values. I have a detailed explanation of trying to write the code if you don't mind looking over it and seeing if I have it correct. First question dealing with the 'target' pot with the steering wheel. The way I understand it is I will have a 'proportional range', since the pot on the steering will have a range of 0-1023. I figured the range will be about 300 - 900. Reason I say this is I have a pin in the steering wheel which only allows the wheel to turn so far to the left and right. I will calculate this range of the pot using my code to see the values. Pin view: http://img560.imageshack.us/img560/7...ngwheelpin.jpg So, I will need to read in the proportional values of the range and try to get it to where it is a very close range when comparing the left to right. So, range from 200 to 500(center) to 800...where 300 is the range on each side(example). Am I off track right now? Next, I will convert this range to an 'error range' where 0 is the center and the range is from -300 and +300 using the above example. I will then take the value of the steering pot(target) and subtract it from the current value of the 'feedback' pot to get the error, then compare it to the 'error range'. This value will be negative or positive, small or large. I will need to get the constant K to use: Turn=K*error, where error is the target-current . With K being (0-800)/(-300-0) = 2.6.. (using example, not sure if K is correct)? I assume, Turn is the value that will be sent to the motor controller(using roboclaw 2x5a) to determine the left/right and how fast (depending on how far away the Turn value is on the 'error range' graph), correct? This is my idea, correct me if I am wrong or if there is an easier way(I am new to this), is this over complicating it? The roboclaw has PID algorithm itself, so I assume it will receive the Turn value and interpret the number and tell the wiper motor what to do and how fast. If this is a correct way, I am currently trying to right the code to incorporate this and determining how to send the value to the roboclaw. Any input, correction, would help. Thanks |
Re: PID algorithm using Arduino
Congratulations on getting your feet wet with PID. It's fun, and an incredibly useful concept to have practical experience with. Last year my roommates were taking a control systems class and were frustrated trying to understand PID - but it made sense to me, because I've seen it in action and gotten my hands dirty coding it.
Now, to your questions: I think you're making it too complicated. (It's ok - It took me weeks to distill PID when I was learning it, but now I can code it in half a dozen lines.) Think about it this way: you have a sensor input which produces a range of values, which you want to use to control the position of the output. The first thing to do is to translate the input sensor value to the output sensor value. This will probably be a linear function, based on the center readings and range of the sensors. Once you have a target measurement, you compare it with the current measurement. This is your error. If the measurements are the same (error is zero), then you don't want to move. If the error is large, you want to move fast. If it's small and negative, you want to move slowly in the other direction. If I have a control input from 200 to 800 (center of 500) and a measurement ranging from 0 to 800 (center of 400), the code would look something like this: Code:
control = readInputValue(); // AnalogRead or whatever you do to get the inputNote that you can't compute kP without modeling the underlying system and doing some nasty mathematical analysis. The best way to determine it is to experiment with some different values and see how they perform. I wouldn't use the RoboClaw's built-in PID to start off. You'll learn more and be less frustrated if you code the feedback loop yourself. I used a RoboClaw 2x5A with and Arduino last year for my senior design project. I selected the RoboClaw specifically because it could handle the PID loop without the Arduino having to do any heavy lifting, but the interface and tuning took a lot of debugging time. |
Re: PID algorithm using Arduino
Thank you for helping. So, I see it is less complicated than I am making it.
So, to get the values that you used of 200 to 800 with the center being 500. Is that the same as me using the min and max of the steering wheel pot? http://img560.imageshack.us/img560/7...ngwheelpin.jpg Using this image, you can see I have a pin that allows me to go left and right only a certain distance. I have code wrote to output the value of the current steering input, so I need to find the min, max, and center using this method? I will be able to use: target = (input - 500) * (500/300) + 400; Once I find the values of my pot? Here is my code for the input arduino('target') and second arduino that is receiving this value. Code:
int potPin = 0; // select input pin Code:
char string[8]; //can be 4, 8 is finecurrent = readSensorValue(); error = target-current; outputPower = error * kP; That you mentioned. Also, I plan to send the outputPower value to the roboclaw to determine left/right and how fast. Is this correct way? And I am a little confused on how exactly to send the value/data to the roboclaw for it to interpret. |
Re: PID algorithm using Arduino
Quote:
![]() Quote:
As a side note, it would be simpler and more efficient to use Serial.write() and Serial.read() to send the bytes directly, rather than converting them to character strings and back. But if you've got it working with print() and atoi(), then carry on! |
| All times are GMT -5. The time now is 00:47. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi