Как программно перезагрузить(ресетить) ардуинку - инструкция

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем Злая Птичка, 18 ноя 2012.

  1. Инструкция по программной перезагрузке Arduino

    Если вы хотите программно ресетить Arduino, то для этого вам нужен следующий код:
    Код (Text):
    void(* resetFunc) (void) = 0;
    Чтобы ресетить Arduino, просто вызовите эту функцию:
    Код (Text):
    resetFunc();
    Например, вот так это реализовано у меня:
    [​IMG]
     
    vetalegg, Mestniy и aysheka нравится это.
  2. nailxx

    nailxx Официальный Нерд Администратор

    Прикольно! Откуда инфа? Есть подозрение, что это некий хак, который вызывает такую ошибку, что Arduino не находит ничего лучшего как перезагрузиться.

    Аппаратно, кстати, для перезагрузки можно дёрнуть пин RESET в ноль. Но это да, уже дополнительный проводок и занятый пин.
     
  3. Инфа отсюда - http://www.arduino.ru/forum/programmirovanie/programmnyi-reset
    Вот, цитирую оттуда:
    Код (Text):
    На самом деле это не настоящий ресет а просто перевод стека в начало программного кода (в нулевой адрес). То есть программа начинает исполнятся с самого начала, при этом не влияя на установки МК на момент исполнения. Например: Если у вас на момент исполнения был установлен какой то порт в "1" и в начале программы его значение не возвращается в "по умолчанию = 0" то после так называемой "программной перезагрузки" порт так и останется с "1".
    Ошибки из темы исправил ;)
     
    nailxx нравится это.
  4. nailxx

    nailxx Официальный Нерд Администратор

    О, теперь всё стало по местам. Грамотное объяснение. Спасибо.
     
  5. Unixon

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

    Если быть более точным, то в общем случае нужно переходить не на нулевой адрес,
    а на адрес либо (а) загрузчика, (б) пользовательской программы, адрес загрузки которой прописан в загрузчике. Для ардуины в случае (б) имеем адрес 0, что отчасти есть совпадение.
     
    nailxx нравится это.
  6. Пожалуйста ;)
     
  7. [​IMG]
     
  8. nailxx

    nailxx Официальный Нерд Администратор

    Тогда ещё кондей с резистором ставим для RC цепочки, чтобы подольше ноль подержался.
     
  9. Программно - проще ;)
     
  10. Megakoteyka

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

    Правильней будет запустить WatchDog и заснуть на время, превышающее порог его срабатывания. Тогда будет полноценный ресет. http://www.arduino.ru/forum/programmirovanie/programmnyi-reset

    void reboot() {
    wdt_disable();
    wdt_enable(WDTO_15MS);
    while (1) {}
    }
     
  11. Megakoteyka

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

  12. И да, программно - удобнее.
     
  13. Iguana

    Iguana Нерд

    Господа, возник вопрос по программному ресету и что-то не получается. Надо сбросить программу через, например, 24 часа. Пробую на blink
    Код (C++):
    unsigned long time;
    // the setup function runs once when you press reset or power the board
    void setup() {
      // initialize digital pin 13 as an output.
      pinMode(13, OUTPUT);
      Serial.begin(9600);
    }

    // the loop function runs over and over again forever
    void loop() {
      digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(500);              // wait for a second
      digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
      delay(500);
      Serial.print("Time: ");
      time = millis();
      //выводим время с момента старта программы
      Serial.println(time);
      delay(10);
      if (time >= 14134){
        asm volatile("jmp 0x00");
      }

    }
    Доходит до нужного значения, на мониторе порта 2016-07-31_08-04-01.png возникает в конце этого значения какой-нибудь знак происходит перезагрузка, а далее все виснет.

    Пробовал разные варианты и тот, что в первом посте, две платы нано и уно, результат один.
    Что я делаю не так?
     
    Последнее редактирование: 31 июл 2016
  14. DIYMan

    DIYMan Гуру

    1. Почему вы решили, что всё виснет?
    2. Добавьте в setup сброс переменной time в 0 ;)
    3. Есть подозрение, что внутренний счётчик millis не сбрасывается при ребуте;
    4. Исходя из пункта 3 - можно попробовать переписать логику:
    Код (C++):
    void setup()
    {
    time = millis();
    }

    void loop()
    {
        if(millis() - time > 14134)
            reboot();
    }
     
     
    Andrey12 нравится это.
  15. Iguana

    Iguana Нерд

    1. Светодиод не блинкает и данных на мониторе порта больше не идут.
    3. Мне тоже так подумалось)).
    В среду продолжу кспиримент, хотя сегодня устройство (радиолюбительский маячек ) в назначенное время заработало как было задумано, без пинка ресетом)))