Ohne zu wissen was der Code machen soll ist es schwer ihn zu korrigieren.
Dein Progamm weiss ab einer bestimmten Stelle garnichtmehr, was es machen soll.
Ich denke der Bug bei 8 Sekunden liegt hier:
--------------------------
If Pina.5 = 1 Then
Call Gerade
End Sub
--------------------------
Da fehlt ein END IF!
Entweder so:
--------------------------
If Pina.5 = 1 Then
Call Gerade
End If
End Sub
--------------------------
oder so:
--------------------------
If Pina.5 = 1 Then Call Gerade
End Sub
--------------------------
Du kannst If in verschiedenen Varianten anwenden (steht aber alles in der Hilfe!!!!)
If a=1 then Gosub Unterprogramm1 Else Gosub Unterprogramm2
oder
If A=1 Then
A=0
Gosub Unterprogramm1
End If
und und und....
Das ist immer abhänig davon was man machen will und wieviele Schritte für eine Bedinung ausgeführt werden sollen.
Zum Programmierstill:
Übersichtlicher und vor allem praktischer ist es, zuerst die Direktiven einzustellen:
----------------------
$regfile = "m16def.dat"
$crystal = 16000000 'Quarzfrequenz
$baud = 9600
----------------------
dann die Ports einstellen:
----------------------
Config Pina.5 = Input
Config Pinc.6 = Output
Config Pinc.7 = Output
Config Pind.4 = Output
Config Pinb.0 = Output
Config Pinb.1 = Output
Config Pind.5 = Output
...
--------------------
Dann Variablen einstellen (hast du jetzt nicht im Programm, ich erzähle es nur der Vollständigkeit halber)
--------------------
Dim A as Byte
Dim C as String * 10
Dim Hollywood as Word
Dim Gerd as Bit
--------------------
Dann sonstiges wie bei dir z.B. die Subs.
--------------------
Declare Sub Turnback()
Declare Sub Gerade()
---------------------
Somit würde der Code am Anfang bis jetzt so aussehen:
----------------------
$regfile = "m16def.dat"
$crystal = 16000000 'Quarzfrequenz
$baud = 9600
Config Pina.5 = Input
Config Pinc.6 = Output
Config Pinc.7 = Output
Config Pind.4 = Output
Config Pinb.0 = Output
Config Pinb.1 = Output
Config Pind.5 = Output
Dim A as Byte
Dim C as String * 10
Dim Hollywood as Word
Dim Gerd as Bit
Declare Sub Turnback()
Declare Sub Gerade()
' Hier folgt das Hauptprogramm
---------------------
Bevor bei dir überhaupt mal was passiert, wird eine Pause von 2 Sekunden eingelegt.
Ist nicht weiter schlimm. Was soll der Bot losfahren, wenn er noch in der Hand ist weil man ihn grade eingeschaltet hat. Aber es ist immer im Einzelfall zu prüfen, ob eine Pause angebracht ist und ob sie wirklich nötig ist. Während einer Pause, macht der AVR wirklich nichts anderes als zu warten das die Zeit abläuft!
Wait 2 ist ok.
Waitms 2000 bewirkt auch eine Pause von 2 Sekunden, aber verbraucht weniger Code. Also wenn möglich Waitms benutzen.
Nachdem alles eingestellt ist (Regfile, Subs, Variablen, ...) kommt normalerweise das Hauptprogramm. Es besteht oft aus einer Schleife, die Endlos läuft und aus der herausgesprungen wird, wenn eine bestimmt Bedinung erfüllt ist.
Ich will mal versuchen, dir das anhand einer (zugegeben blöden) Beispiels zu verdeutlichen.
Du hast deinen freien Tag um liegt im Bett.
Du hast dir für den Tag folgende Regeln aufgestellt:
Um 9:00 machst du Frühstück, aber nur, wenn es nicht regnet. Ansonsten bleibst du liegen.
------------------
Do
If Uhr = 9 then
If regen = 0 then
gosub Frühstückmachen
End if
End if
Loop
Alles zwischen DO und LOOP wird solange ausgeführt, bei der erste Fall (Uhr = 9) eintritt, dann wird geprüft wenn es 9 ist, ob es nicht regnet. Ist das so, wird Frühstück gemacht, bzw in das Unterprogramm gesprungen.
Wenn es nicht 9 ist wird auch nicht abgefragt ob es regnet. Und die Schleife beginnt von vorne. Blöd in diesem Fall ist es, das du nur um 9 Frühstück machen kannst und wenn es um 9 grade regnet musst du im Bett liegen bleiben und verhungern
Also könnte man If Uhr > 9 Then .... abfragen, damit man nach 9 auch noch die Chance auf Essen hat.
Es soll zeigen, das es unsinn wäre um 8 aufzustehen, Frühstück zu machen und dann bis um 9 zu warten und zu merken es regnet und sich wieder ins Bett zu legen bis die Sonne scheint.
So wie du dein Gradeaus und umdrehen erstmal durchläufst ohne das es evtl grade gefordert ist.
In deinem Programm wird immer A.5 abgefragt. Und je machdem im welchen SUB das programm grade ist, sprint es in das andere SUB. Ohne die Schaltung oder denn Sinn des Programms zu kennen ist es mehr als schwer das nachzuvollziehen.
Ich ändere es mal so ab, das wenn A.5=1 ist, eine Kurve gefahren werden soll und wenn nicht es weiter gradeaus geh'n darf.
So könnte das Progamm dann aussehen:
Code:
$regfile = "m16def.dat"
$crystal = 16000000 'Quarzfrequenz
$baud = 9600 'ist im Prinzip überflüssig, weil hier RS232 (noch) nicht genutzt wird.
Config Pina.5 = Input
Config Pinc.6 = Output
Config Pinc.7 = Output
Config Pind.4 = Output
Config Pinb.0 = Output
Config Pinb.1 = Output
Config Pind.5 = Output
' Config Pinc.6 = Output
' Config Pinc.7 = Output
' Config Pind.4 = Output
' Config Pinb.0 = Output
' Config Pinb.1 = Output
' Config Pind.5 = Output
' Die ganzen Pins hattest du schon als Output eingestellt. Es war überflüssig und wäre nicht passiert, wenn alles zusammen aufgelistet gewesen wäre.
' Eine Ausnahme Config PinX.Y mitten im Programm zu schreiben wäre wenn es zu Anfang Output war und dann als Input gebraucht wird.
Declare Sub Turnback()
Declare Sub Gerade()
Waitms 2000
Sound Portd.7 , 350 , 400
Sound Portd.7 , 400 , 500
Waitms 1000
'Hier beginnt das eigentliche Hauptprogramm, indem entschieden wird wo es lang geht.
Do
If Pina.5 = 1 Then Call Turnback
Loop
Sub Gerade()
'Linker Motor ein
Portc.6 = 1
Portc.7 = 0
Portd.4 = 1
'Rechter Motor ein
Portb.0 = 1
Portb.1 = 0
Portd.5 = 1
Waitms 3000
End Sub
Sub Turnback
'Linker Motor ein
Portc.6 = 0
Portc.7 = 1
Portd.4 = 1
'Rechter Motor ein
Portb.0 = 0
Portb.1 = 1
Portd.5 = 1
Waitms 350
Portc.6 = 0
Portc.7 = 1
Portd.4 = 0
Portb.0 = 0
Portb.1 = 1
Portd.5 = 1
Sound Portd.7 , 400 , 400
Sound Portd.7 , 350 , 400
Waitms 1000 'in dieser Sekunde passiert nichts, außer warten!!!
End Sub
End
Ob der Code in den Subs selbst so richtig ist weiss ich nicht.
Ich hoffe es hilft etwas. Und bei Problemen zu bestimmten Befehlen erstmal die Hilfe benutzen. Am einfachsten ist es, wenn du mit dem Cursor auf den Befehl gehst und F1 drückst. Dann kommt sofort die Hilfe zum jeweiligen Befehl.
Oder hier im Forum nach den Befehlen suchen. Da findest du auch viele Beispiele und siehst Lösungsansätze.
Lesezeichen