Benutzer-Werkzeuge

Webseiten-Werkzeuge


mbot_streckenfahren

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
mbot_streckenfahren [2025/03/02 10:54] – [Quellcode (engl. Sourcecode)] torsten.roehlmbot_streckenfahren [2025/03/02 14:38] (aktuell) – [Erklärungen zum Quellcode] torsten.roehl
Zeile 1: Zeile 1:
 ====== mBot Streckenfahren ====== ====== mBot Streckenfahren ======
- 
-FIXME  <color #ed1c24>ABSCHNITT ENTSTEHT GERADE! - CODE NICHT GETESTET! 
-</color> 
- 
 //Der mBot kann, gesteuert über die Infrarot-Fernbedienung, eine zuvor eingegebene Strecke vorwärts oder rückwärts fahren. //Der mBot kann, gesteuert über die Infrarot-Fernbedienung, eine zuvor eingegebene Strecke vorwärts oder rückwärts fahren.
  
Zeile 393: Zeile 389:
 </WRAP> </WRAP>
  
-==== Quellcode (engl. Sourcecode) ==== 
  
-<Code c linenums:1 | Listing 1:MinimalesProgramm.ino> 
-#include "MeMCore.h" 
- 
-// Hardware 
-MeIR ir; 
-MeBuzzer buzzer; 
-MeLineFollower lineFinder(PORT_2); 
-MeRGBLed led(0, 2);   // must be fixed! 
-MeDCMotor motor1(M1); 
-MeDCMotor motor2(M2); 
- 
-// IR-Entprellen 
-static uint8_t lastCode = 0xFF; 
-static unsigned long lastTime = 0; 
-const unsigned long COOL_DOWN = 1000; // in Millisekunden, also 1 Sekunde 
- 
-// Allgemein 
-unsigned long calibrationTravelTime; 
-unsigned long currentTravelTime = 100; 
- 
-// ADJUST AREA START 
-int calibrationDistance = 40; // cm 
-int speed = 180; // Motor speed 
-// ADJUST AREA END 
- 
-// actionCalibration... 
-unsigned long ac_movingStartTimeForward  = 0; 
-unsigned long ac_movingTimeForward = 0; 
-unsigned long ac_movingStartTimeBackward = 0; 
-unsigned long ac_movingTimeBackward = 0; 
-bool ac_isMoving = false; 
-bool ac_isForwardMoving = false; 
-bool ac_isBackwardMoving = false; 
-bool ac_calibrationDone = false; 
- 
-// actionForward 
-bool af_firstRunMotor = true;     // erstes Starten? 
-bool af_motorActive   = false;    // Motorzustand? 
-unsigned long af_motorStartTime = 0; 
-// actionBackward 
-bool ab_firstRunMotor = true;     // erstes Starten? 
-bool ab_motorActive   = false;    // Motorzustand? 
-unsigned long ab_motorStartTime = 0; 
- 
-//FSM 
-enum State { 
-  STATE_OFF, 
-  STATE_BACKWARD, 
-  STATE_CALIBRATION, 
-  STATE_DISTANCE, 
-  STATE_FORWARD 
-}; 
- 
-State state     = STATE_OFF; 
-State lastState = STATE_OFF; 
- 
-enum ExState { 
-  EX_IDLE, 
-  EX_WAIT_FOR_INPUT 
-}; 
-ExState exState       = EX_IDLE; 
-int     inputNumber   = 0;    // Anzahl der eingegebenen Stellen 
-String  inputBuffer   = "";   // Sammeln der Ziffern als Text 
-int     inputDistance = 0;    // Konvertierte Eingabe 
- 
-void setup() { 
-  led.setpin(13); 
-  Serial.begin(9600); 
-  ir.begin(); 
-} 
- 
-void loop() { 
-  // step: command (IR-Taste einlesen) 
-  int cmd = read(); 
-  // step: state bestimmen 
-  state  = decode(cmd); 
-  // step: zustandsabhängige Aktion 
-  switch (state) { 
-    case STATE_CALIBRATION: 
-      actionCalibration(); 
-      break; 
-    case STATE_FORWARD: 
-      actionForward(); 
-      break; 
-    case STATE_BACKWARD: 
-      actionBackward(); 
-      break; 
-    case STATE_DISTANCE: 
-      actionDistance(); 
-      break; 
-    case STATE_OFF: 
-      actionOff(); 
-      break; 
-  } 
-} 
- 
-/* 
-  --------------------------- 
-  Funktionen 
-  --------------------------- 
-*/ 
- 
-int read() { 
-  if (ir.decode()) { 
-    uint32_t code = getIRCode(); 
-    // Vermeidung wiederholter Eingaben 
-    unsigned long now = millis(); 
-    if (code == lastCode && (now - lastTime < COOL_DOWN)) 
-      return -1; 
-    lastCode = code; 
-    lastTime = now; 
-    // 
-    switch (code) { 
-      case IR_BUTTON_E: 
-        buzzer.tone(1200, 200); 
-        return 0;  // STATE_OFF 
-        break; 
-      case IR_BUTTON_B: 
-        buzzer.tone(1200, 200); 
-        return 1;  // STATE_BACKWARD 
-        break; 
-      case IR_BUTTON_C: 
-        buzzer.tone(1200, 200); 
-        return 2;  // STATE_CALIBRATION 
-        break; 
-      case IR_BUTTON_D: 
-        initInput(); 
-        return 3;  // STATE_DISTANCE 
-        break; 
-      case IR_BUTTON_F: 
-        buzzer.tone(1200, 200); 
-        return 4;  // STATE_FORWARD 
-        break; 
- 
-      // Ziffern 0–9 
-      case IR_BUTTON_0: handleInput(0); break; 
-      case IR_BUTTON_1: handleInput(1); break; 
-      case IR_BUTTON_2: handleInput(2); break; 
-      case IR_BUTTON_3: handleInput(3); break; 
-      case IR_BUTTON_4: handleInput(4); break; 
-      case IR_BUTTON_5: handleInput(5); break; 
-      case IR_BUTTON_6: handleInput(6); break; 
-      case IR_BUTTON_7: handleInput(7); break; 
-      case IR_BUTTON_8: handleInput(8); break; 
-      case IR_BUTTON_9: handleInput(9); break; 
- 
-      // Taste 'Setting' = Eingabe abschließen 
-      case IR_BUTTON_SETTING: 
-        finalizeInput(); 
-        return -1;  // Kein direkter Zustandswechsel 
-        break; 
-    } 
-  } 
-  return -1; // keine bekannte/verwertbare Taste 
-} 
- 
-uint32_t getIRCode() { 
-  uint32_t value = ir.value; 
-  value = (value >> 16) & 0xff; 
-  return value; 
-} 
- 
-State decode(int cmd) { 
-  switch (cmd) { 
-    case 0: 
-      lastState = STATE_OFF; 
-      return STATE_OFF; 
-    case 1: 
-      lastState = STATE_BACKWARD; 
-      return STATE_BACKWARD; 
-    case 2: 
-      lastState = STATE_CALIBRATION; 
-      return STATE_CALIBRATION; 
-    case 3: 
-      lastState = STATE_DISTANCE; 
-      return STATE_DISTANCE; 
-    case 4: 
-      lastState = STATE_FORWARD; 
-      return STATE_FORWARD; 
-  } 
- 
-  return lastState; 
-} 
- 
-/* 
-  --------------------------- 
-  Eingabemodus für EX-Befehle 
-  --------------------------- 
-*/ 
-void initInput() { 
-  buzzer.tone(1000, 200); 
-  exState     = EX_WAIT_FOR_INPUT; 
-  inputNumber = 0; 
-  inputBuffer = ""; 
-} 
- 
-void handleInput(int number) { 
- 
-  if (exState != EX_WAIT_FOR_INPUT) return; 
- 
-  // Maximal 3 Stellen erlauben 
-  if (inputNumber >= 3) { 
-    buzzer.tone(300, 300); 
-    delay(200); 
-    buzzer.tone(300, 300); 
-    return; 
-  } 
- 
-  // Zahl anhängen 
-  inputBuffer += String(number); 
-  inputNumber++; 
-  buzzer.tone(1200, 80); 
-} 
- 
-void finalizeInput() { 
-  if (exState == EX_WAIT_FOR_INPUT) { 
-    exState = EX_IDLE; 
-    buzzer.tone(1200, 200); 
-  } 
-} 
- 
-/* 
-  --------------------------- 
-  Funktionen ...actionXXX 
-  --------------------------- 
-*/ 
- 
-void actionCalibration() { 
- 
-  if (ac_calibrationDone) 
-    return; 
- 
-  led.setColorAt(1, 255, 0, 0); 
-  led.setColorAt(0, 255, 0, 0); 
-  led.show(); 
-  int sensorState = lineFinder.readSensors(); 
- 
-  // step - start moving forward 
-  if (!ac_isMoving) { 
-    motor1.stop(); 
-    motor2.stop(); 
-    motor1.run(-speed); 
-    motor2.run(speed); 
-    ac_movingStartTimeForward = millis(); 
-    ac_isMoving = true; 
-    ac_isBackwardMoving = true; 
-    do { 
-      sensorState = lineFinder.readSensors(); 
-    } while ( sensorState != S1_OUT_S2_OUT); 
-  } 
- 
-  // step - end moving forward ... start moving backward 
-  if (ac_isBackwardMoving && sensorState == S1_IN_S2_IN) { 
-    motor1.stop(); 
-    motor2.stop(); 
-    ac_movingTimeForward = millis() - ac_movingStartTimeForward; 
- 
-    motor1.run(speed); 
-    motor2.run(-speed); 
-    ac_movingStartTimeBackward = millis(); 
-    do { 
-      sensorState = lineFinder.readSensors(); 
-    } while ( sensorState != S1_OUT_S2_OUT); 
-    ac_isBackwardMoving = false; 
-    ac_isForwardMoving  = true; 
-  } 
- 
-  // step - end turing right 
-  if (ac_isForwardMoving && sensorState == S1_IN_S2_IN) { 
-    motor1.stop(); 
-    motor2.stop(); 
-    ac_movingTimeBackward = millis() - ac_movingStartTimeBackward; 
-    calibrationTravelTime = (ac_movingTimeForward + ac_movingTimeBackward) / 2.0; 
-    ac_calibrationDone = true; 
-    led.setColorAt(1, 0, 0, 0); 
-    led.setColorAt(0, 0, 0, 0); 
-    led.show(); 
-    buzzer.tone(1200, 600); 
-    lastState = STATE_OFF; 
- 
-  } 
-} 
- 
-void actionForward() { 
-  unsigned long currentMillis = millis(); 
- 
-  // Wenn der Motor aktuell läuft, prüfen wir, ob die Zeit abgelaufen ist 
-  if (af_motorActive) { 
-    if (currentMillis - af_motorStartTime >= currentTravelTime) { 
-      // Zeit ist um → Motor stoppen 
-      motor1.stop(); 
-      motor2.stop(); 
-      af_motorActive = false; 
-      state = STATE_OFF; 
-      lastState = STATE_OFF; 
-    } 
-    // Funktion verlassen 
-    return; 
-  } 
- 
-  if (!af_firstRunMotor) 
-    return; 
- 
-  motor1.run(-speed); 
-  motor2.run(speed); 
-  af_motorStartTime = currentMillis; 
-  af_motorActive    = true; 
-  af_firstRunMotor  = false; 
-} 
- 
-void actionBackward() { 
-  unsigned long currentMillis = millis(); 
- 
-  // Wenn der Motor aktuell läuft, prüfen wir, ob die Zeit abgelaufen ist 
-  if (ab_motorActive) { 
-    if (currentMillis - ab_motorStartTime >= currentTravelTime) { 
-      // Zeit ist um → Motor stoppen 
-      motor1.stop(); 
-      motor2.stop(); 
-      ab_motorActive = false; 
-      state = STATE_OFF; 
-      lastState = STATE_OFF; 
-    } 
-    // Funktion verlassen 
-    return; 
-  } 
- 
-  if (!ab_firstRunMotor) 
-    return; 
-     
-  motor1.run(speed); 
-  motor2.run(-speed); 
-  ab_motorStartTime = currentMillis; 
-  ab_motorActive    = true; 
-  ab_firstRunMotor  = false; 
- 
-} 
- 
-void actionDistance() { 
-  //Serial.println("...actionDistance"); 
-  // noch in der Eingabe? 
-  if (exState == EX_WAIT_FOR_INPUT) { 
-    return; 
-  } 
-  // step: ...calculate distance 
-  inputDistance = inputBuffer.toInt(); 
-  if (inputDistance > 200) { 
-    inputDistance = 200; 
-  } 
-  // step: calculate the travel time (for non blocking-method) 
-  double v = (1.0 * calibrationDistance) / (1.0 * calibrationTravelTime); 
-  currentTravelTime = inputDistance / v; 
-  // Serial.print("Eingegebene Distance: "); 
-  // Serial.println(inputDistance); 
-} 
- 
-void actionOff() { 
-  led.setColorAt(1, 0, 0, 0); 
-  led.setColorAt(0, 0, 0, 0); 
-  led.show(); 
-  // reset 
-  motor1.stop(); 
-  motor2.stop(); 
- 
-  // reset state calibration 
-  ac_isMoving         = false; 
-  ac_isForwardMoving  = false; 
-  ac_isBackwardMoving = false; 
-  ac_calibrationDone  = false; 
- 
-  // reset state forward 
-  af_firstRunMotor = true; 
-  af_motorActive   = false; 
-  af_motorStartTime = 0; 
-  // reset state backward 
-  ab_firstRunMotor = true; 
-  ab_motorActive   = false; 
-  ab_motorStartTime = 0; 
-  // reset state distance 
-  exState       = EX_IDLE; 
-} 
-</Code> 
 ==== Quellcode (engl. Sourcecode) ==== ==== Quellcode (engl. Sourcecode) ====
  
