Bluetooth Maschinensteuerung mit XMC2GO und Android-App

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

von Vision

XMC2GO mit XMC1100

Einleitung

Ziel dieses Projekts war es, eine ältere Industriemaschine (einen Stapelschneider des Typs Ideal 9221-95) komfortabel über ein Tablet oder Smartphone bedienbar zu machen. Dabei sollte die schon vorhandene Elektronik (Motorsteuerung und Bedieneinheit) erhalten bleiben, um die Maschine jederzeit wieder vollständig zurück rüsten zu können. Da ich gerne ein Projekt mit dem XMC2GO umsetzen wollte, war dieses Vorhaben ideal für den Einstig mit der neuen Controllerfamilie.

Hardware

folgende Hardware sollte (weil vorhanden) für die Umsetzung des Projekts verwendet werden:

Software

für die Umsetzung dieses Projektes benötigte ich folgende Software

  • Keil µVision5
  • HTerm 0.8.1 beta
  • MIT App Inventor 2

Projektbeschreibung

Stapelschneider IDEAL 9221-95

Wie oben schon erwähnt, geht es bei diesem Projekt darum, den Bedienkomfort einer Maschine zum Schneiden von Papierstapeln zu erhöhen. Von Werk aus ist der Stapelschneider mit einem elektrisch verstellbaren Tiefenanschlag ausgerüstet. Dabei sorgt ein Gleichstrommotor für die Positionierung. Die Positionsbestimmung erfolgt über eine Encoderscheibe auf der Welle des Motors, die von einem Lichtschranken-Pärchen abgetastet wird. Gesteuert wird das Gerät über ein Potentiometer an der Front. Die aktuelle Position kann auf einer vierstelligen Siebensegmentanzeige abgelesen werden. Die Einstellung über das Potentiometer ist jedoch alles andere als komfortabel, da man damit auch schnell mal über das eigentliche Ziel heraus schießt. Es wäre viel praktischer, die gewünschte Position des Tiefenanschlages einzugeben und die Maschine den Rest machen zu lassen.

Hier startet nun das eigenliche Projekt. Über ein Mikrocontroller und ein Digital-Potentiometer sollte man die Maschine doch steuern können. Wenn noch ein Bluetooth-Modul dazu kommt, dann sogar mit einem Smartphone oder einem Tablet. Zum auslesen der Position bieten sich zwei Möglichkeiten. Zum einen das 'Anzapfen' der Siebensegmentanzeige, zum anderen die Verwertung der Signale der Lichtschranke. Da der 'Eingriff' in die vorhandene Technik möglichst nicht-invasiv sein sollte und die Lichtschranke (sowie Poti und Endschalter) über Stecker an die eigentliche Steuerplatine angeschlossen sind, habe ich mich für die Auswertung der Lichtschranken entschlossen.

Was musste also die Firmware meiner Steuerung können?

1. Externe Interrupts erfassen (Signale der Lichtschranke und des Endschalters)
2. Analog-Digital-Conversion (man soll das Gerät ja auch weiterhin über den vorhandenen Poti steuern können)
3. Three-Wire Serial Interface für die Steuerung des Digitalpotis
4. UART über Bluetooth

Klingt erstmal nach überschaubarem Aufwand. Aber es ist wie überall im Leben - der Teufel steckt im Detail.

Erstellt habe ich die Firmware - wie oben schon aufgeführt - mit der µVision5 IDE von Keil. Für die Controller der Infineon XMC1000-Reihe gibt es eine kostenlose Version, mit der man Programme bis 128k kompilieren und debuggen kann [1]. Nach einer kurzen kostenlosen Registrierung kann man den Installer direkt runterladen und dank der ausführlichen Anleitung fällt auch das Einrichten der IDE nicht weiter schwer.

Nachdem also die IDE installiert war, ging es erst einmal darum, die externen Interrupts zu erfassen. Und genau hier fingen die Schwierigkeiten an. Es sind im Internet noch relativ wenig Informationen über die XMC-Familie zu finden und das, was man findet, stützt sich auf die DAVE3 Entwicklungsumgebung von Infineon mit den diversen DAVE-Apps. Da es sich dabei aber - wie ich es verstanden habe - um dynamisch erzeugten Code handelt, hat es mir bei meiner Frage, wie man die Interrupts in einer anderen IDE ohne DAVE-Apps einrichten und auswerten kann, nicht wirklich weiter geholfen. Hilfe habe ich letztendlich im Forum 'infineonforums.com' [2] erhalten. Dort wurde mir der Link zu einem Code-Example [3] gegeben, welches zwar auch mit der DAVE-IDE erstellt wurde, bei die Initialisierung der Interrupts jedoch manuell ohne App umgesetzt wurde. Damit war es mir nun auch möglich, die Interrupts auf steigende und fallende Flanken an der Lichtschanke, sowie nur der steigenden Flanke des Endschalters zu initialisieren und auf diese zu Reagieren.

Steckerbelegung an der Steuerplatine des Stapelschneiders

