|
|
View previous topic :: View next topic |
Author |
Message |
john42
Joined: 11 May 2010 Posts: 6
|
ball and balancer c code:)) |
Posted: Thu May 13, 2010 3:21 pm |
|
|
Guys I wrote the code but there is a problem. Anybody help me the solve this problem? Sensor did just read between 1630 and 1620 hence did not read other distance so servo motor did not move. And sensor just read center of the beam. What can I do? When I increase the ustlimit and decrease the altlimit, sensor is read but servo motor not balance the ball, just go forward and back.
Code: |
#include<16F877A.h>
#fuses HS, NOWDT, NOPROTECT, NOLVP
#use delay (clock=20000000)
#use rs232(baud=19200,xmit=PIN_C6,rcv=PIN_C7)
#include <stdlib.h>
#include <input.C>
#use fast_io(B)
#use fast_io(D)
#org 0x1F00,0x1FFF{}
#opt 9
void main(){
//define your variables here;
long Kp,Kd,duty,ustlimit,altlimit,i;
long time;
long time1;
long timeold;
Kp=0.01;
Kd=10;
ustlimit=1630;
altlimit=1620; // these are the limit for the center which the sensor when the read this do nothing in order to stop ball.
set_tris_d(0b00000001);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
printf("Program Starts!!!\n\r");
while(TRUE){
delay_ms(1);
//////////*setting the US sensor*////////
set_tris_b(0b00000000);
output_high(PIN_B6);
delay_us(5);
output_low(PIN_B6);
set_tris_b(0b01000000);
/////////////////////////////////////////
////////////*calculating the duration////
delay_us(500);
while (!input(PIN_B6)){ };
set_timer1(0);
while (input(PIN_B6)){ };
time1 = get_timer1();
time=time1/4.3; // =1625 // when the sensor read some values such as 6000/4.3 = any result so this resault will be used in if
delay_us(5);
timeold=time;
printf("%lu\n\r",time);
/////////////////////////////////////////////////
if (time<ustlimit && time>altlimit ){
duty=time;
}
else if (time>ustlimit){
duty=Kp*(ustlimit-time) + Kd*(timeold-time);
}
else if (time<altlimit){
duty=Kp*(time-altlimit) + Kd*(timeold-time);
}
printf("-----duty=%lu\n\r",duty);
if (duty<1500) duty=1500;
if (duty>1700) duty=1700;
printf("-----duty=%lu\n\r",duty);
for(i=0;i<10;i++)
{
output_high(PIN_D7);
delay_us(duty);
output_d(0);
delay_ms(20);
}
//delay_ms(100);
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 13, 2010 4:19 pm |
|
|
Quote: | long Kp,Kd,duty,ustlimit,altlimit,i;
long time;
long time1;
long timeold;
Kp=0.01;
Kd=10; |
A 'long' is an 16-bit unsigned integer in CCS, and it can't hold a floating
point value such as 0.01 |
|
|
john42
Joined: 11 May 2010 Posts: 6
|
|
Posted: Fri May 14, 2010 5:22 am |
|
|
did you mean that i have to convert them to float???? |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Fri May 14, 2010 6:13 am |
|
|
Either use floats, or scale everything up by 100 so Kp = 1, Kd = 1000, etc. Scaling requires more programmer thought, but less CPU power. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|