Mikrocontroller hängt sich auf

Hallo,

ich arbeite mit einem Arduino mega 2560 (Atmel ATmega-2560V). Hab verschieden Sensoren über I2C angeschlossen. Wenn ich ein Fehler simuliere, z.B. Versorgungsspannung des Slaves unterbrechen oder Wackelkontakt an SCL, kommt es u.U. zum komplett Ausfall meines Mikrocontrollers. Hab ich mein USB noch am PC und schließe und öffne das „Serial.Monitor“ Fenster, funktioniert es wieder. Ich habe in Foren gelesen, dass beim Öffnen dieses Fensters ein „Reset“ ausgelöst wird. Wer hat dazu mehr Infos? Und woher könnte der Komplettausfall entstehen?

Beste Dank im Voraus und beste Grüße

Mir ist nicht bekannt, dass der Mega sich da anders verhält als der Uno. Beide lösen beabsichtigt beim öffnen der Konsole einen Reset aus. Das hat soweit ich weiß mit dem Atmega16U2 zu tun, damit auch über USB das programmieren geht.

Es gibt diverse Tutorials, bei denen man das umgeht, (Widerstand ablöten, Kondensator setzen etc). Danach wird aber der manuelle Reset bei jedem Upload erforderlich.

Messe mal den Strom, welcher von der gesamten Platte an I2C Sensoren gezogen wird. Evtl. eine Überlastung?

Hallo,
das "resetten" bei Aufruf des seriellen Monitor ist Systembedingt- läßt sich
aber umgehen:
http://arduino.cc/de/pmwiki.php?n=Main/ArduinoBoardMega2560
"Automatischer (Software) Reset"

Wenn Du an einem Bus-System einen Fehler simulierst- und diesen nicht abfragst,
dann sollte man sich nicht wundern, wenn es hängt…
Du könntest z.B. mit einem A0 "messen" ob Spannung vorhanden ist.
Gruß und Spaß
Andreas

kallejoerg:
Ich habe in Foren gelesen, dass beim Öffnen dieses Fensters ein „Reset“ ausgelöst wird.

Ja.

kallejoerg:
Wer hat dazu mehr Infos?

Reset = Neustart des Controllers

kallejoerg:
Und woher könnte der Komplettausfall entstehen?

Mangelhafte Fehlerbehandlung von auftretenden Fehlerbedingungen in Deinem Sketch.

Das kann z.B. entstehen wenn man Null-Pointer dereferenziert, die man erhält weil eine Funktion keine Daten zurück liefert.

Mit Hilfe des Oszis habe ich herausgekommen, dass vom Slave (A) oder vom Master (B) die SDA-leitung nach unten gezogen wird. Wenn ich kurz die Versorgungsspannung vom Slave, z.B. für Fall A, unterbrechen läuft alles problemlos. Könnte ich irgendwie ein Interrupt auslösen, wenn der µC hängt, damit dieser im Anschluß über ein I/O meine Versorgungsspannung kurz unterbricht?

Beste Grüße

kallejoerg:
Mit Hilfe des Oszis habe ich herausgekommen, dass vom Slave (A) oder vom Master (B) die SDA-leitung nach unten gezogen wird.

Also schließt Du einen defekten Sensor an, der den Bus blockiert, indem er den Bus dauerhaft auf LOW zieht.

Und der Sketch blockiert wegen einer mangelhaften Fehlererkennung in der Wire-Library.

Wenn Du Deinen Arduino mit defekten I2C-Sensoren betreiben möchtest, ohne dass sich der Sketch aufhängt, würde es sich als erstes anbieten, anstelle der standardmäßigen Wire-Library eine andere Library mit verbesserter Fehlerbehandlung zu verwenden.

Zum Beispiel: https://github.com/steamfire/WSWireLib/archive/master.zip

In Deinem Sketch schreibst Du dann statt:

 #include <Wire.h>

die neue Library

 #include <WSWire.h>

Siehe auch: GitHub - steamfire/WSWireLib: Arduino Wire Library modified to add timeouts to the freeze-prone TWI while() loops

Eine andere Option wäre allerdings auch, anstelle des defekten/fehlerhaften Sensors, der den Bus blockiert, einen fehlerfreien Sensor zu verwenden, der sich entsprechend der I2C-Standards verhält.

Hallo Zusammen,

voerst bedanke ich mich für alle Beitäge.

wie bekannt ist, ist meine I2C-Kommunikation bei einer Fehlersimulation (Wackelkontakt SDA- bzw. SCL-Leitung oder SDA- und SCL-Leitung gebrückt) ausgefallen. Mit Hilfe des Oszilloskops habe ich erkannt, dass dann die SDA-Leitung dauerhaft auf LOW liegt. Dieser LOW-Pegel wurde hervorgerufen durch den entsprechende Slave und/ oder des Masters.

Fehlerbehebung konnte erfolgen durch:

Slave-Seite:
Einbau eine bilateralen Switch! Bei einem Fehlerfall wurde der Slave kurzzeitig abgeschalten.

Master-Seite:
Sobald das TWEN: TWI Enable Bit im TWCR Register gesetzt wurde ist kein weiteres Zugriff auf die SCL & SDA I/O Pins möglich. Dieses Bit wird sobald der Befehl „wire.begin();“ aufgerufen wird dauerhaft gesetzt. Da bei einem Fehler ein Problem im I2C-Modul vorliegt, wollte ich versuchen einen Urzustand herzustellen. Dies konnte ich ermöglichen indem ich die wire library mit den Änderung von GitHub - steamfire/WSWireLib: Arduino Wire Library modified to add timeouts to the freeze-prone TWI while() loops vorgenommen und zusätzlich folgendes im twi.cpp file geändert (Fett Markierung):

void twi_init(void)
{
// initialize state
twi_state = TWI_READY;
twi_sendStop = true; // default value
twi_inRepStart = false;

TWCR=0;
delay(1);
pinMode(SDA , OUTPUT);
pinMode(SCL , OUTPUT);

digitalWrite(SDA, 0);
digitalWrite(SCL, 0);
delay (200);

digitalWrite(SDA, 1);
digitalWrite(SCL, 1);
delay(200);

// initialize twi prescaler and bit rate
cbi(TWSR, TWPS0);
cbi(TWSR, TWPS1);
TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;

/* twi bit rate formula from atmega128 manual pg 204
SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))
note: TWBR should be 10 or higher for master mode
It is 72 for a 16mhz Wiring board with 100kHz TWI */

// enable twi module, acks, and twi interrupt
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);

}

Sobald auf Seiten des Master die SDA-Leitung runtergezogen wird, kann das I2C-Modul rückgesetzt werden. Dies wird ermöglicht durch den Codezusatz twi_tout () in den entsprechenden while-Schleifen.

Natürlich könnte man jetzt verschiedene Fehlerrutinen zusätzlich programmiert.

Ich hoffe den einen oder anderen Hilft diese Information.

Beste Grüße

Jörg