We like to help, otherwise they put us back in our cages. - Matt Krass [more]
 Chief Delphi PID algorithm using Arduino
 CD-Media CD-Spy
 portal register members calendar search Today's Posts Mark Forums Read FAQ rules

#1
03-23-2012, 03:46 PM
 tb0508 Registered User no team Join Date: Mar 2012 Location: United States Posts: 3
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.

Last edited by tb0508 : 03-23-2012 at 09:10 PM.
#2
03-23-2012, 09:21 PM
 RyanN RyanN AKA: Ryan Nazaretian FRC #2468 (Team Appreciate) Team Role: Mentor Join Date: Jun 2006 Rookie Year: 2005 Location: Austin, TX Posts: 1,150
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.
__________________
Controls Mentor
@rnazaretian

Current team:
Team Appreciate, FRC 2468

Previous teams:
Team Fusion, FRC 364 (2003 - 2015)
#3
03-23-2012, 10:41 PM
 tb0508 Registered User no team Join Date: Mar 2012 Location: United States Posts: 3
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

Last edited by tb0508 : 03-23-2012 at 10:44 PM.
#4
03-24-2012, 01:05 AM
 StevenB is having FRC withdrawal symptoms. AKA: Steven Bell no team Team Role: College Student Join Date: May 2005 Rookie Year: 2005 Location: Stanford, CA Posts: 422
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 input
// Convert to sensor range:  Subtract the input offset to center
// around 0, multiply by the range scale, and add the output offset
target = (input - 500) * (500/300) + 400;
error = target-current;
outputPower = error * kP; // Assuming output is +/- 127 or similar```

Note 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.
__________________
Need a physics refresher? Want to know if that motor is big enough for your arm? A FIRST Encounter with Physics

2005-2007: Student | Team #1519, Mechanical Mayhem | Milford, NH
2008-2011: Mentor | Team #2359, RoboLobos | Edmond, OK
2011-??: FLL mentor, FRC volunteer, occasional advisor, and ChiefDelphi lurker
#5
03-24-2012, 01:24 AM
 tb0508 Registered User no team Join Date: Mar 2012 Location: United States Posts: 3
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
int val = 0; // variable to store the value

void setup() {
Serial.begin(9600);
}

void loop()
{
Serial.println( val );
delay(1);
}```
second arduino the receives the 'target' through xbee(This arduino also receives the value of the 'current' directly with the bottom wheel pot)
Code:
```char string[8]; //can be 4, 8 is fine
int var;
int index;
boolean started=false;
boolean ended=false;

void setup()
{
Serial.begin(9600);
}

void loop()
{
while(Serial.available() >= 0) //since 0-1023
{
if(var=='<') //not sure what to put in if statement to run until end
{
started = true;
index=0;
string[index]='\0';
}
else if(var=='>')
{
ended = true;
break; //break out of while loop when '>' received
}

else if(started)
{
string[index]=var;
index++;
string[index]='\0';
string[index]=var; //store character
}
}

if(started && ended)
{
//convert portion of string to integer representation
int val=atoi(string);
Serial.print("<");
Serial.print(val);
Serial.print(">");

//next time
started = false;
ended = false;

index = 0;
string[index]='\0';
}
}```
This second arduino will be able to compare the 'target' and 'current' values to use the 'P'. I plan to trial and error the Kp. Now it can use the:
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.

Last edited by tb0508 : 03-24-2012 at 02:22 AM.
#6
03-24-2012, 01:27 PM
 StevenB is having FRC withdrawal symptoms. AKA: Steven Bell no team Team Role: College Student Join Date: May 2005 Rookie Year: 2005 Location: Stanford, CA Posts: 422
Re: PID algorithm using Arduino

Quote:
 Originally Posted by tb0508 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?
Probably, but not necessarily; think about the values you're trying to convert, rather than how to plug it into an equation. The graph below shows an example mapping of input values to output values. The input is the x-axis; these are the readings you get from the steering wheel. The output is the y axis; these are the desired positions for the output. Draw this graph for whatever values you have, and the equation for Y in terms of X will follow naturally from that.

Quote:
 Originally Posted by tb0508 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.
Look through the Roboclaw datasheet and Arduino examples, if you haven't already. In theory you could use any of the four control modes the RoboClaw allows.

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!
__________________
Need a physics refresher? Want to know if that motor is big enough for your arm? A FIRST Encounter with Physics

2005-2007: Student | Team #1519, Mechanical Mayhem | Milford, NH
2008-2011: Mentor | Team #2359, RoboLobos | Edmond, OK
2011-??: FLL mentor, FRC volunteer, occasional advisor, and ChiefDelphi lurker

 Thread Tools Display Modes Rate This Thread Linear Mode Rate This Thread: 5 : Excellent 4 : Good 3 : Average 2 : Bad 1 : Terrible

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts vB code is On Smilies are On [IMG] code is On HTML code is Off
 Forum Jump User Control Panel Private Messages Subscriptions Who's Online Search Forums Forums Home Announcements     User Announcements FIRST     General Forum         FIRST E-Mail Blast Archive     Rumor Mill     Career     Robot Showcase Technical     Technical Discussion     Robotics Education and Curriculum     Motors     Electrical         CAN     Programming         NI LabVIEW         C/C++         Java         Python     Control System         FRC Control System         Sensors     Pneumatics     Kit & Additional Hardware     CAD         Inventor         SolidWorks         Creo     IT / Communications         3D Animation and Competition         Website Design/Showcase         Videography and Photography         Computer Graphics     National Instruments LabVIEW and Data Acquisition         LabView and Data Acquisition Competition     Unsung FIRST Heroes     Awards         Chairman's Award     Rules/Strategy         Scouting         You Make The Call     Team Organization         Fundraising         Starting New Teams         Finding A Team         College Teams     Championship Event     Regional Competitions     District Events     Off-Season Events     Thanks and/or Congrats     FRC Game Design     OCCRA         OCCRA Q&A         OCCRA Programming Other     Chit-Chat         Games/Trivia             Fantasy FIRST     Car Nack's Corner     College & University Education     Dean Kamen's Inventions     FIRST-related Organizations         Western Region Robotics Forum         Southern California Regional Robotics Forum         The Blue Alliance             Video Archives     FIRST In the News...     FIRST Lego League         Lego Mindstorm Discussion     FIRST Tech Challenge     VEX         VEX Robotics Competition         VEX IQ     Televised Robotics     Math and Science         NASA Discussion ChiefDelphi.com Website     CD Forum Support     Extra Discussion

All times are GMT -5. The time now is 09:34 AM.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.

 -- English (12 hour) -- English (24 hour) Contact Us - Chief Delphi - Rules - Archive - Top