Zitat Zitat von timmy19 Beitrag anzeigen
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:
  1. int zahl = 5; -> Arbeitsspeicher für die Variable "zahl" reservieren und 5 reinspeichern
  2. if( zahl>100) -> Ist denn zahl > 100? NEIN, denn zahl ist 5. Also kann der nächste Befehl (also die { blabla } ) übersprungen werden
  3. zahl = 5000; -> Gut, dann speichern wir 5000 in den Arbeitsspeicher der für "zahl" reserviert ist
  4. 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 Zitat von timmy19 Beitrag anzeigen
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 Zitat von timmy19 Beitrag anzeigen
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..