PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Reset bei SRF10 zusammen mit Remote Control



V:X
18.04.2010, 18:53
Hi Leute,

ich habe meinen RP6 mal mit einem SRF10 Ultraschallmodul ausgestattet. Funktioniert auch wunderbar, wenn ich nichts weiter mache, als den SRF10 anzusteuern.
Ich möchte den jetzt aber gerne in das M32-Beispielprogramm "Example_10_Move2" integrieren, in dem ich auch schon eine Funktion zur Steuerung mit einer RC5-Fernbedienung habe.
Folgendes habe ich in "I2C_requestedDataReady" eingebaut:



void I2C_requestedDataReady(uint8_t dataRequestID)
{
// We need to check if this is an INT0 Request from the Robot Base unit.
// The Function call inside the if condition returns true if it was an
// interrupt request, so we have to negate it here and if it was NOT
// an interrupt request from the Robot base we can check any other sensors
// from which you may have requested data...
if(!checkRP6Status(dataRequestID))
{
// Here you can Check other sensors/microcontrollers with their own
// request IDs - if there are any...

uint8_t messageBuf[8];
static uint8_t dist_tmp;
switch(dataRequestID)
{
case MEASURE_US_HIGH: // High data register
// get received data ...
I2CTWI_getReceivedData(messageBuf, 2);
dist_tmp = (messageBuf[0]);
// ... and request low data byte:
I2CTWI_transmitByte(SRF_ADR, 3);
I2CTWI_requestDataFromDevice(SRF_ADR, MEASURE_US_LOW, 1);
break;
case MEASURE_US_LOW: // low data byte:
I2CTWI_getReceivedData(messageBuf, 2);
distance = messageBuf[0] + (dist_tmp << 8); // Formel zur Distanzberechnung; siehe auch SRF10-Doku S.3

// ----------------------------------
// Output measured distance:
writeString_P("Distance: ");
writeInteger(distance, DEC);
writeString_P(" cm | ");
// show a simple text bargraph:
uint16_t dist_count;
for(dist_count = distance; dist_count > 4; dist_count-=2)
writeChar('#');
writeChar('\n');
// ... of course you can also use "distance" as a normal
// variable everywhere else in your program!
// ----------------------------------
break;
}
}
}


Mit den dataRequestIDs



#define MEASURE_US_LOW 1
#define MEASURE_US_HIGH 2


Der Sensor funktioniert damit auch weiterhin super. Sobald ich aber eine Taste auf der Fernbedienung drücke, wird mein Programm resettet. Der Reset ist zeitlich wirklich unmittelbar auf den Tastendruck auf der Fernbedienung zurückzuführen.

Hat da vielleicht jemand ne Idee, woran das liegen könnte? Ich verstehe dieses Verhalten nicht so ganz. Hab keine Ahnung, wo ich da bei der Fehlersuche ansetzen soll :-s

An irgendwelchen I2C Funktionen hab ich nichts verändert (bis natürlich auf die "I2C_requestedDataReady"). Falls ihr noch weitere Infos braucht nur raus damit.

Vielen Dank schonmal für jeden Tip!!
Schöne Grüße,
V:X

-schumi-
19.04.2010, 17:42
Sobald ich aber eine Taste auf der Fernbedienung drücke, wird mein Programm resettet.

Ich hab mir deinen Code nicht wirklich genau angeschaut, aber konkret fallen mir auf die schnelle 2 mögliche Fehler ein:

Sobald du auf die Ferbedienung drückst wird...

... die while (true) { blabla; } -Endlos-Schleife verlassen. Wenn ich mich richtig erinnere kann das zu unvorhergesehenen Reaktionen des RP6 führen

... Dein dazugebasteltes Modul angesteuert und die Ketten bewegt. Wenn dann die Betriebsspannung aufgrund des evtl. sehr hohen Stromverbrauches des Modules fällt weil der Spannungsregler nicht so schnell reagieren kann oder die Akkus schon so leer sind. Sobald der Reset eintritt wird beides wieder ausgeschaltet und die Spannungs ist wieder da.
Musste auf dieses Problem bin ich auch gestoßen, als der RC-Empfänger aus einem alten Spielzeugauto am RP6 ein Signal gekriegt hat und darauf auch geschaltet hat --> plötzlicher Spannungsabfall
Ein Widerstand in der Spannungsversorgung hat das Problem behoben. Falls hoher Stromverbrauch nur sehr kurzweilig ist müsste es ein Kondensator auch tun.

