
Zitat von
timmy19
Wie kann ich es so programmieren, dass er das Infrarot erst dann einschaltet, wenn er sich schonmal gedreht hat?
Also ich habe schon mehreren Leuten (im echten Leben
) C beigebracht. Und diese Frage bestätigt einen Verdacht den ich schon vorher hatte, nämlich dass du noch nicht ganz verstanden hast wie ein Programm abläuft. Komischerweise scheint das aber vielen Leuten zuerst nicht in den Kopf zu gehen, nur die wenigsten checken es sofort..
Desshalb erkläre ich noch bevor irgend ein Code gezeigt wird folgendes:
Stell dir vor du liest eine Bedienungsanleitung. Wie machst du das? Na klar, Schritt für Schritt, und nebenbei machst du immer das was in diesem Schritt zu tun ist. Das was du vorher gemacht hast und was du später machen musst spielt in diesem Moment keine Rolle.
Was du machst wenn du programmierst ist eine Bedienungsanleitung für den Mikrocontroller schreiben. Und der ließt die auch nicht irgendwie durcheinander oder macht alles gleichzeitig, sonder auch streng Schritt für Schritt. Und zwar Zeile für Zeile von oben nach unten. Beispiel:
Code:
int main (void)
{
int zahl = 5;
if( zahl>100)
{
Alarm_Einschalten();
}
zahl = 5000;
return 0; // Programmende
}
Ganz einfach: Eine Variable "zahl" wird mit dem Inhalt 5 erstellt. Wenn die zahl größer 100 ist wird Alarm ausgelöst, und dann wird 5000 in zahl geschrieben.
Was ich denke dass du vermutest dass passiert: sobald das "zahl = 5000;" ausgeführt wird, wird Alarm ausgelöst.
DAS IST NICHT SO 
Denk dir du bist ein Mikrocontroller und liest das Programm, was du tust ist:
- int zahl = 5; -> Arbeitsspeicher für die Variable "zahl" reservieren und 5 reinspeichern
- if( zahl>100) -> Ist denn zahl > 100? NEIN, denn zahl ist 5. Also kann der nächste Befehl (also die { blabla } ) übersprungen werden
- zahl = 5000; -> Gut, dann speichern wir 5000 in den Arbeitsspeicher der für "zahl" reserviert ist
- return 0; -> Programmende. Habe fertig.
Du wirst jetzt warscheinlich sagen: "Ja, aber bei Schritt 3 speichere ich ja 5000 in Zahl, da muss ich doch den Alarm einschalten!". NEIN. Der Mikrocontroller merkt sich nicht was vorher war, er macht folgt strikt Zeile für Zeile den Befehlen. (wie ich schrieb: "Das was du vorher gemacht hast und was du später machen musst spielt in diesem Moment keine Rolle.").
Zurück zu deiner Frage:

Zitat von
timmy19
Wie kann ich es so programmieren, dass er das Infrarot erst dann einschaltet, wenn er sich schonmal gedreht hat?
Und dann den Code:
Code:
#include "qfixMiniBoard.h"
#include "qfixLCD.h"
MiniBoard robot;
// Müssen evtl. angepasst werden:
#define HindernisAbstand 85
#define Schwarzwert 180
#define Drehgeschwindigkeit 25
#define Drehzeit 3000 // in ms
#define Fahrgeschwindigkeit 25
// Feste Konstanten:
#define SensorAbstand 1
#define SensorInfrarot 3
#define Links 1
#define Rechts 2
int main()
{
// Es wird davon ausgegangen, dass der Robo so los fährt wie auf deiner Skizze, also auf der rechten Seite (und somit als erstes nach links muss):
unsigned char naechsteAbbiegungNach = Links
while(1)
{
robot.motors(Fahrgeschwindigkeit,Fahrgeschwindigkeit); // Zuerst mal geradeaus fahren
while(robot.analog(SensorAbstand)>HindernisAbstand); // Und so lange kein Hindernis in sicht nichts anderes tun
robot.motors(0,0); // Jetzt muss ein Hindernis da sein, also erst mal stehen bleiben
if(naechsteAbbiegungNach == Links) // Wenn wir jetzt als nächstes nach links müssen...
robot.motors(-Drehgeschwindigkeit, Drehgeschwindigkeit); // ..drehen wir mal nach links
else if(naechsteAbbiegungNach == Rechts)
robot.motors(Drehgeschwindigkeit, -Drehgeschwindigkeit);
msleep(Drehzeit); // Da es keinen Anhaltspunkt gibt, wie weit nach links, einfach mal eine bestimmte Zeit lang...
robot.motors(Fahrgeschwindigkeit,Fahrgeschwindigkeit); // Und wenn fertig gedreht wieder geradeaus fahren (jetzt bewegt sich der Robo von einer Seite zur anderen)
while(robot.analog(SensorInfrarot)<Schwarzwert); // Solange der Infrarotwert nicht "schwarz" bedeuted, nichts weiter machen
robot.motors(0,0); // Jetzt muss der schwarze Punkt da sein, also erst mal stehen bleiben
// Bsp. für Linksabbiegung: Um die Linksabbiegung abzuschließen muss der Robo sich jetzt wieder nach rechts drehen, damit er wieder gerade steht.
if(naechsteAbbiegungNach == Links)
robot.motors(Drehgeschwindigkeit, -Drehgeschwindigkeit);
else if(naechsteAbbiegungNach == Rechts) // Und um die Rechtsabbiegung abzuschließen nach links drehen
robot.motors(-Drehgeschwindigkeit, Drehgeschwindigkeit);
msleep(Drehzeit); // Da es keinen Anhaltspunkt gibt, wie weit nach links, einfach mal eine bestimmte Zeit lang...
robot.motors(0,0); // fertig gedreht
// So, jetzt hat der Roboter entweder von der rechten auf die linke Seite gewechselt (Linksabbiegung) oder anders herum. Da er durch das zweite Drehen in die andere Richtung
// jetzt auch wieder gerade steht und auf das nächste Hindernis zufahren kann, geht das ganze wieder von vorne losgehen. Nur müssen wir vorher noch die nächste Abbiegung bestimmen,
// die logischerweise genau das Gegenteil von der letzten Abbiegung ist:
if(naechsteAbbiegungNach == Links)
naechsteAbbiegungNach == Rechts;
else if(naechsteAbbiegungNach == Rechts)
naechsteAbbiegungNach == Links;
}
return 0; // Keine Relevanz für den Programmablauf, gehört sich aber für ein sauberes C-Programm
}
Wenn du jetzt nach dem auslesen des Infrarotsensors suchst, wirst du feststellen, dass er nur in der rot markierten Zeile eine vorkommt. In allen anderen Zeilen ist der Infrarotsensore absolut piepschnurzegal! (<- Nicht möchte es nur deutlich genug sagen
) Jetzt merkst du hoffentlich, dass deine Frage keinen Sinn ergibt..

