1. ## PID basics

I have recently ventured into embedded robotics, and to begin this learning process i purchased a AVR 40pin development board from robokits and a 2A motor driver. I am using Atmega16.
I am using avrstudio to write and simulate my code.
I can do a basic code of LEDs, Line sensor array, proximity sensors, and i have written all the codes myself. All examples on the internet gave errors in avrstudio, so i understood all codes and coded myself.
I tried going through the datasheet of atmega16, didnt understand much, but i hope to understand more as i progress.

Now i want to learn PID and PWM.
I tried to read many many PID pages on the internet, i understood some logic, but i am not able to understand how to implement that logic in making a code(especially on avrstudio). I dont want a source code but i want a good algorithm to understand and code PID. I understand it requires EEPROM also (which i have not much idea of).
Does PID require PWM also if i plan to run motors?

The problem statement that i have proposed to myself is to run a robot on
1. P (yet to learn)
2. PD (yet to learn)
3. PDI (yet to learn)
to follow a line or a proximity sensor. and give outputs on either the LEDs or on Motors.

Can someone guide me?

Regards
Vaibhav

2. Hi
whats ur age and qualification

Asimov

3. Hello
I am 19. Doing mechanical engineering 2nd yr.

4. Originally Posted by asimov_18;19728

[url

Asimov
Thank you for the link. I have downloaded it and have skimmed over it once. I will read it in depth on 9th, because my exams will end on 9th.

5. Basically PID is a control scheme that calculates:
1. The present error
2. The total of all previous errors
3. The difference between the present and previous error.

The measurement and the control action loop - meaning
1. System 'sensors' measure the process value (could be temperature, RPM, pressure),
2. System calculates the difference between the process value and set value,
3. System takes a control action (like turn on the heater, increase the motor PWM's duty cycle, open a pressure valve),
4. Go back to step 1.

The PID response is analog, but has been adapted to the digital world rather nicely. Check out the Microchip application note pointed above. It shows how this is done. In control systems I've designed I've used exclusively the scheme I'm indicating below (in pseudo-code) and although the tuning (more on this later) takes some effort, yet the control is great.

To begin with you can leave out the differential component. It complicates things greatly. Begin with a simple proportional control scheme and then move to a PI scheme.
Tuning basically means having to find values of Kp, Ki, Kd. This is best done by experiment (trial/error) although there are tuning schemes also like ZN.

Go through this and let me know if you have any questions.

<code>
PID_Calculate
;------------
;---------------------------------------------------------------------------------
; Ppp
; Produces proportional component by multiplying Error_Hi:Error_Lo by Kp
;
; ProH:Pro = Error_Hi:Error_Lo * PH:PL
;
; This term forces the output close to the desired output quickly,
; but will never completely eliminate the error.
;
; Input Variables:
; Error_Hi:Error_Lo = Error found at top of loop
; n4:n3 = Kp [Proportional gain factor (constant)]
;
; Output Variables:
; ProH:Pro Proportional component
;
; At maximum, Error=0x1000 and Kp=0xA, then ProH2:L2=0xA000
;
;---------------------------------------------------------------------------------

;---------------------------------------------------------------------------------
; IntCom Computes integral component
;
; Multiplies present error by Ki,
;
; IntH:Int = IntH:Int + Error_Hi:Error_Lo * IH:IL
;
; This term will eliminate all error, but not quickly
;
; Input Variables:
; Error_Hi:Error_Lo Present loop error
; IntH:Int Running total of errors
; Ki Integral gain factor (constant)
;
; Output Variables:
; IntH:Int Integral component
;---------------------------------------------------------------------------------

;---------------------------------------------------------------------------------
; DifCom Computes differential component
;
; Finds difference between this loop error and previous loop error
; DifH : Dif = (Error_P_Hi:Error_P_Lo - Error_Hi:Error_Lo) * DHL
;
; This term tends to slow controller response.
;
; Input Variables:
; Error_P_Hi:Error_P_Lo : Previous loop error
; Error_Hi:Error_Lo : Present loop error
; DHL : Differential gain factor (constant)
; XD : Differential division factor (constant)
;
; Output Variables:
; DifHif Differential component
;---------------------------------------------------------------------------------

;---------------------------------------------------------------------------------
; Total Sums proportional, integral, and differential terms
;---------------------------------------------------------------------------------
</code>

6. Okay this is a mess... I am getting smilies where I shouldn't be and I cannot remove them. Also the <code> tags don't seem to work.

7. ## Doubt 1

Originally Posted by MohitM
Basically PID is a control scheme that calculates:
1. The present error
2. The total of all previous errors
3. The difference between the present and previous error.

The measurement and the control action loop - meaning
1. System 'sensors' measure the process value (could be temperature, RPM, pressure),
2. System calculates the difference between the process value and set value,
3. System takes a control action (like turn on the heater, increase the motor PWM's duty cycle, open a pressure valve),
4. Go back to step 1.

The PID response is analog, but has been adapted to the digital world rather nicely. Check out the Microchip application note pointed above. It shows how this is done. In control systems I've designed I've used exclusively the scheme I'm indicating below (in pseudo-code) and although the tuning (more on this later) takes some effort, yet the control is great.

To begin with you can leave out the differential component. It complicates things greatly. Begin with a simple proportional control scheme and then move to a PI scheme.
Tuning basically means having to find values of Kp, Ki, Kd. This is best done by experiment (trial/error) although there are tuning schemes also like ZN.

Go through this and let me know if you have any questions.

<code>
PID_Calculate
;------------
;---------------------------------------------------------------------------------
; Ppp
; Produces proportional component by multiplying Error_Hi:Error_Lo by Kp
;
; ProH:Pro = Error_Hi:Error_Lo * PH:PL
;
; This term forces the output close to the desired output quickly,
; but will never completely eliminate the error.
;
; Input Variables:
; Error_Hi:Error_Lo = Error found at top of loop
; n4:n3 = Kp [Proportional gain factor (constant)]
;
; Output Variables:
; ProH:Pro Proportional component
;
; At maximum, Error=0x1000 and Kp=0xA, then ProH2:L2=0xA000
;
;---------------------------------------------------------------------------------

;---------------------------------------------------------------------------------
; IntCom Computes integral component
;
; Multiplies present error by Ki,
;
; IntH:Int = IntH:Int + Error_Hi:Error_Lo * IH:IL
;
; This term will eliminate all error, but not quickly
;
; Input Variables:
; Error_Hi:Error_Lo Present loop error
; IntH:Int Running total of errors
; Ki Integral gain factor (constant)
;
; Output Variables:
; IntH:Int Integral component
;---------------------------------------------------------------------------------

;---------------------------------------------------------------------------------
; DifCom Computes differential component
;
; Finds difference between this loop error and previous loop error
; DifH : Dif = (Error_P_Hi:Error_P_Lo - Error_Hi:Error_Lo) * DH:DL
;
; This term tends to slow controller response.
;
; Input Variables:
; Error_P_Hi:Error_P_Lo : Previous loop error
; Error_Hi:Error_Lo : Present loop error
; DH:DL : Differential gain factor (constant)
; XD : Differential division factor (constant)
;
; Output Variables:
; DifH:Dif Differential component
;---------------------------------------------------------------------------------

;---------------------------------------------------------------------------------
; Total Sums proportional, integral, and differential terms
;---------------------------------------------------------------------------------
</code>

Sir
Thank you for the pseudo code.
I have read through it many times now. but i am not able to figure out what "Error_Hi:Error_Lo" kind of syntax means in the pseudo code. probably i will be able to figure out more once i am clear with the syntax
Regards
Vaibhav

8. In pseudo-code / assembly, if I would like to represent a 16-bit number on 8-bit devices, I show them like this: Error_Hi:Error_Lo. They are both 8-bit variables in the RAM. Error_Hi is the MSB and Error_Lo is the LSB (B=Byte).
This is to do 16-bit maths on 8-bit microcontrollers.

In C, I'd guess you'd code something like this: "unsigned int16 Error;" and your life is much easier vis-a-vis assembly.

EDIT: Mind you, I just copied directly from a project, removing some code, I think was not required (its all PIC MPASM code while you need AVR code). Also I code in assembly almost entirely. So some pieces may still be left over that may confuse you.

9. I went through both the codes. Still i am not able to get my stepping stone...
I will try to be more objective in my approach.

I am writing my idea of what needs to be done, kindly tell me where i should put what.

I am writing my pseudo-code
Electronics used - L298 Motor driver, 2 DC motors, 7 sensor line sensing array, atmega 16, and all the rest as mentioned in my first post.
Programmed in C in AVRstudio 4

1.take Variables - error, Kp, Ki, Kd, sensor, motor ( i guess i need two variables viz error and new_error)
2. I know - Sensor is in PORTA , Motor is PORTB
3. Set PortA to input , PortB to output.
/*
I have seven sensors "xxxxxxx1" last bit stays high on portA since there is no sensor on last pin
For me the zero error would mean "0b00111001 "
bit 1 means the black line is under the current sensor
bit 0 means the white region is under the current sensor
Positive errors are " 0b11100001 (extreme error) , 0b01110001 (small error) "
Negative errors are " 0b00001111 (extreme error) , 0b00011101 (small error) "
for a beginner i could use these statements
if( PINA == 0b11100001) error= +2; // Turn Left
if( PINA == 0b01110001) error= +1; // Turn Left
if( PINA == 0b00111001) error= 0; // Go straight
if( PINA == 0b00011101) error= -1; // Turn Right
if( PINA == 0b00001111) error= -2; // Turn Right

*/
4. Save input from PortA (PINA) to variable sensor.
5. Now what? //These are my probable guesses
{
1.Calculate error. How ?
2.Form a loop to calculate error, Kp, Ki , Kd , new_error.
3.Send value to motor? I am guessing a PWM, but how do i generate a PWM? what value to send?
}

Regards
Vaibhav

10. I'll get back to you in a day or two. In the meantime can you read up how to generate the PWM on the AVR? That's something described in the datasheet and tutorials.