MFG
-schumi-

V:X
20.04.2010, 19:19
Danke für die schnelle Antwort -schumi- !

Ich hab mir meinen Programmablauf nochmal genau angeschaut. Die while-Schleife in der Main-Funktion wird eigentlich niemals verlassen. Ich hab die Funktion für die Fernsteuerung mit einem eigenen Verhalten (im Beispielprogramm immer englisch als Behaviour bezeichnet) realisiert. Wenn ich den An/Aus Knopf auf der Fernbedienung drücke, wird das Verhalten aktiviert und die weiteren RC-Befehle werden von den Funktionen "behaviourController" und "moveCommand" ausgeführt. Durch das Aktivieren der Fernsteuerung ändert sich also der Programmfluss nicht sonderlich, es wird schön immer weiter "behaviourController" aus der main() aufgerufen.

Zu deinem 2. Tip:
Die Akkus sind bei 7,52V. Das ist ja ein ganz gesunder Wert, wenn ich das bisher alles richtig verstanden hab ;)
Das SRF10 Modul verbraucht doch glaub ich auch nicht soviel Strom, oder? Ich hab auch nirgends etwas von einem zusätzlich erforderlichen Widerstand/Kondensator gelesen.
Wundern würde mich dann auch, warum das ACS und die Bumper wie gewohnt funktionieren und der Reset ausschließlich beim Empfang eines RC5 Signals stattfindet :-s


Ich hab jetzt mal das oben Angegebene aus der "I2C_requestedDataReady" auskommentiert. Und siehe da, das Steuern mit der Fernbedienung funktioniert wieder ganz normal. Der Fehler muss also in diesen paar Zeilen Code liegen.
Aber ich verstehs nicht. Wie zum Geier kann ich denn mit den paar Befehlen da die Hardware resetten?! ](*,)

-schumi-
21.04.2010, 16:03
Danke für die schnelle Antwort -schumi- !
nichts zu danken! Ich kann mir gut vorstellen, dass das auch schneller geht als ein Tag ;-)


Ich hab auch nirgends etwas von einem zusätzlich erforderlichen Widerstand/Kondensator gelesen.

Das wird warscheinlich daran liegen, dass das modul nicht für den RP6 entwickelt wurde, oder?
Widerstand/Kondesator sind nur nötig, wenn der Spannungswandler kurzzeitig überfordert ist.


Das SRF10 Modul verbraucht doch glaub ich auch nicht soviel Strom, oder?
Das kann ich dir leider nicht sagen, denn ich hab das Teil nicht...

Der Fehler wird also warscheinlich im Code sitzen, aber da ich mich mit dem I2C Bus noch nicht wirklich auseinander gesetzt habe, kann ich dir da kaum helfen...
Wie ein paar Befehle die Hardware resetten können weis ich auch nicht, mir fällt nur ein dass du vielleicht irgendwas nicht initialisiert hast.. (wie man das z.B. beim LCD-Display machen muss)

MFG
-schumi-

V:X
01.05.2010, 18:07
@-schumi-: Geht aber auch noch viel langsamer als ein Tag, wie ich mit meiner erst jetzigen Antwort demonstriere ;)

Ich hab jetzt einfach mal als dataRequestID für MEASURE_US_LOW 0 , und für MEASURE_US_HIGH 1 genommen. Dann resettet der RP6 direkt nach dem Start. Er startet also eigentlich gar nicht erst richtig. Das muss doch daran liegen, dass dataRequestID 0 die RP6 Base ist. Die IDs dürfen sich also nicht "überschneiden".

Meine Überlegung ist jetzt, ob durch die Fernbedienung noch eine dataRequestID hinzugefügt wird, sobald ich einen Knopf drücke. Und dass sich dann wieder was "überschneidet" und dadurch mein Programm resettet wird?

