Restablecer un Arduino Uno en el código

19

¿Es posible restablecer un Arduino (es decir, reiniciarlo) desde el código (es decir, desde el propio boceto)? Sé que eso es posible con un circuito especial, pero ¿existe la posibilidad de hacerlo solo con código?

A continuación se muestra mi código y el comentario //resetes donde quiero forzar un reinicio.

#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() {
}

Quiero restablecer el microcontrolador al final de la función de configuración para mostrar el efecto de números aleatorios con y sin semilla.

kimliv
fuente

Respuestas:

22

Hay tres formas de lograr esto. (el último es mi favorito)

1) Conecte un IO no utilizado al pin RESET. Déjelo como ENTRADA para funcionamiento normal, ya que externamente se tira hacia arriba. Y cuando desee restablecerlo, configúrelo como BAJO y Salida. (bang su reinicio).

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.

entonces cuando lo desee ...

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

2) Saltar al comienzo del código.

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

Pero tenga cuidado , esto no realiza un reinicio verdadero, ya que todos los registros NO ESTÁN POR DEFECTO. Más bien, ellos y el IO se quedan como están. Donde se inicializarán algunas cosas del gestor de arranque y luego el montón. Y reiniciar no lo son!

3) Usa el perro guardián. La biblioteca SoftReset lo hace fácil. Aunque no es difícil de implementar directamente. Mostrado a continuación..

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

entonces cuando lo desee ...

...
wdt_enable(WDTO_15MS); // turn on the WatchDog and don't stroke it.
for(;;) { 
  // do nothing and wait for the eventual...
} 
...
mpflaga
fuente
2
De todo lo que he leído, no se recomienda la primera opción. Las opciones 2 y 3 están bien.
Sachleen
2
@sachleen: diga más sobre eso (opt-1).
JRobert
2
La opción 1. o una variante puede ser una forma lo suficientemente limpia de hacerlo siempre y cuando la energía en condiciones transitorias esté diseñada para ello.
Russell McMahon
Cabe señalar que la opción 2 no ejecuta el gestor de arranque.
Edgar Bonet