Serial Event

Тема в разделе "Arduino & Shields", создана пользователем ИгорьК, 14 сен 2016.

  1. ИгорьК

    ИгорьК Гуру

    В примерах IDE можно обнаружить нечто, с названием в заголовке.
    event.jpg

    Выложу код из примера для удобства:
    Код (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() ничто на нее не ссылается. Как же так?
     
    issaom нравится это.
  2. Developer-RU

    Developer-RU Гик

  3. AlexU

    AlexU Гуру

    Есть пользователи 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()'.
     
    Andrey12, issaom и ИгорьК нравится это.
  4. AlexU

    AlexU Гуру

    И ещё одно замечание: если из функции 'loop()' не будет возврата (например, будет крутиться бесконечный цикл), то ни какого вызова функции 'serialEvent()' не будет. Но это и так видно из приведённого выше кода.
     
    Andrey12, issaom и ИгорьК нравится это.
  5. A serialEvent() должен работать с 3-им сериалом? Например так:
    Код (C++):

    void serialEvent() {
      if (Serial3.available()) {
        inputString = Serial3.readStringUntil('\n');
        stringComplete = true;
      }
    }
     
  6. DIYMan

    DIYMan Guest

    А доку почитать, раз исходники лень посмотреть?

    https://www.arduino.cc/en/Reference/SerialEvent

     
    Станислав нравится это.
  7. Ой спасибо! Я только туториал поглядел, а там нема.
     
  8. Airbus

    Airbus Радиохулиган Модератор

    Это типа прерывание по приходу байта в USART?
     
  9. DetSimen

    DetSimen Guest

    Формально - нет,это событие.
     
    Последнее редактирование модератором: 23 июл 2018
  10. Mitrandir

    Mitrandir Гуру

    Не совсем прерывание, оно не прерывает исполнение функции луп, а вызывается между циклами
     
    Andrey12 и Airbus нравится это.