Ich teste mal n bisschen rum, würd mich aber über Meinungen dazu freuen!
Schönen Samstag Abend noch!

SlyD
01.05.2010, 20:19
Hallo V:X,

Du solltest mal das vollständige Programm posten.

Der Controller führt bei Dir keinen echten Reset aus.
Was passieren kann ist, dass da irgendwo ein Pointer ausbüchst und dann das Programm in den RP6 Bootloader "reinrennt" (also in das Programm das am Anfang nach dem einschalten läuft). Das ist also kein echter Reset - eher ein Sprung in den Bootloader - sieht dann nur so aus als wäre es ein Reset, da der Bootloader die meisten Sachen neu initialisiert.

Ist aber wie gesagt kein Reset, sondern ein Fehler irgendwo im Programm. Kann auch durchaus irgendwas in der Library sein, das kann ich nicht ausschließen - es wurde ja nicht jede erdenkliche Nutzungsmöglichkeit getestet... ;)


MfG,
SlyD

PS:
SRF10 und alle anderen US Sensoren brauchen sehr wenig Energie (<50mA typisch). Das ist gar kein Problem für den Spannungsregler auf dem RP6 - der schafft kurzzeitig auch ca. 1500mA. Daran sollte es also nicht liegen.

V:X
02.05.2010, 17:35
Hi SlyD,

ok, ich häng mal mein Programm als .rar Archiv hier an. Es handelt sich dabei also um das Beispielprogramm "Example_10_Move2" für das M32, in welches ich das Verhalten "obey" und die Funktion zur Steuerung mit der Fernbedienung eingebaut hab. Ich hoffe, du findest dich einigermaßen darin zurecht ;)

Ich hab das Problem mittlerweile auf den Aufruf "I2CTWI_getReceivedData()" in der Funktion "void I2C_requestedDataReady(uint8_t dataRequestID)" eingrenzen können. Wenn ich den Aufruf auskommentiere, funktioniert die Fernsteuerung wie gewohnt. Wenn der Aufruf aber aktiv ist, hab ich wieder das beschriebene Problem ](*,)

Wär cool, wenn du mal nen Blick reinwerfen könntest. Ich bin für jeden Lösungsansatz dankbar!

schönen Sonntag noch,
V:X

SlyD
03.05.2010, 14:22
Ich schau es mir mal an sobald ich Zeit habe - aber da gibt es leider viele Möglichkeiten was da Probleme verursachen könnte denn da spielt ja einiges zusammen und vieles läuft quasi parallel.

Du könntest aber in der Zwischenzeit schonmal einige weitere Debug Ausgaben einfügen um genauer zu sehen wie alles genau zeitlich in welcher Reihenfolge abläuft...
(writeString_P("Stelle 1\n") 2, 3, 4 jeweils vor und nach Bedingungen und Funktionsaufrufen einfügen und ggf. paar Variablenwerte ausgeben lassen usw.)

MfG,
SlyD

V:X
08.05.2010, 19:43
Wär super, wenn du bei Gelegenheit mal nen Blick reinwerfen könntest :D
Danke dafür schonmal!

Ich werd auf jeden Fall weiter rumexperimentieren, woran das wohl liegen könnte. Komm nur leider im Moment nicht so oft dazu, wie ich gerne würde (Physik-Studium nimmt mich zur Zeit ziemlich in Beschlag).

Ist das Einfügen von Testausgaben die einzige Möglichkeit des Debuggens? In IDEs gibts ja oft die Funktion "Debuggen".

V:X
23.05.2010, 17:35
Hi zusammen,

da das mit dem I2CTWI_getReceivedData ja im Prinzip problemlos funktioniert, wollte ich mal schaun, ob die Funktionen für das IRCOMM irgendwo eine Art "Kollision" auslösen, und deshalb mein Programm immer zurückgesetzt wird. Aber ich versteh den folgenden Ausdruck noch nicht so ganz:



// RC5 Data reception Handler:

void IRCOMM_RC5dataReady_DUMMY(RC5data_t rc5data){}
static void (*IRCOMM_RC5dataReadyHandler)(RC5data_t rc5data) = IRCOMM_RC5dataReady_DUMMY;

