Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] seeking for hhelp about PID controller for line follower codings ( PIC16f877A)

Status
Not open for further replies.

sadeqali90

Newbie level 3
Joined
Jun 6, 2011
Messages
4
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,345
I am in need for your help and it really appreciated .I hope you can help me and reduce my headache with PID controller
Hello and I hope you are doing good there,
Actually I am I doing my final year project with title “ LINE FOLLOWER ROBOT BASED ON PID CONTROLLER” and I need to apply PID controller using trial and error method .
I am using PIC 16f877A microcontroller . The input for this PIC16f877A come from four array Infared senors (analog input ) .The infared sensor are connected directly to the PIC16f877A through PORTA (pins RA3,RA4,RA5 and RA6) while the PIC is connected to the circuit driver through the port C with pins ( RC0, RC1, RC2 , RC3, RC5, RC6). The IC used for the circuit driver is L298N which is connected to the two dc gear motors.
Sechmatic are below


Note!!!!!!!
I don’t know how to convert the pid algorthem to c programming coding in order for the robot to follow the line . Below are some codings for the PID controller (proportional , integral , derivative )



Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <pic.h>
  
unsigned char qtr_rc_pins[] = {IO_C0, IO_C1, IO_C2, IO_C3, IO_C4, IO_C5};
unsigned char qtr_rc_count  = 6;       
unsigned int  qtr_rc_values[6] = {0};
 
// Ideas is to keep line in the center 
void follow()
{
    int position = qtr_read_line(qtr_rc_values, QTR_EMITTERS_ON);
 
    int center = (( (qtr_rc_count - 1) * 1000) / 2);
    int error  = position - center;
 
    int leftMotorSpeed = 50;
    int rightMotorSpeed = 50;
 
    if (error < -(center/2) )  // the line is on the left
    leftMotorSpeed = 0;  // turn left
    if (error > (center/2) )  // the line is on the right
    rightMotorSpeed = 0;  // turn right
 
    set_motors(leftMotorSpeed,rightMotorSpeed); 
 
}
 
 
float KP = 3 ,KI = 50000 , KD = 16/1;
 
int   integral  = 0;
int   last_proportional = 0;
 
void followPID()
{
    int position = qtr_read_line(qtr_rc_values, QTR_EMITTERS_ON);
 
    int center = (( (qtr_rc_count - 1) * 1000) / 2);
 
    int proportional = position - center;
 
    int derivative = proportional - last_proportional;
 
    int power_difference = proportional / KP + integral / KI + derivative * KD;
    last_proportional    = proportional;
    integral  += proportional;
 
 
    const int max = 200;
    const int max_diffrence = 20;
    const int factor_diffrence = 2;
 
    if(power_difference > max)
        power_difference = max;
    if(power_difference < -max)
        power_difference = -max;
 
    
    // if diffrence is too much robot skids 
 
    int leftMotorSpeed  = max;
    int rightMotorSpeed = max-power_difference;
 
    if(power_difference < 0)
    {
        leftMotorSpeed  = max+power_difference;
        rightMotorSpeed = max;
    }
 
 
    if(leftMotorSpeed - rightMotorSpeed > max_diffrence)
    {
        leftMotorSpeed -= (leftMotorSpeed - rightMotorSpeed)/factor_diffrence;
    } 
    else if(rightMotorSpeed - leftMotorSpeed > max_diffrence)
    {
        rightMotorSpeed -= (rightMotorSpeed - leftMotorSpeed)/factor_diffrence;
    }
 
    set_motors(leftMotorSpeed,rightMotorSpeed);
 
}
 
 
 
int main()
{
 
    set_digital_input(IO_D4, PULL_UP_ENABLED);
 
    while(is_digital_input_high(IO_D4)) {} // Wait for user to press button
    
    qtr_rc_init(qtr_rc_pins,qtr_rc_count, 2000, 255);  // 800 us timeout, no emitter pin
 
    red_led(1);
    delay(1000);
 
    int i;
      for (i = 0; i < 100; i++)  // make the calibration take about 2 seconds
      {
        if(i%25==0)
        {
            if((i/5)%2==0) set_motors(20,-20); 
                else set_motors(-20,20); 
        }
 
        if(i%5)
        {
            if((i/5)%2==0) red_led(0);
                else red_led(1); 
        }
        qtr_calibrate(QTR_EMITTERS_ON);
        delay(20);
      }
 
    set_motors(0,0); 
    red_led(1);
 
    while(is_digital_input_high(IO_D4)) {} // Wait for user to press button
    delay(1000);
 
    while(1)
    {
        //follow(); // If you want to use non PID method 
        followPID();
    }
 
}




