|
|
View previous topic :: View next topic |
Author |
Message |
saw
Joined: 21 May 2011 Posts: 3
|
parking robot |
Posted: Sat May 21, 2011 7:22 am |
|
|
Hello, I'm working on a parallel parking robot using the pic18f252. I'm having a problem.
The car (or tank) gets confused too much. For example, the first time I try it, it works fine. The second time it starts rotating when it shouldn't or even moving backward when it should move forward. It's like the program starts from the middle. I believe that the problem isn't from my code. I don't have alot of experience with microcontrollers. Can someone help me???
thnx! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Sat May 21, 2011 8:42 am |
|
|
We'd have to see your code as well as PIC type, compiler version.
Just a minimal program that demonstates the problem.
It could be your startup code, fuses(config),floating pins,ISRs,etc. IF all the hardware is properly built.
The more info you supply the easier it'll be to diagnose. |
|
|
saw
Joined: 21 May 2011 Posts: 3
|
|
Posted: Sun May 22, 2011 12:16 pm |
|
|
That's my program:
Code: |
#include <APR.h>
///////////////////////////////////////////////////////////////////////////////
//Macros:
#define M1Left() {output_high(PIN_B0); output_low(PIN_B1);}
#define M1Right() {output_low(PIN_B0); output_high(PIN_B1);}
#define M1Stop() {output_low(PIN_B0); output_low(PIN_B1);}
#define M2Left() {output_high(PIN_B2); output_low(PIN_B3);}
#define M2Right() {output_low(PIN_B2); output_high(PIN_B3);}
#define M2Stop() {output_low(PIN_B2); output_low(PIN_B3);}
#define M3Left() {output_high(PIN_B4); output_low(PIN_B5);}
#define M3Right() {output_low(PIN_B4); output_high(PIN_B5);}
#define M3Stop() {output_low(PIN_B4); output_low(PIN_B5);}
#define M4Left() {output_high(PIN_B6); output_low(PIN_B7);}
#define M4Right() {output_low(PIN_B6); output_high(PIN_B7);}
#define M4Stop() {output_low(PIN_B6); output_low(PIN_B7);}
///////////////////////////////////////////////////////////////////////////////
float GetVoltage(int8 Channel)
{
float ret;
set_adc_channel(Channel); //select ADC channel
delay_us(10); //wait for 10 microseconds
ret = ((float)read_adc()*5.0)/255.0; //read ADC and calculate voltage
return ret;
}
///////////////////////////////////////////////////////////////////////////////
float GetDistance(int8 Channel)
{
float ret;
float y1,y2;
float x;
int i;
ret=GetVoltage(Channel);
if(ret<=3.05 && ret>=0.8)
{
y1=ret;
x=(-y1+71./19)/(2/9.5);
}
else
{
y2=ret;
x=((1.115-y2)/19.)*850.;
}
return x;
}
///////////////////////////////////////////////////////////////////////////////
void InitPorts(void)
{
set_tris_a(0x0F);
set_tris_b(0x00);
output_b(0x00);
}
///////////////////////////////////////////////////////////////////////////////
void main()
{
float channel_0;
int i;
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_DIV_2);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
InitPorts();
printf ("\fHello World\n\r");/* "f" to erase everthing on the screen */
channel_0=GetDistance(2);
while(channel_0<=10)
{
printf("Ch0 dist = %f\n\r", channel_0);
M1Right();
M2Right();
M3Right();
M4Right();
channel_0=GetDistance(2);
}
channel_0=GetDistance(2);
while(channel_0>8)
{
M1Right();
M2Right();
M3Right();
M4Right();
channel_0=GetDistance(2);
}
channel_0=GetDistance(2);
M1Stop();
M2Stop();
M3Stop();
M4Stop();
delay_ms(1000);
M1Left();
M2Left();
M3Left();
M4Left();
delay_ms(500);
M1Stop();
M2Stop();
M3Stop();
M4Stop();
delay_ms(1000);
channel_0=GetDistance(2);
while(channel_0>8)
{
M1Right();
M3Right();
M2Left();
M4Left();
channel_0=GetDistance(2);
}
M1Stop();
M2Stop();
M3Stop();
M4Stop();
delay_ms(500);
channel_0=GetDistance(0);
while(channel_0>5)
{
M1Left();
M2Left();
M3Left();
M4Left();
channel_0=GetDistance(0);
}
M1Stop();
M2Stop();
M3Stop();
M4Stop();
delay_ms(500);
channel_0=GetDistance(2);
while(channel_0>=5)
{
M2Right();
M4Right();
M1Left();
M3Left();
channel_0=GetDistance(2);
}
M1Stop();
M2Stop();
M3Stop();
M4Stop();
WHILE(1);
} |
|
|
|
saw
Joined: 21 May 2011 Posts: 3
|
|
Posted: Wed May 25, 2011 3:41 am |
|
|
Help??plz |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed May 25, 2011 12:20 pm |
|
|
Post the contents of this file:
Also post your compiler version.
When I first looked at your code, I said to myself: "This distance
routine is incredibly complicated. Does it really have to be like this ?
Why does it have discontinuities ? Has this all been tested ?".
I'm sure that other people had the same idea, and that's why you didn't
get any replies.
So the first thing I did was to test my hunch that your GetDistance()
routine is flaky. (But, I could be wrong. Maybe it needs to be this way).
The test program below keeps your routines intact, except that I
substituted my own routine, called "my_read_adc()" for the real one. The
new routine just returns a global integer value which I set in a for() loop.
This allows me to step through all the possible ADC return values for
an 8-bit ADC (0 to 255). So now I can exercise your routines and see
what I get. I compiled the program with CCS vs. 4.121, and ran it
in MPLAB simulator with the UART output sent to the Output Window.
To save space, I just had it step through the ADC values in steps of 10.
The result is below, and it's weird. You get negative values, and it jumps
from 3.7 to -90.4. Is that what you want ? I would guess not, and my
advice would be to re-write the GetDistance() routine and make it very
simple. Also, you might consider not calculating voltage, and just use
the raw ADC value of 0-255. That removes one additional source of
error and complexity from your program. The more simple things are,
the more easy it is to check them, and get them right.
Code: |
ADC distance
0: 49.8
10: 41.1
20: 32.3
30: 23.5
40: 14.7
50: 13.0
60: 12.1
70: 11.2
80: 10.2
90: 9.3
100: 8.4
110: 7.5
120: 6.5
130: 5.6
140: 4.7
150: 3.7
160: -90.4
170: -99.2
180: -108.0
190: -116.7
200: -125.5
210: -134.3
220: -143.1
230: -151.8
240: -160.6
250: -169.4
|
Here is the test program:
Code: |
#include <18F252.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
int8 adc_result;
int8 my_read_adc(void)
{
return(adc_result);
}
//----------------------------------------
float GetVoltage(int8 Channel)
{
float ret;
set_adc_channel(Channel); //select ADC channel
delay_us(10); //wait for 10 microseconds
ret = ((float)my_read_adc()*5.0)/255.0;
return ret;
}
//-------------------------------------
float GetDistance(int8 Channel)
{
float ret;
float y1,y2;
float x;
int i;
ret=GetVoltage(Channel);
if(ret<=3.05 && ret>=0.8)
{
y1=ret;
x=(-y1+71./19)/(2/9.5);
}
else
{
y2=ret;
x=((1.115-y2)/19.)*850.;
}
return x;
}
//======================================
void main(void)
{
int16 i;
float distance;
// Step through several ADC values, and see what the
// GetDistance() function returns.
for(i = 0; i < 256; i+=10)
{
adc_result = i; // Fake-up the read_adc() function
distance = GetDistance(0);
printf("%3lu: %6.1f \r", i, distance);
}
while(1);
} |
|
|
|
|
|
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
|