Redefinir um Arduino Uno no código

19

É possível redefinir um Arduino (ou seja, reiniciá-lo) a partir do código (ou seja, do próprio esboço)? Eu sei que é possível com um circuito especial, mas há uma chance de fazê-lo apenas com código?

Abaixo está o meu código e o comentário //reseté onde desejo forçar uma redefinição.

#include <TrueRandom.h>

int i;
int randSeed;
long randNumber;

void setup(){
  Serial.begin(9600);
  Serial.println("20 pseudo Zufallszahlen:");
  for (i=1;i<=20;i++) Serial.print(random(10));
  Serial.println();
  Serial.println();
  //randomSeed(TrueRandom.random());
  randSeed = analogRead (A0);
  randomSeed(randSeed);
  Serial.print("Der 'seed' Wert: ");
  Serial.println(randSeed);
  Serial.println();
  Serial.println("20 Zufallszahlen mit analogem 'seed' Wert:");
  for (i=1;i<=20;i++) Serial.print(random(10));
  Serial.println();
  Serial.println("---------------------------");
  Serial.println();
  delay(500);
  //reset  
}

void loop() {
}

Quero redefinir o microcontrolador no final da função de instalação para mostrar o efeito de números aleatórios com e sem uma semente.

kimliv
fonte

Respostas:

22

Existem três maneiras de conseguir isso. (último é o meu favorito)

1) Ligue uma IO não utilizada ao pino RESET. Deixe-o como ENTRADA para execução normal, pois ele é puxado externamente para cima. E quando desejar redefinir, defina-o como BAIXO e Saída. (bang sua reinicialização).

setup() {
  ...
  pinMode(PINtoRESET, INPUT);    // Just to be clear, as default is INPUT. Not really needed.
  digitalWrite(PINtoRESET, LOW); // Prime it, but does not actually set output. 
  ...                            // Does disable 10K pull Up, but who cares.

então quando desejado ...

...
  pinMode(PINtoRESET, OUTPUT);   // lights out. Assuming it is jumper-ed correctly.
  while(1);                      // never gets here.

2) Salte para o início do código.

void(* resetFunc) (void) = 0;  // declare reset fuction at address 0
...
resetFunc(); //call reset

Mas tenha cuidado , isso não executa uma redefinição verdadeira, pois todos os registros NÃO SÃO PADRÃO. Em vez disso, eles e o IO são deixados como estão. Onde algumas coisas do gerenciador de inicialização e, em seguida, o heap serão inicializadas. E redefinir não são!

3) Use o cão de guarda. A biblioteca SoftReset facilita. Embora não seja difícil de implementar diretamente. Mostrado abaixo..

#include <avr/wdt.h>
...
setup() {
  ...
  MCUSR = 0;  // clear out any flags of prior resets.
  ...

então quando desejado ...

...
wdt_enable(WDTO_15MS); // turn on the WatchDog and don't stroke it.
for(;;) { 
  // do nothing and wait for the eventual...
} 
...
mpflaga
fonte
2
De tudo o que li, a primeira opção não é recomendada. As opções 2 e 3 são boas.
Sachleen
2
@ saachleen: Por favor, diga mais sobre isso (opt-1).
JRobert 19/05
2
A opção 1. ou uma variante pode ser uma maneira limpa o suficiente, desde que a energia em condições transitórias seja projetada.
Russell McMahon
@RussellMcMahon - Como projetar o Power em condições transitórias ?
Greenonline 13/07/2015
Note-se que a opção 2 não executa o gerenciador de inicialização.
Edgar Bonet