Zeile 1039: Zeile 652:
     motor2.stop();     motor2.stop();
     ac_movingTimeForward = millis() - ac_movingStartTimeForward;     ac_movingTimeForward = millis() - ac_movingStartTimeForward;
-    motor1.run(dir * speed); +    motor1.run( dir * speed); 
-    motor2.run( -dir * speed);+    motor2.run(-dir * speed);
     ac_movingStartTimeBackward = millis();     ac_movingStartTimeBackward = millis();
     do {     do {
Zeile 1132: Zeile 745:
 } }
 </Code> </Code>
 +==== Erklärungen zum Quellcode ====
 +=== ⚙️ Setup (setup()) ===
 +Initialisiert die IR-Fernbedienung und setzt den LED-Pin.  
 +  * ''ir.begin()'' → Startet die IR-Signalverarbeitung.  
 +  * ''led.setpin(13)'' → Setzt den LED-Steuerpin.  
 +
 +=== 🔄 Loop (loop()) ===
 +  - **Liest IR-Signale (''read()'')**  
 +  - **Bestimmt den aktuellen Zustand (''decode()'')**  
 +  - **Führt die passende Aktion aus (`actionXXX()`)**  
 +
 +=== 🚦 Zustandsbezogene Aktionen (actionXXX()) ====
 +  * **''actionForward()'' / ''actionBackward()''** → startet Motoren für Vorwärts-/Rückwärtsfahrt.  
 +  * **''actionDistance()''** → Berechnet die Fahrtzeit basierend auf eingegebener Distanz.  
 +  * **''actionCalibration()''** → Bestimmt die Fahrzeit für eine feste Strecke mit dem Linienfolger.  
 +  * **''actionOff()''** → Stoppt alle Motoren und setzt den Zustand zurück.  
 +
 +=== ⌨️ Eingabeverarbeitung (handleInput(), finalizeInput()) ===
 +  - Ermöglicht die Eingabe einer numerischen Distanz per IR-Fernbedienung.  
 +  - ''handleInput(int number)'' → Fügt eine Zahl zur Eingabe hinzu.  
 +  - ''finalizeInput()'' → Wandelt den Eingabewert in eine Strecke um.  
 +
 +=== ⚙️ Die ADJUST AREA ===
 +Hier können **drei zentrale Parameter** angepasst werden:  
 +  * **''calibrationDistance = 40''** → Standardstrecke für die Kalibrierung in cm.  
 +  * **''speed = 200''** → Geschwindigkeit der Motoren.  
 +  * **''dir = 1''** → Richtungskorrektur für Vorwärtsbewegung. 
 +          * Falls das Fahrzeug rückwärts fährt, auf ''-1'' setzen.  
  
 +Die Werte beeinflussen das Fahrverhalten direkt und sollten je nach Umgebung angepasst werden.  
  
  
mbot_streckenfahren.1740912887.txt.gz · Zuletzt geändert: 2025/03/02 10:54 von torsten.roehl