SerialEvent() er ikke en interruptrutine. Den leses for hver runde i loop(). Det betyr at det er vanskelig å lese en datastrøm fra en GPS-enhet uten at noe av data går tapt dersom det er tidskrevende lesing av andre sensorer i programskissen. Under vises en iterruptrutine for UNO som kan brukes til å lese et tegn fra en GPS som bruker Serial-porten, legge den i en buffer og gi en statusvariabel til loop()-rutinen når et linjeskift er påvist. loop()-rutinen kan da behandle GPS-strengen slik som man ønsker mens interruptrutinen fortsetter å samle data uavhenig av tid som brukes til å lese andre sensorer.
Her er de elementene som må legges til i programskissen for å lese tegn fra GPS-enheten med Serial-porten.:
/* UART SERIAL DEFINES */
#define BAUD 4800
#define MYUBRR F_CPU/16/BAUD-1
String gpsbuffer="",buf="",buf1="";
bool gps_ferdig;
void setup()
{
buf1.reserve(100);
gpsbuffer.reserve(100);
USART_Init(MYUBRR);
}
void loop()
{
if (gps_ferdig)
{
RF.println(gpsbuffer); // I dette eksemplet sendes tekststrengen til en RF-telemtrienhet ved hjelp
// av AltiSerial eller SoftSerial-biblioteket
gps_ferdig=false;
}
else
{
// behandle andre sensorer
}
}
// SETUP UART - som kopieres inn i programskissen
void USART_Init( unsigned int ubrr)
{
//Set baud rate
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;
//Enable receiver and transmitter
// UCSR0B = (1<<RXEN0)|(1<<TXEN0);
UCSR0B = (1<<RXCIE0)|(1<<RXEN0);
RF.println(UCSR0B,HEX);
// Set frame format: 8data, 2stop bit
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
ISR(USART_RX_vect)
{
// Called when data received from USART
// Read UDR register to reset flag
char data = UDR0;
// RF.print(data);
// RF.println(buf1);
if ((int(data)!=10) && (int(data)!=13))
buf1 +=data;
else if (int(data)==13)
{
if (buf1.substring(0,6)=="$GPRMC")
{
gpsbuffer=buf1;
gps_ferdig=true;
}
buf1="";
}
}