Как написал parovoZZ, можно использовать UART прерывания. В этом случае управление UART придется переделать с помощью регистров.
#include <avr/interrupt.h> //библиотека прерываний
char c; //байт в который мы считываем данные из uart
void USART_Init(int baudrate ) //Функция инициализации USART
{
/* Set baud rate */
UBRR0H = baudrate>>8;
UBRR0L = baudrate;
//Разрешение на прием и на передачу через USART, прерывания по поступлению и по опустошению
UCSR0B = (1<<RXCIE0)|(1<<TXCIE0)|(1<<RXEN0)|(1<<TXEN0);
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); //размер слова 8 разрядов
sei();
} // USART_Init
void setup() {
pinMode(15, OUTPUT);
USART_Init(103);// число 103 соответствует baudrate 9600 при 16MHz. смотреть datasheet нa ATMega 2560
}
void USART_Transmit( unsigned char data )//Функция отправки данных
{
/* Wait for empty transmit buffer */
while ( !( UCSR0A & (1<<UDRE0)) );
/* Put data into buffer, sends the data */
UDR0 = data;
}
unsigned char USART_Receive( void )//Функция приема данных
{
/* Wait for data to be received */
while ( !(UCSR0A & (1<<RXC0)) );
/* Get and return received data from buffer */
return UDR0;
}
//Обрабатываем прерывание по поступлению байта
ISR(USART0_RX_vect)
{
с = UDR0;//принимаем байт из uart
if(c == '1'){
digitalWrite(15, HIGH);
}else{
digitalWrite(15, LOW);
}
}
void loop() {
}
В данном примере, когда приходят данные вызывается функция ISR(USART0_RX_vect). Не забывайте, что прерывания должны выполняться быстро и не иметь в теле долгого кода.
Есть другой способ. Функция serialEvent(). Она вызывается каждый раз, как заканчивается очередной цикл loop(), если данные пришли.
В ней также нельзя использовать delay(). Вот пример её использования:
String inputString = ""; // a String to hold incoming data
bool stringComplete = false; // whether the string is complete
void setup() {
// initialize serial:
Serial.begin(9600);
// reserve 200 bytes for the inputString:
inputString.reserve(200);
}
void loop() {
// print the string when a newline arrives:
if (stringComplete) {
Serial.println(inputString);
// clear the string:
inputString = "";
stringComplete = false;
}
}
/*
SerialEvent occurs whenever a new data comes in the hardware serial RX. This
routine is run between each time loop() runs, so using delay inside loop can
delay response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag so the main loop can
// do something about it:
if (inChar == '\n') {
stringComplete = true;
}
}
}
Также можно использовать функцию Serial.available(), которая говорит, есть ли данные в буфере или нет. Можно её использовать перед самыми ресурсозатратными задачами контроллера в loop().