App-gesteuertes Boot

Aus HRW FabLab MediaWiki
Wechseln zu: Navigation, Suche
App-gesteuertes Boot
Boot uebersicht.jpg


Entwickler

Justin Wandhöfer, Jan Paul Herrmann

Verwendung

Unterhaltung

Programmiersprachen

C, java

Verwendete Programme

Android Studio, Arduino IDE, Sketchbook, Inkscape, fritzing

Das App-gesteuerte Boot ist ein Modellboot, welches zum ansteuern der Komponenten einen Arduino besitzt, welcher wiederum die Daten anhand von Nutzereingaben von einer Android App mittels Bluetooth empfängt. Zum Empfang der Daten via Bluetooth am Arduino wird ein HC-05 Bluetooth Modul verwendet, welches mittels serieller Kommunikation dem Arduino die Daten liefert.


Idee[Bearbeiten]

Das Boot sollte in erster Linie die Grundlage für ein Reinigungsboot sein, welches in Schwimmbädern die Wasseroberfläche von Dreck (z.B. Grashalme) befreien sollte. Aufgrund von Schwierigkeiten in der Nutzung mit dem Fahrtenregler und weiteren Komponenten, konnte das Projekt nicht in der ursprünglichen Idee ausgearbeitet werden.

Aufbau[Bearbeiten]

Schaltplan

Modellboot[Bearbeiten]

Als Rumpf wurde ein Modellbauboot der Firma robbe verwendet. Zudem wurde der Antriebsstrang mit der Schraube und der Lenkung übernommen.

Funduino Uno[Bearbeiten]

Der Arduino empfängt die Signale, verarbeitet diese und gibt diese an den Servo bzw. an den Fahrtenregler weiter. Die Funktionsweise ist auf dem Arduino programmiert.

HC-05 Bluetooth Modul[Bearbeiten]

Das Bluetooth-Modul empfängt die Signale der Android App und gibt diese an den Arduino weiter.

Servo[Bearbeiten]

Der Servo ist mit dem Ruder verbunden und zuständig für die Lenkung des Bootes.

Motor[Bearbeiten]

Der Motor ist mit der Antriebswelle verbunden und treibt die Schraube an. Angesteuert wird der Motor mittels Fahrtenregler.

Fahrtenregler[Bearbeiten]

Der Fahrtenregler dient als Verbindung zwischen Arduino zum Motor. Dabei verhält sich der Fahrtenregler, wie ein Servo und kann so angesteuert werden.

Akku[Bearbeiten]

Der Akku versorgt den Fahrtenregler, den Arduino, das Bluetooth-Modul, den Motor und das Servo mit Strom.

Prototype Shield[Bearbeiten]

Das Prototype Shield wurde für die Verkabelung der einzelnen Bauteile verwendet und kann direkt auf den Arduino aufgesteckt werden.

Sperrholzplatten[Bearbeiten]

Die Sperrholzplatten mit einer Dicke von ca. 4 mm wurden passend für die Elektronik im Boot zugeschnitten. Auf der kleineren Platte im Heck befindet sich der Servo, der für das Ruder verantwortlich ist. Die vordere Platte ist bestückt mit dem Arduino, Bluetooth HC-05 Modul, Prototype Shield, Fahrtenregler sowie das 7,2V Akku.

Galerie Aufbau[Bearbeiten]

App[Bearbeiten]

Um den Nutzer eine Möglichkeit zur Steuerung des Modellbootes zu ermöglichen, haben wir uns für eine native Android App entschieden, welche die Nutzereingaben verarbeitet und mittels Bluetooth die Daten an den Arduino bzw. das HC-05 Bluetooth Modul sendet.

App Icon


Toggle Button[Bearbeiten]

Das ein-bzw. ausschalten der Bluetooth Kommunikation erfolgt über einen Toggle Button. Nach dem Starten der App und des betätigen des Toogle Buttons wird zuerst überprüft, ob bereits Bluetooth an dem Smartphone/Tablet aktiviert ist. Sollte dies nicht der Fall sein, wird der Nutzer gefragt, ob die App Bluetooth aktivieren darf. Sollte der Nutzer dies Bestätigen wird Bluetooth aktiviert und die App sucht das HC05 Bluetooth Modul. Wenn eine Verbindung erfolgreich hergestellt wurde, werden die Daten (Switches, Seekbars usw.) auf ihre Ursprungswerte zurückgesetzt.


       toggleBT.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
           @Override
           public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
               if (isChecked) {
                   if (setBT() == true) {
                       BTconnection();
                       motorSwitch.setChecked(false);
                       convertedProgressSpeed = 97;
                       speedSeekBar.setProgress(5);
                       speedValue.setText("97");
                       rudderSeekBar.setProgress(20);
                       rudderValue.setText("20");
                   }
               } else {
                   try {
                       os.close();
                       btSocket.close();
                   } catch (IOException e) {
                       e.printStackTrace();
                   }
               }
           }
       });

