Arduino Steuerung mit Android

Übersicht:

Im Rahmen meiner Ingenieurspraxis habe ich eine Android App entwickelt mit der ich einen Zeppelin steuern kann. Zur Verbindung wird ein Diamonback von Linksprite verwendet der über einen WLAN Chip verfügt. Dabei tritt das Handy als Client und das Board als Server auf. Auf den Arduino aufgesetzt wird ein XBEE Modul mit dem die Kommunikation zum Zeppelin hergestellt wird. 

 

Vorbereitung:

 

Zur Androidprogrammierung braucht man die richtige Entwicklungsumgebung.Benötigt wird Eclipse, Android SDK und JDK.

Zur richtigen Installation empfehle ich ein Tutorial wie folgendes zu befolgen:

http://www.app-entwickler-verzeichnis.de/apps-programmierung/24-android/297-android-programmierung-tutorial-der-grosse-android-newbie-guide 

 

LED Steuerung:

  Hier werden zwei LEDs über eine App gesteuert.

Wie bereits gesagt fungiert das Handy als Client und der Arduino als Server. Aufgebaut wird die Verbindung in einem gemeinsamen WLAN Netz, das von einem Accesspoint bereit gestellt wird. Auf der Einstellungen Activity wird die Ip-Adresse und die Portnummer des Arduinos eingegeben. Wird dann "Verbinden" gedrückt werden die eingegebenen Daten gespeichert und eine TCP Verbindung aufgebaut.

 

Pinbelegung:

pin5: LED für TCP Testsignal

pin6: LED1

pin7: LED2

pin9: LED für WLAN

 

 

 

Android:


Bei der App muss man zuerst über den Menü Button ins "Einstellungen" Menü wechseln. Dort wird die Ip Adresse und die Portnummer des Arduino eingegeben. Dann wird über den "Verbinden" Button eine TCP Verbindung aufgebaut. Bei drücken von "TCP Verbindung testen!" wird eine kurze Nachricht über TCP verschickt und die LED an Pin 5 leuchtet kurz auf. Zurück auf der MainActivity kann man über die ToggleButton den Status der LEDs steuern und mit "Senden" über UDP an den Arduino übermitteln.

 

Arduino:

Beim Code für den Arduino ist unbedingt auf folgende zwei Zeilen zu achten.

 

uip_ipaddr(&addr, 0,0,0,0);
c = uip_udp_new(&addr, HTONS(0));

Für die Ip-Adresse und die Port-Nummer müssen Nuller stehen, da der Arduino sonst keine Daten über UDP empfängt. 

 

 Zeppelinsteuerung 

 Für die Steuerung werden eine Seekbar für die Fluhhöhensteuerung und die Bewegungssensoren des Smartphones verwendet.

Seekbar

Die Seekbar wird per Touch bedient und kann Werte zwischen 0 und 255 annehmen. Dieser wird im Datenbyte an Stelle 4 geschrieben. Bei Werten über 128 steigt der Zeppelin und unter 128 sinkt er, indem der Rotor in die andere Richtung dreht. Standardmäßig ist er bei 128 was Stillstand bedeutet.

 

OnSeekBarChangeListener seekBarListener = new OnSeekBarChangeListener() {
		
		public void onProgressChanged(SeekBar power, int progress, boolean fromTouch) {
			ausgabe.setText(progress+"/255");
			data[3] = (byte)progress;
		}
		
		public void onStartTrackingTouch(SeekBar power) {
			//x.setText("Tracking aktiv");
		}
		
		public void onStopTrackingTouch(SeekBar power) {
			//x.setText("Tracking inaktiv");
		}
		
		
	};	

 

Bewegungssensor

 Zuerst wird überprüft ob das Smartphone über einen solchen verfügt. Dies könnte man jedoch weglassen da alle neueren Modelle solche Sensoren besitzen. Um die Werte des Sensors auslesen zu können muss er muss zunächst in der onCreate() Methode initialisiert werden. Zusätzlich wird er in der onResume() Methode registriert, sodass nun Werte zur Verfügung stehen. Um Akku zu sparen wird er sobald gestoppt wird wieder unregistriert. Dies geschieht in der onStop() Methode. 

Der SensorEventListener gibt in bestimmten Zeitabschnitten Werte aus. Es stehen drei verschiedene für die x-, y- und z-Richtung bereit. Verwendet werden aber nur die x und y Koordinate. Die Werte schwanken zwischen -10 und 10 mit fünf Nachkommastellen. Damit der Arduino damit etwas anfangen kann werden sie in Integer von 0 bis 255 umgerechnet und dann in das Datenbyte an Stelle 0 und 1 gepackt.

 

private SensorEventListener accelerometerListener = new SensorEventListener(){

				 @Override
				 public void onAccuracyChanged(Sensor arg0, int arg1) {
				  // TODO Auto-generated method stub
				 
				 }

				 @Override
				 public void onSensorChanged(SensorEvent arg0) {
					 int xwert = 0;
					 int ywert = 0;
				  x_value = arg0.values[0];
				  y_value = arg0.values[1];
if (x_value <= 0) { xwert = 128 - (int)((float)x_value/8 * 100); } else { xwert = 128 - (int)((float)x_value/8 * 100); if (y_value >= 0) { ywert = 128 + (int)((float)y_value/8 * 100); } else { ywert = 128 + (int)((float)y_value/8 * 100); } } data[0] = (byte)ywert; data[1] = (byte)xwert; }};

 

Datenübertragung:

Die Datenübertragung wird in einem eigenen Thread abgewickelt. Dieser wird in der zustanAendern() Methode aufgerufen. 

 

Arduino:

Auf den Arduino wird das xBee-Modul gesteckt, mit dem die Daten an den Zeppelin weitergeleitet werden. Durch die einfache Ausgabe über die serielle Schnittstelle gelangen die Daten zum xBee-Modul, da es mit den gleichen Pins verbunden ist wie der Mini-USB. Um eine bessere Performanz beim steuern des Zeppelins zu erhalten werden die Zahlenwerte noch gerundet. Alle kleiner als 30 werden zu 0, alle größer 225 zu 255 und alle zwischen 108 und 148 zu 128.

 

  if ((temp <= 148) && (temp >= 108))
    temp = 128;
  if (temp < 30)
    temp = 0;
  if (temp > 225)
    temp = 255;