Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Linienfolger-Roboter mit PID-Regelung & Android-App (MIT App Inventor)

Komponenten und Zubehör

BauteilAnzahlHinweis
Arduino Nano R31Hauptcontroller
TCRT5000 4-Kanal IR-Liniensensor-Modul14 Sensoren auf einer Platine
Einzelner TCRT5000 Sensor (5. Sensor)1Für 5er-Array (bessere Auflösung)
HC-06 Bluetooth-Modul1Serielle BT-Kommunikation
2× Continuous Rotation Servo (SM-S4303R)2360° Dauerlauf, Ansteuerung per µs-Puls
Android-Gerät1Für PID-Tuning per App
2× 4×AA NiMH-Akku-Halter (5 V je Satz)2Einer für Servos, einer für Arduino (Vin)
Kugelrad (Ball Caster)1Drittes Rad, lenkbar
Chassis: 2× Holzplatte 80×80 mm, 3× Binderclips, 2× Holzräder 50 mm, Gummibänder, 3M Command-Strips1 SatzLow-Cost, flexibel
Breadboard, Jumper-Kabel, LED, Tasternach Bedarf

Software & Apps

Projektziel

Bau eines Linienfolger-Roboters mit PID-Regelung für präzises, schnelles Spuren. Ein Android-App (via Bluetooth) ermöglicht Live-Tuning der PID-Parameter (Kp, Ki, Kd) sowie manuelle Steuerung – ideal für Wettbewerbe und Lernzwecke. Dies ist Teil 1; Teil 2 wird ein Labyrinth-Löser mit KI.

Linienfolger-Roboter mit PID-Regelung & Android-App (MIT App Inventor)

Schritt-für-Schritt Aufbau

1. Motoren (Continuous Rotation Servos)

Linienfolger-Roboter mit PID-Regelung & Android-App (MIT App Inventor)

Test-Code (Nullpunkt)

#include <Servo.h>
Servo leftServo, rightServo;
void setup() {
  leftServo.attach(5);
  rightServo.attach(3);
  leftServo.writeMicroseconds(1500);
  rightServo.writeMicroseconds(1500);
}
void loop() {}

2. Chassis-Montage

3. Bluetooth HC-06 (Optional)

Linienfolger-Roboter mit PID-Regelung & Android-App (MIT App Inventor)

4. Liniensensoren (5× TCRT5000)

Linienfolger-Roboter mit PID-Regelung & Android-App (MIT App Inventor)

IR-Sensor-Logik & Fehlerberechnung

Digitale Ausgabe: HIGH (1) = schwarze Linie, LOW (0) = heller Untergrund.

Mögliche Sensor-Muster (5 Bit) und zugewiesener Fehlerwert:

Arduino-Implementierung

const int lineFollowSensor[5] = {12, 18, 17, 16, 19};
int LFSensor[5] = {0,0,0,0,0};
int error = 0;

void readLFSsensors() {
  for (int i=0; i<5; i++) LFSensor[i] = digitalRead(lineFollowSensor[i]);
  
  if      (LFSensor[0]==0 && LFSensor[1]==0 && LFSensor[2]==0 && LFSensor[3]==0 && LFSensor[4]==1) error = 4;
  else if (LFSensor[0]==0 && LFSensor[1]==0 && LFSensor[2]==0 && LFSensor[3]==1 && LFSensor[4]==1) error = 3;
  else if (LFSensor[0]==0 && LFSensor[1]==0 && LFSensor[2]==0 && LFSensor[3]==1 && LFSensor[4]==0) error = 2;
  else if (LFSensor[0]==0 && LFSensor[1]==0 && LFSensor[2]==1 && LFSensor[3]==1 && LFSensor[4]==0) error = 1;
  else if (LFSensor[0]==0 && LFSensor[1]==0 && LFSensor[2]==1 && LFSensor[3]==0 && LFSensor[4]==0) error = 0;
  else if (LFSensor[0]==0 && LFSensor[1]==1 && LFSensor[2]==1 && LFSensor[3]==0 && LFSensor[4]==0) error = -1;
  else if (LFSensor[0]==0 && LFSensor[1]==1 && LFSensor[2]==0 && LFSensor[3]==0 && LFSensor[4]==0) error = -2;
  else if (LFSensor[0]==1 && LFSensor[1]==1 && LFSensor[2]==0 && LFSensor[3]==0 && LFSensor[4]==0) error = -3;
  else if (LFSensor[0]==1 && LFSensor[1]==0 && LFSensor[2]==0 && LFSensor[3]==0 && LFSensor[4]==0) error = -4;
  else if (LFSensor[0]==1 && LFSensor[1]==1 && LFSensor[2]==1 && LFSensor[3]==1 && LFSensor[4]==1) mode = STOPPED;
  else if (LFSensor[0]==0 && LFSensor[1]==0 && LFSensor[2]==0 && LFSensor[3]==0 && LFSensor[4]==0) mode = NO_LINE;
}

Regelung: P → PID

Proportional (P) – Basis

Basisgeschwindigkeit iniMotorPower = 250 (µs-Offset von 1500).

rightServo.writeMicroseconds(1500 + iniMotorPower - Kp * error);
leftServo.writeMicroseconds(1500 - iniMotorPower - Kp * error);

Voll-PID (Optional, für bessere Performance)


float Kp = 50, Ki = 0, Kd = 0;
float P, I, D, PIDvalue, previousError = 0;