******** I need you help guys , I have really suffered *************** please help
 
Last edited by a moderator:

thanks Alot
i have the basic about programming in c and how to define the devices connected to the the pic , and how to initialize the ports for the input and output .but , i faced problem how to convert the the algorith for the PID to c programming .
 

the only problem i have is that i can not understand how i can get set the value for the position of the robot regarding to the signal recieved through the POrtA from the infarder sensor .Could you please clearify for me the codig below because it for another conrtller:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
void followPID()
{
    int position = qtr_read_line(qtr_rc_values, QTR_EMITTERS_ON);
 
    int center = (( (qtr_rc_count - 1) * 1000) / 2);
 
    int proportional = position - center;
 
    int derivative = proportional - last_proportional;
 
    int power_difference = proportional / KP + integral / KI + derivative * KD;
    last_proportional    = proportional;
    integral  += proportional;
 
 
    const int max = 200;
    const int max_diffrence = 20;
    const int factor_diffrence = 2;
 
    if(power_difference > max)
        power_difference = max;
    if(power_difference < -max)
        power_difference = -max;
 
    
    // if diffrence is too much robot skids 
 
    int leftMotorSpeed  = max;
    int rightMotorSpeed = max-power_difference;
 
    if(power_difference < 0)
    {
        leftMotorSpeed  = max+power_difference;
        rightMotorSpeed = max;
    }
 
 
    if(leftMotorSpeed - rightMotorSpeed > max_diffrence)
    {
        leftMotorSpeed -= (leftMotorSpeed - rightMotorSpeed)/factor_diffrence;
    } 
    else if(rightMotorSpeed - leftMotorSpeed > max_diffrence)
    {
        rightMotorSpeed -= (rightMotorSpeed - leftMotorSpeed)/factor_diffrence;
    }
 
    set_motors(leftMotorSpeed,rightMotorSpeed);
 
}

 
Last edited by a moderator:
Read the line sensor, change to the value let say from -100 to 100. The PID is the concept to get the set point value. So, the target value is 0 so that the robot will at the center.
 

hi,
last year, i have do a project about PID. i know it.
i am poor in english, maybe i cant explain exactly.
i have skype name haozijun2, you can find me.
when you want the motors speed is exactly, you should get its speed, if the value is lower than your aim, you make it quick, if the value is faster than your aim, you make it slow. how can you do it? you use the way of PID.
just a simple way;
first, your aim is V0,
second, if you give power p0,you get its instantaneous speed v,
third, you get its error, err=v0-v;
4. you give your power p= p0+Kp*err; (1)
in the above form (1), Kp is a unchangable number,
when instantaneous speed v is low, err>0, p>p0, you can get more power, the motor can run faster. when v is high, err<0, p<p0, you can ger less power, the motor can run slower. then, the motor can run with the speed almost v0.
in the above form (1), there is only one parameter Kp, it is the way P
the way is good.
If you want control motor finer, you can use the way PI. i say it in the following.
first, your aim is V0,
second, if you give power p0,you get its instantaneous speed v2,last instantaneous speed is v1;
third, you get its error, e2=v0-v2; last error is e1=v0-v1
4. you give your power p= p0+Kp*errcur+Ki(errcur+errlst); (2)
when you get n speed v1 v2 v3 ,..., vn,
you give your power p= p0+Kp*errcur+Ki*(e1+e2+e3+...+en); (3)
in the above form (3), Kp, Ki is unchangable number.
when instantaneous speed v is low, en>0, you can get more power with Kp*en, if last error en>0, you can get more more power with Ki*(e1+r2+...en),the motor can run faster. when v is high, err<0, you can ger less power, the motor can run slower. then, the motor can run with the speed almost v0.
in the above form (3), there is two parameters Kp and Ki, it is the way PI

you should understand the way P and PI, the two way is good, it can help you control your motor.
you dont have to use PID. if you can use PID, it is good.
i think you should understand the way P and PI at first.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top