Discrete Seekbar[Bearbeiten]

Die diskrete Seekbar wird für die Steuerung des Motors bzw. Fahrtenreglers verwendet. Wir haben uns für die diskrete Variante entschieden, da vor dem Wechsel vom Vorwärts in den Rückwärtsgang, die Seekbar sich für einen Moment in der Neutralstellung befinden muss. Würde sie sich nicht in der Neutralstellung befinden, würde der Fahrtenregler nicht in den Rückwärtsgang schalten, sondern eine Notbremsung ausführen. Es gibt insgesamt elf Schritte, welche die Werte 67 bis 87 für den Rückwärtsgang und die Werte 107 bis 127 für den Vorwärtsgang setzen (pro Schritt wird der Wert um 5 erhöht. Diese Werte werden mittels eines Output Streams über Bluetooth an den Arduino gesendet.


         speedSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
           @Override
           public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                   if(reverseStatus == true){
                       switch (progress) {
                           case 0:
                               convertedProgressSpeed = 67;
                               break;
                           case 1:
                               convertedProgressSpeed = 72;
                               break;
                           case 2:
                               convertedProgressSpeed = 77;
                               break;
                           case 3:
                               convertedProgressSpeed = 82;
                               break;
                           case 4:
                               convertedProgressSpeed = 87;
                               break;
                           case 5:
                               convertedProgressSpeed = 97;
                               break;
                            default:
                                seekBar.setProgress(5);
                                break;
                       }
                   }
                   if(reverseStatus == false) {
                       switch (progress) {
                           case 5:
                               convertedProgressSpeed = 97;
                               break;
                           case 6:
                               convertedProgressSpeed = 107;
                               break;
                           case 7:
                               convertedProgressSpeed = 112;
                               break;
                           case 8:
                               convertedProgressSpeed = 117;
                               break;
                           case 9:
                               convertedProgressSpeed = 122;
                               break;
                           case 10:
                               convertedProgressSpeed = 127;
                               break;
                           default:
                               seekBar.setProgress(5);
                               break;
                       }
                   }
               dataSpeedSeekBar = "<" + Integer.toString(convertedProgressSpeed) + "S>";
               try {
                   os.write(dataSpeedSeekBar.getBytes());
               } catch (IOException e) {
                   e.printStackTrace();
               }
               speedValue.setText(" " + convertedProgressSpeed);
           }
           @Override
           public void onStartTrackingTouch(SeekBar seekBar) {
           }
           @Override
           public void onStopTrackingTouch(SeekBar seekBar) {
           }
       });
   }

Seekbar[Bearbeiten]

Zum Steuern des Ruders kommt eine Seekbar ohne diskrete Werte zum Einsatz. Dies ermöglicht eine genaue Lenkung des Bootes, da sich somit der Winkel des Servos um jeweils 1° ändern lässt. Die Seekbar kann Werte im Bereich von 0 bis 40 annehmen.


       rudderSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
           @Override
           public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
               convertedProgressRudder = progress + 98;
               dataRudderSeekBar = "<" + Integer.toString(convertedProgressRudder) + "R>";
               try {
                   os.write(dataRudderSeekBar.getBytes());
               } catch (IOException e) {
                   e.printStackTrace();
               }
               rudderValue.setText(" " + progress);
           }
           @Override
           public void onStartTrackingTouch(SeekBar seekBar) {
           }
           @Override
           public void onStopTrackingTouch(SeekBar seekBar) {
           }
       });

Switch[Bearbeiten]

Motor Switch[Bearbeiten]

Der Motor Switch dient als eine Art Sicherheitsschalter, welcher erst aktiviert werden muss, um den Motor steuern zu können bzw. damit die Seekbar, mit welcher der Motor gesteuert wird, überhaupt bewegt werden kann.
       motorSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
           @Override
           public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
               if (isChecked) {
                   speedSeekBar.setEnabled(true);
               } else if (!isChecked) {
                   speedSeekBar.setEnabled(false);
               }
           }
       });

