serial reading

How would I make code that waits till a certain amount of bytes have passed (serial) and then read 2 or more bytes and store these values till the next reading?

It's for a DMX512 signal. (for how it works : http://www.arduino.cc/playground/DMX/Protokoll )

250 Kbaud btw

It is connected to the tx/rx pins.

For example, I want to read byte 15,16,17 and 18.

Any ideas?

The serial.available() function will return the number of bytes in the recieve buffer waiting to be read.

You could use that in a loop an wait until the required amount of bytes are ready, then read the bytes into an array and pick the ones you need.

You would probably havre to do some housekeeping on the number of bytes read to make sure that you don't get out of sequence.

The best solution is to use a header or start byte as a reference point. i think there is a "0" byte send first in the DMX protocol, the always look for this byte so you know where in the sequenceyou are. This will help yo make sure that you know where in the sequence you are, even if the input buffer overflows.

Someone with a better knowledge of the DMX protocol might give (sligthly :-) ) better advise

Thanks for the reply but i have no idea how i would do that, waiting till certain bytes are bufferd, how?

I have found code that does it, but it is not arduino code, it is C.

Anyone that can translate or adapt that?

/**** A P P L I C A T I O N   N O T E   ************************************
*
* Title                  : DMX512 reception library
* Version            : v1.2
* Last updated      : 21.04.07
* Target            : Transceiver Rev.3.01 [ATmega8515]
* Clock                  : 8MHz, 16MHz
*
* written by hendrik hoelscher, www.hoelscher-hi.de
***************************************************************************
 This program is free software; you can redistribute it and/or 
 modify it under the terms of the GNU General Public License 
 as published by the Free Software Foundation; either version2 of 
 the License, or (at your option) any later version. 

 This program is distributed in the hope that it will be useful, 
 but WITHOUT ANY WARRANTY; without even the implied warranty of 
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 General Public License for more details. 

 If you have no copy of the GNU General Public License, write to the 
 Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 

 For other license models, please contact the author.

;***************************************************************************/

#include "lib_dmx_in.h"

// ********************* local definitions *********************

enum {IDLE, BREAK, STARTB, STARTADR};                  //DMX states

             uint8_t        gDmxState;
             uint8_t       *gDmxPnt;
             uint16_t       DmxCount;


// *************** DMX Reception Initialisation ****************
void init_DMX(void)
{
#ifdef USE_DIP
DDRC= 0;                                                            //set up DIPs
PORTC= 0xFF;
DDRE &= ~((1<<2)|(1<<1));
PORTE |= (1<<2)|(1<<1);
#endif

DDRD |= (1<<2);
PORTD &= ~(1<<2);                                                //enable reception
UBRRH  = 0;
UBRRL  = ((F_OSC/4000)-1);                                    //250kbaud, 8N2
UCSRC |= (1<<URSEL)|(3<<UCSZ0)|(1<<USBS);
UCSRB |= (1<<RXEN)|(1<<RXCIE);
gDmxState= IDLE;

uint8_t i;
for (i=0; i<DMX_CHANNELS; i++)
      {
      DmxField[i]= 0;
      }

}


// ************* get DMX start address **************
void get_dips(void)
{
#ifdef USE_DIP
uint16_t Temp= (255-PINC);                                    //invert DIP state
if (!(PINE &(1<<2)))
      {
      Temp= Temp +256;                                          //9th bit
      }
if (Temp != 0)
      {
      DmxAddress= Temp;
      if (!(UCSRB &(1<<RXCIE)))                              //if receiver was disabled -> enable and wait for break
            {
            gDmxState= IDLE;
            UCSRB |= (1<<RXCIE);
            }
      }
else
      {
      UCSRB &= ~(1<<RXCIE);                                    //disable Receiver if start address = 0
      for (Temp=0; Temp<DMX_CHANNELS; Temp++)
            {
            DmxField[Temp]= 0;
            }
      }
#endif 
}


// *************** DMX Reception ISR ****************
ISR (UART_RX_vect)
{
uint8_t USARTstate= UCSRA;                                    //get state
uint8_t DmxByte= UDR;                                          //get data
uint8_t DmxState= gDmxState;                              //just get once from SRAM!!!
 
if (USARTstate &(1<<FE))                                    //check for break
      {
      UCSRA &= ~(1<<FE);                                          //reset flag
      DmxCount= DmxAddress;                                    //reset frame counter
      gDmxState= BREAK;
      }

else if (DmxState == BREAK)
      {
      if (DmxByte == 0) 
            {
            gDmxState= STARTB;                                    //normal start code detected
            gDmxPnt= ((uint8_t*)DmxField +1);
            }
      else gDmxState= IDLE;
      }
      
else if (DmxState == STARTB)
      {
      if (--DmxCount == 0)                                    //start address reached?
            {
            gDmxState= STARTADR;
            DmxField[0]= DmxByte;
            }
      }

else if (DmxState == STARTADR)
      {
      uint8_t *DmxPnt;
      DmxPnt= gDmxPnt;
      *DmxPnt= DmxByte;
      if (++DmxPnt >= (DmxField +DMX_CHANNELS))       //all ch received?
            {
            gDmxState= IDLE;
            }
      else gDmxPnt= DmxPnt;
      }                                          
}

lib_dmx_in.h

#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>

#define USE_DIP                                                //use DIPs?
#define DMX_CHANNELS    (2)                              //use at least 2ch
#define F_OSC                  (8000)                          //oscillator freq. in kHz (typical 8MHz or 16MHz)

volatile uint8_t       DmxField[DMX_CHANNELS]; //array of DMX vals (raw)
volatile uint16_t       DmxAddress;                  //start address

extern void init_DMX(void);
extern void get_dips(void);