Homepage von Peter Rachow Startseite - Home

Allgemeines 

Forschung und Entwicklung: LCD-Anzeige | Mikrocontroller | Software | Sensoren | Gehäuse | Erfahrungsberichte

Geräte: SBTC3 | SBTC4 | Datenmodem zum PC | Simulator für Drucksensor

Der Selbstbau-Tauchcomputer (SBTC)

Die Software

Auf dieser Seite wird die Erstellung der Dekompressionssoftware in der Sprache C für den SBTC behandelt. Es wird die Entwicklungsumgebung beschrieben, die man benötigt, um für den ATMega32 kodieren zu können sowie die Technologien um die verschiedenen Erweiterungen des SBTC zu erschließen. Zusätzlich wird vorgestellt, wie die Datenstruktur des EEPROM-Speichers angelegt ist, in dem die Grundeinstellungen des Benutzers und das Tauchprofil gespeichert werden..

1. Die Entwicklungsumgebung
   1.0 Einstellen des Prozessortaktes
   1.1 Das Makefile
   1.2 Das Dekompressionsprogramm
   1.2.1 Funktionen der Software
   1.2.1.1 Grundstruktur des Programmablaufes
   1.2.1.2 Dekompressionsrechnung
1.3 Der Programmcode
1.4 Die Datenübertragung vom SBTC zu einem PC
1.5 Der Simulator für den Drucksensor

1. Die Entwicklungsumgebung

