|
|
View previous topic :: View next topic |
Author |
Message |
The_Todd
Joined: 11 Feb 2007 Posts: 5 Location: Santa Clara University
|
software USART buffer - slow |
Posted: Fri Jul 27, 2007 9:11 pm |
|
|
I have a couple software "bit bang" ports to read digital compass / motor controller etc... and they are seeming a bit slow when I time them on the pic 18f4520.
The compass outputs 21 bytes at 9600 baud, or 19200, i've tried both, yet it takes about 50ms for all of them, which is either 2 or 4x what it should. I'm thinking maybe i'm buffering wrong? I'm getting the data fine (thanks ttelmah), heres what my buffer looks like:
Code: |
#use rs232(baud=9600,parity=N,xmit=PIN_B1,rcv=PIN_B0,bits=8,stream=COMPSTREAM,ERRORS,DISABLE_INTS)
//------OPTIONS----
#define COMP_TIMEOUT 9000 //Time to wait for incoming rs232 characters
int1 comp_timeout_error = 0; //raised when timeout waiting for character
//-----BUFFER------
int compstr[50] = ""; //holds incoming compass data
/**
* This function will wait for a incoming character a certain amount of time
* until it times out and raises the timeout_error flag
**/
char comp_timed_getc() {
int32 timeout=0;
comp_timeout_error=FALSE;
while(!kbhit(COMPSTREAM)&&(timeout<COMP_TIMEOUT)) // wait for character
{
delay_us(1);
timeout++;
}
if(kbhit(COMPSTREAM))
return(fgetc(COMPSTREAM));
else {
comp_timeout_error=TRUE;
return(0);
}
}
/**
* This function updates the global COMPASS variable
* by polling the compass for data
**/
void update_compass()
{
//Variable definitions
int i=0; //used for outside looping
int length=0; //length of bytes recieved
int expect=0; //expected number of bytes to be recieved
while(!comp_timeout_error)
{
compstr[i] = comp_timed_getc(); //fills compstr with data
//only accept the number of bytes specified by the second bit
if(i==1)
{
expect = compstr[i]; //byte count
}
i++; //increment i, which now equals number of bytes recieved
//if number of bytes recieved equals expected, break loop
if(expect == i && i != 0)
{
//we've recieved all bytes we're expecting
//increment i to make length definition below match
i++;
break;
}
}
}
|
the second byte the compass outputs its the byte count, and everything is working, it cuts off instead of timing out, but its still slow, I'm using other nearly identical buffers, and my pic is being sluggish from serial.
Any thoughts?
Thanks so much.
Todd |
|
|
Guest
|
|
Posted: Sat Jul 28, 2007 3:05 am |
|
|
Try changing your buffer size to 64, or 32.
Haven't looked at the code really, but this is a classic 'caveat'. If you use a 'non binary' buffer size (anything but 2,4,8,16 etc.), then the '%' operation in the handler, has to perform a division and a subtraction, instead of a simple binary and. Takes about 50+ instructions....
Best Wishes |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Jul 28, 2007 5:33 am |
|
|
21 bytes * 10 = 210 bits for transmission.
At 19200 baud this takes almost 11 ms.
Is the data you receive correct? If yes, than it is very unlikely for the problem to be in the PIC.
Thing is, do you know for sure the compass is transmitting the data without time in between the bytes? My guess is the compass to be a relative simple and slow device, it would take the compass time to fetch each new byte and prepare it for transmission. RS232 specifies the minimum time in between bytes, but the maximum time is not specifed (can be endless).
Do you have a brand and type number for the compass you are using? |
|
|
The_Todd
Joined: 11 Feb 2007 Posts: 5 Location: Santa Clara University
|
|
Posted: Sat Jul 28, 2007 10:14 am |
|
|
Thanks guest, I will try changing to 32 bits monday and see how things go!
ckielstra
The compass is a PNI TCM3 high performance compass: http://www.pnicorp.com/productDetail?nodeId=cTCM3
The data recieved "most" of the time is correct, I would say 1 out of 20 transmissions get corrupted somehow, but the crc16 check / byte count always catches the bad data. I will try clocking the delay in between bytes and see if thats the case.
--edit: Also I was thinking that I should try changing the delay_us(1) while waiting for bits to delay_us(5) which is 10x the bit rate @ 19200, which may help as well? |
|
|
|
|
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
|