Zitat von
timmy19
Also: Wenn ich ihn so hinsetzte wie bei der Skizze macht er nichts anderes als die dunkle Farbe suchen(Wert 180) und sich darüber im Kreis zu drehen...
Analyse (Versuche es im Quelltext nachzuvollziehen, das grüne entspricht deiner Frage):
- Über der roten Zeile fährt er geradeaus
- In der roten Zeile macht er nichts, solange er den schwarzen Punkt noch nicht gefunden hat
- Dann bleibt er stehen (er hat den Punkt gefunden)
- Dann dreht er je nach Drehrichtung (mit den if's)
- wartet für 3 Sekunden
- Er bleibt stehen
- Dann wechselt er die "nächsteAbbiegungNach" und springt an den Anfang de while-Schleife
- Dann fährt er geradeaus, ändert nichts bis er das Hindernis gefunden hat, bleibt dann stehen
- Er dreht sich wieder für 3 Sekunden
- Fährt dann wieder geradeaus, bzw erster Punkt dieser Aufzählung
Man könnte jetzt also zur Annahme kommen dass deine Entfernungsmessung nicht funktioniert und immer ein Hindernis sieht (rote Zeile).
(Und im übrigen wird man das stehenbleiben auch nicht sehen könne, weil er sofort danach auf eine andere Bewegung umschaltet)
ABER: Dann müsste sich der Robo 3+3 Sekunden in die eine und dann 3+3 Sekunden in die andere Richtung drehen. Du hast aber nicht präzise genug geantwortet, so dass man nicht weis, was der Robo genau tut. Eine richtige Antwort wäre gewesen:
Wenn ich den Robo wie in der Skizze auf seine Startposition setze, ihn
dann einschalte fährt er nur geradeaus. Außer er findet einen schwarzen Punkt, dann dreht er sich auf ihm nach
links und hört auch nach ca.
20 Sekunden nicht damit auf
Ich habe das was du nicht gesagt hast rot markiert:
- Einschalten: Nur so kann man davon ausgehen, dass der Roboter sein Programm auch von vorne an abarbeitet, und nicht "irgendwo mitten in der Bedienungsanleitung drin steckt" wenn du ihn auf seine Startposition setzt
- links: Wenn er sich nur in eine Richtung dreht, stimmt jedenfalls noch mehr nicht als eine nichtfunktionierende Abstandsmessung
- 20 Sekunden: Wenn nur die Abstandsmessung nicht funktioniert, wechselt er alle 3+3 = 6 Sekunden die Drehrichtung. Man weis jetzt nicht; vielleicht hast du den Robo nur für 5 Sekunden drehen lassen?
Ich hoffe deinem Grundverständnis für Programmcode ein wenig auf die Sprünge geholfen zu haben. Nur leider ist es sehr schwer das jemandem übers Internet beizubringen.. Und wenn du ganz ganz genaue Angaben machst was ganz genau der Robo tut und ihn auch sicher erst einschaltest wenn er auf seiner Startposition sitzt, dann bekommen wir das Ding vielleicht noch zum laufen..
Lesezeichen