Zum Entwickeln der Software für den SBTC benötigt man lediglich einen Editor (z. B. Windows Notepad oder Programmer's Notepad , letzteres ist in dem nachfolgend beschriebenen und frei verfügbaren Softwarepaket WINAVR enthalten, läuft aber fehlerfrei erst ab Win98) und einen C-Compiler, der Maschinencode für den AVR-Mikrocontroller erzeugen kann. Neben verschiedenen kommerziellen Compilern (z. B. dem von Atmel in seinen Schriften referenzierten IAR-Compiler) gibt es als preisgünstige und durchdachte Alternative den GNU-AVR-C-Compiler. Er ist im Paket WINAVR enthalten. Dieses Paket WINAVR der Entwicklungsumgebung kann man sich hier laden:

http://sourceforge.net/projects/winavr

Hat man das Paket installiert, verfügt man über eine leistungsfähige Entwicklungsumgebung mit der man Programme in C für den AVR-Controller schreiben kann. Dies eröffnet auch dem in Assembler unerfahrenen Programmierer (wie mir), die Möglichkeit, Software für den ATMEL zu erstellen, insbsesondere deshalb, weil die Kontroller für die Sprache C (bzw. das sich daraus ableitende Compilerergebnis) optimiert wurden.

Bevor man an das Erstellen der eigentlichen Dekompressionssoftware geht, müssen einige Einstellungen am Mikrocontroller selbst optimiert werden. Dabei geht es i. W. um das

1.0 Einstellen des Prozessortaktes

Zuerst ein kleiner Exkurs über die Taktratengenerierung beim ATMEL-Controller: Der AVR-Mikrocontroller beinhaltet die Optionen, verschiedene Oszillatoren als Taktgenerator zu verwenden. Dabei handelt es sich im Wesentlichen um die Unterscheidung "interner" vs. "externer" Oszillator. Man könnte also z. B. auch einen externen Oszillator anschließen. Der interne Oszillator hat jedoch eine Genauigkeit von 1%, was für die Anwendung in einem Tauchcomputer m. E. (besonders, wenn es sich um ein Versuchsgerät handelt) ausreichend ist. Das eigentliche Timing der Datenerfassung vom Wasserdruck und die Dekompressionsrechnung wird über den Timer2 des Mikrocontroller gesteuert, der quarzgesteuert im Sekundentakt eine Zählervariable erhöht und so eine extrem präzise Zeitmessung ergibt. Wer es genauer wissen will, findet im Datenblatt unter "System Clock and Clock Options" die entsprechenden Informationen.

Der Atmel-Controller wird standardmäßig ab Werk in der Einstellung "Interner Taktoszillater f=1MHz geliefert". Für unsere Zwecke ist es aber günstig, die maximal erzielbare Taktrate von 8 MHz einzustellen umd mehr Rechenleistung zu erhalten. Diese Einstellung wird über die sog. "Fuses" des uC vorgenommen. Es handelt sich um ein Muster von Bits, deren Setzung (oder Nichtsetzung) die Grundeinstellungen des Mikrocontroller definiert. Die Einstellung der Taktrate geschieht dabei über die mit CKSEL (Clock Selection) bezeichneten 4 Bits CKSEL3 bis CKSEL0. Laut Datenblatt benötigt man für die Einstellung "interner Oszillator f=8Mhz" folgende Einstellungen:

Auszug aus dem Datenblatt: Die Bitmuster der einzelnen Taktraten
Bild 1: Auszug aus dem Datenblatt: Die Bitmuster der einzelnen Taktraten

Dabei ist zu beachten, dass CKSEL3 von links beginnend gelesen wird und dass weiterhin ein Bit als gesetzt gilt, wenn es auf "0" steht (etwas absurd, man muss hier halt um die Ecke denken können!). Die Einstellung selbst wird mit dem Programm yaap vorgenommen. Man öffnet ein neues Projekt, lässt yaap den Prozessortyp erkennen (Detect Device) und stellt dann folgendes Muster ein:

Bitmuster für yaap um den ATMega32 auf 8 MHz Taktfrequenz zu setzen
Bild 2: Bitmuster für yaap um den ATMega32 auf 8 MHz Taktfrequenz zu setzen

Wichtig: Hier unbedingt genau arbeiten! Bei falschen Einstellungen kann man den Prozessor ins Nirwana schicken, wenn man z. B. auf "Externer Oszillator" umschaltet aber man halt blöderweise keinen zur Hand hat. Pech gehabt! Der Mikrocontroller will dann nämlich unbedingt einen externen Taktgenerator (irgendwoher braucht er ja schließlich sein "Clock"-Signal) und verweigert natürlich auch eine Neuprogrammierung, denn da wo kein Takt da auch kein Abarbeiten von Befehlen.

Ist das erledigt und der Prozessor lebt noch und kommuniziert weiterhin mit einem (z. B. eben über yaap, d. h. man kann die Einstellungen der Bits noch lesen), kann man sich den schönen Dingen des Lebens zuwenden, der Entwicklung der Dekosoftware. Diese Softwareerstellung ist leider ein klein wenig komplizierter als das Programmieren unter Visual Basic, es müssen erst ein paar kleine Vorarbeiten erledigt werden. Die erste ist....

1.1 Das Makefile

Dieser wichtige Schritt betrifft das Projekt selber. Der Compiler benötigt immer ein sog. " Makefile " um die Erstellung eines auf dem AVR-uC lauffähigen Programmes vorzunehmen. In diesem Makefile werden alle wichtigen Informationen das Projekt betreffend dem Compiler übergeben. Diese sind, um nur die wichtigsten zu nennen:
  • Name des Projektes (Daraus leiten sich die im Entwicklungsprozess verwendeteten Dateinamen ab, die projektbezogen sind, u. a. das Target , also die Zieldatei, die dann mit .hex -Suffix den eigentlichen zum uC hochladbaren Code enthält)
  • Der Typ des Zielprozessors für den entwickelt wird (MCU = microcontroller unit, z. B. ATmega32 etc.)
  • Speicher- und Linkeroptionen wie z. B. die einzubindenden Libraries.
  • Den Optimierungsgrad (wählbar zwischen 0 und 5 und 's'), der die Dateigröße ganz wesentlich beeinflusst. Hier sollte man zwischendurch immer wieder mal experimentieren, denn der gleiche Quellcode kann je nach Optimierungsgrad z. B. zwischen 4 und 7 kB einnehmen.
  • etc.
Da das Erstellen  des Makefiles eine kleine Wissenschaft für sich ist, ist hier das Makefile ( sbtc-make.zip ) für das SBTC-Projekt hinterlegt. Die Datei wurde von Christian Zink erzeugt und von mir auf ein möglichst kompaktes Linken hin optimiert. Sie wird in das Arbeitsverzeichnis kopiert, in dem man sein Projekt erstellt und mit der ebenfalls in der ZIP-Datei enthaltenen Batchdatei gestartet.

Mit der in sbtc-make.zip enthaltenen Batchdatei _build.bat kann man den Compiliervorgang starten, aus dem C-Programm wird dann eine sog. "HEX"-Datei erzeugt, also vom Mikrocontroller interpretierbarer Maschinencode, der in selbigen geladen wird.  Wenn man das alles mehrmals gemacht hat, wird es ein automatischer Handlungsablauf:

  • Programm im Editor schreiben (z. B. Windows Notepad) und prüfen.
  • Compilieren mit _build.bat .
  • Hinaufladen zum Mikrocontroller mit yaap
  • Software testen.
Wie viel Speicher im Mikrocontroller man "verbraucht" hat, steht in der Datei _results.txt , die nach jedem Compilieren durch _build.bat erzeugt wird in der Sektion

Size after:
sbtc.elf  :
section     size      addr
.text       6046         0
.data        298   8388704
.bss          13   8389002
.noinit        0   8389015
.eeprom        0   8454144
.stab       7212         0
.stabstr    3225         0
Total      16794

.text und .data dürfen für ATmega32 zusammen nicht mehr als 32767 Byte einnehmen, das dürfte aber schwer zu erreichen sein.

Ein Wort noch zu AVR Studio : Auf der Homepage von ATMEL findet man AVR Studio , eine Entwicklungsumgebung für die AVR-Controller. Anfangs habe ich mit dieser gearbeitet, weil man die Programme, die man geschrieben hat, zuerst in einer Simulationsumgebung testen kann und sich z. B. die Signalmuster, die man an den Ports erzeugt, ansehen kann. Leider hat der Simulator sehr enge Grenzen, z. B. kann er nicht in Echtzeit simulieren. Auch fehlt natürlich die Peripherie, wie das LCD. Da der AVR-ATmega32 dagegen ca. 10000 Zyklen Schreiben in den Flashspeicher zulässt und nur 11,50 Euro kostet, teste ich heute direkt im Controller. Ist das Schreiben des Flash eines Tages nicht mehr möglich, wechselt man eben schnell den Controller. Bis jetzt habe ich allerdings den ersten Controller immer noch am Arbeiten.

1.2 Das Tauchcomputerprogramm

(Zum C-Quellcode der Dekompressionssoftware.)

Das eigentliche Rechenprogramm des SBTC besteht aus den mehreren Funktionsgruppen. Die wichtigsten:

a) Berechnungsfunktionen für

  • Sättigung und Entsättigung mit Inertgas
  • Dekompression und Nullzeit
  • ppO2-abgeleitete Daten (max. zul. Wert mit aktuellem ppO2 vergleichen, ZNS und OTU berechnen)
  • Nach dem Tauchen: Flugverbotszeit ermitteln (Kabinendruck variabel definierbar duech Anwender), Oberflächenpausenzeit, Berechnen der Entsättigung an der Oberfläche
  • etc.
