Advertisement
Guest User

Untitled

a guest
Dec 18th, 2020
492
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Arduino 18.47 KB | None | 0 0
  1. #include <pt.h>                                           // Protothread Library einbinden
  2.  
  3. #define MOTOR_R_C    10                                   // Pin um die Geschwindigkeit der rechten Motoren zu regulieren
  4. #define MOTOR_R1     9                                    // R1 und R2 ergeben durch verscheiden Kombinationen, verschieden Richtungen
  5. #define MOTOR_R2     8                                    // Dabei steuert man ob die Motoren an oder aus sind und in welche Richtung sie sich drehen
  6.  
  7. #define MOTOR_L_C    5                                    // Pin um die Geschwindigkeit der linken Motoren zu regulieren
  8. #define MOTOR_L1     4                                    // L1 und L2 sind dasselbe wie R1 und R2 nur für links
  9. #define MOTOR_L2     3
  10.  
  11. #define slow 64                                           // slow, normal und fast sind Ersatz für verschiedene Drehzahlen
  12. #define normal 128
  13. #define fast 255
  14.  
  15. #define US_trigger      13                                // US_trigger und US_echo sind zur Ansteuerung  des Ultraschallsensors
  16. #define US_echo         12
  17.  
  18. #define button 11                                         // Pin für den Taster definiert
  19.  
  20. int Speed = normal;                                       // Speed ist eine Variable die festlegt, wie schnell das Auto sich bewegt
  21.  
  22. long dauer = 0;                                           // Diese Variablen speichern die Werte des Ultraschallsensors
  23. long entfernung = 0;
  24.  
  25. String script;                                            // script speichert die Befehle die durch den Serial kommen zwischen
  26. bool breakit = false;                                     // breakit gibt den Befehl eine Schleife zu unterbrechen
  27. String result[50];                                        // result speichert die Befehle einzeln in einer Liste nacheinander ab
  28.  
  29. static struct pt pt1, pt2, pt3;                           // pt1, pt2 und pt3 sind verschiedene Threads. Jeder Thread hat bestimmte Aufgaben vorgegeben. Alle Threads führen ihre Aufgaben parallel aus
  30.  
  31. bool processedLED = false;                                // processedLED legt fest, ob die grüne LED leuchtet
  32.  
  33. void forward(void) {                                      // Funktion um das Fahrzeug nach vorne zu bewegen
  34.   analogWrite(MOTOR_R_C, Speed);                          // Die Geschwindigkeit wird festgelegt
  35.   digitalWrite(MOTOR_R1, HIGH);                           // R1 ist an und R2 ist aus.
  36.   digitalWrite(MOTOR_R2, LOW);                            // Dadurch drehen sich die rechten Motoren nach vorne
  37.  
  38.   analogWrite(MOTOR_L_C, Speed);                          // Die Geschwindigkeit wird festgelegt
  39.   digitalWrite(MOTOR_L1, HIGH);                           // L1 ist an und L2 ist aus.
  40.   digitalWrite(MOTOR_L2, LOW);                            // Dadurch drehen sich die linken Motoren nach vorne
  41. }
  42.  
  43. void backward(void) {                                     // Funktion um das Fahrzeug nach hinten zu bewegen
  44.   analogWrite(MOTOR_R_C, Speed);                          // Die Geschwindigkeit wird festgelegt
  45.   digitalWrite(MOTOR_R1, LOW);                            // R1 ist aus und R2 ist an.
  46.   digitalWrite(MOTOR_R2, HIGH);                           // Dadurch drehen sich die rechten Motoren nach hinten
  47.  
  48.   analogWrite(MOTOR_L_C, Speed);                          // Die Geschwindigkeit wird festgelegt
  49.   digitalWrite(MOTOR_L1, LOW);                            // L1 ist aus und L2 ist an.
  50.   digitalWrite(MOTOR_L2, HIGH);                           // Dadurch drehen sich die linken Motoren nach hinten
  51. }
  52.  
  53. void brake(void) {                                        // Funktion um das Fahrzeug zum stehen zu bringen.
  54.   digitalWrite(MOTOR_R1, HIGH);                           // Alle Pins werden auf an gesetzt. Dadurch bewegen sie sich nicht.
  55.   digitalWrite(MOTOR_R2, HIGH);
  56.   digitalWrite(MOTOR_L1, HIGH);
  57.   digitalWrite(MOTOR_L2, HIGH);
  58. }
  59.  
  60. void turn(boolean dir, int dur) {                         // Funktion um das Fahrzeug zu drehen. Wird die Funktion aufgerufen, dann müssen die Richtung und die Dauer übergeben werden. True steht für Rechts, False steht für Links.            
  61.   if (dir == true) {                                      // Wenn Rechts übergeben wird, dann dreht sich eine Seite nach vorne und eine nach hinten.
  62.     analogWrite(MOTOR_R_C, Speed);
  63.     digitalWrite(MOTOR_R1, HIGH);
  64.     digitalWrite(MOTOR_R2, LOW);
  65.  
  66.     analogWrite(MOTOR_L_C, Speed);
  67.     digitalWrite(MOTOR_L1, LOW);
  68.     digitalWrite(MOTOR_L2, HIGH);
  69.   } else {                                                // Wenn Links übergeben wird, dann dreht sich eine Seite nach hinten und eine nach vorne.
  70.     analogWrite(MOTOR_R_C, Speed);
  71.     digitalWrite(MOTOR_R1, LOW);
  72.     digitalWrite(MOTOR_R2, HIGH);
  73.  
  74.     analogWrite(MOTOR_L_C, Speed);
  75.     digitalWrite(MOTOR_L1, HIGH);
  76.     digitalWrite(MOTOR_L2, LOW);
  77.   }
  78.   delay(dur);
  79.   delay(200);
  80.   brake();
  81. }
  82.  
  83.  
  84.  
  85. int measure(void) {                                       // Funktion, welche eine Messung durch den Ultraschallsenssor durchführt und das Resultat zurückgibt
  86.   digitalWrite(US_trigger, LOW);                          
  87.   delay(5);
  88.   digitalWrite(US_trigger, HIGH);
  89.   delay(10);
  90.   digitalWrite(US_trigger, LOW);
  91.   dauer = pulseIn(US_echo, HIGH);
  92.   entfernung = (dauer / 2) / 29.1;
  93.   return entfernung;
  94. }
  95.  
  96.  
  97.  
  98. void splitString(String input, char seperator) {          // Funktion, welche eine Zeile mit Befehlen in eine Liste umwandelt
  99.   long startTime;                                         // Zeitmessung
  100.   startTime = millis();
  101.   int inputIndex = 0;                                     // InputIndex zählt den Index im ursprünglichen String  
  102.   for (int index = 0; index <= 50; index++) {             // Diese Schleife zählt von 0 bis 50. Damit geht man jeden leeren Platz in der result-Liste durch.
  103.     Serial.print("Setting array element at");      
  104.     Serial.println(index);
  105.     String stringBuilder = "                                                   ";   // StringBuilder wird definiert. Der StringBuilder ist ein String, welche gefüllt mit Leerzeichen ist. Dadurch können nachher Buchstaben aneinander angefügt werden.
  106.     Serial.println("Building string");
  107.     for (inputIndex; inputIndex <= 1000; inputIndex++) {        // Diese Schleife zählt von 0 bis 1000. Dadurch werden alle möglichen Zeichen im ursprünglichen String kontrolliert und kopiert.
  108.       for (int demo = 0; demo <= 50; demo++) {                  // Diese Schleife zählt von 0 bis 50. Dadurch werden alle leeren Zeichen im StringBuilder durchgegangen
  109.         if (input.charAt(inputIndex) == seperator) {            // Hier wird geprüft ob es sich beim aktuellen Buchstaben um den Seperator handelt. Der Seperator definiert, wo ein Befehl endet. Dadurch können die Befehle abgetrennt werden.
  110.           Serial.println("Seperator detected. Breaking...");
  111.           demo = 50;
  112.           breakit = true;                                       // Die aktuellen zwei Schleifen werden unterbrochen. Dadurch wird dem Programm der Befehl gegeben, das nächste Element in der Liste zu bearbeiten.
  113.           break;
  114.         } else {                                                // Handelt es sich um einen richtigen Buchstaben, dann passiert folgendes.
  115.           char current = input.charAt(inputIndex);              // Der aktuelle Buchstabe wird herausgenommen.
  116.           stringBuilder.setCharAt(demo, current);               // Der Buchstabe wird an die aktuelle Stelle im StringBuilder platziert.
  117.           Serial.print("Placing char '");
  118.           Serial.print(current);
  119.           Serial.print("' from origin index ");
  120.           Serial.print(inputIndex);
  121.           Serial.print(" to StringBuilder Index ");
  122.           Serial.println(demo);
  123.           inputIndex++;                                         // Es wird der Befehl gegeben, den nächsten Buchstaben im ursprünglichen String zu verwenden.
  124.         }
  125.       }
  126.       if (breakit == true)  {    
  127.         breakit = false;
  128.         break;
  129.       }
  130.  
  131.     }
  132.     inputIndex++;
  133.     stringBuilder.trim();                                // Hier werden die übriggebliebenen Leerstellen entfernt.
  134.     Serial.print("String built! Result: ");
  135.     Serial.println(stringBuilder);
  136.     Serial.println("Cleaning...");
  137.     result[index] = stringBuilder;                       // Der zusammengebaute String wird in die Liste platziert.
  138.     if (inputIndex >= (input.length() - 1)) {            // Hier wird dem Programm befohlen, nicht sinnlos weiterzumachen, wenn das Ende bereits erreicht ist.
  139.       break;
  140.     }
  141.  
  142.   }
  143.   processedLED = true;                                   // Die grüne LED geht an. Dies bedeutet, dass das Script verarbeitet ist.
  144.   long endTime = millis();                              
  145.   Serial.println("==============================");
  146.   Serial.print("Script processed in ");
  147.   Serial.print(endTime - startTime);                     // Es wird die Dauer des Verarbeitungsprozesses angezeigt.
  148.   Serial.println("ms");
  149.   Serial.println("==============================");
  150.  
  151. }
  152.  
  153.  
  154.  
  155.  
  156.  
  157. static int crashPrevention(struct pt *pt) {              // Hier wird definiert, was der eine Thread zu tun hat. Dieser Thread soll verhindern, dass das Auto nicht gegen eine Wand fährt.
  158.   PT_BEGIN(pt);                                          // Beginn des Threads
  159.   static unsigned long lastTimeBlink = 0;                // Diese Variable speichert zwischen, wie lange der Arduino bisher läuft.
  160.   while (1) {                                            
  161.     if ((measure() <= 40)) {                             // Ist der Abstand vom vorderen Ultraschallsensor zum nächsten Objekt kleiner als 40cm dann passiert folgendes.
  162.       brake();                                           // Es wird gebremst
  163.       tone(2, 1000);                                     // Der Summer erzeugt einen Ton
  164.       digitalWrite(7, HIGH);                             // Die rote Lampe leuchtet
  165.       lastTimeBlink = millis();                          // Die Variable speichert die aktuelle Laufzeit des Arduinos zwischen.
  166.       PT_WAIT_UNTIL(pt, millis() - lastTimeBlink > 400); // Der Thread wartet solange, bis die aktuelle Laufzeit minus der zwischengespeicherten Zeit größer als 400 ist. Das bedeutet es ist eine Pause von 400ms.
  167.       noTone(2);                                         // Der Ton geht aus
  168.       digitalWrite(7, LOW);                              // Die Lampe geht aus
  169.       lastTimeBlink = millis();                          // Die Variable speichert die aktuelle Laufzeit des Arduinos zwischen.
  170.       PT_WAIT_UNTIL(pt, millis() - lastTimeBlink > 400); // Der Thread wartet solange, bis die aktuelle Laufzeit minus der zwischengespeicherten Zeit größer als 400 ist. Das bedeutet es ist eine Pause von 400ms.
  171.     } else if ((measure() >= 40)) {
  172.       Speed = normal;
  173.     } else {
  174.       PT_END(pt);                                        // Hier wird der Thread beendet.
  175.     }
  176.   }
  177. }
  178.  
  179. static int commandProcessor(struct pt *pt) {             // Hier wird definiert, was der eine Thread zu tun hat. Dieser Thread soll schauen ob ein Befehl über den Serial geschickt wurde und ihn gegebenenfalls verarbeiten lassen.
  180.   if (processedLED == true) {
  181.     digitalWrite(6, HIGH);
  182.   } else { digitalWrite(6, LOW); }
  183.   PT_BEGIN(pt);                                          // Der Thread wird gestartet
  184.   static unsigned long lastTimeBlink = 0;                // Diese Variable speichert zwischen, wie lange der Arduino bisher läuft
  185.   if (Serial.available()) {                              // Überprüft, ob etwas durch den Serial gesendet wurde
  186.     script = Serial.readString();                        // Lese aus, was gesendet wurde
  187.     Serial.println(script);
  188.     if (script.startsWith("script ")) {                  // Schau ob die Eingabe mit "script" beginnt. Falls ja dann werden die Befehle danach verarbeitet.
  189.       Serial.println("Script received");
  190.       String toProcess = script.substring(7, 1000);      // Das "script " wird vom String entfernt
  191.       Serial.print("Script: ");        
  192.       Serial.println(toProcess);
  193.       splitString(toProcess, ';');                       // Der String wird zur Verarbeitung übergegeben. Dabei wird ";" als Seperator festgelegt.
  194.     } else if (script.startsWith("show")) {              // Schau ob die Eingabe mit "show" beginnt. Falls ja, dann werden alle bisher gespeicherten Befehle in den Serial geschrieben
  195.       Serial.print("{");
  196.       for (String i : result) {
  197.         Serial.print(i);
  198.         Serial.print("|");
  199.       }
  200.       Serial.println("}");
  201.     } else {}
  202.   }
  203.   if (digitalRead(button) == 1) {                        // Schaut, ob der Knopf gedrückt wird.
  204.     Serial.println("Executing script");
  205.     for (String order : result) {
  206.       runCommand(&pt3, order);                           // Jeder Befehl wird nacheinander an den pt3 Thread geschickt. Dadurch werden alle Befehle ausgeführt und das Programm läuft trotzdem weiter.
  207.     }
  208.   }
  209.  
  210.   PT_END(pt);                                            // Der Thread wird beendet.
  211. }
  212.  
  213. static int runCommand(struct pt *pt, String order) {     // Hier wird definiert, was der eine Thread zu tun hat. Dieser Thread soll einen einzelnen Befehl verarbeiten.
  214.   PT_BEGIN(pt);                                          // Der Thread wird gestartet
  215.   static unsigned long lastTimeBlink = 0;                // Diese Variable speichert zwischen, wie lange der Arduino bisher läuft
  216.   if (order.startsWith("fwd")) {                         // Das passiert wenn fwd als Befehl geschrieben wird.
  217.     String dist1 = " ";                                  // Es wird die Zahl aus dem Befehl raus genommen. Also "fwd 9" --> "9". Dann wird das ganze zu einem Integer umgewandelt.
  218.     dist1.setCharAt(0, order.charAt(4));                
  219.     int dist2 = dist1.toInt();
  220.     Serial.println(dist2);
  221.     forward();                                           // Es wird der Befehl gegeben vorwärts zu fahren.
  222.     lastTimeBlink = millis();                                       // Die Variable speichert die aktuelle Laufzeit des Arduinos zwischen.
  223.     PT_WAIT_UNTIL(pt, millis() - lastTimeBlink > (dist2 * 1710));   // Der Thread wartet solange, bis die aktuelle Laufzeit minus der zwischengespeicherten Zeit größer als eine bestimmte Zeit ist. Die bestimmte Zeit ist die Entfernung mal der Koeffizient. Es wird berechnet wie lang gewartet werden muss, damit das Fahrzeug die gewünschte Distanz erreicht.
  224.     brake();                                             // Nach der Pause wird gebremst.
  225.   } else if (order.startsWith("bwd")) {                  // Das passiert wenn bwd als Befehl geschrieben wird.
  226.     String dist1 = " ";                                  // Es wird die Zahl aus dem Befehl raus genommen. Also "bwd 9" --> "9". Dann wird das ganze zu einem Integer umgewandelt.
  227.     dist1.setCharAt(0, order.charAt(4));
  228.     int dist2 = dist1.toInt();
  229.     Serial.println(dist2);
  230.     backward();                                          // Es wird der Befehl gegeben rückwärts zu fahren.
  231.     lastTimeBlink = millis();                                       // Die Variable speichert die aktuelle Laufzeit des Arduinos zwischen.
  232.     PT_WAIT_UNTIL(pt, millis() - lastTimeBlink > (dist2 * 1710));   // Der Thread wartet solange, bis die aktuelle Laufzeit minus der zwischengespeicherten Zeit größer als eine bestimmte Zeit ist. Die bestimmte Zeit ist die Entfernung mal der Koeffizient. Es wird berechnet wie lang gewartet werden muss, damit das Fahrzeug die gewünschte Distanz erreicht.
  233.     brake();                                             // Nach der Pause wird gebremst.
  234.   } else if (order.startsWith("brake")) {                // Das passiert wenn brake als Befehl geschrieben wird.
  235.     brake();                                             // Es wird gebremst
  236.   } else if (order.startsWith("delay")) {                // Das passiert wenn delay als Befehl geschrieben wird.
  237.     String dist1 = "     ";                              // Es wird die Zahl aus dem Befehl raus genommen. Also "delay 1000" --> "1000". Dann wird das ganze zu einem Integer umgewandelt.
  238.     dist1.setCharAt(0, order.charAt(6));
  239.     dist1.setCharAt(1, order.charAt(7));
  240.     dist1.setCharAt(2, order.charAt(8));
  241.     dist1.setCharAt(3, order.charAt(9));
  242.     dist1.setCharAt(4, order.charAt(10));
  243.     int dist2 = dist1.toInt();
  244.     Serial.println(dist2);                        
  245.     lastTimeBlink = millis();                            // Die Variable speichert die aktuelle Laufzeit des Arduinos zwischen.
  246.     PT_WAIT_UNTIL(pt, millis() - lastTimeBlink > dist2); // Der Thread wartet solange, bis die aktuelle Laufzeit minus der zwischengespeicherten Zeit größer als die vorgegebene Zeit ist.
  247.   } else if (order.startsWith("turn")) {                 // Das passiert wenn turn als Befehl geschrieben wird.
  248.     Serial.println("TURN");
  249.     if (order.charAt(5) == 'L') {                        // Es wird geschaut ob links oder rechts gedreht werden soll.
  250.       String rot1 = "   ";                               // Die Gradzahl wird aus dem Befehl rausgeschrieben. Also "turn L 90" --> "90"
  251.       rot1.setCharAt(0, order.charAt(7));
  252.       rot1.setCharAt(1, order.charAt(8));
  253.       rot1.setCharAt(2, order.charAt(9));
  254.       int rot2 = rot1.toInt();
  255.       Serial.println(rot1);
  256.       turn(false, rot2 * 8.3);                           // Die Drehung wird durchgeführt. Die Dauer wird berechnet mit Gradanzahl mal Koefizient.
  257.     } else if (order.charAt(5) == 'R') {
  258.       String rot1 = "   ";
  259.       rot1.setCharAt(0, order.charAt(7));
  260.       rot1.setCharAt(1, order.charAt(8));
  261.       rot1.setCharAt(2, order.charAt(9));
  262.       int rot2 = rot1.toInt();
  263.       Serial.println(rot1);
  264.       turn(true, rot2 * 8.3);
  265.     }
  266.   }
  267.   PT_END(pt);                                            // Der Thread wird beendet.
  268.  
  269. }
  270.  
  271.  
  272.  
  273. void setup() {
  274.   Speed = normal;
  275.  
  276.   Serial.begin(9600);
  277.   Serial.println("ONLINE - Script cleared");
  278.  
  279.   PT_INIT(&pt1);                                                  // Die Threads werden initialisiert.
  280.   PT_INIT(&pt2);
  281.   PT_INIT(&pt3);
  282.  
  283.   pinMode(MOTOR_R_C, OUTPUT);
  284.   pinMode(MOTOR_R1, OUTPUT);
  285.   pinMode(MOTOR_R2, OUTPUT);
  286.  
  287.   pinMode(MOTOR_L_C, OUTPUT);
  288.   pinMode(MOTOR_L1, OUTPUT);
  289.   pinMode(MOTOR_L2, OUTPUT);
  290.  
  291.   pinMode(US_trigger, OUTPUT); // Sets the trigPin as an OUTPUT
  292.   pinMode(US_echo, INPUT); // Sets the echoPin as an INPUT
  293.  
  294.   pinMode(2, OUTPUT);
  295.  
  296.   pinMode(button, INPUT);
  297.   pinMode(6, OUTPUT);
  298.   pinMode(7, OUTPUT);
  299. }
  300.  
  301. void loop() {
  302.   crashPrevention(&pt1);                                        // Die Threads zur Unfallverhinderung und zur Befehlsverarbeitung werden gestartet.
  303.   commandProcessor(&pt2);
  304. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement