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 07:06] – [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 800: Zeile 413:
  
 // ADJUST AREA START // ADJUST AREA START
-int calibrationDistance = 40; // cm +int calibrationDistance = 40;  // in cm 
-int speed = 200; // Motor speed +int speed               = 200; // Motor speed 
-int dir   = 1; // forward direction 1 or -1+int dir                 = 1;   // change to -1 if forward drive backwards!
 // ADJUST AREA END // ADJUST AREA END
  
Zeile 844: Zeile 457:
 void setup() { void setup() {
   led.setpin(13);   led.setpin(13);
-  Serial.begin(9600);+  //Serial.begin(9600);  // debugging
   ir.begin();   ir.begin();
 } }
Zeile 878: Zeile 491:
   ---------------------------   ---------------------------
 */ */
 +void setLED(int r, int g, int b) {
 +  led.setColorAt(0, r, g, b);
 +  led.setColorAt(1, r, g, b);
 +  led.show();
 +}
  
 int read() { int read() {
   if (ir.decode()) {   if (ir.decode()) {
     uint32_t code = getIRCode();     uint32_t code = getIRCode();
 +
     // Vermeidung wiederholter Eingaben     // Vermeidung wiederholter Eingaben
     unsigned long now = millis();     unsigned long now = millis();
Zeile 888: Zeile 507:
     lastCode = code;     lastCode = code;
     lastTime = now;     lastTime = now;
 +
     //     //
     switch (code) {     switch (code) {
Zeile 970: Zeile 590:
   inputNumber = 0;   inputNumber = 0;
   inputBuffer = "";   inputBuffer = "";
-  led.setColorAt(1, 0, 0, 255); +  setLED(0, 0, 255); // LED BLUE
-  led.setColorAt(0, 0, 0, 255); +
-  led.show();+
 } }
  
Zeile 997: Zeile 615:
     exState = EX_IDLE;     exState = EX_IDLE;
     buzzer.tone(1200, 200);     buzzer.tone(1200, 200);
-    led.setColorAt(1, 0, 0, 0); +    setLED(0, 0, 0); // LED OFF
-    led.setColorAt(0, 0, 0, 0); +
-    led.show();+
   }   }
 } }
Zeile 1008: Zeile 624:
   ---------------------------   ---------------------------
 */ */
- 
 void actionCalibration() { void actionCalibration() {
  
Zeile 1014: Zeile 629:
     return;     return;
  
-  led.setColorAt(1, 255, 0, 0); +  setLED(255, 0, 0); // RED ON
-  led.setColorAt(0, 255, 0, 0); +
-  led.show();+
   int sensorState = lineFinder.readSensors();   int sensorState = lineFinder.readSensors();
  
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 1056: Zeile 669:
     calibrationTravelTime = (ac_movingTimeForward + ac_movingTimeBackward) / 2.0;     calibrationTravelTime = (ac_movingTimeForward + ac_movingTimeBackward) / 2.0;
     ac_calibrationDone = true;     ac_calibrationDone = true;
-    led.setColorAt(1, 0, 0, 0); 
-    led.setColorAt(0, 0, 0, 0); 
-    led.show(); 
     buzzer.tone(1200, 600);     buzzer.tone(1200, 600);
     lastState = STATE_OFF;     lastState = STATE_OFF;
Zeile 1082: Zeile 692:
     return;     return;
  
-  led.setColorAt(1, 0, 255, 0); +  setLED(0, 255, 0); // LED GREEN
-  led.setColorAt(0, 0, 255, 0); +
-  led.show(); +
   motor1.run(-go_forward * speed);   motor1.run(-go_forward * speed);
   motor2.run( go_forward * speed);   motor2.run( go_forward * speed);
Zeile 1092: Zeile 699:
   mm_motorActive    = true;   mm_motorActive    = true;
   mm_firstRunMotor  = false;   mm_firstRunMotor  = false;
- 
 } }
  
Zeile 1109: Zeile 715:
  
   // step: ...calculate distance   // step: ...calculate distance
-  inputDistance = inputBuffer.toInt()+  inputDistance = max(0, min(200, inputBuffer.toInt()))
-  if (inputDistance > 200+
-    inputDistance = 200+
-  }+
   // step: calculate the travel time (for non blocking-method)   // step: calculate the travel time (for non blocking-method)
   double v = (1.0 * calibrationDistance) / (1.0 * calibrationTravelTime);   double v = (1.0 * calibrationDistance) / (1.0 * calibrationTravelTime);
Zeile 1121: Zeile 725:
  
 void actionOff() { void actionOff() {
-  led.setColorAt(1, 0, 0, 0); +  setLED(0, 0, 0); // LED OFF
-  led.setColorAt(0, 0, 0, 0); +
-  led.show(); +
   // reset   // reset
   motor1.stop();   motor1.stop();
Zeile 1144: 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.1740899189.txt.gz · Zuletzt geändert: 2025/03/02 07:06 von torsten.roehl