В примерах IDE можно обнаружить нечто, с названием в заголовке. Выложу код из примера для удобства: Код (C++): /* Serial Event example When new serial data arrives, this sketch adds it to a String. When a newline is received, the loop prints the string and clears it. A good test for this is to try it with a GPS receiver that sends out NMEA 0183 sentences. Created 9 May 2011 by Tom Igoe This example code is in the public domain. http://www.arduino.cc/en/Tutorial/SerialEvent */ String inputString = ""; // a string to hold incoming data boolean 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; } } } Заглядывал и сюда: http://www.arduino.cc/en/Tutorial/SerialEvent Все работает замечательно. И все таки остается вопрос: а что же вызывает функцию serialEvent()? В loop() ничто на нее не ссылается. Как же так?
Есть пользователи Arduino IDE, которые думают, что в этой среде используется какой-то специальный язык. На самом деле ни какого специального языка нет, а есть функционал, который берёт скетч в виде файла *.ino и генерирует набор *.h/*.c/*.cpp файлов. Т.е. обычный набор файлов для компилятора C/C++, а точнее для компилятора из семейства GCC -- avr-gcc. Соответственно в этом наборе файлов обязательна должна присутствовать функция 'void main()' -- точка входа в программу. И она конечно же есть и имеет следующий вид: Код (C++): int main(void) { init(); initVariant(); #if defined(USBCON) USBDevice.attach(); #endif setup(); for (;;) { loop(); if (serialEventRun) serialEventRun(); } return 0; } А так же есть декларация функции 'serialEvent()' и код функции 'serialEventRun()': Код (C++): #if defined(HAVE_HWSERIAL0) void serialEvent() __attribute__((weak)); bool Serial0_available() __attribute__((weak)); #endif ........... void serialEventRun(void) { #if defined(HAVE_HWSERIAL0) if (Serial0_available && serialEvent && Serial0_available()) serialEvent(); #endif ......... } Атрибут '__attribute__((weak))' в декларации функции 'serialEvent()' означает, что реализации этой функции может не быть, тогда и вызывать ничего не надо. Я думаю теперь понятно кто вызывает функции 'setup()', 'loop()' и 'serialEvent()'.
И ещё одно замечание: если из функции 'loop()' не будет возврата (например, будет крутиться бесконечный цикл), то ни какого вызова функции 'serialEvent()' не будет. Но это и так видно из приведённого выше кода.
A serialEvent() должен работать с 3-им сериалом? Например так: Код (C++): void serialEvent() { if (Serial3.available()) { inputString = Serial3.readStringUntil('\n'); stringComplete = true; } }