b) LCD-Anzeigesteuerung
c) Druck- und Temperatursensorerfassung
d) Ablaufsteuerung (Tauchen, Oberflächenbetrieb)
e) Benutzermenü
f) Kommunikation mit einem PC
g) Hilfsfunktionen

1.2.1 Funktionen der Software

1.2.1.1 Grundstruktur des Programmablaufes

Wird der uC gestartet, indem Spannung an VDD angelegt wird, steigt er in die Routine main() (also das Hauptprogramm) ein. Dort wird in unserer Version das Display initialisiert, die gewählten Ports des uC werden für Ein- bzw. Ausgabevorgänge eingerichtet etc., es handelt sich um Standardoperationen. Desweiteren werden Grundeinstellungen aus dem EEPROM des uC gelesen.

Anschließend wird ein sog. Interrupthandling mit den Timerfunktionen des uC generiert und über die Funktion sei() (Enable Interupts) freigegeben. Nach dem Ablauf eines der in den uC integrierten Timers (hier Timer2) wird nun jeweils in regelmäßigen Zeitabständen eine Interuptroutine SIGNAL (SIG_OVERFLOW2) aufgerufen, die einen Zähler im Sekundetakt erhöht. Die seit Start des Programmes verstrichene Zeit wird in der Variablen runseconds gespeichert, zusätzlich wird die Oberflächenzeit in der Variablen surf_time abgelegt. Die Tauchzeit wird in diveseconds abgelegt. . Verschiedenen Aktionen (Drucksensor lesen, Dekorechnung durchführen) werden basierend auf diesem dieses Sekundetakt in bestimmten Zeitintervallen (1, 2 und 10 s) durchgeführt. Dadurch erhält man eine sehr präzise Zeitmessung aus der sich alle zeitkritischen Funktionen des Programmes ableiten lassen.

1.2.1.2 Dekompressionsrechnung

Das Rechenprogramm selbst enthält den bekannten Bühlmann-Algorithmus ( ZH-L16 ), der hier möglichst platzsparend kodiert wurde. Das Programm kann außerdem Nullzeiten für N 2 berechnen, was sehr wichtig ist, da man ja sowieso stirbt , wenn man die Nullzeitgrenze überschreitet. ;-)

Der Grundablauf ist in etwa folgender:

a) Messe den Druck jede Sekunde.
b) Errechne daraufhin den Stickstoffpartialdruck (ppN 2 ) bzw. Heliumpartialdruck (ppHe) aller Gewebe (Kompartimentsättigung).
c) Ermittle alle 10 Sekunden die gerade noch erlaubte Tiefe (Dekoberechnung).
d) Ist die gerade noch erlaubte Tiefe größer als 0 Meter berechne ein Dekompressionsphase, ansonsten beginne von vorne.

Die Berechnung der Dekompressionsphase verläuft dann in der Funktion calc_deco()   in folgenden Teilschritten:

a) Kopiere die aktuelle Sättigung aller Gewebe in ein temporäres Datenfeld mit 2x16 diskreten Werten (für N 2 und He).
b) Ermittele von allen 16 Geweben den größten erforderlichen Umgebungsdruck.
c) Ermittele die hierzu korrespodierende Wassertiefe.
d) Verringere den Druck auf dieses Tiefenäquivalent.
e) Berechne nun die Sättigung und erhöhe den Minutenzähler um 1.
f) Ermittele wieder von allen 16 Geweben den größten erforderlichen Umgebungsdruck.
g) Ermittele, ob dieser auch erreicht wird, wenn die Tauchtiefe um 3 m verringert wird.
h) Wenn g) mit JA beantwortet wird, verringe die Tauchtiefe um 3 m, wenn NEIN warte eine weitere Minute auf dieser Tiefe.
i) Setze fort mit e) solange, bis die Dekompressionstiefe 0 beträgt.
j) Dekompressionphase ist beendet, zeige an "NZ" (Nullzeit).

1.3 Der Code

Der C-Code der Software findet sich hier .

Die SBTC-Seiten

Konzeption | LCD-Anzeige | Mikrocontroller | Software | Sensoren | Gehäuse | Erfahrungsberichte