Die Signalquellen sind, wie oben erwähnt, durch Stecker mit der Steuerungsplatine verbunden. Diese Verbindungen nutze ich, um die Signale abzugreifen und die Signale meines Digital-Potentiometers einzuspeisen.

Um eine halbe Phase verschobenes Rechtecksignal

Die ISR (Interrupt Service Routine), die die Positionsänderungen erfassen sollte, gestaltete sich nun recht einfach. Das Lichtschranken-Pärchen liefert logischerweise für jede Lichtschranke ein Rechtecksignal, solange sich der Motor dreht. Die Signale der beiden Lichtschranken sind eine halbe Phase zueinander verschoben. Einen Interrupt habe ich nur für die eine Lichtschranke initialisiert. Dieser löst bei jeder steigenden und fallenden Flanke, also immer wenn sich der Zustand von High auf Low oder von Low auf High ändert, aus. In der ISR brauche ich dann nur noch zu erfassen, welcher Pegel an den beiden Eingängen, an denen die Lichtschranken angeschlossen sind, anliegt und diese beiden Pegel zu vergleichen. Wenn beide Pegel gleich sind (egal ob High oder Low), dreht der Motor in die eine Richtung und ich zähle eine vorher initialisierte Zählervariable um einen Zähler hoch. Sind die beiden Werte unterschiedlich, dreht der Motor in die andere Richtung und ich zähle meine Variable herrunter. Somit habe ich schon einmal eine relative Positionsbestimmung. Allerdings kann ich nicht wissen, an welcher Position die Maschine startet (das weiß die Maschine nicht einmal selbst).

Hier kommt nun der hintere Endschalter ins Spiel. Da die Maschine über keinen nichtflüchtigen Positionsspeicher (wie beispielsweise ein EEPROM) verfügt, 'vergisst' sie bei jedem Ausschalten, an welcher Position sich der Tiefenanschlag befindet. Wenn die Maschine eingeschaltet wird, ist somit eine sogenannte Referenzfahrt nötig. Hierzu muss man im Originalzustand des Stapelschneiders den Poti einmal kurz auf 'zurück' stellen. Eine eingebaute Feder bringt den Poti wieder in die neutrale Stellung und der Tiefenanschlag fährt zurück, bis dieser den Endschalter erreicht hat. Nun weiß die Maschine, dass sich der Schlitten bei genau 520mm hinter dem Messer befindet. In meiner Steuerung habe ich dem Eingang, auf den der Endschaltergelegt ist, auch einen Interrupt spendiert. Sobalt der Endschalter auslöst, setze ich meine oben schon erwähnte Zählerwariable auf den maximalen Wert von 46800. Diese Zahl setzt sich folgendermaßen zusammen: Ich benötige eine genauigkeit von einem Zehntel Millimeter. Der maximal erreichbare Wert bis der Endschalter ausgelöst wird, beträgt 520mm. Das sind 5200 1/10mm. Bei jedem 1/10mm, den sich der Schlitten bewegt, wird neun mal ein Interrupt ausgelöst. Somit ist der Maximalwert meiner Variable 5200x9=46800. Damit diese Position nun beim Starten erfasst wird, wird das digitalpotentiometer beim starten der Firmware für eine kurze Zeitspanne (300ms) auf 'zurück' gestellt und anschließend wieder die Neutralposition eingestellt, ganz so, als würde man die Maschine direkt bedienen.

Analogpoti zur Steuerung des Tiefensnschlags

Um den Stapelschneider weiterhin direkt mit dem analogen Potentiometer an der Maschine zu bedienen, wird laufend der Wert des Potentiometers mittels ADC eingelesen. Wenn dieser von dem beim Start gespeicherten Wert (inkl. einer kleinen Hysterese von +-10) abweicht, wird automatisch das digitale Potentiometer diesem Wert angepasst und eine eventuell noch nicht abgearbeitete Positionsänderung gelöscht.

Damit sind wir auch schon beim nächsten Punkt. Positionsänderungen (bzw. gewünschte absolute Positionen) werden über UART empfangen und abgearbeitet. Dabei musste darauf geachtet werden dass die Positionen immer nur aus einer Richtung angefahren werden dürfen (von hinten), da sich sonst das Umkehrspiel des Schlittens bemerkbar machen würde. Sollte die gewünschte neue Position also hinter der aktuellen Position legen. Muss der Schlitten noch ein stück weiter zurück fahren, um die gewünschte Position dann von hinten anfahren zu können.

