CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

software USART buffer - slow

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
The_Todd



Joined: 11 Feb 2007
Posts: 5
Location: Santa Clara University

View user's profile Send private message

software USART buffer - slow
PostPosted: Fri Jul 27, 2007 9:11 pm     Reply with quote

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








PostPosted: Sat Jul 28, 2007 3:05 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jul 28, 2007 5:33 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jul 28, 2007 10:14 am     Reply with quote

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?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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