title: How to check for a gap between serial data
body: <p>I'm working on an interface that reads serial data from a single wire bus on a car (BMW IBUS). I'm using an Microchip MCP2025 LIN bus transceiver chip to convert the single line bus to regular Rx/Tx to feed into the hardware serial pins (0 &amp; 1) of an Arduino (Nano V3).</p>
  
  <p>BMW's IBUS protocol uses Serial 8E1 at 9600 baud. Messages are variable length (between 5 and 37 bytes) Bus messages are separated by a pause of around 11 milliseconds (considerably longer than the bus high time when receiving) and I need to use this gap to detect the end of one message and the beginning of the next.</p>
  
  <p>1st byte is the Source ID, 
   2nd byte is length of the packet excluding the first two bytes (source &amp; length), 
   3rd byte is the destination ID, 
   4th byte onwards is the actual data, 
   Last byte is the checksum </p>
  
  <p>Checksum is generated by XOR of the entire packet excluding the checksum itself.</p>
  
  <p>My problem is that I don't know how to measure the bus idle time between messages. I think I can use <code>bitRead(PIND,0)</code> to tell when the bus is idle (high), but I'm not sure how to time this and go and process the message after a suitable time has passed.</p>
  
  <p>I'm currently using the following code to read messages from the IBUS. It works for the most part, but gets out of sync when connected to the car. It's doesn't really know when messages have finished, but relies on the second byte of each message (the length byte) to know how many bytes to read in. As long as it reads the length byte correctly, it's fine, but if it gets out of sync, and the length byte is wrong, it reads in the wrong number of bytes and eventually overruns the array and the Arduino resets. If I can detect the idle time between messages I will know for sure that I have a complete message. </p>
  
  <pre><code>    void ReadIBUS()
  { 
    boolean inSTATE = 0;
    byte IBUSbyte[40];
  
    while(Serial.available() &gt; 0 &amp;&amp; inSTATE == 0 )
    { 
      IBUSbyte[0] = Serial.read();  //read source byte
      while (inSTATE == 0)
      {
        if(Serial.available() &gt; 0)
        {
          IBUSbyte[1] = Serial.read();  //read length byte
          inSTATE = 1;       
        }
  
        delay(10);
      }
  
      inSTATE == 0;
      LENGTH = IBUSbyte[1];
      int i = 2;
      while(i &lt;= LENGTH + 1)
      {
        if(Serial.available() &gt; 0)
        {
          IBUSbyte[i] = Serial.read(); 
          i++;
          delay(10);
        }
      }
  
      checksumBYTE = 0;
      byteSTATE = 0;
      for (int i = 0; i &lt; LENGTH + 1; i++){
        checksumBYTE ^= IBUSbyte[i];
      } 
      if (IBUSbyte[LENGTH + 1] == checksumBYTE){
        for(int i = 0; i &lt;= LENGTH + 1; i++)
        {
          mySerial.print(IBUSbyte[i], HEX);
          mySerial.print(" ");
        }
        mySerial.println();
  
      }
      else {
        debug();
        inSTATE = 0;
        byteSTATE = 0;
      }
    } 
  
  }
  </code></pre>