PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Hilfe bei Interruptprogrammierung und Go()



Pitchriddick
08.11.2006, 16:23
Hallo, ich brauche eure Hilfe :

Der Asuro fährt ja ne beliebige Strecke mit der Go Funktion ! Nun soll er aber,wenn er vor Ablauf dieser Strecke auf einen Widerstand trifft (Taster), so soll er z.B rückwärts fahren.
Wie und wo baue ich ein Interrupt ein ?

cu

EDH
08.11.2006, 16:42
bau einfach ans ende while schleife in der go funktion eine tasterabfrage ein.

Pitchriddick
08.11.2006, 16:46
Hm? Wie? Dann fährt er doch seine 12mm aus, erst dann prüft er, ob Tastert betätigt sind... Aber das wollte ich ja nicht, sonder ne Abfrage während er fährt

EDH
08.11.2006, 16:50
äh der fehler ist mir grad auch aufgefallen, und ahb deswegen mein posting entsprechend geändert :oops:

Pitchriddick
08.11.2006, 17:05
du meinst die Funktion inner asuro.c ?
Was bringt mir das denn?Ich will ihn anschließend doch irgendwelche Anweisungen geben... Geht das nicht im normalen Programm

EDH
08.11.2006, 17:20
nacdhem er festgestellt hat, das ein taster gedrückt ist fügst du return 0 ein. dann beendet er dir die funktion an der stelle, und der code wird ganz normal weiter ausgeführt.

mfg EDH

EDH
08.11.2006, 17:53
wenn du das jetzt an den anfang der programm.c (oder wie die bei dir halt heißt) copiertst, musst du gar nichts an der asuro.h ändern.
Die funktion GoTaster fäöhrt eine bestimmte strecke, bleibt aber bei einem hinderniss sofort stehen.
probier mal aus, ob das funktioniert, ich habs auf die schnelle nicht getestet.

hier der code:


int GoTaster(int distance, int speed)
{
int enc_count = 0;
int tot_count = 0;
int diff = 0;
int l_speed = speed, r_speed = speed;
enc_count=abs(distance);

// enc_count=distance*10000;
// enc_count/=12823;

Encoder_Set(0,0); // reset encoder

MotorSpeed(l_speed,r_speed);
if(distance<0) MotorDir(RWD,RWD);
else MotorDir(FWD,FWD);

while(tot_count<enc_count) {
tot_count += encoder[LEFT];
diff = encoder[LEFT] - encoder[RIGHT];
if (diff > 0) { //Left faster than right
if ((l_speed > speed) || (r_speed > 244)) l_speed -= 10;
else r_speed += 10;
}
if (diff < 0) { //Right faster than left
if ((r_speed > speed) || (l_speed > 244)) r_speed -= 10;
else l_speed += 10;
}

Encoder_Set(0,0); // reset encoder
MotorSpeed(l_speed,r_speed);
if (PollSwitch()>0) {
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
return 0;
}
Msleep(1);
}
MotorDir(BREAK,BREAK);
Msleep(200);
return 0;
}


mfg EDH

Pitchriddick
08.11.2006, 19:34
Ne, funktioniert leider überhaupt nicht...
ist das denn so schwer ?

EDH
08.11.2006, 19:56
ja das scheint schon recht diffizil zu sein.

izaseba
08.11.2006, 20:23
ist das denn so schwer ?



ja das scheint schon recht diffizil zu sein.


Wenn man seinen Hirn nicht einschalten kann/will ist es sicher schwer...

Ein Tastendruck löst einen externen Interrupt auf Pin Int1 aus.

Vielleicht bringt es Euch weiter...

Gruß Sebastian

Pitchriddick
08.11.2006, 22:06
Was fürn Ding?? da verstehe ich ja nixX

EDH
09.11.2006, 12:37
mit interrupts hab ich noch nicht so viel gemacht. aber so weit ich weiß macht er nach dem interrupt genau da weiter, wo er aufgehört hat. das hätte zur folge, das er nach dem ausweichen seine strecke x zu ende fahren will.

