Go Down

Topic: Hat jemand von euch NRF24L01+ zum laufen gebracht? (Read 11967 times) previous topic - next topic

Serenifly


Was genau ist mit "neueren AVRs" gemeint?

Steht nicht genau da. Es wird aber der Atmega1281 genannt. Der ist ein Zwischenstück zwischen Atmea328 und Atmega2560.

Ich würde das also immer Einbauen. Es schadet auch nichts, selbst wenn man es nicht bräuchte. Das deaktiviert einfach den WTD sehr früh während der Prozessor anläuft.

Die Bootloader Geschichte gilt wie gesagt nur für den Mega. Für dich dann nicht relevant.

KUCKY

Hallo zusammen,
vielen Dank, auch von mir. Ich glaube, dies auch im Großen und Ganzen verstanden zu haben. Ich werde meinen MEGAs einen aktuellen Bootloader verpassen. Aber wie genau rufe ich die "Reset-Funktion" auf. Ist vielleicht ´ne blöde Frage, stehe aber auf momentan dem Schlauch.

Gruß Willi

Serenifly

Wie gesagt, ich bin mir nicht sicher, dass der Bootloader der bei 1.0.5 dabei ist den Bug wirklich behoben hat. Es gibt aber auch .hex Files die wirklich gepatcht sind. Da kenne ich mich nicht so aus.

Quote

Aber wie genau rufe ich die "Reset-Funktion" auf

Das ist ein Makro, aber es wird genau wie eine Funktion aufgerufen:
Code: [Select]
soft_reset();
Könnte man wohl auch als echte Funktion schreiben

KUCKY

Aha, wieder was gelernt. Danke.

Ich hatte eben das hier gefunden:

Code: [Select]

#include <avr/wdt.h>

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


Meinst Du die ..hex Files von Nickgammon?

Gruß Willi

Serenifly


Ich hatte eben das hier gefunden:

Ja, das geht natürlich genauso.

Und dann eben der Teil:
Code: [Select]

void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));
void wdt_init(void)
{
    MCUSR = 0;
    wdt_disable();

    return;
}

Das ist keine echte Funktion, sondern sieht nur so aus. Das wird automatisch in den Anfang des Speichers geschrieben und ausgeführt ohne das man es explizit aufruft


Quote

Meinst Du die ..hex Files von Nickgammon?

Ja, wobei das wahrscheinlich nicht der einzige Patch ist.

KUCKY

Hallo zusammen,
ich hatte leider keinen Erfolg. Ich habe folgendes mit einem Duemillenova328p probiert:

Code: [Select]

/*
Arduino Software reset
*/

#include <avr/wdt.h>

#define soft_reset()

int led = 13;

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

//void wdt_init(void) {
//    MCUSR = 0;
//    wdt_disable();
//    return;
//}

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

void setup() {               
  pinMode(led, OUTPUT);     
  Serial.begin(115200);
  Serial.println("Start reset test");
}

void loop() {
  digitalWrite(led, HIGH);   
  Serial.println("on");
  delay(1000);               
  digitalWrite(led, LOW);   
  Serial.println("off");
  delay(1000);           
}

void serialEvent() {

byte key = 0;

if(Serial.available() > 0) {

key = Serial.read();

switch (key) {
case 'b':
reboot();
// soft_reset();
Serial.println("Now reset");

default:
break;
}
}
}
//--------------------------- end of serialEvent --------------------------------------------------



Ich habe verschiedene Versionen getestet, deshalb die Auskommentierungen. Erfolg war lediglich, das ich den Arduino neu starten musste. Ich ging davon aus, dass das kleine Programm mit setup wieder startet. Ich muss dazu sagen, das dieses kleine "Projekt" als Unterstützung für mein Hauptprojekt dienen soll.

Gruß Willi

Serenifly

Der jetzige Code ist Murks

Das #define macht gar nichts. Da fehlt der Teil des Makros den er eigentlich statt soft_reset() einsetzen soll.

Und der Funktions-Prototyp für den init Code ist so alleine auch überflüssig.

Der Code nach reboot() wird nie erreicht.



