PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Blutiger Anfänger mit ein paar Fragen



Foooob
08.04.2005, 16:22
Hallo

Ich bin gerade dabei das Programm für meinen Bot zu schreiben.
Der Bot verfügt am Anfang (tja das Geld ^^) nur über 2 Kollisionstaster als Sensoren. Die Taster sind links und rechts von der Front des Bots positioniert.

Wenn der (auf die Wand gesehen) linke Sensor was meldet, soll der Bot seine 2 Räder gegeneinander drehen (nocht nicht das Problem) und das nur für eine ganz bestimmte Zeit. Maybe 1,5s. Wie mache ich das genau mit der Zeit?

Hier mal mein ganzer Code:


'Version 1.0
'----------------------------------------------------------
$regfile = "m8def.dat" 'ATmega8
$crystal = 3686411 'Quarz: 3686411 Hz

Ddrd = &B01111000 'Pin PD3 bis PD6 als Ausgänge
Portd = &B00000000 'Pin PD3 bis PD6 auf Low

Ddrb = &B00000000 'Pin PB4 und 5 als Eingang
Portb = &B00110000 'Pin PB4 und 5 auf High

Do
Portd.3 = 1 'Motoren drehen in gleiche Richtung
Portd.5 = 1

If Pinb.4 = 0 Then
Portd.3 = 1
Portd.4 = 0
Portd.5 = 0
Portd.6 = 1 'Motoren drehen gegeneinander
Else
Portd.3 = 1
Portd.4 = 0
Portd.5 = 1
Portd.6 = 0
Loop
End



Bitte die Motoreneingänge und deren Anschlüsse mal außen vor lassen. Habe ich nur kurz geschrieben, ich weis ned ob der so entgegensetzt drehen würde. Dienen nur als Orientierung. Es geht ja eher um die Dauer.

Würde das so denn bis jetzt funktionieren? Die Platine ist leider noch nicht fertig, möchte mich nur mal im Vorfeld damit vertrauter machen damits nachher leichter läuft.

RCO
08.04.2005, 16:29
Du könntest einen Wait-Befehl einfügen:
wait 1 'eine Sekunde warten
waitms 1500 '1,5 sekunden warten

Foooob
08.04.2005, 16:33
Naja er soll ja nicht warten, er soll ja die If-Schleife eine ganz bestimmte Zeit lang durchführen.

tobimc
08.04.2005, 16:41
Hi!

Hm. Das ist schon schwiriger! Du könntest einen Timer 1,5 Sec warten lassen, und dann in der ISR eine Variable ändern, die dann die IF-Abfrage abschaltet.

Also mal quick & dirty:



'* Timer Configurieren und starten

Dim stop as byte

stop = 255

'...
'...

'* Timer Starten

Do while stop = 255

' Hier dein Code... ... ... ...

loop


'rest d. codes... ... ...

'...
'...

End



timer_ISR:
'... Initialisierungs. und anderer Kram
stop = 0



Grüße,
Tobi

RCO
08.04.2005, 16:44
Also er soll doch, wenn er die Wnad berührt (Pinb.4 = 0?) sich 1,5 Sekunden lang drehen und dann weiter fahren, oder? Ich gehe mal davon aus, das PortD.3 bis 6 die Richung vorgeben?!

Also eignetlich musst du doch nur die Ausgägne so setzen wie du willst, 1, 5 Sekunden warten und dann wieder zurücksetzen. Leider werde ich aus deinem Code nciht ganz schlau, aus deiner Frage leider auch nicht :mrgreen:

tobimc
08.04.2005, 16:47
HI RCO!

Vielleicht möchte er während des drehens weitere Kollisionschecks druchfüren... :D

Grüße,
tobi

RCO
08.04.2005, 16:51
Dann wäre eigentlich sinnfoller, die Sensoren direkt über Interrupts laufen zu lassen. Man könnte z.B. auch mehrere Kollisionstaster über Dioden an einen Interrupt legen und dann in der Routine schauen, welcher Taster es denn nun war.