mfg EDH

Pitchriddick
09.11.2006, 15:07
Aha und an welche stelle kommt dann dieser Taster Interrupt ?

EDH
09.11.2006, 15:28
hast du das buch "mehrs spaß mit asuro" ?
da steht ein bisschen was über interrupts beim asuro drinn

Pitchriddick
09.11.2006, 15:57
Ne habe ich nicht.

Was denn keiner bescheid, menno ist wichtig...

damaltor
09.11.2006, 17:10
das programm wird an der stelle fortgeführt, ja. das heisst nicht, dass der asuro wieder zurück auf die strecke findet und dann weiterfährt... er fährt nur weiter vorwärts bzw. macht er das was er vor dem interrupt auch gemacht hat.

das buch könnte dir tatsächlich recht hilfreich sein. da steht zwar nicht wirklich viel, aber recht hilfreiches zeug.

izaseba
09.11.2006, 17:26
Lösungsvorschlag:

Schaltplan vom Asuro und Dattenblatt vom M8 besorgen.

Programm ablauf:

Globale Variable von mir aus mit dem Namen strecke_frei


In der Int1 ISR wird diese Variable auf 0 gestellt.

In der Main strecke_frei auf 1 setzen und eine Go Funktion aufrufen, die auch einen Wert 1 oder 0 zurückliefert.

Die Go Funktion läßt den Asuro mit hilfe der Odometrie fahren und überwacht ständig die strecke_frei.
Wenn strecke_frei = 1 fährt er weiter bis der Fertig ist und liefert 0 zurück
sollte zwischendurch strecke_frei 0 werden (ein Taster wurde betätigt) wird die Funktion sofort mit dem Wert 1 verlassen.

in der main weißt man aber (anhand des zurückgelieferten Wertes) ob die Strecke abgefahren wurde, oder ob eine Kolision stattgefunden hat, da kann man natürlich entsprechend reagieren.

Da es ja
menno ist wichtig ist, und Du was lernen willst darfst Du Dich um die Software selber kümmern.
Der von mir gezeigte Weg sollte nicht schlecht sein, ganz ohne Bücher, nur mit AVR und C Kenntnissen.

Gruß Sebastian

EDH
09.11.2006, 17:45
eigenlob stinkt ;)
aber funktionierne könnt das schon.

izaseba
09.11.2006, 18:21
Was heißt hier Eigenlob ?

Ich will nur sagen, wem das zu schwer ist, der soll dieses Projekt mal beiseite legen und die Asuro Led's blinken lassen bis er den AVR kennengelernt hat.

Pitchriddick
11.11.2006, 15:20
Ich bekome das nicht hin -.- . Wo soll ich dieses Interrupt einbauen, in die Go -Funktion ?

wie rufe ich Interrupts auf?

damaltor
11.11.2006, 17:12
interrupts werden aufgerufen von einem ereignis, z.B. wenn die taster gedrückt werden. also wird die main funktion abgearbeitet, und wenn ein taster gedrückt wird dann hat die main funktion sozusagen pause und die interrupt-routine wird abgearbeitet. wenn die fertig ist, dann geht der prozessor wieder zu der stelle zurück, an der er stehen geblieben ist und macht die main funktion weiter.
bei der programmierun kann ich dir leider nicht helfen, da musst du mal abwarten...

Pitchriddick
11.11.2006, 18:50
Aah, praktische Funktion... Ja so ein Beispiel wäre jetzt nicht schlecht.
KAnn mir da einer weiterhelfen?

Pitchriddick
13.11.2006, 15:12
ich suche immernoch Hilfe ](*,)

damaltor
13.11.2006, 15:14
da hilft schieben aber gar nix... benenn den thread um in "suche hilfe bei interrupt-programmierung", das könnte helfen. (deinen ersten post bearbeiten und dne titel ändern)

EDH
13.11.2006, 16:00
ähem. also wenn du jetzt einfach den thread umbenennst, hast du das problem, das die alten beiträge ja nicht verschwinden. das sieht jetzt ein bisschen merkwürdig aus.