Das geht bei mir:
Code: [Select]

#include <avr/wdt.h>

void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));
void wdt_init(void)
{
    MCUSR = 0;
    wdt_disable();

    return;
}

#define soft_reset()        \
do                          \
{                           \
    wdt_enable(WDTO_15MS);  \
    for(;;)                 \
    {                       \
    }                       \
} while(0)

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

void loop()
{
  char c = Serial.read();
 
  if(c == 'r')
  {
    soft_reset();
  }
 
  Serial.println("running");
  delay(1000);
}


Da siehst du "START" wenn du 'r' eingibst

KUCKY

Danke für die Hilfe zu dieser Uhrzeit :). Ich habe das Programm 1 zu 1 kopiert. Kein Neustart, aber der Arduino muss neu gestartet werde. Diese Funktionen:

wdt_disable();
soft_reset();

sind unterstrichen mit einer Meldung, ".....es wird ein ")" erwartet". Ist das normal?

Serenifly

Keine Ahnung was da los ist. Ich habe es auf einem ganz normalen UNO getestet.


Statt dem Makro eine Funktion draus zu machen geht bei mir auch:
Code: [Select]

void soft_reset()       
{
    wdt_enable(WDTO_15MS);
    for(;;){}                       
}

KUCKY

Ich habe leider keinen Due. Mit dem Nano hat es auch nicht funktioniert. Ich habe es sogar mit der Arduino IDE probiert. Trotzdem danke für die Geguld. Gute Nacht. 8)

Gruß Willi

Serenifly

Dass du Neustarten musst deutet darauf hin dass der WDT nicht ausgelöst wird. Er wird dann in der Endlosschleife hängen.

Ob das auf dem Due so geht würde ich erst bezweifeln. Das ist für AVR Prozessoren gedacht.

KUCKY

Nicht der DUE, das ist ein ARM-Processor. Ich hatte den Duemilenove(2009) gemeint:
http://arduino.cc/en/pmwiki.php?n=Main/ArduinoBoardDuemilanove.
Und das ist ein AVR.

Woran kann es den liegen, dass WDT nicht ausgelöst wird? Bei Dir funktioniert es ja. Wie gesagt, ich hatte es auch mit der Arduino IDE 1.0.5 versucht. Ansonsten nutze ich VS2012 mit Visualmicro.

KUCKY

Nach Deinem Hinweis, habe gerade das gefunden:

Der WDT läßt sich auch softwaremäßig durch Setzen des WDE-Bits im WDTCR Register aktivieren.


WDT_on:

  in Temp1, WDTCR      ; Write logical one to WDE
  ori Temp1, (1<<WDE)
  out WDTCR, Temp1
  ret

Dieses hat den Vorteil, dass man den WDT auch softwaremäßig wieder deaktivieren kann.

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Watchdog#WDT_durch_WDTON-Fuse_aktivieren.

Könnte das die Lösung sein? Wenn ja, wie geht das?

Serenifly

Probieren kannst du es mal. Das ist aber Assembler Code. Du braucht nur WDTCR = (1<<WDE)

Das ist aber eigentlich auch nix anderes als was das wdt_enable() Makro macht:
http://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html#gaf6cfea2a1b61e2530ea0c4ef8fc572b3
Wobei da noch etwas mehr drin steckt

Auf der Seite wird auch das mit "neueren" AVRs besser erklärt:
Quote

Note that for newer devices (ATmega88 and newer, effectively any AVR that has the option to also generate interrupts), the watchdog timer remains active even after a system reset (except a power-on condition), using the fastest prescaler value (approximately 15 ms).

Geht also bis zum Atmega88 zurück! Was ich schon als alt bezeichnen würde :)

KUCKY

Nee nee, das lasse ich die Finger von. Ich werde mein Prototyp-Platine mit einem Resetknopf versehen. Wie gesagt, das ist "nur" ein Nebenprojekt.
Trotzdem vielen lieben Dank für die Unterstützung, aber ich weiss genau, wo derzeit meine Grenzen sind.

Gruß Willi

Go Up