Foooob
08.04.2005, 16:55
Ok ich versuchs mal zu erklären, war glaub echt Käse ;)

Am Besten wir fangen nochmal von vorne an.

Also mal angenommen am Pin PB4 wäre ein Taster
Sobald der Taster gedrückt wird soll/ist PINB.4 = 0.
Daraufhin sollen die Motorenausgänge zum Einleiten des Ausweichens eingeleitet werden.

Portd.3 = 1 für Motor 1 bekommt Saft und Portd.6 = 1 für Motor 2 ebenfalls. Die anderen 2 Ausgänge für die Motoren stehen so lange auf 0 (Portd.4 = 0 ; Portd.5 = 0). Die Motoren drehen jetzt gegeneinander und er wendet sich. Das soll er dann zum Beispiel 1,5s lang tun und danach in die Hauptroutine zurückfallen in denen er den Pins PD3 und PD5 Saft gibt und die anderen 2 auf Null setzt.

tobimc
08.04.2005, 17:02
Hi!

Ja! Dann ist deine Funktion wait 1 oder waitms 1500.

Also (quick & dirty):



'Code drehsequenz einleiten

waitms 1500

'Weiterer Code



Wie RCO das so meint.
Interrupts sind sowieso eine super Idee!

Grüße,
Tobi

RCO
08.04.2005, 17:12
Vielleicht besteht da ein Missverständniss, "wait" heißt ja nicht, das er garnix macht, sondern nur das der Prozessor nix macht, alle Zustände bleiben ja erhalten, hast du also Pins/Ports gesetzt und sagst "Waitms 1500" dann wird er, wenn vorher so eingestellt sich 1,5 Sekunden lang drehen.

Foooob
08.04.2005, 17:20
Ach so ist das mit dem Wait, vielen Dank.

Ja, Interrupts wären wirklich besser, aber das halte ich mir offen und verwende diese später dann bei den IR-Sensoren.

teslanikola
08.04.2005, 17:22
Also wenn ich deine idee richtig verstandenhabe, dann muss bei deinem Motortreiber ( nehme an es is nen IC oder auch nicht ) am eingang ein Betimmter Pin ( oder ein Transistor ) mit 1 ( + ) angesteuert werden. so und jetzt dein Rückwärtsfahren auf Zeit problem. Du willst das sich beide motoren für die zeit X entgegengesetzt drehen wenn Taster1 oder 2 geschaltet wird. Dein erster code war nicht schlecht, wenn du wie schon erwähnt noch nen WAIT befehl einbaust währe das echt gut, weil wenn der Controler wartet bleiben die ausgänge beschaltet ( also 1 oder 0 ).

'Version 1.0
'----------------------------------------------------------
$regfile = "m8def.dat" 'ATmega8
$crystal = 3686411 'Quarz: 3686411 Hz

Ddrd = &B01111000 'Pin PD3 bis PD6 als Ausgänge
Portd = &B00000000 'Pin PD3 bis PD6 auf Low

Ddrb = &B00000000 'Pin PB4 und 5 als Eingang
Portb = &B00110000 'Pin PB4 und 5 auf High

Do
Portd.3 = 1 'Motoren drehen in gleiche Richtung
Portd.5 = 1

If Pinb.4 = 0 Then
Portd.3 = 1
Portd.4 = 0
Portd.5 = 0
Portd.6 = 1
Waitms 1500 'Motoren drehen sich 1,5 sek. gegeneinander
'Else kannste weglassen
'Portd.3 = 1
'Portd.4 = 0
'Portd.5 = 1
'Portd.6 = 0
Loop
End
so Hab ich auch angefangen ( alerdings mit Phototransistoren als "taster" )

Foooob
08.04.2005, 17:24
Danke nochmals.
Japp der Motortreiber ist ein IC, nämlich der L298 (Getriebemotoren)