Программирование

Тема в разделе "Arduino & Shields", создана пользователем Михаил_робототехник, 9 ноя 2015.

  1. AlexU

    AlexU Гуру

    Работают.
    Можно -- теми же способами, что в Асме и С.

    Вы наверно не очень хорошо понимаете суть работы среды "Arduino IDE":
    все, что Вы пишете в файлах с расширением *.ino в редакторе, среда Arduino IDE преобразовывает в файлы *.cpp (т.е. обычные С++ файлы), которые потом компилируются С-шным компилятором 'avr-gcc' (компилятор из семейства GCC -- GNU Compiler Collection). На выходе компилятора создается файл с расширением *.elf (Executable Linux Format), на основе которого программа 'avr-objcopy' создает файл с расширением *.hex (Intell'овский HEX формат). И уже этот *.hex файл заливается в Arduino программой 'avrdude'. Только весь этот процесс среда Arduino IDE скрывает от Вас.

    Все служебные пргораммы участвующие в процессе можно найти в подкаталоге "hardware/tools/avr/bin/".
     
    Airbus и Alex19 нравится это.
  2. Alex19

    Alex19 Гуру

    Вы можете просто переопределить метод main, вот пример, loop в нем не когда не запустится. Просто киньте данный код в Arduino IDE.
    Код (C++):
    #include "Arduino.h"

    void setup()
    {
      Serial.begin(115200);
      Serial.println("0");
    }

    void loop()
    {
      Serial.println("1");
    }

    int main(void)
    {
        init();

        #if defined(USBCON)
            USBDevice.attach();
        #endif
     
        setup();
     
        //for (;;)
        //{
            //loop();
            //if (serialEventRun) serialEventRun();
        //}
         
        return 0;
    }
     
    Airbus нравится это.
  3. Airbus

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

    Хех!Прикольно!Спасибо.Попробую.Но писать на этом тарабарском языке не люблю.Потому как и правда не понимаю суть работы среды Ардуино. Для меня на асме проще пустой цикл и прерывания. Да и не гоняет там по кругу если специально не сделать этого а в случае чего можно загнать в "тупик" и зациклить. На Сях тоже вроде этого. Здесь как я понял все наши телодвижения (void loop) это вложенные операторы внутри цикла for ( ; ; ) так? А вот если писать на "чистом" Си скетч откомпилируется? Пишу в Студии (Асм) и Кодвижн (си) На Ардуино подсел из-за множества шилдов и удобства сопряжения "железа" Думал и с софтом так же просто((((((((((Вообщем век живи век учись! Спасибо всем!
     
    Последнее редактирование: 10 ноя 2015
  4. AlexU

    AlexU Гуру

    Вопрос можно двояко трактовать, но все же попробую -- пишу "на чистом С/С++" в среде Eclipse скетчи (или прошивки) с использованием Arduino'вских библиотек, т.е. среду Arduino IDE установил только для того, чтобы использовать каталоги с кодом (hardware/arduino/avr/cores/arduino и hardware/arduino/avr/variants/standard). Основной файл с расширением *.cpp (не *.ino как в Arduino) очень похож на файл из Arduino IDE (пример для файла AUnoDefault.cpp):
    Код (C++):
    // Do not remove the include below
    #include "AUnoDefault.h"

    //The setup function is called once at startup of the sketch
    void setup()
    {
    }

    // The loop function is called in an endless loop
    void loop()
    {
    }
    Но такой подход использую, если пишу прошивку для Arduino. Для "чистых" AVR проекты устроены немного по другому -- там все начинается с функции 'main()' (хотя ни что не мешает так же поступать и с кодом для Arduino -- тот же AVR).
    Если речь идет о Atmel Studio (MS Visual Studio), то, как говорится, и карты Вам в руки -- можно писать на asm или c/c++ (с ассемблерными вставками) и "кодевижн" особо не нужен (но тут дело вкуса). Так же студию можно поставить специальный плагин для поддержки Arduino.
     
  5. Airbus

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

    Понятно.Это тот случай когда предыдущий опыт не помогает а мешает (в моём случае) Да речь об Atmel Studio Winawrовские плагины есть но ими не пользуюсь больше Кодвижн нравиться хотя много лишней писанины и приходиться удалять.Пишу и компилирую на них а в Ардуино загружаю НЕХ через XLoader.Спасибо что открыли глаза а то так сидел бы и не врубался почему не работает.Хотя повторюсь что на wiringе не горю желанием писать смотрю скетчи втыкаю как это будет на си иногда убираю лишние телодвижения сразу проверяю как работает.
     
  6. SaheR

    SaheR Нуб

    А если прямо в методе loop() написать
    Код (C++):
    return 0;
    то не должна ли вся программа завершиться?
    ______
    Ага, ошибка:
     
  7. wildofficer

    wildofficer Нуб

    Отличная ветка!!:) Только теперь начал вьезжать в Ардуинку.
    Получается остановить без всяких заморочек только двумя способами. Все записать в void setup() и оставить void loop() пустым. Или в конце скетча в void loop() написать while(true);
    Не понял немного про то, как "С точки зрения потребления энергии правильнее будет вырубить всю периферию и усыпить."? Впрочем для такого чайника как я и того достаточно:D. Очень бы хотелось чтобы ветка продолжилась:rolleyes: к тому вопрос: Как сделать чтобы void loop() выполнился определенное количество раз два три... и остановился?
    Вообще было бы классно если бы кто мог помочь понять вопросы из "Эксперементов" "Задания для самостоятельного решения" для вас же это 4-5й класс;)
    Спасибо:)
     
  8. Tomasina

    Tomasina Сушитель лампочек Модератор

    Код (C++):
    void loop()
    {
      static byte counter = 0;
      do
      {
        // тут код, который выполнится только три раза
        counter++;
      }
      while(counter < 3);
      // тут код, который будет выполняться бесконечно
      // также тут нечто может обнулить counter ;)
    }
     
  9. AlexU

    AlexU Гуру

    При таком подходе не остановится.
    UPD: правильный комментарий:
    Код (C++):
     // тут код, который выполнится бесконечное количество раз
     
  10. wildofficer

    wildofficer Нуб

    Не работает при таком раскладе

    #define LED_PIN 9
    void setup()
    {
    pinMode(LED_PIN, OUTPUT);
    }
    void loop()
    {
    static byte counter = 0;
    do
    {
    analogWrite(LED_PIN, 85);
    delay(250);
    analogWrite(LED_PIN, 170);
    delay(250);
    analogWrite(LED_PIN, 255);
    delay(250);
    counter++;
    }
    }

    Скетч из эксперемента 2 http://wiki.amperka.ru/конспект-arduino:маячок-с-нарастающей-яркостью

    Что я не понимаю???:( Обьясните плс:rolleyes:
     
  11. Tomasina

    Tomasina Сушитель лампочек Модератор

    а где условие окончания срабатывания цикла do?

    Ладно, принцип do...while сложноват для первичного поинмания, вот просто while:
    Код (C++):
    #define LED_PIN 9
    void setup()
    {
      pinMode(LED_PIN, OUTPUT);
      Serial.begin(9600);
    }
    void loop()
    {
      static byte counter = 0;
      while (counter < 3)
      {
        analogWrite(LED_PIN, 85);
        delay(250);
        analogWrite(LED_PIN, 170);
        delay(250);
        analogWrite(LED_PIN, 255);
        delay(250);
        counter++;    
        Serial.println(counter);
      }
    // сюда попадаем только после того, как counter стал равен трём.
    // тут код все равно выполняется бесконечное количество раз.
    // если кода здесь нет, то и выполняться нечему :)
    }
     
    Последнее редактирование: 22 сен 2016
  12. Максимус-Бог

    Максимус-Бог Убийца матрёшек

    Как вызвать конструктор?

    Код (C++):
    class a
    {
    private:
      B field;
    public:
      a(int varible)
      {
         //вызов конструктора B с передачай в него varible
      }
    };
     
     
  13. AlexU

    AlexU Гуру

    Чем же это постусловие (do ... while) сложнее предусловия (while {})?
    В своём примере с постусловием Вы допустили ошибку в логике -- не учли, что функция loop() вызывается в бесконечном цикле, и поэтому постусловие не даст нужного результата.
     
  14. AlexU

    AlexU Гуру

    Код (C++):
    class a
    {
    private:
      B field;
    public:
      a(int varible)
          : field(variable) //вызов конструктора B с передачай в него varible
      {
      }
    };
     
    Максимус-Бог нравится это.
  15. SaheR

    SaheR Нуб

    while(true) однозначно будет гонять в цикле вычисления.
     
  16. Tomasina

    Tomasina Сушитель лампочек Модератор

    И у меня вопросик.

    Есть вот такая функция:
    Код (C++):

    // Функция преобразования даты компиляции в формат "ДД.ММ.ГГ"
    void convertDate(char const *date, char *buff)
    {
      unsigned int month, day, year;
      static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
      sscanf(date, "%s %d %d", buff, &day, &year);
      month = (strstr(month_names, buff) - month_names) / 3 + 1;
      sprintf(buff, "%d.%02d.%02d", day, month, year-2000); // sprintf(buff, "%d.%02d.%04d", day, month, year);
    }
    Вот как с ней работать:
    Код (C++):
    char msg[21];
    convertDate(__DATE__, msg);
    lcd.print(msg);
    Как ее доработать так, чтобы она сама возвращала нужные данные, без глобальных переменных?
    Т.е. чтобы вот так ее использовать:
    Код (C++):
    lcd.print(convertDate(__DATE__));
     
  17. fogary

    fogary Гик

    Вопрос с подвохом?
    Код (C++):
    // Функция преобразования даты компиляции в формат "ДД.ММ.ГГ"
    char* convertDate(char const *date)
    {
      char buff[255];
      buff[0] = 0;
      unsigned int month, day, year;
      static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
      sscanf(date, "%s %d %d", buff, &day, &year);
      month = (strstr(month_names, buff) - month_names) / 3 + 1;
      sprintf(buff, "%d.%02d.%02d", day, month, year-2000); // sprintf(buff, "%d.%02d.%04d", day, month, year);
      return buff;
    }
     
  18. Tomasina

    Tomasina Сушитель лампочек Модератор

    а! вот где была косяка...
    В моих попытках разрулить самостоятельно везде было *buff
    Ну не дружу я с указателями... :(

    Спасибо!
     
    Последнее редактирование: 23 сен 2016
  19. AlexU

    AlexU Гуру

    А так делать:
    Код (C++):
    char* convertDate(char const *date)
    {
      char buff[255];
      buff[0] = 0;
      unsigned int month, day, year;
      static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
      sscanf(date, "%s %d %d", buff, &day, &year);
      month = (strstr(month_names, buff) - month_names) / 3 + 1;
      sprintf(buff, "%d.%02d.%02d", day, month, year-2000); // sprintf(buff, "%d.%02d.%04d", day, month, year);
      return buff;
    }
    нельзя, причём категорически нельзя.
    Проблема в том, что массив 'buff' будет "уничтожен" при выходе из функции 'convertDate', т.к. память выделяется в стеке функции, который освобождается после выхода из функции. И ни кто не даст гарантии, что данные в этом массиве не будут затёрты другими данными. Массиву 'buff' нужно выделять память в глобальной куче через 'malloc', тогда будет гарантия, что данные ни кем не перетрутся:
    Код (C++):
    char* convertDate(char const *date)
    {
      char *buff = malloc(255);
    ..........
    Вот только встает вопрос кто будет отвечать за удаление выделенной памяти -- free()?
    Поэтому и применяется подход, при котором создаётся буфер (локально или глобально -- не важно) и передаётся функции в качестве параметра. А потом этот буфер удаляется тем кто его создал.
    Вот только безопаснее применять функции вида:
    Код (C++):
    void convertDate(char const *date, char *buff, size_t buffSize)
    и использовать:
    Код (C++):
    snprintf(buff, buffSize, "%d.%02d.%02d", day, month, year-2000);
     
    Tomasina и Максимус-Бог нравится это.
  20. Tomasina

    Tomasina Сушитель лампочек Модератор

    исходник не мой, был стырен отсюда. Все равно спасибо :)
    Получается, любая функция, где что-то формируется локально и результат выдается через return xxx, рискует вылететь за пределы отведенной памяти?