Reverse Switch[Bearbeiten]

Um den Rückwärtsgang einlegen zu können, muss der Reverse Switch aktiviert werden. Erst nach der Aktivierung ist es möglich die Seekbar für die Geschwindigkeit in den Bereich zu bewegen, welcher eine Rückwärtsfahrt ermöglicht. Hierdurch ist gewährleistet, dass sich der Slider nicht lange genug in der Neutralstellung befand und somit nicht ausversehen die Notbremsung aktiviert wird.
       gearSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
           @Override
           public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
               if (isChecked) {
                   reverseStatus = true;
               } else if (!isChecked) {
                   reverseStatus = false;
               }
           }
       });

Bluetooth[Bearbeiten]

Die Kommunikation zwischen Arduino bzw. dem HC-05 Bluetooth Modul und der App wird über Bluetooth realisiert. Die Daten, welche durch die beiden Seekbars gesetzt werden, werden mittels eine Output Streams an das HC-05 Modul gesendet. Selbiges schickt die Daten an den Arduino, welcher die empfangenen Daten auswertet und der jeweiligen Komponente, für welche die Daten gedacht sind, zuweist. Zu beginn war es uns nicht möglich uns mit dem Bluetooth Modul zu verbinden. Nach einiger Recherche haben wir eine "spezielle" UUID gefunden, welche man bei bei der Kommunikation zwischen einer Android App und dem HC-05 verwenden muss. Die UUID lautet 00001101-0000-1000-8000-00805F9B34FB und nachdem wir diese in den Code eingefügt hatten, konnte sich das Smartphone mit dem Modul verbinden und kommunizieren.
     public boolean setBT(){
       boolean found = false;
       if(btAdapter == null){
           Toast.makeText(getApplicationContext(),"Bluetooth not Supported", Toast.LENGTH_LONG).show();
       }
       if(!btAdapter.isEnabled()){
           Intent setAdapter = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
           startActivityForResult(setAdapter, 0);
           try{
               Thread.sleep(1000);
           }catch (InterruptedException e){
               e.printStackTrace();
           }
       }
       Set<BluetoothDevice> bondedDevices;
       bondedDevices = btAdapter.getBondedDevices();
       if(bondedDevices.isEmpty()){
           Toast.makeText(getApplicationContext(), "Bluetooth connection to Arduino required!", Toast.LENGTH_LONG).show();
       }else{
           for(BluetoothDevice iterator : bondedDevices){
               String DEVICE_ADDRESS = "98:D3:31:F5:3D:FC";
               if(iterator.getAddress().equals(DEVICE_ADDRESS)){
                   btDevice = iterator;
                   found = true;
               }
           }
       }
       return found;
   }


    public boolean BTconnection(){
       boolean connection = true;
       try{
           btSocket = btDevice.createRfcommSocketToServiceRecord(PORT_UUID);
           btSocket.connect();
           Toast.makeText(getApplicationContext(), "Connection successful", Toast.LENGTH_LONG).show();
       } catch (IOException e) {
           e.printStackTrace();
           connection = false;
       }
       if(connection) {
           try {
               os = btSocket.getOutputStream();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
       return connection;
   }

Galerie Benutzeroberfläche[Bearbeiten]

Arduino[Bearbeiten]

Die Daten werden mittels der seriellen Schnittstelle vom HC-05 Modul empfangen und verarbeitet. Um eine Unterscheidung zwischen den Daten machen zu können, ob diese für den Servo zum steuern des Ruders, oder für den Fahrtenregler zum Regeln der Motorleistung gedacht sind, benutzen wir einen Indikator, welcher in der Android App in den Output Stream der jeweiligen Seekbar mit Eingefügt wird. Für den Servo wird ein „R“ angefügt, für den Fahrtenregler hingegen ein „S“.


Erweiterungsmöglichkeiten[Bearbeiten]

Eine Erweiterungsmöglichkeit wäre ein autonomer Fahrmodus. Hierfür könnte in der App ein Button eingefügt werden, welcher das autonome Fahren aktiviert. Zur Erkennung von Hindernissen könnten Ultraschallsensoren benutzt werden, die sich jeweils an Bug, Heck, Backbord und Steuerbord befinden und mittels mathematischer Berechnungen den idealen Fahrweg ermitteln.

Team[Bearbeiten]