title: PIC Interrupt driven UART with circular buffer at high baud rate
body: <p>I am trying to read from a sensor with PIC 18f4550 at baud rate=38400. With a FIFO Circular buffer, I am able to store data from the sensor to an array. </p>
  
  <p>The sensor will respond to a request command and return a measurement of 15 bytes (<strong>the same as the circular buffer I created</strong>). I have to grab all <strong>15 bytes</strong> and put \r\n at the end to separate each measurement since there is no deliminator.</p>
  
  <p>So I used two pointers, <strong>inputpointer</strong> and <strong>outputpointer</strong> to store bytes and transmit byte out. Because 18f4550 only has one hard UART, I use it to read data and send commands to sensor and at the same time use a software UART to output to a laptop via RS232.</p>
  
  <p>I request a new measurement when the buffer is read and sent to serial port.</p>
  
  <p>It works well but I just want to know if there is a better way to avoid FIFO overrun when the head pointer overruns tail pointer, ie when there is a lot of data getting buffered but they cannot get output in time. </p>
  
  <p>Here is the code:  16MHZ  PIC 18f4550  mikroC compiler</p>
  
  <pre><code>char dataRx[15];
  char unsigned inputpointer=0;
  char unsigned outputpointer=0;
          // initialize pointers and buffer.
  void main() {
        ADCON1=0x0F;  //turn analog off
  
        UART1_Init(115200);  //initialize hardware UART @baudrate=115200, the same setting for the sensor
        Soft_UART_Init(&amp;PORTD,7,6,38400,0); //Initialize soft UART to commnuicate with a laptop
        Delay_ms(100); //let them stablize
  
  
  
        PIE1.RCIE = 1;                //enable interrupt source
        INTCON.PEIE = 1;
        INTCON.GIE = 1;
  
  
        UART1_Write(0x00);            //request a measurement.
        UART1_Write(0xE1);            //each request is 2 bytes
  
        while(1){
  
          Soft_UART_Write(dataRx[outputpointer]);  //output one byte from the buffer to laptop
          outputpointer++;                        //increment output pointer
          if(outputpointer==0x0F)                 //reset pointer if it's at the end of the array
          {
              outputpointer=0x00;
              Soft_UART_Write(0x0D);              //if it's at the end, that means the buffer is filled with exactly one measurement and it has been output to the laptop. So I can request another measurement.
              Soft_UART_Write(0x0A);              //add \r\n
              UART1_Write(0x00);                  //request another measurement
              UART1_Write(0xE1);
          }
  
  
  
  }
  void interrupt(void){ //interrupt routine when a byte arrives
        dataRx[inputpointer]=UART1_Read();            //put a byte to a buffer
        inputpointer++;
        if (inputpointer==0x0F){inputpointer=0;}      //reset pointer.
  </code></pre>
  
  <p>}</p>