mfg EDH

damaltor
14.11.2006, 10:45
Macht nix... ich zum beispiel klicke immer gleich auf "zum letzten beitrag".

ausserdem sollte das hier keine bedienungsanleitung für das forum sien sondern eine hilfesuche bei der interruptprogrammierung =)

ansonsten: neuen thread (nach benutzuing der suche) aufmachen. irgend jemand muss das hier doch können... ich versuch mich mal da reinzulesen.

Mastermsc
14.11.2006, 14:27
ne sorry, war nichts...

damaltor
15.11.2006, 09:08
Soooo dann will ich dir mal was über interrupts erzählen...
(habe mich selbst dmit noch nicht befasst; ich lese quasi nur vor was ich rausgefunden hab..)

Folgende Interrupts gibt es:

SIG_INTERRUPT0 //kann von einer Erweiterungsplatine genutzt werden
SIG_INTERRUPT1 //Wird von den Tastern verwendet. Dieser Interrupt wird nur dann ausgelöst, wenn vorher StartSwitch() aufgerufen wurde, und wird nicht mehr ausgelöst nachdem StopSwitch() aufgerufen wurde.
SIG_OUTPUT_COMPARE2 //Sowie der Counter2 einen bestimmten Wert erreicht hat, wird dieser Interrupt ausgelöst.
SIG_OVERFLOW2 //Wenn der Counter Überläuft (bzw wieder 0 ist, weil er seinen maximalen Wert Erreicht hat)

(es gibt noch einige andere interrupts, aber die spare ich mir jetzt hier. genaueres dazu im buch "MEHR SPAß MIT ASURO I".

um zu definieren, was beim auslösen eines interrupts (z.B. dem Tasterinterrupt) passieren soll, mach folgendes:

SIGNAL(SIG_INTERRUPT1)
{
Hier deine anweisungen... vergiss auf keinen fall, dass hier StopSwitch stehen muss, sonst wird diese Routine in alle ewigkeiten ausgeführt weil die taster ja immer gedrückt bleiben und der interrupt somit ewig ausgelöst wird.
Beispiel:
Hindernis_entdeckt=1;
StopSwitch();
}

... und in der Main Funktion wird dann, sowie hindernis_entdeckt nicht mehr null ist, eine entsprechende Maßnahme eingeleitet.

Beispiel: die Sleep-Funktion. (nicht Msleep!)

Der Interrupt SIG_OUTPUT_COMPARE2 wird 36000mal pro sekunde aufgerufen. die Routine dazu sieht folgendermaßen aus:

SIGNAL(SIG_OUTPUT_COMPARE2)
{
count36kHz++;
}

Die Variable count36kHz wird also 36000x pro sekunde um eins erhöht.

die Sleep-Funktion sieht folgendermaßen aus:

void Sleep(unsigned char time36kHz)
{
count32kHz=0; //Die Variable, die 36000x pro sekunde erhöht wird, wird auf null gesetzt
while(count36kHz < time36kHz); // in dieser while schleife bleibt der Prozessor so lange, bis count36kHz so weit hoch gezählt wurde dass sie größer ist als time36kHz (der Parameter der Sleepfunktion)
}

Die Sleep Funktion wartet also time36kHz mal 1/36000 sekunden, bevor das programm weiter läuft. und weil in der sleep funktion nur der startwert 0 und die bedingung zum verlassen der schleife steht, wird mit einem 36000mal pro sekunde ausgelöstem interrupt die variable erhöht, um irgendwann wieder rauszukommen aus der sleep funktion.

was noch wichtig ist:

mit sei(); werden alle Interrupts aktiviert.
mit cli(); werden alle interrupts deaktiviert (ACHTUNG! hier kann z.B. die Sleep Funktion eine endlosschleife werden, schliesslich wird count36kHz ja nicht mehr erhöht...)

so ich hoffe, das hilft dir ein wenig... schreib mir wenn nicht =)

viel Glück!