Структуры в Arduino IDE

Тема в разделе "Arduino & Shields", создана пользователем Faberge, 26 июн 2015.

  1. Faberge

    Faberge Administrator Администратор

    В общем-то, только что столкнулся с такой интересной штукой:

    Объявляю вне всех функций структуру vector с переменными внутри. Инициализирую её значениями в setup() :
    Код (Text):
    struct vector
    {
      double x;
      double y;
      double z;
    };

    void setup()
    {
      vector velocity_vector;

      velocity_vector.x = 5.0;
      velocity_vector.y = 6.0;
      velocity_vector.z = 7.0;
    }

    void loop()
    {
      SerialUSB.println("Vector is now:");
      SerialUSB.print(velocity_vector.x);
      SerialUSB.println();
      SerialUSB.print(velocity_vector.y);
      SerialUSB.println();
      SerialUSB.print(velocity_vector.z);
      SerialUSB.println();
      toggleLED();
      delay(100);
      toggleLED();
      delay(900);
    }
     
    Компилятор выдает ошибку:
    Окей, перекидываю в main():
    Код (Text):
    struct vector
    {
      double x;
      double y;
      double z;
    };

    void setup()
    {

    }

    void loop()
    {
      vector velocity_vector;

      velocity_vector.x = 5.0;
      velocity_vector.y = 6.0;
      velocity_vector.z = 7.0;

      SerialUSB.println("Vector is now:");
      SerialUSB.print(velocity_vector.x);
      SerialUSB.println();
      SerialUSB.print(velocity_vector.y);
      SerialUSB.println();
      SerialUSB.print(velocity_vector.z);
      SerialUSB.println();
      toggleLED();
      delay(100);
      toggleLED();
      delay(900);
    }
     
    Ошибка исчезает и все еомпилируется успешно. Для меня это очень странно, так как я всегда считал, что в Arduino IDE функции setup() и main() являются всего лишь отражениями организации вида:

    Код (Text):
    int main()
    {
      // Code that runs only once
      while (1)
      {
        // Code that runs in a loop

      }
    }
    Что мне теперь думать, я в смятении?
     
  2. Unixon

    Unixon Оракул Модератор

    Вы объявили переменную в setup(), а пытаетесь воспользоваться ей в loop(), где ее не существует.
     
  3. Unixon

    Unixon Оракул Модератор

    Учите C++, Arduino IDE это просто редактор текста с кнопочками вызова компилятора и программатора.
     
  4. Faberge

    Faberge Administrator Администратор

    До этого же я и дошел с помощью компилятора. Просто странно как-то. Я хотел объявить и сразу же инициализировать.
     
  5. Faberge

    Faberge Administrator Администратор

    Я Си учу сейчас) Только Си, только хардкор!)
     
  6. geher

    geher Гуру

    Скорее так
    Код (Text):

    int main()
    {
      setup();
      while (1)
      {
        loop();
      }
    }
     
    Так что вопрос с областью видимости переменных в функциях setup и loop сохраняется, а чтобы было видимо в обеих функциях, приходится объявлять глобально.

    В данном конкретном случае, если необходимо, чтобы velocity_vector инициализировался только один раз, но не хочется выносить его в глобальные, можно сделать в начале loop такое объявление:
    Код (Text):
     
    static vector velocity_vector={5.0, 6.0, 7.0};
     
    static обеспечивает сохранение значения полей структуры между вызовами, а список в фигурных скобках обеспечивает первичную инициализацию.
     
    Faberge и Unixon нравится это.
  7. Faberge

    Faberge Administrator Администратор

    Да, такая компоновка проясняет момент с видимостью. Спасибо, воспользуюсь вашим советом.
     
  8. Megakoteyka

    Megakoteyka Оракул Модератор

    Если хотите хардкора, учите ассемблер :)
     
  9. Faberge

    Faberge Administrator Администратор

    Я так и думал, что мне кто-то это посоветует :)
    Но ассемблер для больших проектов-то не годится. А планы у меня, как водится, грандиозные)
     
  10. Unixon

    Unixon Оракул Модератор

    Тогда уж Brainfuck.
     
  11. geher

    geher Гуру

    При программировании на C/C++ тоже можно "снизойти" на уровень ниже, и не пользовать библиотеки Arduino IDE, а непосредственно работать с регистрами МК.
    Например, не
    digitalWrite(13, HIGH);
    а
    PORTB|=1<<5;
     
  12. Faberge

    Faberge Administrator Администратор

    Я вот, кстати, как раз так и делал в своем предыдущем проекте, когда контроллировал сервы через программный ШИМ. В этом даже есть какая-то своя эстетика. И сильно выигрываешь в быстродействии и размере программного кода.

    Только желательно избавиться от магических чисел в коде дефайнами.