void IRCOMM_setRC5DataReadyHandler(void (*rc5Handler)(RC5data_t rc5data))
{
IRCOMM_RC5dataReadyHandler = rc5Handler;
}


Das erste ist ja eine Funktion, die eine Variable vom Typ RC5data_t erwartet, aber gar nichts weiter macht. Was ist dann das mit dem static void? Ich verstehe das als Variablendeklaration, aber was genau passiert da?
Danach kommt wieder eine Funktion. Wo kommt da das "rc5Handler" her? Und was genau soll die Funktion machen?

Wär super, wenn mir das jemand erklären könnte :)

schönes Wochenende noch,
V:X

SlyD
23.05.2010, 18:53
Sorry bin noch nicht dazu gekommen mir das anzuschauen.
Und hab die nächsten Tage auch zuviel zu tun.
Wie gesagt - bau nach jedem wichtigen Schritt im Programm eine Textausgabe rein um rauszufinden wo er genau hängen bleibt.


> Ist das Einfügen von Testausgaben die einzige Möglichkeit des Debuggens?


Auf dem AVR läuft ja kein Betriebssystem (oder Interpreter wie der C-Control wo man über die serielle durchaus debuggen kann).

Debuggen ist schon möglich, aber nur mit Zusatzhardware von Atmel. AVR JTAG ICE oder AVR Dragon, damit könntest Du auch mit AVRStudio zur Laufzeit debuggen. Lohnt sich aber nicht wenn man das nur alle paar Wochen mal braucht.



> Wär super, wenn mir das jemand erklären könnte Smile

Das ist nur unleserliche C Syntax ;) und hat nix mit Deinem Problem zu tun.
IRCOMM_RC5dataReadyHandler ist ein Pointer auf eine Funktion. Den Pointer kann man dynamisch zur Laufzeit ändern und so eben selbst im Programm eine Funktion zuweisen die (von dem anderen Programmteil der davon erstmal nix weiss) aufgerufen werden soll.
Zu beginn ist einfach die DUMMY Funktion zugewiesen die nichts tut.

> Wo kommt da das "rc5Handler" her?

Das ist ein Parameter der Funktion IRCOMM_setRC5DataReadyHandler - wird also genau da deklariert ;)

MfG,
SlyD

V:X
20.06.2010, 18:39
Hi zusammen,

mal ein aktueller Stand von mir:

in der Funktion "checkRP6Status" gibt es den folgenden Abschnitt:



// Check if there was a RC5 Reception:
uint8_t readBuf[2];

if(compare & MASK_RC5)
{
I2CTWI_transmitByte(I2C_RP6_BASE_ADR,I2C_REG_RC5_A DR);
I2CTWI_readBytes(I2C_RP6_BASE_ADR, readBuf, 2);

RC5data_t tmp;
tmp.data = (readBuf[0] << 6) | (readBuf[1]);
IRCOMM_RC5dataReadyHandler(tmp);
}



Wenn ich da das "I2CTWI_readBytes(I2C_RP6_BASE_ADR, readBuf, 2);" auskommentiere, dann gibt es keinen Reset.
Wenn ich es unter "if(compare & MASK_BUMPER)" einfüge, gibt es den Reset, beim Druck auf einen Bumper.
Wenn ich es mit einem Taster auf dem M32 aufrufe, gibt es keinen Reset.

Für mich sieht es im Moment so aus, als würde der Reset nur dann kommen, wenn durch ein Ereignis vom Slave mit "I2CTWI_readBytes" etwas gelesen werden soll. Wenn ich die Funktion nur über das M32 verwende (bspw. mit den Tastern) läuft alles normal weiter.

Hat jemand da eine Idee, was da schief laufen könnte?


Um das zu Umgehen würde ich dann versuchen, die Funktionen für die Fernsteuerung einfach in das Slave-Programm einzubauen. Ich denke, damit sollte ich dem Reset-Problem eigentlich aus dem Weg gehen können. Mal schauen ob das so klappt, wie ich mir das vorstelle.

Mich würde allerdings immer noch brennend interessieren, was genau denn da eigentlich miteinander kollidiert und mein Programm resettet :-s