void calculatePID() {
  P = error;
  I = I + error;           // Integral: Summe vergangener Fehler
  D = error - previousError; // Differenzial: Fehleränderung
  PIDvalue = (Kp * P) + (Ki * I) + (Kd * D);
  previousError = error;
}

void motorPIDcontrol() {
  int leftMotorSpeed  = 1500 - iniMotorPower - PIDvalue;
  int rightMotorSpeed = 1500 + iniMotorPower - PIDvalue;
  leftServo.writeMicroseconds(leftMotorSpeed);
  rightServo.writeMicroseconds(rightMotorSpeed);
}

PID-Tuning (Manuell / Try-Error)

  1. Kd = 0, Ki = 0. Kp erhöhen bis Roboter der Linie folgt, aber nicht oszilliert (~25–50).
  2. Kd hinzufügen: Start mit Kp/2, Kd/2 (z. B. 25/25). Kd erhöht → weniger Überschwingen. Zu hoch → Instabilität.
  3. Ki meist 0 bei kleinen Robotern (kein stationärer Fehler, kompliziert Tuning).
  4. Loop-Rate (Delay in loop()) beeinflusst Reglerverhalten stark – mit anpassen.

Hauptprogramm (Loop)


#define STOPPED 0
#define FOLLOWING_LINE 1
#define NO_LINE 2

int mode = STOPPED;
int buttonPin = 9;
int iniMotorPower = 250;

void loop() {
  readLFSsensors();
  
  switch (mode) {
    case STOPPED:
      motorStop();
      break;
    case NO_LINE:
      motorStop();
      motorTurn(LEFT, 180);  // 180° Wende
      break;
    case FOLLOWING_LINE:
      calculatePID();
      motorPIDcontrol();
      break;
  }
}

Android-App für PID-Tuning (MIT App Inventor 2)

Linienfolger-Roboter mit PID-Regelung & Android-App (MIT App Inventor)

App-Funktionen

Arduino-Seite: BT-Kommando-Verarbeitung


#include <SoftwareSerial.h>
SoftwareSerial bt(10, 11);  // RX, TX
String command = "";

void checkBTcmd() {
  while (bt.available()) {
    char c = bt.read();
    if (c == '\n') break;
    command += c;
  }
}

void manualCmd() {
  switch (command[0]) {
    case 'g': mode = FOLLOWING_LINE; break;
    case 's': motorStop(); break;
    case 'f': motorForward(); break;
    case 'r': motorTurn(RIGHT, 30); motorStop(); break;
    case 'l': motorTurn(LEFT, 30); motorStop(); break;
    case 'b': motorBackward(); break;
    case 'p': Kp = command.substring(2).toFloat(); break;
    case 'i': Ki = command.substring(2).toFloat(); break;
    case 'd': Kd = command.substring(2).toFloat(); break;
  }
}

void checkPIDvalues() {
  // Optional: PID-Werte auf LCD anzeigen
}

void setup() {
  // ... (Pin-Modes, Servo-Attach, BT.begin(9600))
  while (digitalRead(buttonPin) && !mode) {
    checkBTcmd();
    manualCmd();
    command = "";
  }
  checkPIDvalues();
  mode = STOPPED;
}

App-Dateien

Fazit & Ausblick

Linienfolger-Roboter mit PID-Regelung & Android-App (MIT App Inventor)

Teil 1 abgeschlossen: Funktionierender Linienfolger mit PID, Bluetooth-Tuning, Zustandsautomat (Stopp, Linie verloren, Folgen). Nächster Schritt: Maze Solver – Roboter erkundet Labyrinth mit einfacher KI (Rechtshänder-Regel, Dead-End-Memory).

Updates & weitere Tutorials: GitHub Repo | MJRoBot.org Blog

Grüße vom Südrand der Welt! – Marcelo

Schaltplan (Fritzing)

Linienfolger-Roboter mit PID-Regelung & Android-App (MIT App Inventor)

Herstellungsprozess

  1. Robotik im 21. Jahrhundert: Verteilte Systeme, Telepräsenz & Weltraumforschung
  2. Line-Tracking-Sensor mit Raspberry Pi – Einfacher KY-033 Tür/Line Detektor
  3. Raspberry Pi Sensor & Aktuator Steuerung meistern: Beschleunigungsmesser, Servo und Datenstreaming
  4. WLAN-gesteuerter Roboter mit Raspberry Pi & Android Smartphone bauen
  5. Wittmann Battenfeld stellt WX153 vor: Fortgeschrittene Roboterlinie für Hochkraft-Spritzgießautomatisierung
  6. FANUC erweitert SCARA‑Roboter‑Portfolio: Sechs Modelle, 3–20 kg Traglast, 400–1.100 mm Reichweite
  7. Universelle Android-Fernbedienung mit Arduino, 1Sheeld & IR-Steuerung
  8. Industrieroboter für Materialtransport – Linienfolger mit RFID & Ultraschall
  9. PID-Regelung für 3D-Robotergreifer in MATLAB/Simulink
  10. Verpackungsqualitätssicherung optimieren: Fortschrittliche automatisierte Kontrollsysteme
Sensor-Array (0–4)FehlerBedeutung
0 0 1 0 00Zentriert (Ideal)
0 0 0 0 1+4Weit rechts
0 0 0 1 1+3Rechts-außen
0 0 0 1 0+2Rechts
0 0 1 1 0+1Leicht rechts
0 1 1 0 0-1Leicht links
0 1 0 0 0-2Links
1 1 0 0 0-3Links-außen
1 0 0 0 0-4Weit links
1 1 1 1 1STOPQuerbalken / Ende
0 0 0 0 0NO_LINELinie verloren