Reboot Arduino per Software

Hi,

wenn ich den Arduino aus der Software rebooten will, dann hab ich ja m.E. zwei Möglichkeiten:

  • Transistor an Ausgang und Spannung weg (will ich hier nicht verwenden)
  • per Code:asm volatile ("jmp 0");

Da steht allerdings dabei:

Restarts program from beginning but does not reset the peripherals and registers

Versteh ich nicht so ganz:

Wird da nur das Anwenderprogramm neu gestartet? Oder ist das so, wie wenn sich der Arduino neu startet. Also auch noch durch den Bootloader läuft.
Und was hat es mit den Registern auf sich? Wo könnte ich da Probleme haben?

Gruß/hk007

Ein Reset ruft den Bootloader auf. Dieser, nach dem er auf ein eventuelles Upload vom PC gewartet hat, den geladenen Sketch. Register ecc werden bei einem Reset auf die Anfangswerte gesetzt und der Sketch ( in einem Teil der automatish zu allen Sketchen dazugefügt wird, oder wieso ist ein leerer Sketch schon 1kByte groß) setzt auch noch Register und macht Anfangseinstellungen.

Resetieren über HW birgt ein Risiko. Der Resetimpuls muß eine gewisse Länge haben. Ein Impuls auf Reset durch einen Ausgang funktioniert deshalb nicht zuverlässig.

Transistor an Ausgang und Spannung weg (will ich hier nicht verwenden)

verstehe ich jetzt nicht, wie genau Du das meinst.

Grundsätzlich ist zu sagen daß wenn Du einen Sketch resetieren mußt dieser falsch programmiert ist. es gibt keinen Grund um Arduino vom Sketch aus zu resetieren.

Grüße Uwe

der Sketch ( in einem Teil der automatish zu allen Sketchen dazugefügt wird, oder wieso ist ein leerer Sketch schon 1kByte groß) setzt auch noch Register und macht Anfangseinstellungen.

... alle globalen Variablen auf Anfangswerte aus dem Flash bzw. 0 setzen wird auch nach asm ("jmp 0"); durchlaufen.

Mich interessiert eher, werden auch OUTPUT Pins kurzzeitig auf INPUT zurückgesetzt, bis setup() dran kommt?
Oder macht das die Hardware, bevor der Arduino zu laufen anfängt?

Je nach fuses-Einstellungen fängt der Arduino auch nicht bei 0, sondern am oberen Ende beim bootloader an zu laufen, und der springt - evtl. erst nach getaner Arbeit - auf 0 an den Sketch - Anfang.

Die empfohlene Methode für Reset per Sketch sei, den Watchdog scharf zu schalten und auslösen lassen.

uwefed:
Grundsätzlich ist zu sagen daß wenn Du einen Sketch resetieren mußt dieser falsch programmiert ist. es gibt keinen Grund um Arduino vom Sketch aus zu resetieren.

:o
Das lass ich jetzt erst mal auf mich einwirken.......

Viel Wahres daran ist, mein Jedi-(Arduino) Meister.

Watchdog ist was anderes. Der ist dazu da zu kontrollieren ob ein Programm nicht total blockiert ist oder in einer Endlosschleife festhängt. Der Watchdog funktioniert autonom ohne zugab vom Programm. Das Programm muß ihm nur regelmäßig Lebenszeichen schicken.

Grüße Uwe

uwefed:
Watchdog ist was anderes. Der ist dazu da zu kontrollieren ob ein Programm nicht total blockiert ist oder in einer Endlosschleife festhängt.

Und genau so macht man einen echten Software Reset. Man startet den Watchdog Timer und geht in eine Endlosschleife.

Und was macht der Watchdog-reset anders als das "jmp 0" ?

Er setzt auch die Register auf 0 zurück