Die Positionsänderungen wurden, wie oben erwähnt, ursprünglich mit einem Analogen 1k-Ohm Potentiometer durchgeführt. In Neutralstellung war das Poti auf etwa 800 Ohm eingestellt. Um den Tiefenanschlag nach hinten zu bewegen, musste man das Potentiometer richtung 1000 Ohm verdrehen. Wenn man losgelassen hat, ist es, durch eine Feder getrieben, utomatisch wieder auf die Neutralstellung zurück gesprungen. Um den Schlitten nach vorne zu bewegen, musste das Poti richtung 0 Ohm verstellt werden. Je näher man an 0 Ohm heran gekommen ist, desto schneller bewegte sich der Schlitten. In dieser Richtung ist das Potentiometer nach dem loslassen nicht wieder zurück gesprungen. Dieses Aufgabe übernimmt nun ein Digital-Potentiometer, dass über das 3-Wire Serial Interface angesteuert wird. Die Ansteuerng ist dabei denkbar einfach. Verwand ist das 3-Wire Serial Interface mit dem SPI. Es gibt eine CS-Leitung (Chip Select), die das Potentiometer bei Low-Potenzial aktiviert. Als zweite der drei Leitungen gibt es einen U/D-Eingang (Up/Down). Bei High-Potenzial wird der Wiper-Tab-Ausgang des Potentiometers niederohmiger (die Spannung wird höher), bei Low-Potenzial dann logischerweise hochohmiger. Als drittes und letztes gibt es dann noch die INC-Leitung (Increment). Diese ist vergleichbar mit der Clock-Leitung bei der SPI-Schnittstelle. Bei jeder negativen Flanke wird der Widerstand je nach U/D-Pegel größer oder kleiner.

Bluetooth-Modul BTM222

Nachdem die Grundfunktionalität der Firmware nun gegeben war, musste nun die drahtlose Kommunikation her. Diese Aufgabe übernimmt bei mir ein BTM222. Es hat den Vorteil, dass es eine große Reichweite hat (Class1: 100m) und einfach anzusteuern ist. Um eine UART-Funkbrücke zu realisieren, muss man nur die Rx- und Tx-Pins des Moduls mit den Tx- und Rx-Pins des Mikrocontrollers verbinden (Achtung: über Kreuz verbinden. Tx an Rx und Rx an Tx). Dann noch die Stromversorgung des Moduls und eine Antenne (bei mir ein paar cm Klingeldraht) und es kann los gehen. Für den XMC2GO habe ich dabei die von Uwe Becker bereitgestellte UART-Lib [4] genommen und leicht modifiziert. In der Lib sind TX auf P2.1 und RX auf R2.2 gelegt. Das macht auch Sinn, da damit die auf dem XMC2GO integrierte UART-to-USB Bridge angesprochen wird. Da ich jedoch TX und RX mit meinem BTM222 verbinden möchte, müssen diese auf die Pin-Leisten umgelegt werden. Ich habe mich nach einem Blick ins Datenblatt für die Pins P0.14 (RX) und P0.15 (TX) entschieden. Das hat den einfachen Grund, weil in der Lib die Input-Daten intern von DX3 (P2.2) auf DX0 umgeleitet werden. Da DX0 an P0.14 liegt, kann diese Umleitung einfach entfernt werden. Danach muss nur noch DOUT0 auf P0.15 umgeleitet werden und einer Kommunikation steht (fast) nichts mehr im Wege. Da das Modul standardmäßig mit einer Baudrate von 19200bps arbeitet, in der UART-Lib aber 115200bps eingestellt sind, muss nun eines von beidem angepasst werden. Ich habe mich dafür entschieden, die Baudrate des Moduls anzupassen. Dafür habe ich einen USB-UART-Wandler an die Tx- und Rx-Pins angeschlossen und den Befehl ATL5 über das Programm hTerm an des Bluetooth-Modul gesendet. Damit wird auch auf dem BTM222 eine Baudrate von 115200bps eingestellt und XMC2GO und BTM222 können kommunizieren.

Soweit so gut. Jetzt 'nur' noch die Android App. Zum testen habe ich mich damit begnügt, mir eine App mit dem MIT App Inventor 2 [5] zu erstellen. Dies ist eine kostenlose cloudbasierte Entwicklungsumgebung nach dem Baukastenprinzip, mit der man 'auf die Schnelle' Apps für Android-Geräte erstellen kann. Benötigt wird nur ein Google-Account (den man für den Android PlayStore ja sowiso braucht). Dabei werden die verschiedenen Module und Logig-Einheiten als Puzzleteile dargestellt, die man dann zusammen stellen kann. Meiner Meinung nach reicht dies für kleinere Projekte durchaus aus, wird bei etwas mehr Umfang aber sehr schnell unübersichtlich. Die App, die ich mit diesem System erstellt habe, soll momentan nur dafür verwendet werden, die Technik des Projekts auf Herz und Nieren zu testen. Die eigentliche Steuerungsapp werde ich höchstwarscheinlich in einer richtigen IDE erstellen.

Ich hoffe, ich konnte euch mein Projekt etwas näher bringen und der eine oder andere kann vielleicht noch einen Codeschnipsel oder eine Idee für ein eigenes Projekt übernehmen.

Ich möchte an dieser Stelle noch darauf hinweisen, dass sich das ganze Projekt noch in der Erprobungsphase befindet und es noch einige Bugs und sicherlich auch noch die eine oder andere Änderung an der Hardware gibt. Beispielsweise ist mir bewusst, dass es nicht optimal ist, die 5V-Signale der Maschine durch einen Spannungsteiler auf 3,3V zu bringen. Für die nächste Hardware-Version ist schon ein Levelshifter eingeplant :-)

Downloads

Bilder zum Projekt

Siehe auch