Da gehören zum einen die elementarsten Recheneinheiten des Prozessors dazu, sowie eine Reihe besonders schnell adressierbarer Bytes im Speicher die von Funktionen als Zwischenspeicher verwendet werden.
Aber hier sind vor allem spezielle Speicherzellen im unteren RAM Bereich gemeint mit denen die internen Prozessor-Funktionen gesteuert werden. Wenn man z.B. den I/Os sagen möchte dass sie Ausgänge sind setzt man Bits in einem bestimmten Register. Timer werden über Register konfiguriert. Und auch alle anderen Dinge wie Interrupts, I2C oder SPI. Da hat dann jedes Bit eine genau definierte Funktion und man setzt oder löscht diese Bits damit die Hardware bestimmte Sachen macht.

Siehe auch:

OK,

also dann so:

#include <avr/wdt.h>
wdt_enable(WDTO_2S) // 2 Sekunden;

und dann am Ende der Loop den
wdt_reset();

Ist das so richtig programmiert?

Ich hab irgendwo gelesen, dass es Probleme mit dem Bootloader geben kann? Aber das was ich oben geschrieben habe, ist ja nur Software und von der weiss doch der Bootloader noch nichts beim Neustart.

Nein. Du willst beim einem Reset den Timer ja gerade NICHT zurücksetzten:
http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_softreset

Nimm am besten das:

Ist nicht viel Code, aber dadurch ist das alles versteckt

Die Probleme mit dem Bootloader kann es auf dem Mega geben. Der Bootloader da hatte lange einen Bug der den WDT nach dem Reset aktiviert lies. Der Bootloader braucht eine lange Zeit während dessen der WDT nicht resettet wird. Dadurch hat man dann ständig einen Reset. Aktuelle Versionen sind angeblich ausgebessert.
Laut der Seite kann das auch auf einem Atmega328 auftreten, aber man liest in diesem Zusammenhang hauptsächlich von Ärger mit dem Mega.
Aber man kann auch einfach den Bootloader updaten.

Ich glaube, da haben wir von 2 Dingen geredet.

So wie ich beschrieben, wäre es doch ein Watchdog, der den Arduino zurücksetzt, wenn er nicht mehr "arbeitet", oder? Heisst bei meinem Beispiel, dass er rebootet, wenn die loop länger als 2 Sekunden braucht um durchzulaufen.

Du meinst einen aktiven Reset per Software.

Die Probleme mit dem Bootloader kann es auf dem Mega geben. Der Bootloader da hatte lange einen Bug der den WDT nach dem Reset aktiviert lies.

Das geht mir nicht in die Birne. Wird der WDT irgendwo ins Flash oder EEprom geschrieben? Denn wenn der nur im RAM ist, kanns dem Bootloader doch wurscht sein, da er nichts aus dem RAM zum booten verwendet. Und wenns in den Registern steht, dann werden die, lt. deinem Post weiter oben, auch zuückgesetzt.

Aber man kann auch einfach den Bootloader updaten.

Bis zu welcher Version war das fehlerhaft?
Und v.a. wie kann man aus dem Arduino auslesen, welcher Bootloader drauf ist?

Und v.a. wie kann man aus dem Arduino auslesen, welcher Bootloader drauf ist?

Man sollte alles von Nick Gammon gelesen haben :wink:

michael_x:
Man sollte alles von Nick Gammon gelesen haben :wink:

OK.
Aber nur für die Info zwei Arduinos mühsam zusammen zu koppeln...
Da nehm ich lieber meinen USBASP und knall den neuesten Bootloader drauf.

Gut man könnte auch den Flash auslesen, und dann mit nem Hex-Editor das Ausgelesene mit dem hex-File vergleichen.

Sind die bei der Arduino IDE mitgelieferten Bootloader auch immer aktuell?
Also der "stk500boot_v2_mega2560" für den MEGA?

Hallo zusammen,
ich bin auf diesen Thread gestoßen. Ich möchte meinen QuadroCoper u.U. per RC reseten. Dieser Code:

void ArduinoReset() {
 asm volatile ("  jmp 0");

funktioniert, aber nicht wenn ich ihn in eine Klasse schreibe.

.cpp
void HARDwareClass::ArduinoReset() {
 asm volatile ("  jmp 0");
.h
void ArduinoReset();

Im Gegenteil, der Arduino MEGA250 flasht gar nicht mehr. Erst nach abstöpseln des USB Kabels und etwas warten, ist wieder alles OK.

Diese Kombination hatte gar keinen Erfolg:

void HARDwareClass::wdt_init() {

 MCUSR= 0;
 wdt_disable();
 return;
}//--------------------------- end of wdt_init ----------------------------------------------

 void wdt_init(void) __attribute__((nacked)) __attribute__((section(".init3")));

Auch ohne Klasse nicht.

Wie schreibe ich das richtig?

Gruß
Willi

funktioniert, aber nicht wenn ich ihn in eine Klasse schreibe.

Warum willst du es in eine Klasse schreiben?
Warum ist die Methode nicht static?
Wie rufst du sie auf?
Warum zeigst du keinen kompletten Sketch, der nicht funktioniert? (Brauchst keine 3 Dateien für eine Klasse)

Ein Flugobjekt während des Flugs zu Resetten finde ich übrigens super.
Ich würde aber auch den RC-Empfänger per RC abschalten. Damit der den Arduino nicht wieder stört.

Ein Reset unterbricht die Steuerung Deines QuadroCoper.
Darum darf das im Flug nicht passieren/geschehen.

Grüße Uwe

Ooops, hab ich etwa smileys vergessen ?

Statt "Flugobjekt" sollte ich evtl. "Alles ausser Heissluftballon" schreiben.
und selbst da ist es nicht zulässig, wenn der Ballonführer während der Fahrt ein kurzes Nickerchen macht, fürchte ich. :wink:

Unabhängig von der aktuellen Anwendung und der damit verbundenen Frage, "warum Reset überhaupt?"
(Antwort: "Weil mein Code noch Macken hat, die ich nicht finde ...")

... , könntest du die schwierige Antwort auf

Warum zeigst du keinen kompletten Sketch, der nicht funktioniert?

einfach durch einen kleinen Beispielsketch umgehen.

Hallo Micheal_x,
Danke für die Antworten. Ich bin aber gestern selbst drauf gekommen. Ich habe lediglich den Arduino 2-3 mal stromlosgemacht. Alles wieder OK. Nun zu Deinen Rückfragen:

Warum willst du es in eine Klasse schreiben? Weil ich den Code in Module aufgeteilt habe, und ein reseten fand ich nun mal gut im Modul Hardware.ccp aufgehoben.

Warum ist die Methode nicht static? Weil ich mit static so meine Probleme habe :confused:

Wie rufst du sie auf? Derzeit über die Tastatur, später über eine Funkverbindung, ABER NATÜRLICH NICHT IM FLUGMODUS :wink: :smiley:

Warum zeigst du keinen kompletten Sketch, der nicht funktioniert? (Brauchst keine 3 Dateien für eine Klasse) Ich wollte nicht unnötig Platz verschwenden, war vielleicht zu kurz gedacht.

Sollte das aber diese Woche nicht funktionieren, werde ich den kompletten Code posten. Bis dahin erstmal vielen Dank.

Ich habe lediglich den Arduino 2-3 mal stromlosgemacht. Alles wieder OK.

Soo große Kondensatoren sind da ja nicht drauf, dass theoretisch ein Unterschied zwischen ein- und mehrmals stromlos machen bestehen sollte.
Sogar (echtes Hardware-)Reset oder aus/ein schalten sollte keinen Unterschied machen.
Ausser für andere Shields/Komponenten, die evtl. auch einen Reset per Spannungswiederkehr brauchen.

Ein kleiner Unterschied zwischen asm("jmp 0"); und reset besteht allerdings. Deswegen wird offiziell das Reset über WDT empfohlen.

Werde beide Methoden noch mal probieren. In einem anderen Post von heute, habe ich das seltsame Verhalten des NRF24 Moduls beschrieben. Gerade hier hatte das Gefühl, dass diese Dinge zusammen hingen.

http://forum.arduino.cc/index.php?topic=220388.255