<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://www.mikrocontroller.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Matze88</id>
	<title>Mikrocontroller.net - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://www.mikrocontroller.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Matze88"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/Matze88"/>
	<updated>2026-04-23T14:53:13Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:SparmaticZerov2_Schaltplan.png&amp;diff=61483</id>
		<title>Datei:SparmaticZerov2 Schaltplan.png</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:SparmaticZerov2_Schaltplan.png&amp;diff=61483"/>
		<updated>2011-11-07T11:36:09Z</updated>

		<summary type="html">&lt;p&gt;Matze88: hat eine neue Version von „Datei:SparmaticZerov2 Schaltplan.png“ hochgeladen:&amp;amp;#32;Neue Version von Knut Ballhause&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Sparmatic_Heizungsthermostate&amp;diff=61440</id>
		<title>Sparmatic Heizungsthermostate</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Sparmatic_Heizungsthermostate&amp;diff=61440"/>
		<updated>2011-11-05T10:09:09Z</updated>

		<summary type="html">&lt;p&gt;Matze88: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel sammelt Informationen zu den elektronischen Heizkörperthermostaten der Reihe &amp;quot;Sparmatic&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Modelle ==&lt;br /&gt;
&lt;br /&gt;
Den Sparmatic gibt es in verschiedenen Ausführungen:&lt;br /&gt;
&lt;br /&gt;
Der Sparmatic Zero hat gleich zwei Versionen:&lt;br /&gt;
Die alte Version ist mit Schrauben zu öffnen und hat hinter der Batterie einen Pin-Header für den JTAG des Controllers.&lt;br /&gt;
&lt;br /&gt;
Die neue Version hingegen ist mit Plastiknasen so verschlossen, dass er nach dem Öffnen nur mit Hilfsmitteln wieder fest verschließbar ist. Unter den Batterien sieht man jeweils hinter den Batteriekontakten 6 Testpads (2x3 Anordnung).&lt;br /&gt;
Die Pads auf der Seite des &amp;quot;+&amp;quot; Batteriekontaktes enthalten dabei den JTAG des Controllers, die andere Seite unter anderem den ISP.&lt;br /&gt;
&lt;br /&gt;
Der Sparmatic Comet hat nur drei Tasten, dafür einen zusätzlichen Drehimpulsgeber.&lt;br /&gt;
Hiervon existieren baugleiche(?) Modelle, z.B. der bei Aldi verkaufte &amp;quot;Thermy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Für Informationen in diesem Thread kann man die genannten Thermostate anhand der Beschaltung des Controllers in zwei Kategorien einteilen:&lt;br /&gt;
# Sparmatic Zero alt&lt;br /&gt;
# Sparmatic Zero neu, Comet, Thermy&lt;br /&gt;
&lt;br /&gt;
== Sparmatic Zero v1 ==&lt;br /&gt;
&lt;br /&gt;
Dieser wurde bereits ausführlich im Forum diskutiert.&lt;br /&gt;
Im folgenden Thread wurde eine alternative Firmware entwickelt:&lt;br /&gt;
http://www.mikrocontroller.net/topic/160462&lt;br /&gt;
&lt;br /&gt;
== Sparmatic Zero v2 / Comet / Thermy ==&lt;br /&gt;
&lt;br /&gt;
Die Entwicklung läuft noch. Aktuelle Informationen finden sich im Forum:&lt;br /&gt;
http://www.mikrocontroller.net/topic/237375&lt;br /&gt;
&lt;br /&gt;
=== Schaltpläne und Platinenaufnahmen === &lt;br /&gt;
&lt;br /&gt;
Comet (Leopold B.):&lt;br /&gt;
&lt;br /&gt;
[[Bild:SparmaticComet_Schaltplan.png|600px]]&lt;br /&gt;
&lt;br /&gt;
[[Bild:SparmaticComet_Platine_TOP.jpg|300px]]&lt;br /&gt;
[[Bild:SparmaticComet_Platine_BOT.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Zero v2 (vorläufig):&lt;br /&gt;
&lt;br /&gt;
[[Bild:SparmaticZerov2_Schaltplan.png|600px]]&lt;br /&gt;
&lt;br /&gt;
[[Bild:SparmaticZerov2_Platine_TOP.jpg|300px]]&lt;br /&gt;
[[Bild:SparmaticZerov2_Platine_BOT.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:SparmaticComet_LCD_Segment_Belegung.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
tabellarische Darstellung der einzelnen 14-Segment-Module:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SparmaticComet_SegmentMapping.png|600px]]&lt;br /&gt;
&lt;br /&gt;
Initialisierung des LCD Controllers wie in der Originalfirmware (Leopold B.):&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
LCDCRB = (1&amp;lt;&amp;lt;LCDCS)|(0&amp;lt;&amp;lt;LCD2B)|(1&amp;lt;&amp;lt;LCDMUX1)|(1&amp;lt;&amp;lt;LCDMUX0)|(1&amp;lt;&amp;lt;LCDPM2)|(1&amp;lt;&amp;lt;LCDPM1)|(1&amp;lt;&amp;lt;LCDPM0);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDCS)                            // Das LCD wird im asynchronen Modus (LCDCS-Bit=1)&lt;br /&gt;
                                               mit der Frequenz des Quarzes TOSC1 = 32.768Hz als LCD Clock betrieben.&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCD2B)                           // 1/3 bias is used&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDMUX1)|(1&amp;lt;&amp;lt;LCDMUX0)            // 1/4 Duty; COM0:3;&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDPM2)|(1&amp;lt;&amp;lt;LCDPM1)|(1&amp;lt;&amp;lt;LCDPM0); // SEG0:24&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDFRR = (0&amp;lt;&amp;lt;LCDPS2)|(0&amp;lt;&amp;lt;LCDPS1)|(0&amp;lt;&amp;lt;LCDPS0)|(0&amp;lt;&amp;lt;LCDCD2)|(0&amp;lt;&amp;lt;LCDCD1)|(1&amp;lt;&amp;lt;LCDCD0);&lt;br /&gt;
/*&lt;br /&gt;
      (0&amp;lt;&amp;lt;LCDPS2)|(0&amp;lt;&amp;lt;LCDPS1)|(0&amp;lt;&amp;lt;LCDPS0)    // N = 16&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDCD2)|(0&amp;lt;&amp;lt;LCDCD1)|(1&amp;lt;&amp;lt;LCDCD0);  // D = 2&lt;br /&gt;
      // ergo f(frame) = 128Hz&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDCCR = (1&amp;lt;&amp;lt;LCDDC2)|(0&amp;lt;&amp;lt;LCDDC1)|(0&amp;lt;&amp;lt;LCDDC0)|(/*config.lcd_contrast*/ 10 &amp;lt;&amp;lt; LCDCC0);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDDC2)|(0&amp;lt;&amp;lt;LCDDC1)|(0&amp;lt;&amp;lt;LCDDC0)   // 575 µs&lt;br /&gt;
      |(config.lcd_contrast &amp;lt;&amp;lt; LCDCC0);     // Set the initial LCD contrast level&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDCRA = (1&amp;lt;&amp;lt;LCDEN)|(1&amp;lt;&amp;lt;LCDAB)|(0&amp;lt;&amp;lt;LCDIE)|(0&amp;lt;&amp;lt;LCDBL);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDEN)    // Enable LCD&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDAB)   // Low Power Waveform&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDIE)   // disable Interrupt&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDBL);  // No Blanking&lt;br /&gt;
*/&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
=== Stellmotor ===&lt;br /&gt;
&lt;br /&gt;
An ADC2 (PF2) kann die Stromaufnahme des Motors gemessen werden. Der Shunt besitzt 2,2 Ohm, der maximale Spannungsabfall ist durch eine parallele Diode begrenzt.&lt;br /&gt;
Leopold B. hat mal eine Stellfahrt oszillographiert:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SparmaticComet_Spannung_an_PF2_beim_Schliessen.png|600px]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:SparmaticComet_Spannung_an_PF2_beim_Schliessen.png&amp;diff=61439</id>
		<title>Datei:SparmaticComet Spannung an PF2 beim Schliessen.png</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:SparmaticComet_Spannung_an_PF2_beim_Schliessen.png&amp;diff=61439"/>
		<updated>2011-11-05T10:08:06Z</updated>

		<summary type="html">&lt;p&gt;Matze88: http://www.mikrocontroller.net/topic/160462#1950022
Leopold B.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;http://www.mikrocontroller.net/topic/160462#1950022&lt;br /&gt;
Leopold B.&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Sparmatic_Heizungsthermostate&amp;diff=61438</id>
		<title>Sparmatic Heizungsthermostate</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Sparmatic_Heizungsthermostate&amp;diff=61438"/>
		<updated>2011-11-05T10:07:19Z</updated>

		<summary type="html">&lt;p&gt;Matze88: Bildgrößen&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel sammelt Informationen zu den elektronischen Heizkörperthermostaten der Reihe &amp;quot;Sparmatic&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Modelle ==&lt;br /&gt;
&lt;br /&gt;
Den Sparmatic gibt es in verschiedenen Ausführungen:&lt;br /&gt;
&lt;br /&gt;
Der Sparmatic Zero hat gleich zwei Versionen:&lt;br /&gt;
Die alte Version ist mit Schrauben zu öffnen und hat hinter der Batterie einen Pin-Header für den JTAG des Controllers.&lt;br /&gt;
&lt;br /&gt;
Die neue Version hingegen ist mit Plastiknasen so verschlossen, dass er nach dem Öffnen nur mit Hilfsmitteln wieder fest verschließbar ist. Unter den Batterien sieht man jeweils hinter den Batteriekontakten 6 Testpads (2x3 Anordnung).&lt;br /&gt;
Die Pads auf der Seite des &amp;quot;+&amp;quot; Batteriekontaktes enthalten dabei den JTAG des Controllers, die andere Seite unter anderem den ISP.&lt;br /&gt;
&lt;br /&gt;
Der Sparmatic Comet hat nur drei Tasten, dafür einen zusätzlichen Drehimpulsgeber.&lt;br /&gt;
Hiervon existieren baugleiche(?) Modelle, z.B. der bei Aldi verkaufte &amp;quot;Thermy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Für Informationen in diesem Thread kann man die genannten Thermostate anhand der Beschaltung des Controllers in zwei Kategorien einteilen:&lt;br /&gt;
# Sparmatic Zero alt&lt;br /&gt;
# Sparmatic Zero neu, Comet, Thermy&lt;br /&gt;
&lt;br /&gt;
== Sparmatic Zero v1 ==&lt;br /&gt;
&lt;br /&gt;
Dieser wurde bereits ausführlich im Forum diskutiert.&lt;br /&gt;
Im folgenden Thread wurde eine alternative Firmware entwickelt:&lt;br /&gt;
http://www.mikrocontroller.net/topic/160462&lt;br /&gt;
&lt;br /&gt;
== Sparmatic Zero v2 / Comet / Thermy ==&lt;br /&gt;
&lt;br /&gt;
Die Entwicklung läuft noch. Aktuelle Informationen finden sich im Forum:&lt;br /&gt;
http://www.mikrocontroller.net/topic/237375&lt;br /&gt;
&lt;br /&gt;
=== Schaltpläne und Platinenaufnahmen === &lt;br /&gt;
&lt;br /&gt;
Comet (Leopold B.):&lt;br /&gt;
[[Bild:SparmaticComet_Schaltplan.png|500px]]&lt;br /&gt;
[[Bild:SparmaticComet_Platine_TOP.jpg250px]]&lt;br /&gt;
[[Bild:SparmaticComet_Platine_BOT.jpg|250px]]&lt;br /&gt;
&lt;br /&gt;
Zero v2 (vorläufig):&lt;br /&gt;
[[Bild:SparmaticZerov2_Schaltplan.png|500px]]&lt;br /&gt;
[[Bild:SparmaticZerov2_Platine_TOP.jpg|250px]]&lt;br /&gt;
[[Bild:SparmaticZerov2_Platine_BOT.jpg|250px]]&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:SparmaticComet_LCD_Segment_Belegung.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
tabellarische Darstellung der einzelnen 14-Segment-Module: [[Bild:SparmaticComet_SegmentMapping.png|400px]]&lt;br /&gt;
&lt;br /&gt;
Initialisierung des LCD Controllers wie in der Originalfirmware (Leopold B.):&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
LCDCRB = (1&amp;lt;&amp;lt;LCDCS)|(0&amp;lt;&amp;lt;LCD2B)|(1&amp;lt;&amp;lt;LCDMUX1)|(1&amp;lt;&amp;lt;LCDMUX0)|(1&amp;lt;&amp;lt;LCDPM2)|(1&amp;lt;&amp;lt;LCDPM1)|(1&amp;lt;&amp;lt;LCDPM0);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDCS)                            // Das LCD wird im asynchronen Modus (LCDCS-Bit=1)&lt;br /&gt;
                                               mit der Frequenz des Quarzes TOSC1 = 32.768Hz als LCD Clock betrieben.&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCD2B)                           // 1/3 bias is used&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDMUX1)|(1&amp;lt;&amp;lt;LCDMUX0)            // 1/4 Duty; COM0:3;&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDPM2)|(1&amp;lt;&amp;lt;LCDPM1)|(1&amp;lt;&amp;lt;LCDPM0); // SEG0:24&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDFRR = (0&amp;lt;&amp;lt;LCDPS2)|(0&amp;lt;&amp;lt;LCDPS1)|(0&amp;lt;&amp;lt;LCDPS0)|(0&amp;lt;&amp;lt;LCDCD2)|(0&amp;lt;&amp;lt;LCDCD1)|(1&amp;lt;&amp;lt;LCDCD0);&lt;br /&gt;
/*&lt;br /&gt;
      (0&amp;lt;&amp;lt;LCDPS2)|(0&amp;lt;&amp;lt;LCDPS1)|(0&amp;lt;&amp;lt;LCDPS0)    // N = 16&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDCD2)|(0&amp;lt;&amp;lt;LCDCD1)|(1&amp;lt;&amp;lt;LCDCD0);  // D = 2&lt;br /&gt;
      // ergo f(frame) = 128Hz&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDCCR = (1&amp;lt;&amp;lt;LCDDC2)|(0&amp;lt;&amp;lt;LCDDC1)|(0&amp;lt;&amp;lt;LCDDC0)|(/*config.lcd_contrast*/ 10 &amp;lt;&amp;lt; LCDCC0);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDDC2)|(0&amp;lt;&amp;lt;LCDDC1)|(0&amp;lt;&amp;lt;LCDDC0)   // 575 µs&lt;br /&gt;
      |(config.lcd_contrast &amp;lt;&amp;lt; LCDCC0);     // Set the initial LCD contrast level&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDCRA = (1&amp;lt;&amp;lt;LCDEN)|(1&amp;lt;&amp;lt;LCDAB)|(0&amp;lt;&amp;lt;LCDIE)|(0&amp;lt;&amp;lt;LCDBL);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDEN)    // Enable LCD&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDAB)   // Low Power Waveform&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDIE)   // disable Interrupt&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDBL);  // No Blanking&lt;br /&gt;
*/&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
=== Stellmotor ===&lt;br /&gt;
&lt;br /&gt;
An ADC2 (PF2) kann die Stromaufnahme des Motors gemessen werden. Der Shunt besitzt 2,2 Ohm, der maximale Spannungsabfall ist durch eine parallele Diode begrenzt.&lt;br /&gt;
Leopold B. hat mal eine Stellfahrt oszillographiert: [[Bild:SparmaticComet_Spannung_an_PF2_beim_Schliessen.png|500px]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:SparmaticComet_SegmentMapping.png&amp;diff=61437</id>
		<title>Datei:SparmaticComet SegmentMapping.png</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:SparmaticComet_SegmentMapping.png&amp;diff=61437"/>
		<updated>2011-11-05T10:05:39Z</updated>

		<summary type="html">&lt;p&gt;Matze88: http://www.mikrocontroller.net/topic/160462#1943939
Leopold B.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;http://www.mikrocontroller.net/topic/160462#1943939&lt;br /&gt;
Leopold B.&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:SparmaticComet_LCD_Segment_Belegung.jpg&amp;diff=61436</id>
		<title>Datei:SparmaticComet LCD Segment Belegung.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:SparmaticComet_LCD_Segment_Belegung.jpg&amp;diff=61436"/>
		<updated>2011-11-05T10:05:12Z</updated>

		<summary type="html">&lt;p&gt;Matze88: http://www.mikrocontroller.net/topic/160462#1938053
Leopold B.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;http://www.mikrocontroller.net/topic/160462#1938053&lt;br /&gt;
Leopold B.&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:SparmaticZerov2_Platine_BOT.jpg&amp;diff=61435</id>
		<title>Datei:SparmaticZerov2 Platine BOT.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:SparmaticZerov2_Platine_BOT.jpg&amp;diff=61435"/>
		<updated>2011-11-05T10:04:33Z</updated>

		<summary type="html">&lt;p&gt;Matze88: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:SparmaticZerov2_Platine_TOP.jpg&amp;diff=61434</id>
		<title>Datei:SparmaticZerov2 Platine TOP.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:SparmaticZerov2_Platine_TOP.jpg&amp;diff=61434"/>
		<updated>2011-11-05T10:04:21Z</updated>

		<summary type="html">&lt;p&gt;Matze88: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:SparmaticZerov2_Schaltplan.png&amp;diff=61433</id>
		<title>Datei:SparmaticZerov2 Schaltplan.png</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:SparmaticZerov2_Schaltplan.png&amp;diff=61433"/>
		<updated>2011-11-05T10:04:07Z</updated>

		<summary type="html">&lt;p&gt;Matze88: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:SparmaticComet_Platine_BOT.jpg&amp;diff=61432</id>
		<title>Datei:SparmaticComet Platine BOT.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:SparmaticComet_Platine_BOT.jpg&amp;diff=61432"/>
		<updated>2011-11-05T10:03:39Z</updated>

		<summary type="html">&lt;p&gt;Matze88: http://www.mikrocontroller.net/topic/160462#1935344
Leopold B.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;http://www.mikrocontroller.net/topic/160462#1935344&lt;br /&gt;
Leopold B.&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:SparmaticComet_Platine_TOP.jpg&amp;diff=61431</id>
		<title>Datei:SparmaticComet Platine TOP.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:SparmaticComet_Platine_TOP.jpg&amp;diff=61431"/>
		<updated>2011-11-05T10:03:20Z</updated>

		<summary type="html">&lt;p&gt;Matze88: http://www.mikrocontroller.net/topic/160462#1935344
Leopold B.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;http://www.mikrocontroller.net/topic/160462#1935344&lt;br /&gt;
Leopold B.&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Sparmatic_Heizungsthermostate&amp;diff=61430</id>
		<title>Sparmatic Heizungsthermostate</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Sparmatic_Heizungsthermostate&amp;diff=61430"/>
		<updated>2011-11-05T10:02:36Z</updated>

		<summary type="html">&lt;p&gt;Matze88: Bilder richtig&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel sammelt Informationen zu den elektronischen Heizkörperthermostaten der Reihe &amp;quot;Sparmatic&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Modelle ==&lt;br /&gt;
&lt;br /&gt;
Den Sparmatic gibt es in verschiedenen Ausführungen:&lt;br /&gt;
&lt;br /&gt;
Der Sparmatic Zero hat gleich zwei Versionen:&lt;br /&gt;
Die alte Version ist mit Schrauben zu öffnen und hat hinter der Batterie einen Pin-Header für den JTAG des Controllers.&lt;br /&gt;
&lt;br /&gt;
Die neue Version hingegen ist mit Plastiknasen so verschlossen, dass er nach dem Öffnen nur mit Hilfsmitteln wieder fest verschließbar ist. Unter den Batterien sieht man jeweils hinter den Batteriekontakten 6 Testpads (2x3 Anordnung).&lt;br /&gt;
Die Pads auf der Seite des &amp;quot;+&amp;quot; Batteriekontaktes enthalten dabei den JTAG des Controllers, die andere Seite unter anderem den ISP.&lt;br /&gt;
&lt;br /&gt;
Der Sparmatic Comet hat nur drei Tasten, dafür einen zusätzlichen Drehimpulsgeber.&lt;br /&gt;
Hiervon existieren baugleiche(?) Modelle, z.B. der bei Aldi verkaufte &amp;quot;Thermy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Für Informationen in diesem Thread kann man die genannten Thermostate anhand der Beschaltung des Controllers in zwei Kategorien einteilen:&lt;br /&gt;
# Sparmatic Zero alt&lt;br /&gt;
# Sparmatic Zero neu, Comet, Thermy&lt;br /&gt;
&lt;br /&gt;
== Sparmatic Zero v1 ==&lt;br /&gt;
&lt;br /&gt;
Dieser wurde bereits ausführlich im Forum diskutiert.&lt;br /&gt;
Im folgenden Thread wurde eine alternative Firmware entwickelt:&lt;br /&gt;
http://www.mikrocontroller.net/topic/160462&lt;br /&gt;
&lt;br /&gt;
== Sparmatic Zero v2 / Comet / Thermy ==&lt;br /&gt;
&lt;br /&gt;
Die Entwicklung läuft noch. Aktuelle Informationen finden sich im Forum:&lt;br /&gt;
http://www.mikrocontroller.net/topic/237375&lt;br /&gt;
&lt;br /&gt;
=== Schaltpläne und Platinenaufnahmen === &lt;br /&gt;
&lt;br /&gt;
Comet (Leopold B.):&lt;br /&gt;
[[Bild:SparmaticComet_Schaltplan.png]]&lt;br /&gt;
[[Bild:SparmaticComet_Platine_TOP.jpg]]&lt;br /&gt;
[[Bild:SparmaticComet_Platine_BOT.jpg]]&lt;br /&gt;
&lt;br /&gt;
Zero v2 (vorläufig):&lt;br /&gt;
[[Bild:SparmaticZerov2_Schaltplan.png]]&lt;br /&gt;
[[Bild:SparmaticZerov2_Platine_TOP.jpg]]&lt;br /&gt;
[[Bild:SparmaticZerov2_Platine_BOT.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:SparmaticComet_LCD_Segment_Belegung.jpg]]&lt;br /&gt;
&lt;br /&gt;
tabellarische Darstellung der einzelnen 14-Segment-Module: [[Bild:SparmaticComet_SegmentMapping.png]]&lt;br /&gt;
&lt;br /&gt;
Initialisierung des LCD Controllers wie in der Originalfirmware (Leopold B.):&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
LCDCRB = (1&amp;lt;&amp;lt;LCDCS)|(0&amp;lt;&amp;lt;LCD2B)|(1&amp;lt;&amp;lt;LCDMUX1)|(1&amp;lt;&amp;lt;LCDMUX0)|(1&amp;lt;&amp;lt;LCDPM2)|(1&amp;lt;&amp;lt;LCDPM1)|(1&amp;lt;&amp;lt;LCDPM0);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDCS)                            // Das LCD wird im asynchronen Modus (LCDCS-Bit=1)&lt;br /&gt;
                                               mit der Frequenz des Quarzes TOSC1 = 32.768Hz als LCD Clock betrieben.&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCD2B)                           // 1/3 bias is used&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDMUX1)|(1&amp;lt;&amp;lt;LCDMUX0)            // 1/4 Duty; COM0:3;&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDPM2)|(1&amp;lt;&amp;lt;LCDPM1)|(1&amp;lt;&amp;lt;LCDPM0); // SEG0:24&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDFRR = (0&amp;lt;&amp;lt;LCDPS2)|(0&amp;lt;&amp;lt;LCDPS1)|(0&amp;lt;&amp;lt;LCDPS0)|(0&amp;lt;&amp;lt;LCDCD2)|(0&amp;lt;&amp;lt;LCDCD1)|(1&amp;lt;&amp;lt;LCDCD0);&lt;br /&gt;
/*&lt;br /&gt;
      (0&amp;lt;&amp;lt;LCDPS2)|(0&amp;lt;&amp;lt;LCDPS1)|(0&amp;lt;&amp;lt;LCDPS0)    // N = 16&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDCD2)|(0&amp;lt;&amp;lt;LCDCD1)|(1&amp;lt;&amp;lt;LCDCD0);  // D = 2&lt;br /&gt;
      // ergo f(frame) = 128Hz&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDCCR = (1&amp;lt;&amp;lt;LCDDC2)|(0&amp;lt;&amp;lt;LCDDC1)|(0&amp;lt;&amp;lt;LCDDC0)|(/*config.lcd_contrast*/ 10 &amp;lt;&amp;lt; LCDCC0);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDDC2)|(0&amp;lt;&amp;lt;LCDDC1)|(0&amp;lt;&amp;lt;LCDDC0)   // 575 µs&lt;br /&gt;
      |(config.lcd_contrast &amp;lt;&amp;lt; LCDCC0);     // Set the initial LCD contrast level&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDCRA = (1&amp;lt;&amp;lt;LCDEN)|(1&amp;lt;&amp;lt;LCDAB)|(0&amp;lt;&amp;lt;LCDIE)|(0&amp;lt;&amp;lt;LCDBL);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDEN)    // Enable LCD&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDAB)   // Low Power Waveform&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDIE)   // disable Interrupt&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDBL);  // No Blanking&lt;br /&gt;
*/&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
=== Stellmotor ===&lt;br /&gt;
&lt;br /&gt;
An ADC2 (PF2) kann die Stromaufnahme des Motors gemessen werden. Der Shunt besitzt 2,2 Ohm, der maximale Spannungsabfall ist durch eine parallele Diode begrenzt.&lt;br /&gt;
Leopold B. hat mal eine Stellfahrt oszillographiert: http://www.mikrocontroller.net/attachment/93404/SparmaticComet_Spannung_an_PF2_beim_Schliessen.png&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:SparmaticComet_Schaltplan.png&amp;diff=61429</id>
		<title>Datei:SparmaticComet Schaltplan.png</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:SparmaticComet_Schaltplan.png&amp;diff=61429"/>
		<updated>2011-11-05T09:59:46Z</updated>

		<summary type="html">&lt;p&gt;Matze88: http://www.mikrocontroller.net/topic/160462#1935344
Leopold B.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;http://www.mikrocontroller.net/topic/160462#1935344&lt;br /&gt;
Leopold B.&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Sparmatic_Heizungsthermostate&amp;diff=61428</id>
		<title>Sparmatic Heizungsthermostate</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Sparmatic_Heizungsthermostate&amp;diff=61428"/>
		<updated>2011-11-05T09:58:36Z</updated>

		<summary type="html">&lt;p&gt;Matze88: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel sammelt Informationen zu den elektronischen Heizkörperthermostaten der Reihe &amp;quot;Sparmatic&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Modelle ==&lt;br /&gt;
&lt;br /&gt;
Den Sparmatic gibt es in verschiedenen Ausführungen:&lt;br /&gt;
&lt;br /&gt;
Der Sparmatic Zero hat gleich zwei Versionen:&lt;br /&gt;
Die alte Version ist mit Schrauben zu öffnen und hat hinter der Batterie einen Pin-Header für den JTAG des Controllers.&lt;br /&gt;
&lt;br /&gt;
Die neue Version hingegen ist mit Plastiknasen so verschlossen, dass er nach dem Öffnen nur mit Hilfsmitteln wieder fest verschließbar ist. Unter den Batterien sieht man jeweils hinter den Batteriekontakten 6 Testpads (2x3 Anordnung).&lt;br /&gt;
Die Pads auf der Seite des &amp;quot;+&amp;quot; Batteriekontaktes enthalten dabei den JTAG des Controllers, die andere Seite unter anderem den ISP.&lt;br /&gt;
&lt;br /&gt;
Der Sparmatic Comet hat nur drei Tasten, dafür einen zusätzlichen Drehimpulsgeber.&lt;br /&gt;
Hiervon existieren baugleiche(?) Modelle, z.B. der bei Aldi verkaufte &amp;quot;Thermy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Für Informationen in diesem Thread kann man die genannten Thermostate anhand der Beschaltung des Controllers in zwei Kategorien einteilen:&lt;br /&gt;
# Sparmatic Zero alt&lt;br /&gt;
# Sparmatic Zero neu, Comet, Thermy&lt;br /&gt;
&lt;br /&gt;
== Sparmatic Zero v1 ==&lt;br /&gt;
&lt;br /&gt;
Dieser wurde bereits ausführlich im Forum diskutiert.&lt;br /&gt;
Im folgenden Thread wurde eine alternative Firmware entwickelt:&lt;br /&gt;
http://www.mikrocontroller.net/topic/160462&lt;br /&gt;
&lt;br /&gt;
== Sparmatic Zero v2 / Comet / Thermy ==&lt;br /&gt;
&lt;br /&gt;
Die Entwicklung läuft noch. Aktuelle Informationen finden sich im Forum:&lt;br /&gt;
http://www.mikrocontroller.net/topic/237375&lt;br /&gt;
&lt;br /&gt;
=== Schaltplan === &lt;br /&gt;
&lt;br /&gt;
Comet (Leopold B.)&lt;br /&gt;
http://www.mikrocontroller.net/attachment/92338/SparmaticComet_Schaltplan.png&lt;br /&gt;
[[Bild:SparmaticComet_Schaltplan.png]]&lt;br /&gt;
&lt;br /&gt;
Platinenfotos: http://www.mikrocontroller.net/attachment/92339/SparmaticComet_TOP.jpg&lt;br /&gt;
[[Bild:SparmaticComet_Platine_TOP.jpg]]&lt;br /&gt;
http://www.mikrocontroller.net/attachment/92340/SparmaticComet_BOT.jpg&lt;br /&gt;
[[Bild:SparmaticComet_Platine_BOT.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
&lt;br /&gt;
Segmente: http://www.mikrocontroller.net/attachment/92552/SparmaticComet_LCD_Segment_Belegung.jpg&lt;br /&gt;
&lt;br /&gt;
tabellarische Darstellung der einzelnen 14-Segment-Module: http://www.mikrocontroller.net/attachment/92916/SparmaticComet_SegmentMapping.png&lt;br /&gt;
&lt;br /&gt;
Initialisierung des LCD Controllers wie in der Originalfirmware (Leopold B.):&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
LCDCRB = (1&amp;lt;&amp;lt;LCDCS)|(0&amp;lt;&amp;lt;LCD2B)|(1&amp;lt;&amp;lt;LCDMUX1)|(1&amp;lt;&amp;lt;LCDMUX0)|(1&amp;lt;&amp;lt;LCDPM2)|(1&amp;lt;&amp;lt;LCDPM1)|(1&amp;lt;&amp;lt;LCDPM0);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDCS)                            // Das LCD wird im asynchronen Modus (LCDCS-Bit=1)&lt;br /&gt;
                                               mit der Frequenz des Quarzes TOSC1 = 32.768Hz als LCD Clock betrieben.&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCD2B)                           // 1/3 bias is used&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDMUX1)|(1&amp;lt;&amp;lt;LCDMUX0)            // 1/4 Duty; COM0:3;&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDPM2)|(1&amp;lt;&amp;lt;LCDPM1)|(1&amp;lt;&amp;lt;LCDPM0); // SEG0:24&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDFRR = (0&amp;lt;&amp;lt;LCDPS2)|(0&amp;lt;&amp;lt;LCDPS1)|(0&amp;lt;&amp;lt;LCDPS0)|(0&amp;lt;&amp;lt;LCDCD2)|(0&amp;lt;&amp;lt;LCDCD1)|(1&amp;lt;&amp;lt;LCDCD0);&lt;br /&gt;
/*&lt;br /&gt;
      (0&amp;lt;&amp;lt;LCDPS2)|(0&amp;lt;&amp;lt;LCDPS1)|(0&amp;lt;&amp;lt;LCDPS0)    // N = 16&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDCD2)|(0&amp;lt;&amp;lt;LCDCD1)|(1&amp;lt;&amp;lt;LCDCD0);  // D = 2&lt;br /&gt;
      // ergo f(frame) = 128Hz&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDCCR = (1&amp;lt;&amp;lt;LCDDC2)|(0&amp;lt;&amp;lt;LCDDC1)|(0&amp;lt;&amp;lt;LCDDC0)|(/*config.lcd_contrast*/ 10 &amp;lt;&amp;lt; LCDCC0);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDDC2)|(0&amp;lt;&amp;lt;LCDDC1)|(0&amp;lt;&amp;lt;LCDDC0)   // 575 µs&lt;br /&gt;
      |(config.lcd_contrast &amp;lt;&amp;lt; LCDCC0);     // Set the initial LCD contrast level&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDCRA = (1&amp;lt;&amp;lt;LCDEN)|(1&amp;lt;&amp;lt;LCDAB)|(0&amp;lt;&amp;lt;LCDIE)|(0&amp;lt;&amp;lt;LCDBL);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDEN)    // Enable LCD&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDAB)   // Low Power Waveform&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDIE)   // disable Interrupt&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDBL);  // No Blanking&lt;br /&gt;
*/&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
=== Stellmotor ===&lt;br /&gt;
&lt;br /&gt;
An ADC2 (PF2) kann die Stromaufnahme des Motors gemessen werden. Der Shunt besitzt 2,2 Ohm, der maximale Spannungsabfall ist durch eine parallele Diode begrenzt.&lt;br /&gt;
Leopold B. hat mal eine Stellfahrt oszillographiert: http://www.mikrocontroller.net/attachment/93404/SparmaticComet_Spannung_an_PF2_beim_Schliessen.png&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Sparmatic_Heizungsthermostate&amp;diff=61427</id>
		<title>Sparmatic Heizungsthermostate</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Sparmatic_Heizungsthermostate&amp;diff=61427"/>
		<updated>2011-11-05T09:57:56Z</updated>

		<summary type="html">&lt;p&gt;Matze88: Bilder einfügen&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel sammelt Informationen zu den elektronischen Heizkörperthermostaten der Reihe &amp;quot;Sparmatic&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Modelle ==&lt;br /&gt;
&lt;br /&gt;
Den Sparmatic gibt es in verschiedenen Ausführungen:&lt;br /&gt;
&lt;br /&gt;
Der Sparmatic Zero hat gleich zwei Versionen:&lt;br /&gt;
Die alte Version ist mit Schrauben zu öffnen und hat hinter der Batterie einen Pin-Header für den JTAG des Controllers.&lt;br /&gt;
&lt;br /&gt;
Die neue Version hingegen ist mit Plastiknasen so verschlossen, dass er nach dem Öffnen nur mit Hilfsmitteln wieder fest verschließbar ist. Unter den Batterien sieht man jeweils hinter den Batteriekontakten 6 Testpads (2x3 Anordnung).&lt;br /&gt;
Die Pads auf der Seite des &amp;quot;+&amp;quot; Batteriekontaktes enthalten dabei den JTAG des Controllers, die andere Seite unter anderem den ISP.&lt;br /&gt;
&lt;br /&gt;
Der Sparmatic Comet hat nur drei Tasten, dafür einen zusätzlichen Drehimpulsgeber.&lt;br /&gt;
Hiervon existieren baugleiche(?) Modelle, z.B. der bei Aldi verkaufte &amp;quot;Thermy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Für Informationen in diesem Thread kann man die genannten Thermostate anhand der Beschaltung des Controllers in zwei Kategorien einteilen:&lt;br /&gt;
# Sparmatic Zero alt&lt;br /&gt;
# Sparmatic Zero neu, Comet, Thermy&lt;br /&gt;
&lt;br /&gt;
== Sparmatic Zero v1 ==&lt;br /&gt;
&lt;br /&gt;
Dieser wurde bereits ausführlich im Forum diskutiert.&lt;br /&gt;
Im folgenden Thread wurde eine alternative Firmware entwickelt:&lt;br /&gt;
http://www.mikrocontroller.net/topic/160462&lt;br /&gt;
&lt;br /&gt;
== Sparmatic Zero v2 / Comet / Thermy ==&lt;br /&gt;
&lt;br /&gt;
Die Entwicklung läuft noch. Aktuelle Informationen finden sich im Forum:&lt;br /&gt;
http://www.mikrocontroller.net/topic/237375&lt;br /&gt;
&lt;br /&gt;
=== Schaltplan === &lt;br /&gt;
&lt;br /&gt;
Comet (Leopold B.)&lt;br /&gt;
http://www.mikrocontroller.net/attachment/92338/SparmaticComet_Schaltplan.png&lt;br /&gt;
[[Bild:SparmaticComet_Schaltplan.png]&lt;br /&gt;
&lt;br /&gt;
Platinenfotos: http://www.mikrocontroller.net/attachment/92339/SparmaticComet_TOP.jpg&lt;br /&gt;
[[Bild:SparmaticComet_Platine_TOP.jpg]]&lt;br /&gt;
http://www.mikrocontroller.net/attachment/92340/SparmaticComet_BOT.jpg&lt;br /&gt;
[[Bild:SparmaticComet_Platine_BOT.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
&lt;br /&gt;
Segmente: http://www.mikrocontroller.net/attachment/92552/SparmaticComet_LCD_Segment_Belegung.jpg&lt;br /&gt;
&lt;br /&gt;
tabellarische Darstellung der einzelnen 14-Segment-Module: http://www.mikrocontroller.net/attachment/92916/SparmaticComet_SegmentMapping.png&lt;br /&gt;
&lt;br /&gt;
Initialisierung des LCD Controllers wie in der Originalfirmware (Leopold B.):&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
LCDCRB = (1&amp;lt;&amp;lt;LCDCS)|(0&amp;lt;&amp;lt;LCD2B)|(1&amp;lt;&amp;lt;LCDMUX1)|(1&amp;lt;&amp;lt;LCDMUX0)|(1&amp;lt;&amp;lt;LCDPM2)|(1&amp;lt;&amp;lt;LCDPM1)|(1&amp;lt;&amp;lt;LCDPM0);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDCS)                            // Das LCD wird im asynchronen Modus (LCDCS-Bit=1)&lt;br /&gt;
                                               mit der Frequenz des Quarzes TOSC1 = 32.768Hz als LCD Clock betrieben.&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCD2B)                           // 1/3 bias is used&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDMUX1)|(1&amp;lt;&amp;lt;LCDMUX0)            // 1/4 Duty; COM0:3;&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDPM2)|(1&amp;lt;&amp;lt;LCDPM1)|(1&amp;lt;&amp;lt;LCDPM0); // SEG0:24&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDFRR = (0&amp;lt;&amp;lt;LCDPS2)|(0&amp;lt;&amp;lt;LCDPS1)|(0&amp;lt;&amp;lt;LCDPS0)|(0&amp;lt;&amp;lt;LCDCD2)|(0&amp;lt;&amp;lt;LCDCD1)|(1&amp;lt;&amp;lt;LCDCD0);&lt;br /&gt;
/*&lt;br /&gt;
      (0&amp;lt;&amp;lt;LCDPS2)|(0&amp;lt;&amp;lt;LCDPS1)|(0&amp;lt;&amp;lt;LCDPS0)    // N = 16&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDCD2)|(0&amp;lt;&amp;lt;LCDCD1)|(1&amp;lt;&amp;lt;LCDCD0);  // D = 2&lt;br /&gt;
      // ergo f(frame) = 128Hz&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDCCR = (1&amp;lt;&amp;lt;LCDDC2)|(0&amp;lt;&amp;lt;LCDDC1)|(0&amp;lt;&amp;lt;LCDDC0)|(/*config.lcd_contrast*/ 10 &amp;lt;&amp;lt; LCDCC0);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDDC2)|(0&amp;lt;&amp;lt;LCDDC1)|(0&amp;lt;&amp;lt;LCDDC0)   // 575 µs&lt;br /&gt;
      |(config.lcd_contrast &amp;lt;&amp;lt; LCDCC0);     // Set the initial LCD contrast level&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDCRA = (1&amp;lt;&amp;lt;LCDEN)|(1&amp;lt;&amp;lt;LCDAB)|(0&amp;lt;&amp;lt;LCDIE)|(0&amp;lt;&amp;lt;LCDBL);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDEN)    // Enable LCD&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDAB)   // Low Power Waveform&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDIE)   // disable Interrupt&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDBL);  // No Blanking&lt;br /&gt;
*/&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
=== Stellmotor ===&lt;br /&gt;
&lt;br /&gt;
An ADC2 (PF2) kann die Stromaufnahme des Motors gemessen werden. Der Shunt besitzt 2,2 Ohm, der maximale Spannungsabfall ist durch eine parallele Diode begrenzt.&lt;br /&gt;
Leopold B. hat mal eine Stellfahrt oszillographiert: http://www.mikrocontroller.net/attachment/93404/SparmaticComet_Spannung_an_PF2_beim_Schliessen.png&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Sparmatic_Heizungsthermostate&amp;diff=61426</id>
		<title>Sparmatic Heizungsthermostate</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Sparmatic_Heizungsthermostate&amp;diff=61426"/>
		<updated>2011-11-05T09:56:04Z</updated>

		<summary type="html">&lt;p&gt;Matze88: Display von Leopold B. aus dem Forum kopiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel sammelt Informationen zu den elektronischen Heizkörperthermostaten der Reihe &amp;quot;Sparmatic&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Modelle ==&lt;br /&gt;
&lt;br /&gt;
Den Sparmatic gibt es in verschiedenen Ausführungen:&lt;br /&gt;
&lt;br /&gt;
Der Sparmatic Zero hat gleich zwei Versionen:&lt;br /&gt;
Die alte Version ist mit Schrauben zu öffnen und hat hinter der Batterie einen Pin-Header für den JTAG des Controllers.&lt;br /&gt;
&lt;br /&gt;
Die neue Version hingegen ist mit Plastiknasen so verschlossen, dass er nach dem Öffnen nur mit Hilfsmitteln wieder fest verschließbar ist. Unter den Batterien sieht man jeweils hinter den Batteriekontakten 6 Testpads (2x3 Anordnung).&lt;br /&gt;
Die Pads auf der Seite des &amp;quot;+&amp;quot; Batteriekontaktes enthalten dabei den JTAG des Controllers, die andere Seite unter anderem den ISP.&lt;br /&gt;
&lt;br /&gt;
Der Sparmatic Comet hat nur drei Tasten, dafür einen zusätzlichen Drehimpulsgeber.&lt;br /&gt;
Hiervon existieren baugleiche(?) Modelle, z.B. der bei Aldi verkaufte &amp;quot;Thermy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Für Informationen in diesem Thread kann man die genannten Thermostate anhand der Beschaltung des Controllers in zwei Kategorien einteilen:&lt;br /&gt;
# Sparmatic Zero alt&lt;br /&gt;
# Sparmatic Zero neu, Comet, Thermy&lt;br /&gt;
&lt;br /&gt;
== Sparmatic Zero v1 ==&lt;br /&gt;
&lt;br /&gt;
Dieser wurde bereits ausführlich im Forum diskutiert.&lt;br /&gt;
Im folgenden Thread wurde eine alternative Firmware entwickelt:&lt;br /&gt;
http://www.mikrocontroller.net/topic/160462&lt;br /&gt;
&lt;br /&gt;
== Sparmatic Zero v2 / Comet / Thermy ==&lt;br /&gt;
&lt;br /&gt;
Die Entwicklung läuft noch. Aktuelle Informationen finden sich im Forum:&lt;br /&gt;
http://www.mikrocontroller.net/topic/237375&lt;br /&gt;
&lt;br /&gt;
=== Schaltplan === &lt;br /&gt;
&lt;br /&gt;
Comet (Leopold B.)&lt;br /&gt;
http://www.mikrocontroller.net/attachment/92338/SparmaticComet_Schaltplan.png&lt;br /&gt;
&lt;br /&gt;
Platinenfotos: http://www.mikrocontroller.net/attachment/92339/SparmaticComet_TOP.jpg&lt;br /&gt;
http://www.mikrocontroller.net/attachment/92340/SparmaticComet_BOT.jpg&lt;br /&gt;
&lt;br /&gt;
=== Display ===&lt;br /&gt;
&lt;br /&gt;
Segmente: http://www.mikrocontroller.net/attachment/92552/SparmaticComet_LCD_Segment_Belegung.jpg&lt;br /&gt;
&lt;br /&gt;
tabellarische Darstellung der einzelnen 14-Segment-Module: http://www.mikrocontroller.net/attachment/92916/SparmaticComet_SegmentMapping.png&lt;br /&gt;
&lt;br /&gt;
Initialisierung des LCD Controllers wie in der Originalfirmware (Leopold B.):&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
LCDCRB = (1&amp;lt;&amp;lt;LCDCS)|(0&amp;lt;&amp;lt;LCD2B)|(1&amp;lt;&amp;lt;LCDMUX1)|(1&amp;lt;&amp;lt;LCDMUX0)|(1&amp;lt;&amp;lt;LCDPM2)|(1&amp;lt;&amp;lt;LCDPM1)|(1&amp;lt;&amp;lt;LCDPM0);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDCS)                            // Das LCD wird im asynchronen Modus (LCDCS-Bit=1)&lt;br /&gt;
                                               mit der Frequenz des Quarzes TOSC1 = 32.768Hz als LCD Clock betrieben.&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCD2B)                           // 1/3 bias is used&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDMUX1)|(1&amp;lt;&amp;lt;LCDMUX0)            // 1/4 Duty; COM0:3;&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDPM2)|(1&amp;lt;&amp;lt;LCDPM1)|(1&amp;lt;&amp;lt;LCDPM0); // SEG0:24&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDFRR = (0&amp;lt;&amp;lt;LCDPS2)|(0&amp;lt;&amp;lt;LCDPS1)|(0&amp;lt;&amp;lt;LCDPS0)|(0&amp;lt;&amp;lt;LCDCD2)|(0&amp;lt;&amp;lt;LCDCD1)|(1&amp;lt;&amp;lt;LCDCD0);&lt;br /&gt;
/*&lt;br /&gt;
      (0&amp;lt;&amp;lt;LCDPS2)|(0&amp;lt;&amp;lt;LCDPS1)|(0&amp;lt;&amp;lt;LCDPS0)    // N = 16&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDCD2)|(0&amp;lt;&amp;lt;LCDCD1)|(1&amp;lt;&amp;lt;LCDCD0);  // D = 2&lt;br /&gt;
      // ergo f(frame) = 128Hz&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDCCR = (1&amp;lt;&amp;lt;LCDDC2)|(0&amp;lt;&amp;lt;LCDDC1)|(0&amp;lt;&amp;lt;LCDDC0)|(/*config.lcd_contrast*/ 10 &amp;lt;&amp;lt; LCDCC0);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDDC2)|(0&amp;lt;&amp;lt;LCDDC1)|(0&amp;lt;&amp;lt;LCDDC0)   // 575 µs&lt;br /&gt;
      |(config.lcd_contrast &amp;lt;&amp;lt; LCDCC0);     // Set the initial LCD contrast level&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
LCDCRA = (1&amp;lt;&amp;lt;LCDEN)|(1&amp;lt;&amp;lt;LCDAB)|(0&amp;lt;&amp;lt;LCDIE)|(0&amp;lt;&amp;lt;LCDBL);&lt;br /&gt;
/*&lt;br /&gt;
      (1&amp;lt;&amp;lt;LCDEN)    // Enable LCD&lt;br /&gt;
      |(1&amp;lt;&amp;lt;LCDAB)   // Low Power Waveform&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDIE)   // disable Interrupt&lt;br /&gt;
      |(0&amp;lt;&amp;lt;LCDBL);  // No Blanking&lt;br /&gt;
*/&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
=== Stellmotor ===&lt;br /&gt;
&lt;br /&gt;
An ADC2 (PF2) kann die Stromaufnahme des Motors gemessen werden. Der Shunt besitzt 2,2 Ohm, der maximale Spannungsabfall ist durch eine parallele Diode begrenzt.&lt;br /&gt;
Leopold B. hat mal eine Stellfahrt oszillographiert: http://www.mikrocontroller.net/attachment/93404/SparmaticComet_Spannung_an_PF2_beim_Schliessen.png&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Sparmatic_Heizungsthermostate&amp;diff=61425</id>
		<title>Sparmatic Heizungsthermostate</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Sparmatic_Heizungsthermostate&amp;diff=61425"/>
		<updated>2011-11-05T09:51:47Z</updated>

		<summary type="html">&lt;p&gt;Matze88: /* Sparmatic Zero v2 / Comet / Thermy */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel sammelt Informationen zu den elektronischen Heizkörperthermostaten der Reihe &amp;quot;Sparmatic&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Modelle ==&lt;br /&gt;
&lt;br /&gt;
Den Sparmatic gibt es in verschiedenen Ausführungen:&lt;br /&gt;
&lt;br /&gt;
Der Sparmatic Zero hat gleich zwei Versionen:&lt;br /&gt;
Die alte Version ist mit Schrauben zu öffnen und hat hinter der Batterie einen Pin-Header für den JTAG des Controllers.&lt;br /&gt;
&lt;br /&gt;
Die neue Version hingegen ist mit Plastiknasen so verschlossen, dass er nach dem Öffnen nur mit Hilfsmitteln wieder fest verschließbar ist. Unter den Batterien sieht man jeweils hinter den Batteriekontakten 6 Testpads (2x3 Anordnung).&lt;br /&gt;
Die Pads auf der Seite des &amp;quot;+&amp;quot; Batteriekontaktes enthalten dabei den JTAG des Controllers, die andere Seite unter anderem den ISP.&lt;br /&gt;
&lt;br /&gt;
Der Sparmatic Comet hat nur drei Tasten, dafür einen zusätzlichen Drehimpulsgeber.&lt;br /&gt;
Hiervon existieren baugleiche(?) Modelle, z.B. der bei Aldi verkaufte &amp;quot;Thermy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Für Informationen in diesem Thread kann man die genannten Thermostate anhand der Beschaltung des Controllers in zwei Kategorien einteilen:&lt;br /&gt;
# Sparmatic Zero alt&lt;br /&gt;
# Sparmatic Zero neu, Comet, Thermy&lt;br /&gt;
&lt;br /&gt;
== Sparmatic Zero v1 ==&lt;br /&gt;
&lt;br /&gt;
Dieser wurde bereits ausführlich im Forum diskutiert.&lt;br /&gt;
Im folgenden Thread wurde eine alternative Firmware entwickelt:&lt;br /&gt;
http://www.mikrocontroller.net/topic/160462&lt;br /&gt;
&lt;br /&gt;
== Sparmatic Zero v2 / Comet / Thermy ==&lt;br /&gt;
&lt;br /&gt;
Die Entwicklung läuft noch. Aktuelle Informationen finden sich im Forum:&lt;br /&gt;
http://www.mikrocontroller.net/topic/237375&lt;br /&gt;
&lt;br /&gt;
=== Schaltplan === &lt;br /&gt;
&lt;br /&gt;
Comet (Leopold B.)&lt;br /&gt;
Schaltplan: http://www.mikrocontroller.net/attachment/92338/SparmaticComet_Schaltplan.png&lt;br /&gt;
Platinenfotos: http://www.mikrocontroller.net/attachment/92339/SparmaticComet_TOP.jpg&lt;br /&gt;
http://www.mikrocontroller.net/attachment/92340/SparmaticComet_BOT.jpg&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Stellmotor ===&lt;br /&gt;
&lt;br /&gt;
An ADC2 (PF2) kann die Stromaufnahme des Motors gemessen werden. Der Shunt besitzt 2,2 Ohm, der maximale Spannungsabfall ist durch eine parallele Diode begrenzt.&lt;br /&gt;
Leopold B. hat mal eine Stellfahrt oszillographiert: http://www.mikrocontroller.net/attachment/93404/SparmaticComet_Spannung_an_PF2_beim_Schliessen.png&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Sparmatic_Heizungsthermostate&amp;diff=61424</id>
		<title>Sparmatic Heizungsthermostate</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Sparmatic_Heizungsthermostate&amp;diff=61424"/>
		<updated>2011-11-05T09:47:07Z</updated>

		<summary type="html">&lt;p&gt;Matze88: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel sammelt Informationen zu den elektronischen Heizkörperthermostaten der Reihe &amp;quot;Sparmatic&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Modelle ==&lt;br /&gt;
&lt;br /&gt;
Den Sparmatic gibt es in verschiedenen Ausführungen:&lt;br /&gt;
&lt;br /&gt;
Der Sparmatic Zero hat gleich zwei Versionen:&lt;br /&gt;
Die alte Version ist mit Schrauben zu öffnen und hat hinter der Batterie einen Pin-Header für den JTAG des Controllers.&lt;br /&gt;
&lt;br /&gt;
Die neue Version hingegen ist mit Plastiknasen so verschlossen, dass er nach dem Öffnen nur mit Hilfsmitteln wieder fest verschließbar ist. Unter den Batterien sieht man jeweils hinter den Batteriekontakten 6 Testpads (2x3 Anordnung).&lt;br /&gt;
Die Pads auf der Seite des &amp;quot;+&amp;quot; Batteriekontaktes enthalten dabei den JTAG des Controllers, die andere Seite unter anderem den ISP.&lt;br /&gt;
&lt;br /&gt;
Der Sparmatic Comet hat nur drei Tasten, dafür einen zusätzlichen Drehimpulsgeber.&lt;br /&gt;
Hiervon existieren baugleiche(?) Modelle, z.B. der bei Aldi verkaufte &amp;quot;Thermy&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Für Informationen in diesem Thread kann man die genannten Thermostate anhand der Beschaltung des Controllers in zwei Kategorien einteilen:&lt;br /&gt;
# Sparmatic Zero alt&lt;br /&gt;
# Sparmatic Zero neu, Comet, Thermy&lt;br /&gt;
&lt;br /&gt;
== Sparmatic Zero v1 ==&lt;br /&gt;
&lt;br /&gt;
Dieser wurde bereits ausführlich im Forum diskutiert.&lt;br /&gt;
Im folgenden Thread wurde eine alternative Firmware entwickelt:&lt;br /&gt;
http://www.mikrocontroller.net/topic/160462&lt;br /&gt;
&lt;br /&gt;
== Sparmatic Zero v2 / Comet / Thermy ==&lt;br /&gt;
&lt;br /&gt;
Die Entwicklung läuft noch. Aktuelle Informationen finden sich im Forum:&lt;br /&gt;
http://www.mikrocontroller.net/topic/237375&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Standardbauelemente&amp;diff=33083</id>
		<title>Standardbauelemente</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Standardbauelemente&amp;diff=33083"/>
		<updated>2008-12-08T17:00:01Z</updated>

		<summary type="html">&lt;p&gt;Matze88: /* N-MOSFET */ preis irlz34n wurde bei reichelt auf 43 cent erhöht&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Gerade Neulinge kennen das Problem: Man hat eine tolle Schaltung mit vielen Operationsverstärkern, Spannungsreglern, Logikbausteinen, ADCs, was auch immer entwickelt und jetzt geht&#039;s an die Realisierung.&lt;br /&gt;
&lt;br /&gt;
Aber welche Bausteine nehmen unter dem Wust der Angebote? Also erstmal auf die Seiten der Hersteller und die Produktpalette durchforsten. Nach einigen Stunden gewissenhafter Recherche hat man dann endlich alle Bauteile beisammen und will bestellen. Und dann kommt das böse Erwachen: Einige Bauelemente gibt&#039;s nur bei Reichelt, andere nur bei Conrad. Farnell hat zwar das meiste, aber da kann man als Privatperson leider nicht bestellen. Manche ICs bekommt man nur in 1000er Stückzahlen oder sind halt einfach nur viel zu teuer.&lt;br /&gt;
&lt;br /&gt;
Nach einigen Jahren praktischer Erfahrung hat man dann seine &amp;quot;Standardbauelemente&amp;quot;, die man immer wieder verwendet. Dieser Artikel soll helfen andere von dieser Erfahrung profitieren zu lassen. Ähnliche Anregungen findet man auch in der de.sci.electronics-FAQ: Grundausstattung des Bastlers [[http://dse-faq.elektronik-kompendium.de/dse-faq.htm#F.2]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hinweise ==&lt;br /&gt;
Hier soll eine Liste von häufig anzutreffenden, preiswerten und verfügbaren Standardbauelementen entstehen. Diese Liste soll knapp und bündig sein, für technische Daten wird auf die Datenblätter verwiesen. Hier gilt: &amp;quot;weniger ist mehr&amp;quot;, exotische Bauelemente sind also unerwünscht. Für hier gelistete Typen sollte gelten:&lt;br /&gt;
* für Privatpersonen verfügbar&lt;br /&gt;
* preiswert (nicht billig)&lt;br /&gt;
&lt;br /&gt;
Nicht gelistet werden sollen:&lt;br /&gt;
* hunderte Typen, die alle den gleichen Zweck erfüllen, aber keinen Mehrwert bringen. Stattdessen auf die bekanntesten / preiswertesten beschränken.&lt;br /&gt;
* Details. Stattdessen die Felder &amp;quot;Besonderheiten&amp;quot; und &amp;quot;Anwendungen&amp;quot; benutzen, z.B. &amp;quot;I²C, 12bit&amp;quot; bei Besonderheiten für einen ADC oder &amp;quot;Präzision, Audio&amp;quot; bei Anwendungen für einen OpAmp.&lt;br /&gt;
&lt;br /&gt;
Wer eine Sparte, oder eine Anwendung vermisst, aber selber nichts dazu beitragen kann: Einfach hinzufügen. Wer z.B. einen HF OpAmp sucht und hier nicht fündig wird sollte also eine neue Zeile einfügen und in die Spalte Anwendungen &amp;quot;HF&amp;quot; eintragen. Vielleicht kann ja jemand den Rest der Zeile füllen.&lt;br /&gt;
&lt;br /&gt;
Immer den Grundtypen listen und nicht eine der Varianten, und schon gar nicht alle Varianten einzeln! Also z.B. &amp;quot;LM324&amp;quot; statt &amp;quot;LM324N&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Wenn möglich Direktlinks auf Datenblätter vermeiden und eine Suchmaschine befragen: &amp;quot;http://www.datasheetarchive.com/search.php?q=lm324&amp;quot;&lt;br /&gt;
* so werden alle Varianten gefunden&lt;br /&gt;
* und tote Links vermieden&lt;br /&gt;
&lt;br /&gt;
Die wichtigsten, allgemeinen Standard-Typen ganz oben in der Tabelle listen, danach erst die Spezialtypen für bestimmte Anwendungen.&lt;br /&gt;
&lt;br /&gt;
Und weil es mir so wichtig ist nochmal: Ich rufe geradezu dazu auf, überflüssige, unverfügbare Typen zu löschen!&lt;br /&gt;
&lt;br /&gt;
= Aktive Bauelemente =&lt;br /&gt;
== Analog ==&lt;br /&gt;
&lt;br /&gt;
=== Transistoren ===&lt;br /&gt;
====NPN====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;transistors-npn&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| BC 337&lt;br /&gt;
| 0,04&lt;br /&gt;
| Standardtyp&lt;br /&gt;
| bis ~300mA sinnvoll&lt;br /&gt;
| R,D&lt;br /&gt;
| [http://www.google.de/search?num=100&amp;amp;hl=de&amp;amp;q=datasheet+bc337+filetype%3Apdf&amp;amp;btnG=Suche&amp;amp;meta=lr%3Dlang_de%7Clang_en PDF]&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| MMBT 2222A&lt;br /&gt;
| 0,05&lt;br /&gt;
| SMD TO-23 Gehäuse, Ptot bis 350mW&lt;br /&gt;
| bis ~ 300mA sinnvoll &lt;br /&gt;
| R,D&lt;br /&gt;
| [http://www.reichelt.de/?;ACTION=7;LA=6;OPEN=1;INDEX=0;FILENAME=A100%252F2N2222ASMD%2523FAI.pdf;SID=29Jo9LE6wQAR0AADnPx904c70c3257c398b8b92e44b2052e44b2f]&lt;br /&gt;
|-&lt;br /&gt;
| BC 547/847&lt;br /&gt;
| 0,03&lt;br /&gt;
| Standardtyp, BC847 in SMD&lt;br /&gt;
| bis ~50mA sinnvoll&lt;br /&gt;
| R,D&lt;br /&gt;
| [http://www.semiconductors.philips.com/acrobat_download/datasheets/BC847_BC547_SER_6.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| BC 635/639&lt;br /&gt;
| 0,07&lt;br /&gt;
| andere Pinbelegung als BC547 (= BD135 in anderem Gehäuse)&lt;br /&gt;
| bis ~500mA sinnvoll&lt;br /&gt;
| R,D&lt;br /&gt;
| [http://www.semiconductors.philips.com/acrobat/datasheets/BC635_BCP54_BCX54_6.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| BD 433/437&lt;br /&gt;
| 0,19&lt;br /&gt;
| niedrige Sättigungsspannung&lt;br /&gt;
| bis ~2A sinnvoll&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.fairchildsemi.com/ds/BD%2FBD435.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| TIP41C&lt;br /&gt;
| 0,24&lt;br /&gt;
| Ptot: 65W, geringe Stromversärkung (max.75)&lt;br /&gt;
| Grenzwert 10A&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.datasheetcatalog.org/datasheet/fairchild/TIP41C.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| TIP102&lt;br /&gt;
| 0,42&lt;br /&gt;
| Ptot bis 80W mit Kühlkörper, hohe Stromverstärkung von über 1000 über einen sehr großen Bereich.&lt;br /&gt;
| Grenzwert 8A&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.fairchildsemi.com/ds/TI%2FTIP102.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| TIP 3055&lt;br /&gt;
| 0,75&lt;br /&gt;
| Ptot bis 90W mit Kühlkörper, Stromverstärkung sehr niedrig (bei großen Strömen &amp;lt;&amp;lt; 100)&lt;br /&gt;
| Grenzwert 15A &lt;br /&gt;
| R&lt;br /&gt;
| [http://www.ortodoxism.ro/datasheets/PowerInnovations/mXvutwr.pdf PDF]&lt;br /&gt;
|-====&lt;br /&gt;
| 2N6284&lt;br /&gt;
| 2-3€&lt;br /&gt;
| Linearer NPN-PowerDarlington; Ptot 160W; Antiparalele C-E Diode; komplementärtyp: 2N6287&lt;br /&gt;
| Vcbo 100V; Vceo 100V;Vebo 5V;Ic 20A (peak 40A);Ib 0,5A &lt;br /&gt;
| R&lt;br /&gt;
| [http://www.ortodoxism.ro/datasheets/SGSThomsonMicroelectronics/mXvsruq.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====PNP====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;transistors-pnp&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| BC 327&lt;br /&gt;
| 0,04&lt;br /&gt;
| Komplementärtyp zu BC337&lt;br /&gt;
| bis ~300mA sinnvoll&lt;br /&gt;
| R,D&lt;br /&gt;
| [http://www.google.de/search?num=100&amp;amp;hl=de&amp;amp;q=datasheet+bc327+filetype%3Apdf&amp;amp;btnG=Suche&amp;amp;meta=lr%3Dlang_de%7Clang_en PDF]&lt;br /&gt;
|-&lt;br /&gt;
| BC 557&lt;br /&gt;
| 0,03&lt;br /&gt;
| Komplementärtyp zu BC547C&lt;br /&gt;
| bis ~50mA sinnvoll&lt;br /&gt;
| R,D&lt;br /&gt;
| [http://www.semiconductors.philips.com/acrobat_download/datasheets/BC556_557_4.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| BC 636/640&lt;br /&gt;
| 0,07&lt;br /&gt;
| Komplementärtyp zu BC635&lt;br /&gt;
| bis ~500mA sinnvoll&lt;br /&gt;
| R,D&lt;br /&gt;
| [http://www.semiconductors.philips.com/acrobat/datasheets/BC640_BCP53_BCX53_6.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| TIP 2955&lt;br /&gt;
| 0,75&lt;br /&gt;
| Ptot bis 90W mit Kühlkörper&lt;br /&gt;
| Grenzwert 15A&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.ortodoxism.ro/datasheets/motorola/TIP2955.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[Transistor-Übersicht]]&lt;br /&gt;
&lt;br /&gt;
====N-MOSFET====&lt;br /&gt;
&lt;br /&gt;
BUZ10, BUZ11 etc. sind wie alle BUZ Typen ziemlich veraltet. Bitte nicht listen; es gibt fast immer was besseres von IRF.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;mosfet-n&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| IRF1010N&lt;br /&gt;
| 0,87&lt;br /&gt;
| max 50V, max 85A, 11 mOhm On-Widerstand&lt;br /&gt;
| Alles, was mit POWER zu tun hat ...&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.irf.com/product-info/datasheets/data/irf1010n.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| IRLZ34N&lt;br /&gt;
| 0,43&lt;br /&gt;
| max 55V, max 30A, 35 mOhm On-Widerstand&lt;br /&gt;
| Gatespannung kompatibel mit 5V-Controllern.&lt;br /&gt;
| R, D&lt;br /&gt;
| [http://www.irf.com/product-info/datasheets/data/irlz34n.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| IRLML2502&lt;br /&gt;
| 0,42&lt;br /&gt;
| max 20V, max 4,2A (cont.), 45 mOhm On-Widerstand&lt;br /&gt;
| SOT23 SMD-FET, extrem niedrige V_GS_th, bei niedrigem R_DS_on&lt;br /&gt;
| D&lt;br /&gt;
| [http://www.irf.com/product-info/datasheets/data/irlml2502.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| BS170&lt;br /&gt;
| 0,13&lt;br /&gt;
| max 60V, bis 500mA, 5 Ohm On-Widerstand&lt;br /&gt;
| veraltete Technik, aber in bastelfreundlichem TO-92 Gehäuse&lt;br /&gt;
| R,D&lt;br /&gt;
| [http://www.fairchildsemi.com/ds/BS/BS170.pdf PDF] (Fairchild)&lt;br /&gt;
|-&lt;br /&gt;
| BSS123&lt;br /&gt;
| 0,06&lt;br /&gt;
| max 100V, max 170mA (cont.), Thresholdspannung 1,7V, On-Widerstand 1,3Ohm&lt;br /&gt;
| SOT23 SMD-FET, auch für 3V3-versorgte Schaltungen bestens geeignet&lt;br /&gt;
| R,D&lt;br /&gt;
| [http://www.fairchildsemi.com/ds/BS/BSS123.pdf PDF] (Fairchild)&lt;br /&gt;
|-&lt;br /&gt;
| BUK100-50GL &lt;br /&gt;
| &lt;br /&gt;
| Logic-Level Power&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| [http://www.nxp.com/pip/BUK100-50GL_1.html PDF] (NXP)&lt;br /&gt;
|-&lt;br /&gt;
| IRLIZ44N &lt;br /&gt;
| &lt;br /&gt;
| Logic-Level Power&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| IRLR2905, IRLU2905 &lt;br /&gt;
| &lt;br /&gt;
| Logic-Level Power&lt;br /&gt;
| &lt;br /&gt;
| C&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| IRLU3410&lt;br /&gt;
| &lt;br /&gt;
| Logic-Level Power&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====P-MOSFET====&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;mosfet-p&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| IRLML6401&lt;br /&gt;
| 0,21&lt;br /&gt;
| max -12V, ca -4,3A (cont.), ca. 0,05 Ohm On-Widerstand&lt;br /&gt;
| SOT-23 SMD FET, extrem niedrige V_GS_th, bei niedrigem R_DS_on&lt;br /&gt;
| D&lt;br /&gt;
| [http://www.irf.com/product-info/datasheets/data/irlml6401.pdf]&lt;br /&gt;
|-&lt;br /&gt;
| IRF7220&lt;br /&gt;
| 1,10&lt;br /&gt;
| max -14V, ca -10A (cont.), ca. 0,02 Ohm On-Widerstand&lt;br /&gt;
| Gehäuse SO-8, brauchbar in 3,3V Systemen&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.irf.com/product-info/datasheets/data/irf7220.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| IRFR5305&lt;br /&gt;
| 0,56&lt;br /&gt;
| max -55V, -31A (cont.), ca. 0,065 Ohm On-Widerstand&lt;br /&gt;
| Gehäuse D-Pak (SMD, TO-252AA), Uth=-2 bis -4V&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.irf.com/product-info/datasheets/data/irfr5305.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| BS250&lt;br /&gt;
| 0,26&lt;br /&gt;
| max -45V, bis -230mA (cont.), 14 (und mehr) Ohm On-Widerstand&lt;br /&gt;
| veraltete Technik aber in bastelfreundlichem TO-92 Gehäuse von R lieferbar &lt;br /&gt;
| R&lt;br /&gt;
| [http://www.vishay.com/docs/70209/70209.pdf PDF] (Vishay)&lt;br /&gt;
|-&lt;br /&gt;
| NDS0610&lt;br /&gt;
| 0,07&lt;br /&gt;
| max -60V, bis -120mA (cont.), 20 (und mehr) Ohm On-Widerstand&lt;br /&gt;
| SMD Gehäuse Anwendung z.B. als [http://www.mikrocontroller.net/topic/42113#317220 Verpolschutz mit geringem Spannungsabfall]&lt;br /&gt;
| D DK&lt;br /&gt;
| [http://www.fairchildsemi.com/ds/ND%2FNDS0610.pdf PDF] (Fairchild)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====MOSFET-Pärchen====&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;mosfet-n-p&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| IRF7389&lt;br /&gt;
| 0,51&lt;br /&gt;
| 30 V, &amp;gt;2,5 A, 30/60 mOhm On-Widerstand&lt;br /&gt;
| Gehäuse SO-8&lt;br /&gt;
| D,R&lt;br /&gt;
| [http://www.irf.com/product-info/datasheets/data/irf7389.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[Mosfet-Übersicht]]&lt;br /&gt;
&lt;br /&gt;
=== Dioden ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;mosfet-p&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| 1N4148&lt;br /&gt;
| 0,02&lt;br /&gt;
| Kleinsignal-Gleichrichterdiode&lt;br /&gt;
| &lt;br /&gt;
| R,D&lt;br /&gt;
| [http://www.fairchildsemi.com/ds/1N%2F1N4148.pdf D]&lt;br /&gt;
|-&lt;br /&gt;
| 1N4001..1N4007&lt;br /&gt;
| 0,02&lt;br /&gt;
| Mehrzweck-Gleichrichterdiode, 1N4001..1N4007 mit gestaffelter Sperrspannung&lt;br /&gt;
| 1A&lt;br /&gt;
| R,D&lt;br /&gt;
| [http://www.fairchildsemi.com/ds/1N/1N4001.pdf D]&lt;br /&gt;
|-&lt;br /&gt;
| UF4001..UF4007&lt;br /&gt;
| 0,06 - 0,07&lt;br /&gt;
| UltraFast-Gleichrichterdiode, gestaffelte Sperrspannung, trr&amp;lt;50ns bzw 75ns&lt;br /&gt;
| 1A&lt;br /&gt;
| R, D&lt;br /&gt;
| [http://www.ortodoxism.ro/datasheets/vishay/uf4001.pdf Datenblatt]&lt;br /&gt;
|-&lt;br /&gt;
| 1N5400..1N5408&lt;br /&gt;
| 0,06&lt;br /&gt;
| Mehrzweck-Gleichrichterdiode, 1N5400..1N5408 mit gestaffelter Sperrspannung&lt;br /&gt;
| 3A, 50..1000V&lt;br /&gt;
| R, D&lt;br /&gt;
| [http://www.ortodoxism.ro/datasheets/fairchild/1N5401.pdf D]&lt;br /&gt;
|-&lt;br /&gt;
| UF5404, UF5408&lt;br /&gt;
| 0,11 bzw 0,22&lt;br /&gt;
| UltraFast-Gleichrichterdiode, gestaffelte Sperrspannung, trr&amp;lt;50ns bzw 75ns&lt;br /&gt;
| 3A, 50..1000V&lt;br /&gt;
| R&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| BAT46&lt;br /&gt;
| 0,10&lt;br /&gt;
| Kleinsignal-Schottky-Diode&lt;br /&gt;
| 150mA&lt;br /&gt;
| D,R&lt;br /&gt;
| [http://www.alldatasheet.com/view.jsp?Searchword=BAT46 D]&lt;br /&gt;
|-&lt;br /&gt;
| BAT54(A/C/S)&lt;br /&gt;
| 0,072&lt;br /&gt;
| sehr schnelle Kleinsignal-(Doppel-)Schottky-Diode&lt;br /&gt;
| 200mA&lt;br /&gt;
| R, D&lt;br /&gt;
| [http://www.alldatasheet.com/view.jsp?Searchword=BAT54 D]&lt;br /&gt;
|-&lt;br /&gt;
| SB120-SB160&lt;br /&gt;
| 0,13&lt;br /&gt;
| Schottky-Diode&lt;br /&gt;
| 1A 20-60V&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.alldatasheet.com/view.jsp?Searchword=SB140 D]&lt;br /&gt;
|-&lt;br /&gt;
| 1N5817-1N5819&lt;br /&gt;
| 0,15&lt;br /&gt;
| Schottky-Diode, sehr ähnlich zu SB120-140&lt;br /&gt;
| 1A 20/30/40V&lt;br /&gt;
| R, D, C&lt;br /&gt;
| [http://www.alldatasheet.com/view.jsp?Searchword=1N5819 D]&lt;br /&gt;
|-&lt;br /&gt;
| BA159&lt;br /&gt;
| 0,051&lt;br /&gt;
| Standard-Diode&lt;br /&gt;
| HF 1A 1000V&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.alldatasheet.com/view.jsp?Searchword=BA159 D]&lt;br /&gt;
|-&lt;br /&gt;
| BAV99&lt;br /&gt;
| 0,041&lt;br /&gt;
| Standard-Doppeldiode, SOT-23&lt;br /&gt;
| ESD-Schutz&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.alldatasheet.com/view.jsp?Searchword=BAV99 D]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[Dioden-Übersicht]]&lt;br /&gt;
&lt;br /&gt;
=== Instrumentenverstärker ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;opamps&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| INA128&lt;br /&gt;
| 6,15 (R)&lt;br /&gt;
| Verstärkung über 1 Widerstand einstellbar&lt;br /&gt;
| Brückenverstärker , Datenerfassung&lt;br /&gt;
| R,F&lt;br /&gt;
| [http://focus.ti.com/lit/ds/symlink/ina128.pdf#search=%22ina128%22 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| INA326&lt;br /&gt;
| ca. 3 (DK)&lt;br /&gt;
| Low Power, läuft an 3.3 oder 5 V&lt;br /&gt;
| Medizintechnik (EKG), Sensoren&lt;br /&gt;
| DK&lt;br /&gt;
| [http://www.ti.com/lit/gpn/ina326 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| AD620&lt;br /&gt;
| ca. 8 (R)&lt;br /&gt;
| Standardtyp&lt;br /&gt;
| EKG, EEG, Brückenverstärker&lt;br /&gt;
| R, RS, DK&lt;br /&gt;
| [http://www.analog.com/UploadedFiles/Data_Sheets/37793330023930AD620_e.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Operationsverstärker ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;opamps&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| LM358&lt;br /&gt;
| 0,09&lt;br /&gt;
| Single Supply&lt;br /&gt;
| 2-fach Standard-OP&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=lm358 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| LM324&lt;br /&gt;
| 0,13&lt;br /&gt;
| Single Supply&lt;br /&gt;
| 4-fach Standard-OP&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=lm324 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| LM393&lt;br /&gt;
| 0,10&lt;br /&gt;
| Single Supply&lt;br /&gt;
| 2-fach Standard-Komparator&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=lm393 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| LM339&lt;br /&gt;
| 0,10&lt;br /&gt;
| Single Supply&lt;br /&gt;
| 4-fach Standard-Komparator&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=lm339 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| TLC3702&lt;br /&gt;
| 0,80&lt;br /&gt;
| Single Supply&lt;br /&gt;
| 2-fach Micropower-Komparator (20µA) PushPull Ausgang&lt;br /&gt;
| F&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=tlc3702 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| NE5532&lt;br /&gt;
| 0,23&lt;br /&gt;
| 2 * Audio OP&lt;br /&gt;
| kann 600 Ohm treiben&lt;br /&gt;
| alle?&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=NE5532 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| LMC6484&lt;br /&gt;
| 2,35&lt;br /&gt;
| rail-to-rail in/out&lt;br /&gt;
| 4-fach OP&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.national.com/ds.cgi/LM/LMC6484.pdf D]&lt;br /&gt;
|-&lt;br /&gt;
| TS912&lt;br /&gt;
| 1&lt;br /&gt;
| rail-to-rail in/out&lt;br /&gt;
| 2-fach OP&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.st.com/stonline/products/literature/ds/2325/ts912.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| OP07&lt;br /&gt;
| 0,25&lt;br /&gt;
| geringer Offset&lt;br /&gt;
| &amp;lt;80µV je nach Hersteller&lt;br /&gt;
| R,D&lt;br /&gt;
| [http://www.reichelt.de/?;ACTION=7;LA=6;OPEN=1;INDEX=0;FILENAME=A200%252FOP07%2523AD.pdf; PDF]&lt;br /&gt;
|-&lt;br /&gt;
| TL062&lt;br /&gt;
| 0,17&lt;br /&gt;
| Low Power/JFET Eingang&lt;br /&gt;
| 2-fach OP&lt;br /&gt;
| R&lt;br /&gt;
| [http://focus.ti.com/lit/ds/symlink/tl062.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| TL072&lt;br /&gt;
| 0,15&lt;br /&gt;
| Low Noise/JFET Eingang&lt;br /&gt;
| 2-fach OP&lt;br /&gt;
| R&lt;br /&gt;
| [http://focus.ti.com/lit/ds/symlink/tl072.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| LMC6062&lt;br /&gt;
| 2,05&lt;br /&gt;
| Micropower, CMOS&lt;br /&gt;
| 2-fach OP, Is=40 µA (typ.)&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.national.com/ds.cgi/LM/LMC6062.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| LM4250&lt;br /&gt;
| 0,98&lt;br /&gt;
| Micropower, &amp;quot;programmierbar&amp;quot;&lt;br /&gt;
| 1-fach OP, Is=10 µA&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.national.com/ds.cgi/LM/LM4250.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| ICL7611&lt;br /&gt;
| 0,82&lt;br /&gt;
| Micropower, &amp;quot;programmierbar&amp;quot;&lt;br /&gt;
| 1-fach OP, Is=10 µA&lt;br /&gt;
| R&lt;br /&gt;
| [http://datasheets.maxim-ic.com/en/ds/ICL7611-ICL764X.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| ICL7621&lt;br /&gt;
| 1,10&lt;br /&gt;
| Micropower&lt;br /&gt;
| 2-fach OP, Is=100 µA&lt;br /&gt;
| R&lt;br /&gt;
| [http://datasheets.maxim-ic.com/en/ds/ICL7611-ICL764X.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| LM 13600&lt;br /&gt;
| 0,90&lt;br /&gt;
| National&lt;br /&gt;
| OTA - Steilheits-OP 50V/µs&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.national.com/ds.cgi/LM/LM13700.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| CA 3140&lt;br /&gt;
| 0,47&lt;br /&gt;
| Intersil&lt;br /&gt;
| BIMOS-OP - kleiner Eingangsstrom&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.intersil.com/data/fn/fn957.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Warum findet sich in obiger Liste kein 741, war er doch lange Zeit &amp;quot;der&amp;quot; OPV schlechthin? Nun, er wird allgemein als &amp;quot;veraltet&amp;quot; angesehen, da er aus den 60er Jahren stammt (1968 von Fairchild vorgestellt, etwa ab 1969 kommerziell erhältlich) und keine besonderen technischen Daten aufweist. Der immerhin etwa fünf Jahre jüngere 324 (von 1974) kostet häufig ein paar Cent weniger, enthält dafür aber vier statt einen OPV mit besseren Daten.&lt;br /&gt;
&lt;br /&gt;
Bitte oben noch einige günstige Low-Power-OPVs einfügen! Danke!&lt;br /&gt;
&lt;br /&gt;
=== Spannungsregler ===&lt;br /&gt;
==== Linearregler ====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;linearregler&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| LP2950&lt;br /&gt;
| 0,39 - 0,53&lt;br /&gt;
| Festspannungsregler Low-Dropout&lt;br /&gt;
| 3 - 5V 100mA, TO-92, &amp;lt;120µA Ruhestrom&lt;br /&gt;
| R, D&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=LP2950 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| LM317&lt;br /&gt;
| 0,22&lt;br /&gt;
| Linearer einstellbarer Spannungsregler&lt;br /&gt;
| max 40V -&amp;gt; 1,2 - 37V, max 1.5A, TO220&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=LM317 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| MAX663&lt;br /&gt;
| 1,80&lt;br /&gt;
| Linearer, einstellbarer Spannungsregler&lt;br /&gt;
| sehr niedriger Eigenstromverbrauch&lt;br /&gt;
| R&lt;br /&gt;
| [http://datasheets.maxim-ic.com/en/ds/MAX663-MAX666.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| LM78xx&lt;br /&gt;
| &amp;lt;1,00&lt;br /&gt;
| Festspannungregler (xx=05: 5V, xx=12: 12V ...)&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
| alle&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| LM79xx&lt;br /&gt;
| &amp;lt;1,00&lt;br /&gt;
| Festspannungregler, negative Spannung (xx=05: -5V, xx=12: -12V ...)&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
| alle&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| LF33&lt;br /&gt;
| &amp;lt;1,00&lt;br /&gt;
| Festspannungregler &lt;br /&gt;
| +3,3V, TO-220, 1A&lt;br /&gt;
| R&lt;br /&gt;
| &amp;amp;nbsp;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [http://www.national.com/an/AN/AN-1148.pdf AN-1148: Application Note 1148 Linear Regulators: Theory of Operation and Compensation] von National Semiconductor Corporation (PDF)&lt;br /&gt;
&lt;br /&gt;
==== Schaltregler ====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;schaltregler&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| LM2576&lt;br /&gt;
| 1,60&lt;br /&gt;
| Step-Down&lt;br /&gt;
| max 40V -&amp;gt; 1,2 - 37V, max 3A, TO220-5&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=LM2576 PDF] - [http://www.mikrocontroller.net/topic/58094#450561 mit Funk-Entstördrossel FED100µ (Reichelt...) bis 3 A]&lt;br /&gt;
|-&lt;br /&gt;
| MC34063A&lt;br /&gt;
| 0,25&lt;br /&gt;
| Step-Up/-Down&lt;br /&gt;
| SO-8/DIP-8; Tool zum Berechnen auf www.nomad.ee&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.onsemi.com/pub/Collateral/MC34063A-D.PDF PDF], [http://www.mikrocontroller.net/articles/MC34063]&lt;br /&gt;
|-&lt;br /&gt;
| PR4401&lt;br /&gt;
| 0,50&lt;br /&gt;
| Led-Treiber, Step-Up, Batteriebetrieb mit einer Zelle (bis 0,9 V)&lt;br /&gt;
| SO-23&lt;br /&gt;
| R, [http://www.ak-modul-bus.de/ AK Modul-Bus]&lt;br /&gt;
| [http://www.prema.com/pdf/pr4401.pdf PDF]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Shuntregler/[[Spannungsreferenz]] ====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;schaltregler&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| TL431&lt;br /&gt;
| 0,10&lt;br /&gt;
| Shuntregler mit 2,5 V interner Präzisions-Referenz &amp;lt;&amp;amp;nbsp;2&amp;amp;nbsp;%&lt;br /&gt;
| Präzise Alternative zur Z-Diode, Spannungsbegrenzung&lt;br /&gt;
| C, R, DK&lt;br /&gt;
|[http://www.datasheetarchive.com/search.php?q=TL431 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| LT1021&lt;br /&gt;
| 5,00&lt;br /&gt;
| Shuntregler mit interner Präzisions-Referenz &amp;lt;&amp;amp;nbsp;0,05&amp;amp;nbsp;%&lt;br /&gt;
| hoch präzise Alternative zur Z-Diode&lt;br /&gt;
| C, R, DK&lt;br /&gt;
|[http://www.datasheetarchive.com/search.php?q=LT1021 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| LM336&lt;br /&gt;
| 0,30&lt;br /&gt;
| Shuntregler mit interner Präzisions-Referenz &amp;lt;&amp;amp;nbsp;4&amp;amp;nbsp;%&lt;br /&gt;
| Präzise Alternative zur Z-Diode&lt;br /&gt;
| C, R, DK&lt;br /&gt;
|[http://www.datasheetarchive.com/search.php?q=LM336 PDF]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Timer ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;can&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| 555&lt;br /&gt;
| 0,15&lt;br /&gt;
| Universeller Zeitgeber.&lt;br /&gt;
| Für alles, wirklich alles. CMOS-Versionen lassen sich aufgrund ihrere niedrigeren Betriebsspannung besser mit µCs verbinden.&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.google.de/search?q=555+Datasheet Google]&lt;br /&gt;
|-&lt;br /&gt;
| DS1307&lt;br /&gt;
| 1,95&lt;br /&gt;
| 64 X 8 Serial Real Time Clock. Quarzuhr / Kalender Baustein mit serieller TWI-Schnittstelle.  &lt;br /&gt;
| Uhrenfunktion, unabhängig vom µC, aber µC-Steuerbar. Batteriepufferbar (3V-Knopfzelle wie CR2032) um die Zeit bei ausgeschalteter Board-Betriebsspannung weiter zu zählen.&lt;br /&gt;
| D, R&lt;br /&gt;
| [http://www.google.de/search?q=DS1307 Google]&lt;br /&gt;
|-&lt;br /&gt;
| PCF8583&lt;br /&gt;
| 1,50&lt;br /&gt;
| I²C/TWI Real Time Clock, Calendar, SRAM, Alarm, Timer, Eventcounter&lt;br /&gt;
| Auf Basis eines SRAM-chips, deshalb kann ein großer Teil als SRAM genutzt werden (ca 240 bytes). Berechnet Datum (4 jahre, jahr0 = schaltjahr), Uhrzeit (12/24), Wochentag. ein 32khz-Uhrenquarz ist nötig, sonst als Uhr unbrauchbar da  störempfindlich. Möglichkeit eines Interruptausganges bei voreingestellter Alarmzeit. Bemerkenswert einfaches Protokoll. Kann umgeschaltet werden in einen Timer-Modus (einfacher Counter mit bestimmter Timebase) oder Event-Counter-Modus (Eingangssignale zählen).&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.alldatasheet.com/view.jsp?Searchword=PCF8583]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Analogschalter und Multiplexer ===&lt;br /&gt;
Die DG2xx DG3xx DG4xx, teilweise auch DG5xx bezeichnen Analogschalter und Multiplexer die sich zum Industriestandard entwickelt haben. Es gibt sie von vielen Herstellern und zahlreichen Ausführungen in allen R(on) Bereichen und sind Pinkompatibel. Anstelle von &amp;quot;DGxxx&amp;quot; benutzen Hersteller für verbesserte/moderne Präzissions-Versionen ihre eigenen Präfixe wie &amp;quot;ADGxxx&amp;quot; von Analog Devices oder &amp;quot;MAXxxx&amp;quot; von Maxim. Für einfache Schalter werden häufig die letzten zwei Ziffern 01 bis 05 und 11-13 benutzt, 06/07/08/09 bezeichnet 16:1 8:1 und 4:1 Multiplexer in Single Ended und Differential Ended. Spannungsbereich geht bis +/-12 oder +/-15 V, die Steuereingänge haben zum Teil TTL-Kompatibilität, andernfalls einen Pin der den Logikpegel definiert (z.B. VCC).&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;can&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| DG201/DG202/DG212&lt;br /&gt;
| ~2-3€&lt;br /&gt;
| Vierfach Einzelschalter in SPST, SPDT, &lt;br /&gt;
| Zum µC-gesteuerten schalten von Analogsignalen, in Audio, Video, und Messschaltungen, in OP-Schaltungen für programmierbare Verstärkungen&lt;br /&gt;
| Maxim, Analog Devices, u.a.&lt;br /&gt;
| [http://search.datasheetcatalog.net/cgi-bin/helo.pl?text=DG202&amp;amp;action=Search]&lt;br /&gt;
|-&lt;br /&gt;
| DG306/DG406&lt;br /&gt;
| ~4-10€&lt;br /&gt;
| 16:1 Analog-Multiplexer&lt;br /&gt;
| Zum Multiplexen von Analogsignalen, Kanalauswahl für ADC-Messschaltungen.&lt;br /&gt;
| Maxim, Analog Devices, u.a.&lt;br /&gt;
| [http://search.datasheetcatalog.net/cgi-bin/helo.pl?text=DG306&amp;amp;action=Search]&lt;br /&gt;
|-&lt;br /&gt;
| DG307/DG408&lt;br /&gt;
| ~4-10€&lt;br /&gt;
| Zweifach 8:1 bzw Einfach 8:1 differential ended (8 Doppelkanäle)&lt;br /&gt;
| Zum Multiplexen von Analogsignalen, Kanalauswahl für ADC-Messschaltungen auch für differentielle Eingänge. &lt;br /&gt;
| Maxim, Analog Devices, u.a.&lt;br /&gt;
| [http://search.datasheetcatalog.net/cgi-bin/helo.pl?text=DG308&amp;amp;action=Search]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Digital ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== CAN ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;can&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| MCP2515&lt;br /&gt;
| 2,55&lt;br /&gt;
| SPI-CAN 2.0B Baustein&lt;br /&gt;
| &lt;br /&gt;
| D,F,R&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q= PDF]&lt;br /&gt;
|-&lt;br /&gt;
| SJA1000&lt;br /&gt;
| 4,55&lt;br /&gt;
| PellCAN 2.0B 1Mbit/s&lt;br /&gt;
|&lt;br /&gt;
| F,R&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Logik ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;opamps&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (€)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| 74HC4050&lt;br /&gt;
| 0,27&lt;br /&gt;
| z.B. 5V =&amp;gt; 3V&lt;br /&gt;
| Pegelwandler unidirektional abwärts&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=74hc4050 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| HEF4104B&lt;br /&gt;
| 0,77&lt;br /&gt;
| z.B. 5V =&amp;gt; 12V&lt;br /&gt;
| Pegelwandler unidirektional aufwärts&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=HEF4104B PDF]&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== USB ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;usb&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| FT232&lt;br /&gt;
| 3,59&lt;br /&gt;
| USB &amp;lt;-&amp;gt; RS232 Wandler&lt;br /&gt;
| Zugriff über virtuellen COM Port&lt;br /&gt;
| D, R&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=ft232 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| FT245&lt;br /&gt;
| 4,79&lt;br /&gt;
| USB &amp;lt;-&amp;gt; Seriell Wandler mit paralleler Schnittstelle&lt;br /&gt;
| Zugriff über virtuellen COM Port&lt;br /&gt;
| D, R&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=ft245 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| TUSB3410&lt;br /&gt;
| 3,50&lt;br /&gt;
| USB &amp;lt;-&amp;gt; RS232 mit 8052 CPU&lt;br /&gt;
| Zugriff über virtuellen COM Port&lt;br /&gt;
| DK&lt;br /&gt;
| [http://focus.ti.com/docs/prod/folders/print/tusb3410.html PDF]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Treiber ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;opamps&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| ULN2003A&lt;br /&gt;
| 0,17&lt;br /&gt;
| 7-fach Low-Side Treiber&lt;br /&gt;
| 50V/500mA&lt;br /&gt;
| R, D&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=ULN2003 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| ULN2803A&lt;br /&gt;
| 0,44&lt;br /&gt;
| 8-fach Low-Side Treiber&lt;br /&gt;
| 50V/500mA&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=ULN2803 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| UDN2981&lt;br /&gt;
| 1,50&lt;br /&gt;
| 8-fach High-Side Treiber&lt;br /&gt;
| 50V/500mA&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=UDN2981 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| ICL7667&lt;br /&gt;
| 1&lt;br /&gt;
| Dual inverting FET Treiber&lt;br /&gt;
| 18V, 20ns@1nF&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=ICL7667 PDF]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Analogschalter aus der 4000 Logikreihe ===&lt;br /&gt;
Die folgenden Schalter werden digital gesteuert, daher sind sie im Kapitel [[#Digital|Digital]] einsortiert. Sie basieren auf standard CMOS-Technologien, sind daher weit verbreitet, günstig, haben aber daher auch nur mäßige Eigenschaften und begrenzte Anwendungsbereiche. Analogschalter für Präzisionsanwendungen sind im Kapitel [[#Analog|Analog]].&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;can&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| 4051&lt;br /&gt;
| 0,25&lt;br /&gt;
| 8:1 Analogmultiplexer.&lt;br /&gt;
| Zum µC-gesteuerten Umschalten von Analogsignalen. Je nach Typ sind Analogsignale bis in den 100 MHz Bereich mit einer Schaltfrequenz bis mehrere 10 MHz möglich.&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.google.de/search?q=4051+datasheet Google]&lt;br /&gt;
|-&lt;br /&gt;
| 4052&lt;br /&gt;
| 0,11&lt;br /&gt;
| Zwei 4:2 Analogmultiplexer.&lt;br /&gt;
| Zum µC-gesteuerten Umschalten von Analogsignalen. Je nach Typ sind Analogsignale bis in den 100 MHz Bereich mit einer Schaltfrequenz bis mehrere 10 MHz möglich.&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.google.de/search?q=4052+datasheet Google]&lt;br /&gt;
|-&lt;br /&gt;
| 4053&lt;br /&gt;
| 0,16&lt;br /&gt;
| Drei 3:2 Analogmultiplexer.&lt;br /&gt;
| Zum µC-gesteuerten Umschalten von Analogsignalen. Je nach Typ sind Analogsignale bis in den 100 MHz Bereich mit einer Schaltfrequenz bis mehrere 10 MHz möglich.&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.google.de/search?q=4053+datasheet Google]&lt;br /&gt;
|-&lt;br /&gt;
| 4066&lt;br /&gt;
| 0,15&lt;br /&gt;
| Vierfach Analogschalter&amp;amp;nbsp;/ -koppler.&lt;br /&gt;
| Zum µC-gesteuerten Schalten oder Umschalten von Analogsignalen. Je nach Typ sind  Analogsignale bis in den 100 MHz Bereich mit einer Schaltfrequenz bis mehrere 10 MHz möglich.&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.google.de/search?q=4066+datasheet Google]&lt;br /&gt;
|-&lt;br /&gt;
| 4067&lt;br /&gt;
| 0,60&lt;br /&gt;
| 1:16 Analogmultiplexer/-demultiplexer&lt;br /&gt;
|&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.google.de/search?q=4067+datasheet Google]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Galvanische Trennelemente ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;opamps&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| CNY17&lt;br /&gt;
| 0,17&lt;br /&gt;
| Optisch, Standardtyp&lt;br /&gt;
| billig&lt;br /&gt;
| R,C&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=CNY17 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| 6N137&lt;br /&gt;
| 0,49&lt;br /&gt;
| Optisch, Logikausgang&lt;br /&gt;
| sehr schnell&lt;br /&gt;
| R,D&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=6N137 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| ADUM240*&lt;br /&gt;
| 10&lt;br /&gt;
| Induktiv, 3V/5V Logik&lt;br /&gt;
| extrem schnell, EN90650, 5kV&lt;br /&gt;
| F&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=adum240 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| ISO72*&lt;br /&gt;
| 1,25&lt;br /&gt;
| Kapazitiv, 3V/5V&lt;br /&gt;
| 6kV, bis zu 150MHz&lt;br /&gt;
| DK,F&lt;br /&gt;
| [http://focus.ti.com/paramsearch/docs/parametricsearch.tsp?family=analog&amp;amp;familyId=897&amp;amp;uiTemplateId=NODE_STRY_PGE_T PDF]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Displays ===&lt;br /&gt;
Bei den Textdisplays eignet sich praktisch jedes HD44780 konforme Display.&lt;br /&gt;
Praktisch jeder Elektronikversender hat eine Auswahl an verschiedenen Größen zu bieten. &lt;br /&gt;
Wer keinen besonderen Anspruch auf die Größe der Displays hat sollte sich bei Pollin und in Ebay umschauen.&lt;br /&gt;
&lt;br /&gt;
=== Speicher ===&lt;br /&gt;
&lt;br /&gt;
==== [[EEPROM]] ====&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;EEPROMmemory&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| ST 24C01 BN6, ST 24C02 BN6, ST 24C256 BN6 (allgemein 24C## mit ## Größe in kbit)&lt;br /&gt;
| 0,14€ - 1,40€&lt;br /&gt;
| EEPROM Speicher mit seriellem (I2C) Interface, 1kbit bis 256 kbit Speicher. Viele verschiedene Hersteller.&lt;br /&gt;
| Speichern von Konfigurationsdaten &lt;br /&gt;
| R&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=24C PDF]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Converter ==&lt;br /&gt;
=== ADC ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;opamps&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Geschwindigkeit&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| ADC830&lt;br /&gt;
| 6&lt;br /&gt;
| AD-Wandler&lt;br /&gt;
| 8770CPS&lt;br /&gt;
| C,R&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=adc830 PDF]&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| LTC2400&lt;br /&gt;
| 9,55&lt;br /&gt;
| 24-Bit-ADC&lt;br /&gt;
| ca. 6CPS&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1155,C1001,C1152,P1636,D1887]&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DAC ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;opamps&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| 08&lt;br /&gt;
| 0,90&lt;br /&gt;
| 8-Bit DAC mit parallelem Businterface.&lt;br /&gt;
| Alt, preiswert. Benötigt viele µC Pins (min. 8, paralleler Bus) und eine doppelte Spannungsversorgung. Langsamere Version: 0808.&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.google.de/search?q=LTC1456+Datasheet Google]&lt;br /&gt;
|-&lt;br /&gt;
| 7524 &lt;br /&gt;
| 3,00&lt;br /&gt;
| 8-Bit DAC mit parallelem Businterface&lt;br /&gt;
| Benötigt viele µC Pins. Single-Supply (5V bis 15V).&lt;br /&gt;
| alle&lt;br /&gt;
| [http://www.google.de/search?q=7524+Datasheet Google]&lt;br /&gt;
|-&lt;br /&gt;
| TDA8444 &lt;br /&gt;
| 1,20&lt;br /&gt;
| Achtfach 6-Bit DAC mit seriellem TWI-Businterface. Bezahlbarer sechsfach-DAC, allerdings mit geringer Auflösung.&lt;br /&gt;
| Dort wo µC gesteuert viele Ausgangskanäle mit geringer, ungenauer Auflösung benötigt werden.&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.google.de/search?q=TDA8444+Datasheet Google]&lt;br /&gt;
|-&lt;br /&gt;
| PCF8591&lt;br /&gt;
| 2,50&lt;br /&gt;
| 8-Bit DAC, 8-Bit ADC mit seriellem TWI-Businterface.&lt;br /&gt;
| Z.B. in Regelkreisen wo sowohl ein DAC, als auch ein ADC benötigt wird.&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.google.de/search?q=PFC8591+Datasheet Google]&lt;br /&gt;
|-&lt;br /&gt;
| TDA8702&lt;br /&gt;
| 2,50&lt;br /&gt;
| 8-Bit Video DAC mit parallelem Businterface und Clock-Eingang.&lt;br /&gt;
| Schnelle Wandlung bis 30 MHz. Benötigt viele µC Pins.&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.google.de/search?q=TDA8702+Datasheet Google]&lt;br /&gt;
|-&lt;br /&gt;
| LTC1661&lt;br /&gt;
| 3,70&lt;br /&gt;
| Dual 10-bit DAC mit seriellem 3-Leitungs-Businterface.&lt;br /&gt;
| Guter Kompromiss aus Preis und Leistung.&lt;br /&gt;
| F, C (Suchfunktion weigert sich manchmal ihn im Conrad-Shop zu finden), R&lt;br /&gt;
| [http://www.google.de/search?q=LTC1661+Datasheet Google]&lt;br /&gt;
|-&lt;br /&gt;
| LTC1257&lt;br /&gt;
| 8,-&lt;br /&gt;
| 12-bit DAC mit kaskadierbarem seriellen 3-Leitungs-Businterface.&lt;br /&gt;
| Genauer µC-steuerbarer DAC.&lt;br /&gt;
| C, F, R&lt;br /&gt;
| [http://www.google.de/search?q=LTC1257+Datasheet Google]&lt;br /&gt;
|-&lt;br /&gt;
| LTC1456&lt;br /&gt;
| 10,-&lt;br /&gt;
| 12-bit DAC mit kaskadierbarem seriellen 3-Leitungs-Businterface.&lt;br /&gt;
| Genauer µC-steuerbarer DAC.&lt;br /&gt;
| C&lt;br /&gt;
| [http://www.google.de/search?q=LTC1456+Datasheet Google]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Sensoren (aktiv) ==&lt;br /&gt;
=== [[Temperatursensor|Temperatur]] ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;opamps&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| LM75&lt;br /&gt;
| 1,75&lt;br /&gt;
| Temperatursensor mit I²C (TWI) Bus Interface (3.3V und 5V Version) (SMD)&lt;br /&gt;
| &lt;br /&gt;
| D, R&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=LM75 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| DS1621&lt;br /&gt;
| ~5&lt;br /&gt;
| Temperatursensor mit I²C (TWI) Bus Interface (wie LM75, kein SMD)&lt;br /&gt;
| &lt;br /&gt;
| C, D&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| DS18B20&lt;br /&gt;
| 2,95&lt;br /&gt;
| Temperatursensor mit 1-Wire Interface&lt;br /&gt;
|&lt;br /&gt;
| D, R&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=DS18B20 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| LM35&lt;br /&gt;
| 1,19&lt;br /&gt;
| Analoger Temperatursensor&lt;br /&gt;
| 10mV/°C absolut&lt;br /&gt;
| D&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=LM35 PDF]&lt;br /&gt;
|-&lt;br /&gt;
| LM335&lt;br /&gt;
| 0,87&lt;br /&gt;
| Analoger Temperatursensor&lt;br /&gt;
| 10mV/K absolut&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q=LM335 PDF]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
Wenn man z.B. einen Übertemperaturschutz (oder eine andere Schaltung, bei der es nur eine Schaltschwelle gibt) bauen will, dann empfiehlt sich die Verwendung eines NTCs. Dessen Kennlinie ist gegenüber den Kennlinien von z.B. LM335 dahingehend im Vorteil, dass eine geringe Temperaturänderung besser messbar ist.&lt;br /&gt;
&lt;br /&gt;
= Passive Bauelemente =&lt;br /&gt;
== Sensoren (passiv)==&lt;br /&gt;
=== Licht ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;opamps&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| BPX 65&lt;br /&gt;
| 3,35&lt;br /&gt;
| Fotodiode 10µA, 350-1000nm&lt;br /&gt;
| schnelle Lichtmessungen (bis MHz Bereich), großer Wellenlängenbereich&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.ortodoxism.ro/datasheets/infineon/1-bpx65.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== [[Temperatursensor|Temperatur]] ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;opamps&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| KTY81&lt;br /&gt;
| ~0,50&lt;br /&gt;
| nichtlinear, bis 150°C&lt;br /&gt;
| in &amp;amp;#956;C Schaltungen&lt;br /&gt;
| R, D&lt;br /&gt;
| [http://www.semiconductors.philips.com/acrobat/datasheets/KTY84_SERIES_5.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| KTY84&lt;br /&gt;
| 0,72&lt;br /&gt;
| nichtlinear, bis 300°C&lt;br /&gt;
| in &amp;amp;#956;C Schaltungen&lt;br /&gt;
| R&lt;br /&gt;
| [http://www.datasheetcatalog.org/datasheet2/e/0l2lc3p1dl8e5dgghsfh2oee43py.pdf PDF]&lt;br /&gt;
|-&lt;br /&gt;
| PT100 / PT1000&lt;br /&gt;
| ab 3,00&lt;br /&gt;
| lineare Kennlinie&lt;br /&gt;
| analoge Messschaltungen&lt;br /&gt;
| F C&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Widerstände ==&lt;br /&gt;
Mit einem Widerstandssortiment, welches die E12-Werte enthält, kann man normalerweise nicht falsch liegen. Denn früher oder später benötigt man jeden Widerstandswert der E12-Reihe einmal.&lt;br /&gt;
&lt;br /&gt;
Für einen Einstieg eignen sich die Sortimente vom Pollin. Auch ein Blick in Ebay kann sich lohnen um ein Einstiegssortiment zu bekommen.&lt;br /&gt;
&lt;br /&gt;
== Kondensatoren ==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;opamps&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| 100nF Keramik&lt;br /&gt;
| ~0.05&lt;br /&gt;
| &lt;br /&gt;
| Als sogenannter Abblockkondensator zwischen VCC und GND vor allem bei Digital-ICs zwingend erforderlich, schadet aber auch bei den meisten Analog-ICs nicht.&lt;br /&gt;
| &lt;br /&gt;
| [http://www.datasheetarchive.com/search.php?q= PDF]&lt;br /&gt;
|-&lt;br /&gt;
| 100nF Keramik SMD 0603&lt;br /&gt;
| ~0.01 (bei 100 Stück)&lt;br /&gt;
| SMD 0603&lt;br /&gt;
| Als sogenannter Abblockkondensator zwischen VCC und GND vor allem bei Digital-ICs zwingend erforderlich, schadet aber auch bei den meisten Analog-ICs nicht.&lt;br /&gt;
| D&lt;br /&gt;
| [http://www.google.de/search?num=100&amp;amp;hl=de&amp;amp;q=datasheet+0603+chip-capacitors+filetype%3Apdf&amp;amp;btnG=Suche&amp;amp;meta=lr%3Dlang_de%7Clang_en PDF]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Mechanische Bauelemente =&lt;br /&gt;
&lt;br /&gt;
== Taster / Schalter ==&lt;br /&gt;
&lt;br /&gt;
== Steckverbinder ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;opamps&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Preis (&amp;amp;euro;)&lt;br /&gt;
! Beschreibung&lt;br /&gt;
! Anwendungen&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
|-&lt;br /&gt;
| WSL 10G&lt;br /&gt;
| 0,07&lt;br /&gt;
| Wannenstecker, 10-polig, gerade, Raster 2,54 mm&lt;br /&gt;
| Verbindung zwischen zwei Platinen mit Flachbandkabel&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
| PFL 10&lt;br /&gt;
| 0,09&lt;br /&gt;
| Pfostenleiste, 10-polig, Schneidklemmtechnik, Raster 2,54 mm&lt;br /&gt;
| Verbindung zwischen zwei Platinen mit Flachbandkabel&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
| -&lt;br /&gt;
| 3,55&lt;br /&gt;
| Flachbandkabel, 10-polig, 3 Meter, Raster 1,27 mm&lt;br /&gt;
| Verbindung zwischen zwei Platinen mit Flachbandkabel&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| 0,70&lt;br /&gt;
| D-Sub 9-polig auf 10-polig Pfostenleiste mit Flachbandkabel&lt;br /&gt;
| Anschluss für serielle Schnittstelle am PC&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| 0,35&lt;br /&gt;
| Flachkabel-IC-Sockelverbinder&lt;br /&gt;
| Übergang von Leiterplatte auf Steckbrett&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| 0,40 &lt;br /&gt;
| Reihenklemme/Anreihklemme (verschieden Typen, für Lochraster: Raster 5.08)&lt;br /&gt;
| Anschluss der Spannungsversorung, leistungsstarke Verbraucher&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| 0,30&lt;br /&gt;
| Hohlstecker/DC-Stecker&lt;br /&gt;
| siehe englische Wikipedia [http://en.wikipedia.org/wiki/Coaxial_power_connector Coaxial power connector] &lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Lieferanten =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Lokale Lieferanten: [[Lokale Anbieter]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Allgemeine Lieferantenliste: [[Elektronikversender]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;opamps&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Kürzel&lt;br /&gt;
! Name&lt;br /&gt;
! Webseite&lt;br /&gt;
! Kommentar&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;B&amp;lt;/b&amp;gt;&lt;br /&gt;
|Bürklin&lt;br /&gt;
|[http://www.buerklin.de www.buerklin.de]&lt;br /&gt;
|Versand nur Firmen &amp;amp; Studenten, Ladengeschäft in München und Düsseldorf&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;C&amp;lt;/b&amp;gt;&lt;br /&gt;
|Conrad&lt;br /&gt;
|[http://www.conrad.de www.conrad.de]&lt;br /&gt;
|&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;D&amp;lt;/b&amp;gt;&lt;br /&gt;
|CSD-Electronics&lt;br /&gt;
|[http://www.csd-electronics.de www.csd-electronics.de]&lt;br /&gt;
|&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;DK&amp;lt;/b&amp;gt;&lt;br /&gt;
|Digikey&lt;br /&gt;
|[http://de.digikey.com www.de.digikey.com]&lt;br /&gt;
|Mindestbestellmenge&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;F&amp;lt;/b&amp;gt;&lt;br /&gt;
|Farnell&lt;br /&gt;
|[http://www.farnell.de www.farnell.de]&lt;br /&gt;
|Versand nur Firmen &amp;amp; Studenten&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;M&amp;lt;/b&amp;gt;&lt;br /&gt;
|Meilhaus&lt;br /&gt;
|[http://www.meilhaus.de www.meilhaus.de]&lt;br /&gt;
|Nur gewerbliche Kunden&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;P&amp;lt;/b&amp;gt;&lt;br /&gt;
|Pollin&lt;br /&gt;
|[http://www.pollin.de www.pollin.de]&lt;br /&gt;
|&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;b&amp;gt;R&amp;lt;/b&amp;gt;&lt;br /&gt;
|Reichelt&lt;br /&gt;
|[http://www.reichelt.de www.reichelt.de]&lt;br /&gt;
|Hohe Mindestbestellmenge für Ausland&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:Bauteile|!]]&lt;br /&gt;
[[Category:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Diskussion:Leistungsaufnahme_von_Mikrocontrollern&amp;diff=31289</id>
		<title>Diskussion:Leistungsaufnahme von Mikrocontrollern</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Diskussion:Leistungsaufnahme_von_Mikrocontrollern&amp;diff=31289"/>
		<updated>2008-09-21T13:11:05Z</updated>

		<summary type="html">&lt;p&gt;Matze88: sry, völliger schwachsinn entstanden bei meiner letzten bearbeitung&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Diskussion:Leistungsaufnahme_von_Mikrocontrollern&amp;diff=31288</id>
		<title>Diskussion:Leistungsaufnahme von Mikrocontrollern</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Diskussion:Leistungsaufnahme_von_Mikrocontrollern&amp;diff=31288"/>
		<updated>2008-09-21T13:10:17Z</updated>

		<summary type="html">&lt;p&gt;Matze88: Die Seite wurde neu angelegt: -Stromaufnahme Mega88 3,3V im OFF State beträgt nie und nimmer 300µA. Das sind wesentlich weniger, allerdings habe ich gerade keine Zahl parat. Kontrolle?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-Stromaufnahme Mega88 3,3V im OFF State beträgt nie und nimmer 300µA. Das sind wesentlich weniger, allerdings habe ich gerade keine Zahl parat. Kontrolle?&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=31090</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=31090"/>
		<updated>2008-09-15T16:59:15Z</updated>

		<summary type="html">&lt;p&gt;Matze88: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, in dem die meiste Arbeit steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts:&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.3.zip| GPS Mini Navigator Version beta 0.3]]&lt;br /&gt;
&lt;br /&gt;
Behobene Fehler:&lt;br /&gt;
* Falscher Variablentyp verhinderte ein Anzeigen von Distanzen &amp;gt; 255 Metern&lt;br /&gt;
* Dezimalausgabe (genutzt von GPS Länge, Breite, Höhe) wurde direkt wieder überschrieben&lt;br /&gt;
* Bugreport 12.09.2008 bezügl. Tastensperre war fehlerhaft; Der Fehler trat durch eine bereits behobene Endlosschleife auf.&lt;br /&gt;
&lt;br /&gt;
Bekannte Fehler:&lt;br /&gt;
* Abspeichern falscher Werte als Wegpunkt (siehe b0.2)&lt;br /&gt;
* Öffnen der Wegpunktdatei 0xFF (siehe b0.2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.2.zip| GPS Mini Navigator Version beta 0.2]]&lt;br /&gt;
&lt;br /&gt;
Behobene Fehler:&lt;br /&gt;
* Wiedereinschalten aus dem Standby wurde nicht ausreichend überprüft. (Achtung. Verändertes Timing beim Einschalten, siehe Changelog)&lt;br /&gt;
* Fehler beim Laden der nächsten Waypoint Datei, sofern rückwärts navigieren aktiviert und zuvor die letzte Waypoint Datei geladen war führte zu einer Endlosschleife.&lt;br /&gt;
&lt;br /&gt;
Bekannte Fehler:&lt;br /&gt;
* Race Condition: Mit einer SEHR geringen Wahrscheinlichkeit wird beim Wegpunkte abspeichern ein völlig falscher Wert gespeichert, falls der GPS Interrupt gerade die Positionsdaten aktualisiert UND dabei gerade eine Wertänderung stattfindet, die nicht nur das letzte Byte betrifft. Die Wahrscheinlichkeit ist so enorm gering (Ich habs noch nicht ausgerechnet, aber sie dürfte weit unter 1:1 Million liegen), dass ein Fix (-&amp;gt; Zugriffssperre) zur Zeit noch nicht lohnt, erstmal sind wichtigere Sachen (z.B. PC Software) dran.&lt;br /&gt;
* Nach der letzten Wegpunktdatei wird die Datei 0xFF geöffnet als Schutz vor einer Endlosschleife (falls keine Wegpunktdatei existiert). Weitere Überprüfungen notwendig, sodass wieder bei der ersten Wegpunktdatei begonnen wird.&lt;br /&gt;
* Entdeckt 12.09.2008: Nutzt man die &amp;quot;Tastensperre&amp;quot; (Shutdown bei aktiviertem GPS LOG), so treten Fehler bei der Aufzeichnung auf. Dies wird weiter untersucht, wenn ich mehr Zeit habe.&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Achtung:&#039;&#039; Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
Für das Rechnen mit Koordinaten benutze ich hauptsächlich eine Funktion:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t calculate_distance (gps_coords *a, gps_coords *b)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t latstate = 0;&lt;br /&gt;
  uint32_t lat_distance;&lt;br /&gt;
  if(a-&amp;gt;lat &amp;gt; b-&amp;gt;lat)&lt;br /&gt;
  {&lt;br /&gt;
    latstate = 1;&lt;br /&gt;
    lat_distance = a-&amp;gt;lat - b-&amp;gt; lat;&lt;br /&gt;
  }&lt;br /&gt;
  else lat_distance = b-&amp;gt;lat - a-&amp;gt;lat;&lt;br /&gt;
  lat_distance = mul32_16u(div32u(lat_distance,100),11112);	// * 10^7 * 10^-2 *10^-1= *10^4 meters&lt;br /&gt;
  lat_distance = div32u(lat_distance, 10000);&lt;br /&gt;
  uint16_t distance_cache = lat_distance;			&lt;br /&gt;
  lat_distance = mul32_16u(lat_distance, lat_distance);		// square of lat_distance&lt;br /&gt;
&lt;br /&gt;
  uint8_t lonstate = 0;&lt;br /&gt;
  uint32_t lon_distance;&lt;br /&gt;
  if(a-&amp;gt;lon &amp;gt; b-&amp;gt;lon)&lt;br /&gt;
  {&lt;br /&gt;
    lonstate = 1;&lt;br /&gt;
    lon_distance = a-&amp;gt;lon - b-&amp;gt;lon;&lt;br /&gt;
  }&lt;br /&gt;
  else lon_distance = b-&amp;gt;lon - a-&amp;gt;lon;&lt;br /&gt;
  /* square(((lon_diff / 1000) * cos_val * 1113) / 10000) = lon_diff * 111,3 * cos(angle)*/&lt;br /&gt;
  lon_distance = mul32_16u(div32u(lon_distance, 1000), my_cos(div32u(labs(a-&amp;gt;lat),10000000)));  //-&amp;gt;10^6  // simplification:&lt;br /&gt;
                                              //a-&amp;gt;lat instead of a-&amp;gt;lat+b-&amp;gt;lat/2&lt;br /&gt;
  lon_distance = div32u(mul32_16u(lon_distance, 1113),10000); // -&amp;gt;meters&lt;br /&gt;
  lon_distance = isqrt32(mul32_16u(lon_distance, lon_distance) + lat_distance);&lt;br /&gt;
  uint8_t temp_angle = (my_acos(div32u(mul32_16u(distance_cache,100),lon_distance)) * 100) &amp;gt;&amp;gt; 8;	// 0-90 deg. angle&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  if(latstate)&lt;br /&gt;
  {&lt;br /&gt;
    if(lonstate) temp_angle +=70;&lt;br /&gt;
    else temp_angle = 70 - temp_angle;&lt;br /&gt;
  }&lt;br /&gt;
  else if(lonstate)&lt;br /&gt;
    temp_angle = 140 - temp_angle;&lt;br /&gt;
  &lt;br /&gt;
 return (lon_distance) | ((uint32_t)temp_angle &amp;lt;&amp;lt; 16);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Zusammenarbeit mit einfachsten, auf Tabellen basierenden Kosinus- und Umkehrfunktion liefert diese Ergebnisse mit meistens nicht einmal 2 % Abweichung. Der Ablauf:&lt;br /&gt;
# Breitendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Längendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Nach dem Satz des Pythagoras den Abstand der Punkte bestimmen, Länge und Breite stehen dabei für orthogonale Vektoren, somit haben wir ein rechtwinkliges Dreieck&lt;br /&gt;
# Da wir hier gleich alle Seiten berechnet haben, kann einfach der Winkel zwischen Ankathete und Hypothenuse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
Der Winkel muss zum Schluss noch korrigiert werden, jenachdem, in welchem Quadranten (Koordinate a als Ursprung und b als Punkt im 2 dimensionalen Koordinatensystem betrachtet) wir uns befinden.&lt;br /&gt;
Diese Funktion liefert für alle Punkte, die nicht mehr als 65535 Meter auseinander liegen korrekte Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variable Anzahl).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 4 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;0 - allgemeine GPS Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;1 - GPS Logger Funktionen&#039;&#039;&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1, 16, 128, 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;2 - Wegpunkt Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei (Erneuter Aufruf: Nächste Wegpunkt Datei öffnen)&lt;br /&gt;
** 1* - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 an ist, sind es 2048 Meter Schritte.&lt;br /&gt;
** 2* - Erster Aufruf: Anzeige des Kurses zum Wegpunkt relativ zur Bewegungsrichtung&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts (bzw. rückwärts sofern die Option angewählt ist) in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der aktuell annavigierte Punkt weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
** LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
     * Für 1 und 2 gilt: Erneuter Aufruf springt zum nachfolgenden Wegpunkt.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;3 - Wegpunkte einspeichern&#039;&#039;&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkt Datei und gibt die Nummer binär aus. Die Wegpunktdatei kann parallel zum GPS Log erstellt &amp;amp; abgespeichert werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;4 - Allgemeine Optionen&#039;&#039;&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 1000 ms muss sie losgelassen und nach weiteren 600 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt. (LED 5 und 6 geben den ungefähren Batteriestatus wieder. 6 ist voll, 5 ist fast leer (max. 30 Minuten GPS verbleibend). Sind beide LEDs aus, so wird das GPS Modul bis zum Aufladen deaktiviert.)&lt;br /&gt;
&lt;br /&gt;
== PC Interaktion ==&lt;br /&gt;
Für den PC habe ich bereits einfachste Übertragungsprogramme geschrieben, welche jedoch zur Zeit noch ungetestet und stark aufs Debugging ausgelegt sind. Diese werden erst zu späterer Zeit veröffentlicht.&lt;br /&gt;
[[http://www.gpsbabel.org/ GPS Babel]] eignet sich wunderbar, um ausgelesene Daten in ein Google Earth kompatibles Format umzuwandeln, um sich z.B. die GPS Logs anzusehen. Auch können in Google Earth erstellte Pfade so als Waylist für den Mini Navigator umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;br /&gt;
[[Category:GPS|G]]&lt;br /&gt;
[[Category:Projekte|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=31089</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=31089"/>
		<updated>2008-09-15T16:57:57Z</updated>

		<summary type="html">&lt;p&gt;Matze88: /* Menü */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(Achtung: Diesen Artikel habe ich nach Wettbewerbsschluss noch bearbeitet, bitte beachtet beim Bewerten, dass ihr euch die alte Version anschaut. Danke)&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, in dem die meiste Arbeit steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts:&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.3.zip| GPS Mini Navigator Version beta 0.3]]&lt;br /&gt;
&lt;br /&gt;
Behobene Fehler:&lt;br /&gt;
* Falscher Variablentyp verhinderte ein Anzeigen von Distanzen &amp;gt; 255 Metern&lt;br /&gt;
* Dezimalausgabe (genutzt von GPS Länge, Breite, Höhe) wurde direkt wieder überschrieben&lt;br /&gt;
* Bugreport 12.09.2008 bezügl. Tastensperre war fehlerhaft; Der Fehler trat durch eine bereits behobene Endlosschleife auf.&lt;br /&gt;
&lt;br /&gt;
Bekannte Fehler:&lt;br /&gt;
* Abspeichern falscher Werte als Wegpunkt (siehe b0.2)&lt;br /&gt;
* Öffnen der Wegpunktdatei 0xFF (siehe b0.2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.2.zip| GPS Mini Navigator Version beta 0.2]]&lt;br /&gt;
&lt;br /&gt;
Behobene Fehler:&lt;br /&gt;
* Wiedereinschalten aus dem Standby wurde nicht ausreichend überprüft. (Achtung. Verändertes Timing beim Einschalten, siehe Changelog)&lt;br /&gt;
* Fehler beim Laden der nächsten Waypoint Datei, sofern rückwärts navigieren aktiviert und zuvor die letzte Waypoint Datei geladen war führte zu einer Endlosschleife.&lt;br /&gt;
&lt;br /&gt;
Bekannte Fehler:&lt;br /&gt;
* Race Condition: Mit einer SEHR geringen Wahrscheinlichkeit wird beim Wegpunkte abspeichern ein völlig falscher Wert gespeichert, falls der GPS Interrupt gerade die Positionsdaten aktualisiert UND dabei gerade eine Wertänderung stattfindet, die nicht nur das letzte Byte betrifft. Die Wahrscheinlichkeit ist so enorm gering (Ich habs noch nicht ausgerechnet, aber sie dürfte weit unter 1:1 Million liegen), dass ein Fix (-&amp;gt; Zugriffssperre) zur Zeit noch nicht lohnt, erstmal sind wichtigere Sachen (z.B. PC Software) dran.&lt;br /&gt;
* Nach der letzten Wegpunktdatei wird die Datei 0xFF geöffnet als Schutz vor einer Endlosschleife (falls keine Wegpunktdatei existiert). Weitere Überprüfungen notwendig, sodass wieder bei der ersten Wegpunktdatei begonnen wird.&lt;br /&gt;
* Entdeckt 12.09.2008: Nutzt man die &amp;quot;Tastensperre&amp;quot; (Shutdown bei aktiviertem GPS LOG), so treten Fehler bei der Aufzeichnung auf. Dies wird weiter untersucht, wenn ich mehr Zeit habe.&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Achtung:&#039;&#039; Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
Für das Rechnen mit Koordinaten benutze ich hauptsächlich eine Funktion:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t calculate_distance (gps_coords *a, gps_coords *b)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t latstate = 0;&lt;br /&gt;
  uint32_t lat_distance;&lt;br /&gt;
  if(a-&amp;gt;lat &amp;gt; b-&amp;gt;lat)&lt;br /&gt;
  {&lt;br /&gt;
    latstate = 1;&lt;br /&gt;
    lat_distance = a-&amp;gt;lat - b-&amp;gt; lat;&lt;br /&gt;
  }&lt;br /&gt;
  else lat_distance = b-&amp;gt;lat - a-&amp;gt;lat;&lt;br /&gt;
  lat_distance = mul32_16u(div32u(lat_distance,100),11112);	// * 10^7 * 10^-2 *10^-1= *10^4 meters&lt;br /&gt;
  lat_distance = div32u(lat_distance, 10000);&lt;br /&gt;
  uint16_t distance_cache = lat_distance;			&lt;br /&gt;
  lat_distance = mul32_16u(lat_distance, lat_distance);		// square of lat_distance&lt;br /&gt;
&lt;br /&gt;
  uint8_t lonstate = 0;&lt;br /&gt;
  uint32_t lon_distance;&lt;br /&gt;
  if(a-&amp;gt;lon &amp;gt; b-&amp;gt;lon)&lt;br /&gt;
  {&lt;br /&gt;
    lonstate = 1;&lt;br /&gt;
    lon_distance = a-&amp;gt;lon - b-&amp;gt;lon;&lt;br /&gt;
  }&lt;br /&gt;
  else lon_distance = b-&amp;gt;lon - a-&amp;gt;lon;&lt;br /&gt;
  /* square(((lon_diff / 1000) * cos_val * 1113) / 10000) = lon_diff * 111,3 * cos(angle)*/&lt;br /&gt;
  lon_distance = mul32_16u(div32u(lon_distance, 1000), my_cos(div32u(labs(a-&amp;gt;lat),10000000)));  //-&amp;gt;10^6  // simplification:&lt;br /&gt;
                                              //a-&amp;gt;lat instead of a-&amp;gt;lat+b-&amp;gt;lat/2&lt;br /&gt;
  lon_distance = div32u(mul32_16u(lon_distance, 1113),10000); // -&amp;gt;meters&lt;br /&gt;
  lon_distance = isqrt32(mul32_16u(lon_distance, lon_distance) + lat_distance);&lt;br /&gt;
  uint8_t temp_angle = (my_acos(div32u(mul32_16u(distance_cache,100),lon_distance)) * 100) &amp;gt;&amp;gt; 8;	// 0-90 deg. angle&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  if(latstate)&lt;br /&gt;
  {&lt;br /&gt;
    if(lonstate) temp_angle +=70;&lt;br /&gt;
    else temp_angle = 70 - temp_angle;&lt;br /&gt;
  }&lt;br /&gt;
  else if(lonstate)&lt;br /&gt;
    temp_angle = 140 - temp_angle;&lt;br /&gt;
  &lt;br /&gt;
 return (lon_distance) | ((uint32_t)temp_angle &amp;lt;&amp;lt; 16);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Zusammenarbeit mit einfachsten, auf Tabellen basierenden Kosinus- und Umkehrfunktion liefert diese Ergebnisse mit meistens nicht einmal 2 % Abweichung. Der Ablauf:&lt;br /&gt;
# Breitendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Längendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Nach dem Satz des Pythagoras den Abstand der Punkte bestimmen, Länge und Breite stehen dabei für orthogonale Vektoren, somit haben wir ein rechtwinkliges Dreieck&lt;br /&gt;
# Da wir hier gleich alle Seiten berechnet haben, kann einfach der Winkel zwischen Ankathete und Hypothenuse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
Der Winkel muss zum Schluss noch korrigiert werden, jenachdem, in welchem Quadranten (Koordinate a als Ursprung und b als Punkt im 2 dimensionalen Koordinatensystem betrachtet) wir uns befinden.&lt;br /&gt;
Diese Funktion liefert für alle Punkte, die nicht mehr als 65535 Meter auseinander liegen korrekte Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variable Anzahl).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 4 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;0 - allgemeine GPS Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;1 - GPS Logger Funktionen&#039;&#039;&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1, 16, 128, 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;2 - Wegpunkt Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei (Erneuter Aufruf: Nächste Wegpunkt Datei öffnen)&lt;br /&gt;
** 1* - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 an ist, sind es 2048 Meter Schritte.&lt;br /&gt;
** 2* - Erster Aufruf: Anzeige des Kurses zum Wegpunkt relativ zur Bewegungsrichtung&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts (bzw. rückwärts sofern die Option angewählt ist) in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der aktuell annavigierte Punkt weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
** LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
     * Für 1 und 2 gilt: Erneuter Aufruf springt zum nachfolgenden Wegpunkt.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;3 - Wegpunkte einspeichern&#039;&#039;&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkt Datei und gibt die Nummer binär aus. Die Wegpunktdatei kann parallel zum GPS Log erstellt &amp;amp; abgespeichert werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;4 - Allgemeine Optionen&#039;&#039;&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 700 ms muss sie losgelassen und nach weiteren 400 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt. (LED 5 und 6 geben den ungefähren Batteriestatus wieder. 6 ist voll, 5 ist fast leer (max. 30 Minuten GPS verbleibend). Sind beide LEDs aus, so wird das GPS Modul bis zum Aufladen deaktiviert.)&lt;br /&gt;
&lt;br /&gt;
== PC Interaktion ==&lt;br /&gt;
Für den PC habe ich bereits einfachste Übertragungsprogramme geschrieben, welche jedoch zur Zeit noch ungetestet und stark aufs Debugging ausgelegt sind. Diese werden erst zu späterer Zeit veröffentlicht.&lt;br /&gt;
[[http://www.gpsbabel.org/ GPS Babel]] eignet sich wunderbar, um ausgelesene Daten in ein Google Earth kompatibles Format umzuwandeln, um sich z.B. die GPS Logs anzusehen. Auch können in Google Earth erstellte Pfade so als Waylist für den Mini Navigator umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;br /&gt;
[[Category:GPS|G]]&lt;br /&gt;
[[Category:Projekte|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=31088</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=31088"/>
		<updated>2008-09-15T16:54:55Z</updated>

		<summary type="html">&lt;p&gt;Matze88: Rechtschreibung, verschönerung und ein paar Details&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(Achtung: Diesen Artikel habe ich nach Wettbewerbsschluss noch bearbeitet, bitte beachtet beim Bewerten, dass ihr euch die alte Version anschaut. Danke)&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, in dem die meiste Arbeit steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts:&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.3.zip| GPS Mini Navigator Version beta 0.3]]&lt;br /&gt;
&lt;br /&gt;
Behobene Fehler:&lt;br /&gt;
* Falscher Variablentyp verhinderte ein Anzeigen von Distanzen &amp;gt; 255 Metern&lt;br /&gt;
* Dezimalausgabe (genutzt von GPS Länge, Breite, Höhe) wurde direkt wieder überschrieben&lt;br /&gt;
* Bugreport 12.09.2008 bezügl. Tastensperre war fehlerhaft; Der Fehler trat durch eine bereits behobene Endlosschleife auf.&lt;br /&gt;
&lt;br /&gt;
Bekannte Fehler:&lt;br /&gt;
* Abspeichern falscher Werte als Wegpunkt (siehe b0.2)&lt;br /&gt;
* Öffnen der Wegpunktdatei 0xFF (siehe b0.2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.2.zip| GPS Mini Navigator Version beta 0.2]]&lt;br /&gt;
&lt;br /&gt;
Behobene Fehler:&lt;br /&gt;
* Wiedereinschalten aus dem Standby wurde nicht ausreichend überprüft. (Achtung. Verändertes Timing beim Einschalten, siehe Changelog)&lt;br /&gt;
* Fehler beim Laden der nächsten Waypoint Datei, sofern rückwärts navigieren aktiviert und zuvor die letzte Waypoint Datei geladen war führte zu einer Endlosschleife.&lt;br /&gt;
&lt;br /&gt;
Bekannte Fehler:&lt;br /&gt;
* Race Condition: Mit einer SEHR geringen Wahrscheinlichkeit wird beim Wegpunkte abspeichern ein völlig falscher Wert gespeichert, falls der GPS Interrupt gerade die Positionsdaten aktualisiert UND dabei gerade eine Wertänderung stattfindet, die nicht nur das letzte Byte betrifft. Die Wahrscheinlichkeit ist so enorm gering (Ich habs noch nicht ausgerechnet, aber sie dürfte weit unter 1:1 Million liegen), dass ein Fix (-&amp;gt; Zugriffssperre) zur Zeit noch nicht lohnt, erstmal sind wichtigere Sachen (z.B. PC Software) dran.&lt;br /&gt;
* Nach der letzten Wegpunktdatei wird die Datei 0xFF geöffnet als Schutz vor einer Endlosschleife (falls keine Wegpunktdatei existiert). Weitere Überprüfungen notwendig, sodass wieder bei der ersten Wegpunktdatei begonnen wird.&lt;br /&gt;
* Entdeckt 12.09.2008: Nutzt man die &amp;quot;Tastensperre&amp;quot; (Shutdown bei aktiviertem GPS LOG), so treten Fehler bei der Aufzeichnung auf. Dies wird weiter untersucht, wenn ich mehr Zeit habe.&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Achtung:&#039;&#039; Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
Für das Rechnen mit Koordinaten benutze ich hauptsächlich eine Funktion:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t calculate_distance (gps_coords *a, gps_coords *b)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t latstate = 0;&lt;br /&gt;
  uint32_t lat_distance;&lt;br /&gt;
  if(a-&amp;gt;lat &amp;gt; b-&amp;gt;lat)&lt;br /&gt;
  {&lt;br /&gt;
    latstate = 1;&lt;br /&gt;
    lat_distance = a-&amp;gt;lat - b-&amp;gt; lat;&lt;br /&gt;
  }&lt;br /&gt;
  else lat_distance = b-&amp;gt;lat - a-&amp;gt;lat;&lt;br /&gt;
  lat_distance = mul32_16u(div32u(lat_distance,100),11112);	// * 10^7 * 10^-2 *10^-1= *10^4 meters&lt;br /&gt;
  lat_distance = div32u(lat_distance, 10000);&lt;br /&gt;
  uint16_t distance_cache = lat_distance;			&lt;br /&gt;
  lat_distance = mul32_16u(lat_distance, lat_distance);		// square of lat_distance&lt;br /&gt;
&lt;br /&gt;
  uint8_t lonstate = 0;&lt;br /&gt;
  uint32_t lon_distance;&lt;br /&gt;
  if(a-&amp;gt;lon &amp;gt; b-&amp;gt;lon)&lt;br /&gt;
  {&lt;br /&gt;
    lonstate = 1;&lt;br /&gt;
    lon_distance = a-&amp;gt;lon - b-&amp;gt;lon;&lt;br /&gt;
  }&lt;br /&gt;
  else lon_distance = b-&amp;gt;lon - a-&amp;gt;lon;&lt;br /&gt;
  /* square(((lon_diff / 1000) * cos_val * 1113) / 10000) = lon_diff * 111,3 * cos(angle)*/&lt;br /&gt;
  lon_distance = mul32_16u(div32u(lon_distance, 1000), my_cos(div32u(labs(a-&amp;gt;lat),10000000)));  //-&amp;gt;10^6  // simplification:&lt;br /&gt;
                                              //a-&amp;gt;lat instead of a-&amp;gt;lat+b-&amp;gt;lat/2&lt;br /&gt;
  lon_distance = div32u(mul32_16u(lon_distance, 1113),10000); // -&amp;gt;meters&lt;br /&gt;
  lon_distance = isqrt32(mul32_16u(lon_distance, lon_distance) + lat_distance);&lt;br /&gt;
  uint8_t temp_angle = (my_acos(div32u(mul32_16u(distance_cache,100),lon_distance)) * 100) &amp;gt;&amp;gt; 8;	// 0-90 deg. angle&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  if(latstate)&lt;br /&gt;
  {&lt;br /&gt;
    if(lonstate) temp_angle +=70;&lt;br /&gt;
    else temp_angle = 70 - temp_angle;&lt;br /&gt;
  }&lt;br /&gt;
  else if(lonstate)&lt;br /&gt;
    temp_angle = 140 - temp_angle;&lt;br /&gt;
  &lt;br /&gt;
 return (lon_distance) | ((uint32_t)temp_angle &amp;lt;&amp;lt; 16);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Zusammenarbeit mit einfachsten, auf Tabellen basierenden Kosinus- und Umkehrfunktion liefert diese Ergebnisse mit meistens nicht einmal 2 % Abweichung. Der Ablauf:&lt;br /&gt;
# Breitendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Längendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Nach dem Satz des Pythagoras den Abstand der Punkte bestimmen, Länge und Breite stehen dabei für orthogonale Vektoren, somit haben wir ein rechtwinkliges Dreieck&lt;br /&gt;
# Da wir hier gleich alle Seiten berechnet haben, kann einfach der Winkel zwischen Ankathete und Hypothenuse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
Der Winkel muss zum Schluss noch korrigiert werden, jenachdem, in welchem Quadranten (Koordinate a als Ursprung und b als Punkt im 2 dimensionalen Koordinatensystem betrachtet) wir uns befinden.&lt;br /&gt;
Diese Funktion liefert für alle Punkte, die nicht mehr als 65535 Meter auseinander liegen korrekte Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variable Anzahl).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 4 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;0 - allgemeine GPS Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;1 - GPS Logger Funktionen&#039;&#039;&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1, 16, 128, 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;2 - Wegpunkt Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei (Erneuter Aufruf: Nächste Wegpunkt Datei öffnen)&lt;br /&gt;
** 1* - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 an ist, sind es 2048 Meter Schritte.&lt;br /&gt;
** 2* - Erster Aufruf: Anzeige des Kurses zum Wegpunkt relativ zur Bewegungsrichtung&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts (bzw. rückwärts sofern die Option angewählt ist) in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der aktuell annavigierte Punkt weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
** LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
     * Für 1 und 2 gilt: Erneuter Aufruf springt zum nachfolgenden Wegpunkt.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;3 - Wegpunkte einspeichern&#039;&#039;&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkt Datei und gibt die Nummer binär aus. Die Wegpunktdatei kann parallel zum GPS Log erstellt &amp;amp; abgespeichert werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;4 - Allgemeine Optionen&#039;&#039;&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 700 ms muss sie losgelassen und nach weiteren 400 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt&lt;br /&gt;
&lt;br /&gt;
(LED 5 und 6 geben den Batteriestatus wieder. 6 ist voll, 5 ist fast leer und garnichts steht für leer)&lt;br /&gt;
&lt;br /&gt;
== PC Interaktion ==&lt;br /&gt;
Für den PC habe ich bereits einfachste Übertragungsprogramme geschrieben, welche jedoch zur Zeit noch ungetestet und stark aufs Debugging ausgelegt sind. Diese werden erst zu späterer Zeit veröffentlicht.&lt;br /&gt;
[[http://www.gpsbabel.org/ GPS Babel]] eignet sich wunderbar, um ausgelesene Daten in ein Google Earth kompatibles Format umzuwandeln, um sich z.B. die GPS Logs anzusehen. Auch können in Google Earth erstellte Pfade so als Waylist für den Mini Navigator umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;br /&gt;
[[Category:GPS|G]]&lt;br /&gt;
[[Category:Projekte|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:GPSMiniNavigatorb0.3.zip&amp;diff=31087</id>
		<title>Datei:GPSMiniNavigatorb0.3.zip</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:GPSMiniNavigatorb0.3.zip&amp;diff=31087"/>
		<updated>2008-09-15T16:48:37Z</updated>

		<summary type="html">&lt;p&gt;Matze88: GPS Mini Navigator Software Version beta 0.3
für Lizenz und Changelog siehe im Zip-Archiv&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GPS Mini Navigator Software Version beta 0.3&lt;br /&gt;
für Lizenz und Changelog siehe im Zip-Archiv&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=31086</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=31086"/>
		<updated>2008-09-15T16:47:17Z</updated>

		<summary type="html">&lt;p&gt;Matze88: /* Software */ Release b0.3&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(Achtung: Diesen Artikel habe ich nach Wettbewerbsschluss noch bearbeitet, bitte beachtet beim Bewerten, dass ihr euch die alte Version anschaut. Danke)&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, in dem die meiste Arbeit steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts:&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.3.zip| GPS Mini Navigator Version beta 0.3]]&lt;br /&gt;
&lt;br /&gt;
Behobene Fehler:&lt;br /&gt;
* Falscher Variablentyp verhinderte ein Anzeigen von Distanzen &amp;gt; 255 Metern&lt;br /&gt;
* Dezimalausgabe (genutzt von GPS Länge, Breite, Höhe) wurde direkt wieder überschrieben&lt;br /&gt;
* Bugreport 12.09.2008 bezügl. Tastensperre war fehlerhaft; Der Fehler trat durch eine bereits behobene Endlosschleife auf.&lt;br /&gt;
&lt;br /&gt;
Bekannte Fehler:&lt;br /&gt;
* Abspeichern falscher Werte als Wegpunkt (siehe b0.2)&lt;br /&gt;
* Öffnen der Wegpunktdatei 0xFF (siehe b0.2)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.2.zip| GPS Mini Navigator Version beta 0.2]]&lt;br /&gt;
&lt;br /&gt;
Behobene Fehler:&lt;br /&gt;
* Wiedereinschalten aus dem Standby wurde nicht ausreichend überprüft. (Achtung. Verändertes Timing beim Einschalten, siehe Changelog)&lt;br /&gt;
* Fehler beim Laden der nächsten Waypoint Datei, sofern rückwärts navigieren aktiviert und zuvor die letzte Waypoint Datei geladen war führte zu einer Endlosschleife.&lt;br /&gt;
&lt;br /&gt;
Bekannte Fehler:&lt;br /&gt;
* Race Condition: Mit einer SEHR geringen Wahrscheinlichkeit wird beim Wegpunkte abspeichern ein völlig falscher Wert gespeichert, falls der GPS Interrupt gerade die Positionsdaten aktualisiert UND dabei gerade eine Wertänderung stattfindet, die nicht nur das letzte Byte betrifft. Die Wahrscheinlichkeit ist so enorm gering (Ich habs noch nicht ausgerechnet, aber sie dürfte weit unter 1:1 Million liegen), dass ein Fix (-&amp;gt; Zugriffssperre) zur Zeit noch nicht lohnt, erstmal sind wichtigere Sachen (z.B. PC Software) dran.&lt;br /&gt;
* Nach der letzten Wegpunktdatei wird die Datei 0xFF geöffnet als Schutz vor einer Endlosschleife (falls keine Wegpunktdatei existiert). Weitere Überprüfungen notwendig, sodass wieder bei der ersten Wegpunktdatei begonnen wird.&lt;br /&gt;
* Entdeckt 12.09.2008: Nutzt man die &amp;quot;Tastensperre&amp;quot; (Shutdown bei aktiviertem GPS LOG), so treten Fehler bei der Aufzeichnung auf. Dies wird weiter untersucht, wenn ich mehr Zeit habe.&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Achtung:&#039;&#039; Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
Für das Rechnen mit Koordinaten benutze ich hauptsächlich eine Funktion:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t calculate_distance (gps_coords *a, gps_coords *b)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t latstate = 0;&lt;br /&gt;
  uint32_t lat_distance;&lt;br /&gt;
  if(a-&amp;gt;lat &amp;gt; b-&amp;gt;lat)&lt;br /&gt;
  {&lt;br /&gt;
    latstate = 1;&lt;br /&gt;
    lat_distance = a-&amp;gt;lat - b-&amp;gt; lat;&lt;br /&gt;
  }&lt;br /&gt;
  else lat_distance = b-&amp;gt;lat - a-&amp;gt;lat;&lt;br /&gt;
  lat_distance = mul32_16u(div32u(lat_distance,100),11112);	// * 10^7 * 10^-2 *10^-1= *10^4 meters&lt;br /&gt;
  lat_distance = div32u(lat_distance, 10000);&lt;br /&gt;
  uint16_t distance_cache = lat_distance;			&lt;br /&gt;
  lat_distance = mul32_16u(lat_distance, lat_distance);		// square of lat_distance&lt;br /&gt;
&lt;br /&gt;
  uint8_t lonstate = 0;&lt;br /&gt;
  uint32_t lon_distance;&lt;br /&gt;
  if(a-&amp;gt;lon &amp;gt; b-&amp;gt;lon)&lt;br /&gt;
  {&lt;br /&gt;
    lonstate = 1;&lt;br /&gt;
    lon_distance = a-&amp;gt;lon - b-&amp;gt;lon;&lt;br /&gt;
  }&lt;br /&gt;
  else lon_distance = b-&amp;gt;lon - a-&amp;gt;lon;&lt;br /&gt;
  /* square(((lon_diff / 1000) * cos_val * 1113) / 10000) = lon_diff * 111,3 * cos(angle)*/&lt;br /&gt;
  lon_distance = mul32_16u(div32u(lon_distance, 1000), my_cos(div32u(labs(a-&amp;gt;lat),10000000)));  //-&amp;gt;10^6  // simplification:&lt;br /&gt;
                                              //a-&amp;gt;lat instead of a-&amp;gt;lat+b-&amp;gt;lat/2&lt;br /&gt;
  lon_distance = div32u(mul32_16u(lon_distance, 1113),10000); // -&amp;gt;meters&lt;br /&gt;
  lon_distance = isqrt32(mul32_16u(lon_distance, lon_distance) + lat_distance);&lt;br /&gt;
  uint8_t temp_angle = (my_acos(div32u(mul32_16u(distance_cache,100),lon_distance)) * 100) &amp;gt;&amp;gt; 8;	// 0-90 deg. angle&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  if(latstate)&lt;br /&gt;
  {&lt;br /&gt;
    if(lonstate) temp_angle +=70;&lt;br /&gt;
    else temp_angle = 70 - temp_angle;&lt;br /&gt;
  }&lt;br /&gt;
  else if(lonstate)&lt;br /&gt;
    temp_angle = 140 - temp_angle;&lt;br /&gt;
  &lt;br /&gt;
 return (lon_distance) | ((uint32_t)temp_angle &amp;lt;&amp;lt; 16);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Zusammenarbeit mit einfachsten, auf Tabellen basierenden Kosinus- und Umkehrfunktion liefert diese Ergebnisse mit meistens nicht einmal 2 % Abweichung. Der Ablauf:&lt;br /&gt;
# Breitendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Längendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Nach dem Satz des Pythagoras den Abstand der Punkte bestimmen, Länge und Breite stehen dabei für orthogonale Vektoren, somit haben wir ein rechtwinkliges Dreieck&lt;br /&gt;
# Da wir hier gleich alle Seiten berechnet haben, kann einfach der Winkel zwischen Ankathete und Hypothenuse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
Der Winkel muss zum Schluss noch korrigiert werden, jenachdem, in welchem Quadranten (Koordinate a als Ursprung und b als Punkt im 2 dimensionalen Koordinatensystem betrachtet) wir uns befinden.&lt;br /&gt;
Diese Funktion liefert für alle Punkte, die nicht mehr als 65535 Meter auseinander liegen korrekte Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variabel, bis zu 5).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 5 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;0 - allgemeine GPS Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;1 - GPS Logging Funktionen&#039;&#039;&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1 16 128 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;2 - Wegpunkt Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei (Erneuter Aufruf: Nächste Wegpunkt Datei öffnen)&lt;br /&gt;
** 1* - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 = 1 sind es 2048 Meter Schritte.&lt;br /&gt;
** 2* - Erster Aufruf: Anzeige des Kurses zum Wegpunkt. LED 0 ist dabei die Bewegungsrichtung.&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der jetzige weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
** LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
     * Für 1 und 2 gilt: Erneuter Aufruf navigiert den nachfolgenden Wegpunkt an.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;3 - Wegpunkte einspeichern&#039;&#039;&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkte Datei und gibt die Nummer binär aus. Diese Schreibzugriffe können parallel zum GPS Log durchgeführt werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;4 - Allgemeine Optionen&#039;&#039;&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 700 ms muss sie losgelassen und nach weiteren 400 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt.&lt;br /&gt;
** (LED 5 und 6 geben den Batteriestatus wieder. 6 ist voll, 5 ist fast leer und garnichts steht für leer)&lt;br /&gt;
&lt;br /&gt;
== PC Interaktion ==&lt;br /&gt;
Für den PC habe ich bereits einfachste Übertragungsprogramme geschrieben, welche jedoch zur Zeit noch ungetestet und stark aufs Debugging ausgelegt sind. Diese werden erst zu späterer Zeit veröffentlicht.&lt;br /&gt;
[[http://www.gpsbabel.org/ GPS Babel]] eignet sich wunderbar, um ausgelesene Daten in ein Google Earth kompatibles Format umzuwandeln, um sich z.B. die GPS Logs anzusehen. Auch können in Google Earth erstellte Pfade so als Waylist für den Mini Navigator umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;br /&gt;
[[Category:GPS|G]]&lt;br /&gt;
[[Category:Projekte|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Interrupt&amp;diff=31077</id>
		<title>Interrupt</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Interrupt&amp;diff=31077"/>
		<updated>2008-09-15T10:28:04Z</updated>

		<summary type="html">&lt;p&gt;Matze88: Änderung 31076 von 91.57.253.196 (Diskussion) wurde rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Bei bestimmten Ereignissen in Prozessoren wird ein &#039;&#039;&#039;Interrupt&#039;&#039;&#039; ausgelöst. Dabei wird das Programm unterbrochen und ein Unterprogramm, die sogenannte &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;S&#039;&#039;&#039;ervice &#039;&#039;&#039;R&#039;&#039;&#039;outine (&#039;&#039;&#039;ISR&#039;&#039;&#039;), aufgerufen. Wenn dieses beendet ist läuft das Hauptprogramm ganz normal weiter.&lt;br /&gt;
&lt;br /&gt;
Bei [[Mikrocontroller]]n werden Interrupts z.B. ausgelöst wenn:&lt;br /&gt;
* sich der an einem bestimmten Eingangs-Pin anliegende Pegel ändert&lt;br /&gt;
* eine vorher festgelegte Zeitspanne abgelaufen ist ([[Timer]])&lt;br /&gt;
* eine [[Seriell|serielle]] Übertragung abgeschlossen ist&lt;br /&gt;
* eine Messung des [[ADC |Analog-Digital-Wandlers]] abgeschlossen ist&lt;br /&gt;
&lt;br /&gt;
== Wichtige Eigenschaften von ISRs ==&lt;br /&gt;
&lt;br /&gt;
ISRs reagieren auf ein bestimmtes Ereignis, welches relativ oft oder selten passiert. Prinzipiell sollte man ISRs möglichst kurz halten und schnell beenden. &#039;&#039;&#039;Im Mittel muss die Interruptroutine kürzer sein als die Periodendauer des Ereignises, anderenfalls wird es passieren, dass Interrupts &amp;quot;verschluckt&amp;quot; werden&#039;&#039;&#039;, d.h. beim UART gehen Daten verloren, beim Timer gehen Zählzyklen verloren, beim AD-Wandler gehen Daten verloren etc. &#039;&#039;&#039;Solche verschluckten Interrupts sind bisweilen schwer zu finden, weil es nur sehr wenige in ganz bestimmten Konstellationen sind.&#039;&#039;&#039; Wenn dann eine per Timer realisierte Uhr in der Stunde um 1s falsch geht, merkt man das oft nicht. &#039;&#039;&#039;Langwierige Berechnungen, Auswertungen, Ausgaben oder gar Warteschleifen haben in ISRs nichts zu suchen.&#039;&#039;&#039; Typische C-Funktionen wie printf(), scanf(), längere Ausgaben auf ein [[LCD]] etc. sollte man nicht in ISRs vornehmen. Hier kommt sinnvollerweise eine andere Programmiertechnik zu Einsatz, nämlich die Übergabe von Parametern bzw. Steuersignalen an das Hauptprogramm.&lt;br /&gt;
&lt;br /&gt;
=== Interruptsteuerung ===&lt;br /&gt;
&lt;br /&gt;
Interrupts müssen wie alle anderen Module und Funktionen eines Mikrocontrollers gesteuert werden. Dazu wird auf praktisch allen Mikrocontrollern ein zweistufiges System verwendet.&lt;br /&gt;
* Globale Interruptsteuerung über ein CPU-Statusbit: Beim [[AVR]] ist das das I-Bit (Interrupt) im Statusregister (SREG). Dieses Bit wirkt wie ein Hauptschalter und kann global die Ausführung aller Interrupts ein - und ausschalten. Das heisst aber nicht, dass während der Zeit der inaktiven Interrupts diese verloren gehen. Vielmehr wird das jeweilige Interruptbit gesetzt, und wenn die Interrupts wieder freigegeben werden wird der Interrupt ausgeführt. Verloren gehen Interrupts erst dann, wenn die Sperrzeit zu gross ist und währenddessen mehr als ein Interrupt vom selben Typ eintrifft. Siehe [[# Zeitverhalten eines Timerinterrupts]] und [[#Zeitverhalten des UART Empfangsinterrupt]]&lt;br /&gt;
* Lokale Interruptsteuerung für jede einzelne Interruptquelle über Maskenbits in mehreren Interruptmaskenregistern. Hier kann jede einzelne Interruptquelle individuell ein- und ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
Dieses System hat eine Reihe von Vorteilen. So können sehr schnell und einfach alle Interrupts kurzzeitig gesperrt werden, wenn beispielsweise [[#Atomarer Datenzugriff | atomare]] Operationen durchgeführt werden sollen, oder besonders zeitkritische Abläufe ausgeführt werden. Danach können alle konfigurierten Interrupts einfach wieder freigeschaltet werden, ohne dass die CPU viele verschiedene Interruptmaskenbits verwalten müsste.&lt;br /&gt;
&lt;br /&gt;
Eine ISR wird demnach nur dann ausgeführt, wenn&lt;br /&gt;
* die Interrupts global freigeschaltet sind&lt;br /&gt;
* das individuelle Maskenbit gesetzt ist&lt;br /&gt;
* der Interrupt eintritt&lt;br /&gt;
&lt;br /&gt;
=== Verschachtelte Interrupts ===&lt;br /&gt;
&lt;br /&gt;
Einige Mikrocontroller, wie z.B. der [[AVR]] kennen nur zwei CPU-Zustände. Normale Programmausführung und Interruptausführung, gesteuert durch das I-Bit der CPU. Die normale Programmausführung kann jederzeit durch Interrupts unterbrochen werden. Die Interruptausführung kann nicht durch neue Interrupts unterbrochen werden. Die ISR wird erst zu Ende bearbeitet, zurück in die normale Programmausführung gesprungen und erst dann werden neue, wartende (engl. pending) Interrupts bearbeitet.&lt;br /&gt;
&lt;br /&gt;
Etwas komplexere Mikrocontroller oder große Prozessoren bieten verschiedene Interruptlevel (Stufen) an . Dabei gilt meist je niedriger die Zahl des Levels, um so höher die Priorität. Ein Interrupt mit höherer Priorität kann einen Interrupt mit niedriger Priorität unterbrechen. Ein Interrupt mit gleicher Priorität wie der gerade bearbeitete Interrupt kann das im allgemeinen nicht. Das nennt man verschachtelte Interrupts (engl. nested interrupts). Klassische Vertreter hierfür sind [[8051]], PowerPC, [[X86]] und Motorola 68000.&lt;br /&gt;
&lt;br /&gt;
Auf dem AVR kann man [[AVR-GCC-Tutorial#Unterbrechbare_Interruptroutinen | verschachtelte Interrupts]] sowohl in Assembler als auch in C nachbilden, allerdings mit einigen Einschränkungen und Tücken. Das ist jedoch Leuten vorbehalten, die schon viel Erfahrung auf diesem Gebiet haben. Zu 99,9% braucht man sie nicht.&lt;br /&gt;
&lt;br /&gt;
=== Zeitverhalten eines Timerinterrupts ===&lt;br /&gt;
&lt;br /&gt;
Ein Timerinterrupt wird im allgemeinen dazu genutzt, in konstanten, periodischen Abständen bestimmte Funktionen aufzurufen. Es ist möglich, dass während eines Timerinterrupts derselbe Interrupt wieder aktiv wird, weil die Routine sehr verzweigt ist und dieses Mal sehr lange dauert.&lt;br /&gt;
&lt;br /&gt;
Wenn zum Beispiel der Timerinterrupt mit einer Periodendauer von 100ms aufgerufen wird, er aber unter bestimmten Umständen 180ms benötigt, dann wird nach 100ms nach Eintritt in die ISR der Interrupt wieder aktiv, das Timer Interrupt Flag wird gesetzt. Da aber gerade ein Interrupt bearbeitet wird, wird er nicht sofort angesprungen, weil währenddessen die Interruptfunktion global gesperrt ist (beim AVR ist das I-Bit in der CPU gelöscht). Der Interrupt wird zu Ende bearbeitet, die CPU springt zurück zum Hauptprogramm. Dabei werden die Interrupts wieder global eingeschaltet. Der zwischenzeitlich eingetroffene und zwischengespeicherte Interrupt wird nun sofort ausgeführt, sodass das Hauptprogramm praktisch gar nicht weiter kommt, bestenfalls einen Maschinenbefehl. Nun sind aber nur noch 20ms bis zum nächsten Timerinterrupt übrig. Wenn dieser nun wieder 180 ms benötigt werden in dieser Zeit aber &#039;&#039;&#039;zwei&#039;&#039;&#039; Interrupts ausgelöst, nach 20ms und 120ms. Da diese aber nicht gezählt oder andersweitig einzeln gespeichert werden können, geht ein Interrupt verloren. Das ist ein Programmfehler.&lt;br /&gt;
&lt;br /&gt;
=== Zeitverhalten des UART Empfangsinterrupts ===&lt;br /&gt;
&lt;br /&gt;
Ein [[UART]] Interrupt zum Empfang von Daten per [[RS232]] mit 115200 [[Baud]] ist ein recht häufiges Ereignis (1 Zeichen = 10 Bits = 86,8&amp;amp;mu;s). Wenn kontinuierlich Daten empfangen werden, wird nach jeweils 86,8&amp;amp;mu;s ein neuer Interrupt ausgelöst. Dabei wird das empfangene Datenbyte vom UART aus dem Empfangsschiebegregister in einem Puffer kopiert. Während das neue Zeichen Bit für Bit empfangen wird, wird es zunächst im Schieberegister des UART gespeichert. Die Daten im Puffer bleiben davon unberührt. Die CPU muss nun schnell das empfangene Datenbyte aus dem Empfangsbuffer auslesen. Die maximale Verzögerung, die sich die CPU erlauben kann von der Aktivierung des Interrupts bis zum tatsächlichen Auslesen des Datenregisters beträgt ziemlich genau die Übertragungszeit von einem Zeichen. Wenn bis dahin nicht das Zeichen von der CPU ausgelesen wurde, wird es vom UART überschrieben und ein Fehler im Statusregister des UART signalisiert (Overrun, Überlauf des Datenpuffers). Die UARTs in heutigen Mikrocontrollern haben mindestens ein Byte Puffer wie hier beschrieben. Die neueren [[AVR]]s haben sogar effektiv 3 Byte Puffer im UART, praktisch ein kleines [[FIFO]], womit der Datenempfang besser gepuffert werden kann, wenn die CPU gerade mit anderen sehr wichtigen Dingen beschäftigt ist. D.h. kurzzeitig kann sich die CPU erlauben, die Übertragungszeit von bis zu drei Zeichen zu warten, ehe sie die Daten ausliest. Dann müssen sie aber sehr schnell hintereinander gelesen werden. Im Mittel hat die CPU aber nur die Übertragungszeit eines Zeichens zur Verfügung, um es abzuholen.&lt;br /&gt;
&lt;br /&gt;
=== Zusammenfassung ===&lt;br /&gt;
&lt;br /&gt;
Interruptserviceroutinen:&lt;br /&gt;
* sollten so kurz wie möglich gehalten werden&lt;br /&gt;
* können im Einzelfall nahezu doppelt so lange dauern wie die kürzeste Periodendauer des Ereignisses, ohne dass Interrupts verloren gehen (z.B. Timerinterrupt).&lt;br /&gt;
* dürfen im Mittel maximal solange dauern wie die kürzeste Periodendauer des Ereignisses&lt;br /&gt;
* dürfen maximal solange dauern, wie die kürzeste Periodendauer des Ereignisses, wenn man auf Nummer sicher gehen will, dass keine Interrupts verschluckt werden&lt;br /&gt;
* Die Interruptzeit versteht sich immer abzüglich einer kleinen Reserve für das Anspringen und Verlassen des Interrupt minus Panikreserve&lt;br /&gt;
&lt;br /&gt;
== Beispiele für die praktische Programmierung ==&lt;br /&gt;
&lt;br /&gt;
Die Beispiele sind mit WINAVR 20060421 compiliert und getestet worden. Als Mikrocontroller wird ein AVR vom Typ ATmega32 verwendet. Alle Programme wurden mit Optimierungsstufe -Os compiliert.&lt;br /&gt;
&lt;br /&gt;
=== Steuersignale zwischen ISR und Hauptprogramm ===&lt;br /&gt;
&lt;br /&gt;
In vielen Anwendungen wird ein Timer verwendet, um in regelmässigen Abständen bestimmte Aktionen auszuführen, wie z.B. Tasten abfragen, ADC-auslesen, ein LCD auffrischen etc. Wenn viele Dinge zu erledigen sind, nebenbei aber noch andere Interrupts verwendet werden, dann ist es notwendig die Funktionsaufrufe aus dem Timerinterrupt in die Hauptschleife zu verlagern. Der Interrupt signalisiert über eine Steuervariable (engl. Flag, Flagge), das ein neuer Timerzyklus begonnen hat. Dadurch wird der Timerinterrupt sehr kurz und die langwierigen, aber meist nicht zeitkritischen Funktionen werden als normales Programm ausgeführt. Damit kann die CPU auf andere Interrupts schnell reagieren.&lt;br /&gt;
&lt;br /&gt;
Wichtig ist auf jeden Fall, dass die Steuervariable, welche in der ISR und in der Hauptschleife verwendet wird, mit [http://www.netrino.com/Embedded-Systems/How-To/C-Volatile-Keyword &#039;&#039;&#039;volatile&#039;&#039;&#039;] deklariert wird. Ausserdem muss sowohl der Lese- als auch Schreibzugriff auf die Steuersignale [[#Atomarer Datenzugriff | &#039;&#039;&#039;atomar&#039;&#039;&#039;]] sein. Auf dem AVR ist das mit 8 Bit Variablen direkt möglich, für grössere Variablen müssen die Interrupts kurzzeitig gesperrt werden.&lt;br /&gt;
&lt;br /&gt;
Das Beispiel ist sehr einfach gehalten um das Prinzip zu veranschaulichen. Ein Timer mit einer Überlaufperiodendauer von ca. 65ms stösst periodisch eine Funktion zum Togglen einer LED an, welche dadurch mit ca. 7 Hz blinkt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
*******************************************************************************&lt;br /&gt;
*&lt;br /&gt;
* Timer Interrupt Demo&lt;br /&gt;
*&lt;br /&gt;
* ATmega32 mit internem 1 MHz Oszillator&lt;br /&gt;
*&lt;br /&gt;
* LOW Fuse Byte = 0xE1&lt;br /&gt;
*&lt;br /&gt;
* An PD5 muss eine LED mit 1 kOhm Vorwiderstand angeschlossen werden&lt;br /&gt;
*&lt;br /&gt;
*******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
 &lt;br /&gt;
#define F_CPU 1000000&lt;br /&gt;
 &lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
// globale Variablen&lt;br /&gt;
 &lt;br /&gt;
volatile uint8_t flag;&lt;br /&gt;
 &lt;br /&gt;
int main() {&lt;br /&gt;
 &lt;br /&gt;
// IO konfigurieren&lt;br /&gt;
 &lt;br /&gt;
    DDRA = 0xFF;&lt;br /&gt;
    DDRB = 0xFF;&lt;br /&gt;
    DDRC = 0xFF;&lt;br /&gt;
    DDRD = 0xFF;&lt;br /&gt;
 &lt;br /&gt;
// Timer2 konfigurieren&lt;br /&gt;
 &lt;br /&gt;
    TCCR2  = 6;                     // Vorteiler 256 -&amp;gt; ~65ms Überlaufperiode&lt;br /&gt;
    TIMSK |= (1&amp;lt;&amp;lt;TOIE2);            // Timer Overflow Interrupt freischalten &lt;br /&gt;
 &lt;br /&gt;
// Interrupts freigeben&lt;br /&gt;
 &lt;br /&gt;
    sei();&lt;br /&gt;
 &lt;br /&gt;
// Endlose Hauptschleife&lt;br /&gt;
 &lt;br /&gt;
    while(1) {&lt;br /&gt;
        if (flag == 1) { // Neuer Timerzyklus ?&lt;br /&gt;
            flag = 0;&lt;br /&gt;
 &lt;br /&gt;
            // hier steht jetzt in Normalfall ein grosser Programmblock ;-) &lt;br /&gt;
            PORTD ^= (1 &amp;lt;&amp;lt; PD5);    // LED toggeln&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// Timer2 overflow Interrupt&lt;br /&gt;
// hier wird der Hauptschleife ein neuer Timerinterrupt signalisiert&lt;br /&gt;
 &lt;br /&gt;
ISR( TIMER2_OVF_vect ) {&lt;br /&gt;
    flag = 1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== UART mit Interrupts ===&lt;br /&gt;
&lt;br /&gt;
Der UART ist ein oft benutztes Modul eines Mikrocontrollers. Anfänger nutzen ihn meist im sogenannten Polling Betrieb (engl. to poll, abfragen). D.h. wenn ein Zeichen empfangen werden soll, fragt eine Funktion den UART in einer Schleife ununterbrochen ab, ob Daten empfangen wurden. In dieser Zeit macht die CPU nichts anderes! Und wenn lange kein Zeichen eintrifft tut sie sehr lange nichts, sie ist praktisch blockiert! Senden verläuft ähnlich, nur dass hier die CPU vor dem Senden prüft, ob der UART ein neues Byte aufnehmen kann. D.h. während der UART selbsttätig das Zeichen sendet ist die CPU zum Warten verdammt. All diese Nachteile haben nur einen Vorteil. Die Funktionen und Mechanismen zur UART-Nutzung sind sehr einfach, klein und leicht anwendbar.&lt;br /&gt;
&lt;br /&gt;
Will man aber die CPU nicht sinnlos warten lassen, was vor allem bei niedrigeren Baudraten ziemlich lange sein kann, muss man die Interrupts nutzen. Der AVR hat gleich drei davon.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RXC&#039;&#039;&#039; (Receive Complete): Ein Zeichen wurde empfangen.&lt;br /&gt;
* &#039;&#039;&#039;UDRE&#039;&#039;&#039; (UART Data Register Empty): Der Zwischenpuffer des Senders ist leer und kann ein neues Zeichen aufnehmen. Dieser Zwischenpuffer ist wichtig, um lückenlos auch bei hohen Baudraten senden zu können.&lt;br /&gt;
* &#039;&#039;&#039;TXC&#039;&#039;&#039; (Transmit Complete): Das aktuelle Zeichen wurde vollständig inclusive Stopbit gesendet und es liegt kein neues Datenbyte im Sendepuffer. Dieser Interrupt ist extrem nützlich für eine Halbduplexkommunikation, z.B. auf einem RS485-[[Bus]]. Hier kann man nach dem vollständigen Senden aller Bytes den Bustranceiver (z.B. MAX485) von Senden auf Empfangen umschalten, um den Bus freizugeben.&lt;br /&gt;
&lt;br /&gt;
Bei Nutzung der Interrupts kann die CPU andere Dinge bearbeiten und muss nur kurz einen Interrupt ausführen, wenn ein Zeichen empfangen oder gesendet wurde.&lt;br /&gt;
&lt;br /&gt;
Die Kommunikation zwischen ISRs und Hauptschleife erfolgt wieder durch Flags und zwei Pufferarrays (uart_rx_buffer und uart_tx_buffer). Es gibt zwei Funktionen, eine zum Senden von Strings, eine zum Empfangen. Das Senden sowie Empfangen kann parallel erfolgen und läuft vollkommen unabhängig vom Hauptprogramm. Die Daten werden in spezielle Puffer kopiert, sodass das Hauptprogramm mit seinen Strings sofort weiterarbeiten kann. Im Beispiel ist die CPU nicht wirklich mit sinnvollen Dingen beschäftigt, zur Demonstration des Prinzips aber ausreichend.&lt;br /&gt;
&lt;br /&gt;
Um das das Programm real zu nutzen braucht man ein Terminalprogramm, z.B. Hyperterminal von Windows. Dort muss nur die richtige Baudrate eingestellt werden (9600 8N1, 9600 Baud, 8 Bits, keine Parität, 1 Stopbit, keine Flusskontrolle). Ausserdem muss man im Menu Datei -&amp;gt; Eigenschaften -&amp;gt; Einstellungen -&amp;gt; ASCII Konfiguration den Punkt &amp;quot;Eingegebene Zeichen lokal ausgeben (lokales Echo)&amp;quot; aktivieren. Nun kann man beliebige Texte eintippen. Mit RETURN wird die Eingabe abgeschlossen und der AVR vermittelt den empfangenen String an das Hauptprogramm. Diese sendet ihn einfach zurück, paralle dazu wird der String gemorst per LED angezeigt. Sollte es Probleme bei der Inbetriebnahme des UART geben, so findet man hier wichtige Hinweise zur [[AVR_Checkliste#UART.2FUSART | Fehlersuche]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
*******************************************************************************&lt;br /&gt;
*&lt;br /&gt;
* UART Interrupt Demo&lt;br /&gt;
*&lt;br /&gt;
* ATmega32 mit 3,6864 MHz Quarz an XTAL1/XTAL2&lt;br /&gt;
*&lt;br /&gt;
* LOW Fuse Byte = 0xFF&lt;br /&gt;
*&lt;br /&gt;
* An PD5 muss eine LED mit 1 kOhm Vorwiderstand angeschlossen werden&lt;br /&gt;
* An PD0/PD1 ist ein MAX232 angeschlosssen, um Daten vom PC zu empfangen/senden&lt;br /&gt;
*&lt;br /&gt;
*******************************************************************************&lt;br /&gt;
*/&lt;br /&gt;
 &lt;br /&gt;
// Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden!&lt;br /&gt;
#define F_CPU 3686400L               &lt;br /&gt;
// &amp;quot;Morsedauer&amp;quot; für ein Bit in Millisekunden&lt;br /&gt;
#define BITZEIT 100     &lt;br /&gt;
 &lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
// Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!&lt;br /&gt;
#define BAUD 9600L          &lt;br /&gt;
 &lt;br /&gt;
// Berechnungen&lt;br /&gt;
// clever runden&lt;br /&gt;
#define UBRR_VAL  ((F_CPU+BAUD*8)/(BAUD*16)-1)  &lt;br /&gt;
// Reale Baudrate&lt;br /&gt;
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     &lt;br /&gt;
// Fehler in Promille &lt;br /&gt;
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) &lt;br /&gt;
 &lt;br /&gt;
#if ((BAUD_ERROR&amp;gt;10) || (BAUD_ERROR&amp;lt;-10))&lt;br /&gt;
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! &lt;br /&gt;
#endif&lt;br /&gt;
 &lt;br /&gt;
// globale Variablen für den UART&lt;br /&gt;
 &lt;br /&gt;
// Puffergrösse in Bytes, RX und TX sind gleich gross&lt;br /&gt;
#define uart_buffer_size 32             &lt;br /&gt;
 &lt;br /&gt;
volatile uint8_t uart_rx_flag=0;            // Flag, String komplett empfangen&lt;br /&gt;
volatile uint8_t uart_tx_flag=1;            // Flag, String komplett gesendet&lt;br /&gt;
char uart_rx_buffer[uart_buffer_size];      // Empfangspuffer&lt;br /&gt;
char uart_tx_buffer[uart_buffer_size];      // Sendepuffer&lt;br /&gt;
 &lt;br /&gt;
// lange, variable Wartezeit, Einheit in Millisekunden&lt;br /&gt;
void long_delay(uint16_t ms) {&lt;br /&gt;
    for (; ms&amp;gt;0; ms--) _delay_ms(1);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// einen String senden&lt;br /&gt;
// vor Aufruf der Funktion muss man prüfen, ob uart_t_flag==1 ist&lt;br /&gt;
// nur dann kann ein neuer String gesendet werden&lt;br /&gt;
 &lt;br /&gt;
void put_string(char *daten) {&lt;br /&gt;
 &lt;br /&gt;
   if (uart_tx_flag==1) {&lt;br /&gt;
      // String daten ind en Sendepuffer kopieren&lt;br /&gt;
      strcpy(uart_tx_buffer, daten);      &lt;br /&gt;
      // Flag für &#039;Senden ist komplett&#039; löschen, &lt;br /&gt;
      uart_tx_flag = 0;                    &lt;br /&gt;
      // UDRE Interrupt einschalten, los gehts&lt;br /&gt;
      UCSRB |= (1&amp;lt;&amp;lt;UDRIE); &lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// einen empfangenen String kopieren&lt;br /&gt;
// vor Aufruf der Funktion muss man prüfen, ob uart_rx_flag==1 ist&lt;br /&gt;
// anderenfalls ist der RX Buffer noch ungültig&lt;br /&gt;
 &lt;br /&gt;
void get_string(char *daten) {&lt;br /&gt;
 &lt;br /&gt;
   if (uart_rx_flag==1) {&lt;br /&gt;
      // String kopieren&lt;br /&gt;
      strcpy(daten, uart_rx_buffer);      &lt;br /&gt;
      // Flag löschen&lt;br /&gt;
      uart_rx_flag = 0;                    &lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// Ein Byte im RS232 Format auf eine LED ausgeben&lt;br /&gt;
 &lt;br /&gt;
void morse(uint8_t data) {&lt;br /&gt;
    uint8_t i;&lt;br /&gt;
 &lt;br /&gt;
    // Startbit, immer 0&lt;br /&gt;
    PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PD5);           // LED aus&lt;br /&gt;
    long_delay(BITZEIT);&lt;br /&gt;
 &lt;br /&gt;
    for(i=0; i&amp;lt;8; i++) {&lt;br /&gt;
        if (data &amp;amp; 0x01)            // Prüfe Bit #0&lt;br /&gt;
            PORTD |= (1 &amp;lt;&amp;lt; PD5);    // LED an&lt;br /&gt;
        else&lt;br /&gt;
            PORTD &amp;amp;= ~(1 &amp;lt;&amp;lt; PD5);   // LED aus      &lt;br /&gt;
        long_delay(BITZEIT);        &lt;br /&gt;
        data &amp;gt;&amp;gt;= 1;                 // nächstes Bit auf Bit #0 schieben&lt;br /&gt;
    }&lt;br /&gt;
    // Stopbit, immer 1&lt;br /&gt;
    PORTD |= (1 &amp;lt;&amp;lt; PD5);            // LED an&lt;br /&gt;
    long_delay(BITZEIT);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// Hauptprogramm&lt;br /&gt;
 &lt;br /&gt;
int main (void) {&lt;br /&gt;
 &lt;br /&gt;
    char stringbuffer[64];  // Allgemeiner Puffer für Strings&lt;br /&gt;
    uint8_t buffer_full=0;  // noch ein Flag, aber nur in der Hauptschleife&lt;br /&gt;
    char * charpointer;     // Hilfszeiger&lt;br /&gt;
    &lt;br /&gt;
// IO konfigurieren&lt;br /&gt;
 &lt;br /&gt;
    DDRA = 0xFF;&lt;br /&gt;
    DDRB = 0xFF;&lt;br /&gt;
    DDRC = 0xFF;&lt;br /&gt;
    DDRD = 0xFF;&lt;br /&gt;
 &lt;br /&gt;
// UART konfigurieren&lt;br /&gt;
 &lt;br /&gt;
    UBRRH = UBRR_VAL &amp;gt;&amp;gt; 8;&lt;br /&gt;
    UBRRL = UBRR_VAL &amp;amp; 0xFF;&lt;br /&gt;
    UCSRB = (1&amp;lt;&amp;lt;RXCIE) | (1&amp;lt;&amp;lt;RXEN) | (1&amp;lt;&amp;lt;TXEN); &lt;br /&gt;
 &lt;br /&gt;
// Stringpuffer initialisieren&lt;br /&gt;
 &lt;br /&gt;
    stringbuffer[0] = &#039;\n&#039;;&lt;br /&gt;
    stringbuffer[1] = &#039;\r&#039;;&lt;br /&gt;
 &lt;br /&gt;
// Interrupts freigeben&lt;br /&gt;
 &lt;br /&gt;
    sei();&lt;br /&gt;
    &lt;br /&gt;
// Endlose Hauptschleife&lt;br /&gt;
 &lt;br /&gt;
    while(1) {&lt;br /&gt;
 &lt;br /&gt;
        // &amp;quot;Sinnvolle&amp;quot; CPU Tätigkeit &lt;br /&gt;
        PORTD &amp;amp;= ~(1&amp;lt;&amp;lt;PD5);&lt;br /&gt;
        long_delay(300);&lt;br /&gt;
        PORTD |= (1&amp;lt;&amp;lt;PD5);&lt;br /&gt;
        long_delay(300);&lt;br /&gt;
    &lt;br /&gt;
        // Wurde ein kompletter String empfangen &lt;br /&gt;
        // und der Buffer ist leer?&lt;br /&gt;
        if (uart_rx_flag==1 &amp;amp;&amp;amp; buffer_full==0) {    &lt;br /&gt;
            // ja, dann String lesen, &lt;br /&gt;
            // die ersten zwei Zeichen &lt;br /&gt;
            // aber nicht überschreiben&lt;br /&gt;
            get_string(stringbuffer+2);             &lt;br /&gt;
            buffer_full=1;&lt;br /&gt;
        }&lt;br /&gt;
 &lt;br /&gt;
        // Ist letzte Stringsendung abgeschlossen &lt;br /&gt;
        // und ein neuer String verfügbar?&lt;br /&gt;
        if (uart_tx_flag==1 &amp;amp;&amp;amp; buffer_full==1) {    &lt;br /&gt;
            // Newline + Carrige return anfügen&lt;br /&gt;
            strcat(stringbuffer, &amp;quot;\n\r&amp;quot;);           &lt;br /&gt;
            put_string(stringbuffer); // zurücksenden&lt;br /&gt;
            buffer_full=0; // Buffer ist wieder verfügbar&lt;br /&gt;
            // Alle Zeichen per LED morsen&lt;br /&gt;
            charpointer = stringbuffer;&lt;br /&gt;
            while(*charpointer) morse(*charpointer++);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// UART RX complete interrupt&lt;br /&gt;
 &lt;br /&gt;
// hier werden Daten vom PC empfangen und in einem String zwischengespeichert&lt;br /&gt;
// Wird ein Stringterminator empfangen, wird ein Flag gesetzt, welches dem &lt;br /&gt;
// Hauptprogramm den kompletten Empfang signalisiert&lt;br /&gt;
 &lt;br /&gt;
ISR(USART_RXC_vect) {&lt;br /&gt;
    &lt;br /&gt;
    static uint8_t uart_rx_cnt;     // Zähler für empfangene Zeichen&lt;br /&gt;
    uint8_t data;&lt;br /&gt;
 &lt;br /&gt;
    // Daten auslesen, dadurch wird das Interruptflag gelöscht              &lt;br /&gt;
    data = UDR;&lt;br /&gt;
    &lt;br /&gt;
    // Ist Puffer frei für neue Daten? &lt;br /&gt;
    if (!uart_rx_flag) {&lt;br /&gt;
        // ja, ist Ende des Strings (RETURN) erreicht?&lt;br /&gt;
        if (data==&#039;\r&#039;) {&lt;br /&gt;
            // ja, dann String terminieren&lt;br /&gt;
            uart_rx_buffer[uart_rx_cnt]=0;              &lt;br /&gt;
            // Flag für &#039;Empfangspuffer voll&#039; setzen&lt;br /&gt;
            uart_rx_flag=1;&lt;br /&gt;
            // Zähler zurücksetzen&lt;br /&gt;
            uart_rx_cnt=0;&lt;br /&gt;
        }&lt;br /&gt;
        else if (uart_rx_cnt&amp;lt;(uart_buffer_size-1)) {     &lt;br /&gt;
            // Daten in Puffer speichern&lt;br /&gt;
            // aber durch if() Pufferüberlauf vermeiden&lt;br /&gt;
            uart_rx_buffer[uart_rx_cnt]=data;          &lt;br /&gt;
            uart_rx_cnt++; // Zähler erhöhen&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// UART TX data register empty interrupt&lt;br /&gt;
// hier werden neue Daten in das UART Senderegister geladen&lt;br /&gt;
 &lt;br /&gt;
ISR(USART_UDRE_vect) {&lt;br /&gt;
    // Zeiger auf Sendepuffer&lt;br /&gt;
    static char* uart_tx_p = uart_tx_buffer;    &lt;br /&gt;
    uint8_t data;&lt;br /&gt;
 &lt;br /&gt;
    // zu sendendes Zeichen lesen, &lt;br /&gt;
    // Zeiger auf Sendepuffer erhöhen&lt;br /&gt;
    data = *uart_tx_p++;&lt;br /&gt;
    &lt;br /&gt;
    // Ende des nullterminierten Strings erreicht?&lt;br /&gt;
    if (data==0 ) {        &lt;br /&gt;
        UCSRB &amp;amp;= ~(1&amp;lt;&amp;lt;UDRIE);       // ja, dann UDRE Interrupt ausschalten        &lt;br /&gt;
        uart_tx_p = uart_tx_buffer; // Pointer zurücksetzen&lt;br /&gt;
        uart_tx_flag = 1;           // Flag setzen, Übertragung beeendet&lt;br /&gt;
    }&lt;br /&gt;
    else UDR = data;                // nein, Daten senden&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Wie lange dauert meine Interruptroutine ? ===&lt;br /&gt;
&lt;br /&gt;
Diese Frage sollte man beantworten können, zumindest sollte eine Worst Case Abschätzung gemacht werden. Das geht auf zwei Wegen.&lt;br /&gt;
&lt;br /&gt;
* Simulation, dabei muss in einer verzweigten ISR der längste Pfad simuliert werden. Dazu müssen alle beteiligten Variablen auf den ensprechenden Wert gesetzt werden.&lt;br /&gt;
* Messung mit dem [[Oszilloskop]], dabei wird zum Beginn der ISR ein Pin auf HIGH gesetzt und am Ende auf LOW. Damit kann man in Echtzeit die Dauer der ISR messen. Die zusätzlichen Taktzyklen zum Aufruf und verlassen der ISR sind konstant und im wesentlichen bekannt. Mit einem modernen Digitaloszilloskop und dem &amp;quot;Infinite Persistence Mode&amp;quot; kann man eine Worst Case Messung vornehmen&lt;br /&gt;
&lt;br /&gt;
Als Hilfmittel zur Fehlersuche kann man auch am Ende der ISR prüfen, ob das jeweilige Interrupt-Request Bit schon wieder gesetzt ist. Wenn ja, dann ist die ISR in den meisten Fällen zu lang. Auch hier kann man einen Ausgang auf HIGH setzen und somit den Fehler anzeigen.&lt;br /&gt;
&lt;br /&gt;
==Interruptfeste Programmierung==&lt;br /&gt;
&lt;br /&gt;
=== Atomarer Datenzugriff ===&lt;br /&gt;
&lt;br /&gt;
Von einem atomaren (engl. atomic) Datenzugriff spricht man, wenn der Zugriff innerhalb einer nicht unterbrechbaren Maschinenanweisung abgearbeitet wird.&lt;br /&gt;
&lt;br /&gt;
Alle Variablen, Steuerregister und I/O-Ports, die sowohl im Hauptprogramm als auch in Interrupts verwendet werden, sind mit viel Sorgfalt zu behandeln.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  port |= 0x03;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
übersetzt sich auf AVR Prozessoren in&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
  IN  r16,port&lt;br /&gt;
  ORI r16,0x03&lt;br /&gt;
  OUT port,r16&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
Wenn nun zwischen IN und OUT ein Interrupt auftritt, der beispielsweise Bit 7 verändert, dann geht mit dem OUT-Befehl diese Änderung verloren, da der OUT Befehl den alten Zustand vor dem Interrupt wiederherstellt.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Gefährlich ist das insbesondere deshalb, weil der Fall nur selten auftritt und dies Verhalten sehr schlecht reproduzierbar ist.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Bei verschiedenen Prozessor-Architekturen tritt das Problem verschieden häufig auf. So übersetzt sich obiger Code bei MSP430 Prozessoren in einen einzelnen Befehl&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  OR  #0x03,port&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
und stellt somit kein Problem dar. Im Zweifel hilft nur ein Blick in den erzeugten Assembler-Code. Bei der Übernahme fremden Codes ist dies zu beachten. Was bei i51 kein Problem war, kann bei AVR zu einem Problem werden, unter Umständen sogar abhängig von verwendeten Port sein.&lt;br /&gt;
&lt;br /&gt;
Ein ähnliches Problem entsteht bei Variablen, deren Grösse die Wortbreite der Maschine übersteigt. Bei 8-Bit-Prozessoren wie AVR oder i51 also bereits bei normalen &amp;quot;int&amp;quot; Variablen. Diese Variablen werden zwangsläufig byteweise verarbeitet. Wenn genau dazwischen ein Interrupt erfolgt, wird ein falscher Wert gelesen. Wenn beispielsweise eine Interrupt-Routine einen 16-Bit-Zähler verwendet und von 0x00FF auf 0x0100 hochzählt, dann kann das Hauptprogramm auch schon mal versehentlich die Werte 0x01FF oder 0x0000 lesen.&lt;br /&gt;
&lt;br /&gt;
Dies ist auch ein Grund, weshalb für Programmierung auf derart &amp;quot;niedriger&amp;quot; Ebene Kenntnisse in Prozessorarchitektur und Assembler-Programmierung sehr hilfreich sind.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Abhilfe&#039;&#039;&#039;: Wenn man sich nicht wirklich ganz sicher ist, sollten um kritische Aktivitäten herum jedesmal die Interrupts abgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel ([[AVR-GCC]]):&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  cli(); // Interrupts abschalten&lt;br /&gt;
  port |= 0x03;&lt;br /&gt;
  sei(); // Interrupts wieder einschalten&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn man ein globales Einschalten der Interrupts mit sei() vermeiden will, kann man die folgende Methode benutzen. Hierbei werden die Interrupts nur eingeschaltet, wenn sie vorher bereits eingeschaltet waren (Hinweis aus der FAQ von avr-libc):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  // ...&lt;br /&gt;
  {&lt;br /&gt;
    uint8_t sreg; // Lokale Sicherungskopie von SREG&lt;br /&gt;
    sreg = SREG;&lt;br /&gt;
    cli();&lt;br /&gt;
    // hierhin kommt der Code mit atomarem Zugriff&lt;br /&gt;
    SREG = sreg;&lt;br /&gt;
  } &lt;br /&gt;
  // ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Je nach Prozessor kann man das Problem manchmal auch ohne Abschalten von Interrupts durch geeignete Programmierung lösen. So führt&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  port = (port &amp;amp; ~0x0F) | lcd_data;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
immer zum beschriebenen Problem,&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  port &amp;amp;= ~0x0F;&lt;br /&gt;
  port |= lcd_data;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
jedoch nicht, wenn die beiden Zeilen zu jeweils einem Assembler-Befehl übersetzt werden. Was dann aber abhängig von den Optimierungs-Einstellungen des Compilers werden kann. Eine Interrupt-feste Variante für AVR-Prozessoren der neuesten Generation, wie beispielsweise Tiny2313 und Mega88 (alle ab 2004):&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  PINx = (PORTx &amp;amp; 0x0F) ^ lcd_data;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Reentrante Funktionen ===&lt;br /&gt;
&lt;br /&gt;
Eine Funktion ist reentrant (wiedereintrittsfest), wenn sie mehrmals gleichzeitig aktiv sein kann, ohne dass sich diese Aufrufe gegenseitig beeinflussen. Betrifft beispielsweise Funktionen, die sowohl im Hauptprogramm als auch in Interrupts aufgerufen werden. Manche C Compiler erfordern eine besondere Kennzeichnung solcher Funktionen. Wenn möglich sollte man es jedoch vermeiden, eine Funktion aus dem Hauptprogramm &#039;&#039;&#039;und&#039;&#039;&#039; aus einem Interrupt aus aufzurufen. Das ist meist problemlos machbar.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Timer]]&lt;br /&gt;
* [[AVR-Tutorial: Interrupts | AVR-Tutorial - Interrupts in Assembler]]&lt;br /&gt;
* [[AVR-GCC-Tutorial#Programmieren_mit_Interrupts | AVR-GCC-Tutorial - Interrupts in C]]&lt;br /&gt;
* [[ADC]]&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html Atomare Operationen im AVR-GCC]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=31017</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=31017"/>
		<updated>2008-09-12T11:13:32Z</updated>

		<summary type="html">&lt;p&gt;Matze88: /* Software */ Bugreport&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(Achtung: Diesen Artikel habe ich nach Wettbewerbsschluss noch bearbeitet, bitte beachtet beim Bewerten, dass ihr euch die alte Version anschaut. Danke)&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, in dem die meiste Arbeit steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts:&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.2.zip| GPS Mini Navigator Version beta 0.2]]&lt;br /&gt;
&lt;br /&gt;
Behobene Fehler:&lt;br /&gt;
* Wiedereinschalten aus dem Standby wurde nicht ausreichend überprüft. (Achtung. Verändertes Timing beim Einschalten, siehe Changelog)&lt;br /&gt;
* Fehler beim Laden der nächsten Waypoint Datei, sofern rückwärts navigieren aktiviert und zuvor die letzte Waypoint Datei geladen war führte zu einer Endlosschleife.&lt;br /&gt;
&lt;br /&gt;
Bekannte Fehler:&lt;br /&gt;
* Race Condition: Mit einer SEHR geringen Wahrscheinlichkeit wird beim Wegpunkte abspeichern ein völlig falscher Wert gespeichert, falls der GPS Interrupt gerade die Positionsdaten aktualisiert UND dabei gerade eine Wertänderung stattfindet, die nicht nur das letzte Byte betrifft. Die Wahrscheinlichkeit ist so enorm gering (Ich habs noch nicht ausgerechnet, aber sie dürfte weit unter 1:1 Million liegen), dass ein Fix (-&amp;gt; Zugriffssperre) zur Zeit noch nicht lohnt, erstmal sind wichtigere Sachen (z.B. PC Software) dran.&lt;br /&gt;
* Nach der letzten Wegpunktdatei wird die Datei 0xFF geöffnet als Schutz vor einer Endlosschleife (falls keine Wegpunktdatei existiert). Weitere Überprüfungen notwendig, sodass wieder bei der ersten Wegpunktdatei begonnen wird.&lt;br /&gt;
* Entdeckt 12.09.2008: Nutzt man die &amp;quot;Tastensperre&amp;quot; (Shutdown bei aktiviertem GPS LOG), so treten Fehler bei der Aufzeichnung auf. Dies wird weiter untersucht, wenn ich mehr Zeit habe.&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Achtung:&#039;&#039; Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
Für das Rechnen mit Koordinaten benutze ich hauptsächlich eine Funktion:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t calculate_distance (gps_coords *a, gps_coords *b)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t latstate = 0;&lt;br /&gt;
  uint32_t lat_distance;&lt;br /&gt;
  if(a-&amp;gt;lat &amp;gt; b-&amp;gt;lat)&lt;br /&gt;
  {&lt;br /&gt;
    latstate = 1;&lt;br /&gt;
    lat_distance = a-&amp;gt;lat - b-&amp;gt; lat;&lt;br /&gt;
  }&lt;br /&gt;
  else lat_distance = b-&amp;gt;lat - a-&amp;gt;lat;&lt;br /&gt;
  lat_distance = mul32_16u(div32u(lat_distance,100),11112);	// * 10^7 * 10^-2 *10^-1= *10^4 meters&lt;br /&gt;
  lat_distance = div32u(lat_distance, 10000);&lt;br /&gt;
  uint16_t distance_cache = lat_distance;			&lt;br /&gt;
  lat_distance = mul32_16u(lat_distance, lat_distance);		// square of lat_distance&lt;br /&gt;
&lt;br /&gt;
  uint8_t lonstate = 0;&lt;br /&gt;
  uint32_t lon_distance;&lt;br /&gt;
  if(a-&amp;gt;lon &amp;gt; b-&amp;gt;lon)&lt;br /&gt;
  {&lt;br /&gt;
    lonstate = 1;&lt;br /&gt;
    lon_distance = a-&amp;gt;lon - b-&amp;gt;lon;&lt;br /&gt;
  }&lt;br /&gt;
  else lon_distance = b-&amp;gt;lon - a-&amp;gt;lon;&lt;br /&gt;
  /* square(((lon_diff / 1000) * cos_val * 1113) / 10000) = lon_diff * 111,3 * cos(angle)*/&lt;br /&gt;
  lon_distance = mul32_16u(div32u(lon_distance, 1000), my_cos(div32u(labs(a-&amp;gt;lat),10000000)));  //-&amp;gt;10^6  // simplification:&lt;br /&gt;
                                              //a-&amp;gt;lat instead of a-&amp;gt;lat+b-&amp;gt;lat/2&lt;br /&gt;
  lon_distance = div32u(mul32_16u(lon_distance, 1113),10000); // -&amp;gt;meters&lt;br /&gt;
  lon_distance = isqrt32(mul32_16u(lon_distance, lon_distance) + lat_distance);&lt;br /&gt;
  uint8_t temp_angle = (my_acos(div32u(mul32_16u(distance_cache,100),lon_distance)) * 100) &amp;gt;&amp;gt; 8;	// 0-90 deg. angle&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  if(latstate)&lt;br /&gt;
  {&lt;br /&gt;
    if(lonstate) temp_angle +=70;&lt;br /&gt;
    else temp_angle = 70 - temp_angle;&lt;br /&gt;
  }&lt;br /&gt;
  else if(lonstate)&lt;br /&gt;
    temp_angle = 140 - temp_angle;&lt;br /&gt;
  &lt;br /&gt;
 return (lon_distance) | ((uint32_t)temp_angle &amp;lt;&amp;lt; 16);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Zusammenarbeit mit einfachsten, auf Tabellen basierenden Kosinus- und Umkehrfunktion liefert diese Ergebnisse mit meistens nicht einmal 2 % Abweichung. Der Ablauf:&lt;br /&gt;
# Breitendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Längendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Nach dem Satz des Pythagoras den Abstand der Punkte bestimmen, Länge und Breite stehen dabei für orthogonale Vektoren, somit haben wir ein rechtwinkliges Dreieck&lt;br /&gt;
# Da wir hier gleich alle Seiten berechnet haben, kann einfach der Winkel zwischen Ankathete und Hypothenuse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
Der Winkel muss zum Schluss noch korrigiert werden, jenachdem, in welchem Quadranten (Koordinate a als Ursprung und b als Punkt im 2 dimensionalen Koordinatensystem betrachtet) wir uns befinden.&lt;br /&gt;
Diese Funktion liefert für alle Punkte, die nicht mehr als 65535 Meter auseinander liegen korrekte Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variabel, bis zu 5).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 5 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;0 - allgemeine GPS Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;1 - GPS Logging Funktionen&#039;&#039;&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1 16 128 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;2 - Wegpunkt Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei (Erneuter Aufruf: Nächste Wegpunkt Datei öffnen)&lt;br /&gt;
** 1* - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 = 1 sind es 2048 Meter Schritte.&lt;br /&gt;
** 2* - Erster Aufruf: Anzeige des Kurses zum Wegpunkt. LED 0 ist dabei die Bewegungsrichtung.&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der jetzige weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
** LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
     * Für 1 und 2 gilt: Erneuter Aufruf navigiert den nachfolgenden Wegpunkt an.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;3 - Wegpunkte einspeichern&#039;&#039;&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkte Datei und gibt die Nummer binär aus. Diese Schreibzugriffe können parallel zum GPS Log durchgeführt werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;4 - Allgemeine Optionen&#039;&#039;&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 700 ms muss sie losgelassen und nach weiteren 400 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt.&lt;br /&gt;
** (LED 5 und 6 geben den Batteriestatus wieder. 6 ist voll, 5 ist fast leer und garnichts steht für leer)&lt;br /&gt;
&lt;br /&gt;
== PC Interaktion ==&lt;br /&gt;
Für den PC habe ich bereits einfachste Übertragungsprogramme geschrieben, welche jedoch zur Zeit noch ungetestet und stark aufs Debugging ausgelegt sind. Diese werden erst zu späterer Zeit veröffentlicht.&lt;br /&gt;
[[http://www.gpsbabel.org/ GPS Babel]] eignet sich wunderbar, um ausgelesene Daten in ein Google Earth kompatibles Format umzuwandeln, um sich z.B. die GPS Logs anzusehen. Auch können in Google Earth erstellte Pfade so als Waylist für den Mini Navigator umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;br /&gt;
[[Category:GPS|G]]&lt;br /&gt;
[[Category:Projekte|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30937</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30937"/>
		<updated>2008-09-09T09:03:19Z</updated>

		<summary type="html">&lt;p&gt;Matze88: /* Software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(Achtung: Diesen Artikel habe ich nach Wettbewerbsschluss noch bearbeitet, bitte beachtet beim Bewerten, dass ihr euch die alte Version anschaut. Danke)&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, in dem die meiste Arbeit steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts:&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.2.zip| GPS Mini Navigator Version beta 0.2]]&lt;br /&gt;
&lt;br /&gt;
Behobene Fehler:&lt;br /&gt;
* Wiedereinschalten aus dem Standby wurde nicht ausreichend überprüft. (Achtung. Verändertes Timing beim Einschalten, siehe Changelog)&lt;br /&gt;
* Fehler beim Laden der nächsten Waypoint Datei, sofern rückwärts navigieren aktiviert und zuvor die letzte Waypoint Datei geladen war führte zu einer Endlosschleife.&lt;br /&gt;
&lt;br /&gt;
Bekannte Fehler:&lt;br /&gt;
* Race Condition: Mit einer SEHR geringen Wahrscheinlichkeit wird beim Wegpunkte abspeichern ein völlig falscher Wert gespeichert, falls der GPS Interrupt gerade die Positionsdaten aktualisiert UND dabei gerade eine Wertänderung stattfindet, die nicht nur das letzte Byte betrifft. Die Wahrscheinlichkeit ist so enorm gering (Ich habs noch nicht ausgerechnet, aber sie dürfte weit unter 1:1 Million liegen), dass ein Fix (-&amp;gt; Zugriffssperre) zur Zeit noch nicht lohnt, erstmal sind wichtigere Sachen (z.B. PC Software) dran.&lt;br /&gt;
* Nach der letzten Wegpunktdatei wird die Datei 0xFF geöffnet als Schutz vor einer Endlosschleife (falls keine Wegpunktdatei existiert). Weitere Überprüfungen notwendig, sodass wieder bei der ersten Wegpunktdatei begonnen wird.&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Achtung:&#039;&#039; Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
Für das Rechnen mit Koordinaten benutze ich hauptsächlich eine Funktion:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t calculate_distance (gps_coords *a, gps_coords *b)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t latstate = 0;&lt;br /&gt;
  uint32_t lat_distance;&lt;br /&gt;
  if(a-&amp;gt;lat &amp;gt; b-&amp;gt;lat)&lt;br /&gt;
  {&lt;br /&gt;
    latstate = 1;&lt;br /&gt;
    lat_distance = a-&amp;gt;lat - b-&amp;gt; lat;&lt;br /&gt;
  }&lt;br /&gt;
  else lat_distance = b-&amp;gt;lat - a-&amp;gt;lat;&lt;br /&gt;
  lat_distance = mul32_16u(div32u(lat_distance,100),11112);	// * 10^7 * 10^-2 *10^-1= *10^4 meters&lt;br /&gt;
  lat_distance = div32u(lat_distance, 10000);&lt;br /&gt;
  uint16_t distance_cache = lat_distance;			&lt;br /&gt;
  lat_distance = mul32_16u(lat_distance, lat_distance);		// square of lat_distance&lt;br /&gt;
&lt;br /&gt;
  uint8_t lonstate = 0;&lt;br /&gt;
  uint32_t lon_distance;&lt;br /&gt;
  if(a-&amp;gt;lon &amp;gt; b-&amp;gt;lon)&lt;br /&gt;
  {&lt;br /&gt;
    lonstate = 1;&lt;br /&gt;
    lon_distance = a-&amp;gt;lon - b-&amp;gt;lon;&lt;br /&gt;
  }&lt;br /&gt;
  else lon_distance = b-&amp;gt;lon - a-&amp;gt;lon;&lt;br /&gt;
  /* square(((lon_diff / 1000) * cos_val * 1113) / 10000) = lon_diff * 111,3 * cos(angle)*/&lt;br /&gt;
  lon_distance = mul32_16u(div32u(lon_distance, 1000), my_cos(div32u(labs(a-&amp;gt;lat),10000000)));  //-&amp;gt;10^6  // simplification:&lt;br /&gt;
                                              //a-&amp;gt;lat instead of a-&amp;gt;lat+b-&amp;gt;lat/2&lt;br /&gt;
  lon_distance = div32u(mul32_16u(lon_distance, 1113),10000); // -&amp;gt;meters&lt;br /&gt;
  lon_distance = isqrt32(mul32_16u(lon_distance, lon_distance) + lat_distance);&lt;br /&gt;
  uint8_t temp_angle = (my_acos(div32u(mul32_16u(distance_cache,100),lon_distance)) * 100) &amp;gt;&amp;gt; 8;	// 0-90 deg. angle&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  if(latstate)&lt;br /&gt;
  {&lt;br /&gt;
    if(lonstate) temp_angle +=70;&lt;br /&gt;
    else temp_angle = 70 - temp_angle;&lt;br /&gt;
  }&lt;br /&gt;
  else if(lonstate)&lt;br /&gt;
    temp_angle = 140 - temp_angle;&lt;br /&gt;
  &lt;br /&gt;
 return (lon_distance) | ((uint32_t)temp_angle &amp;lt;&amp;lt; 16);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Zusammenarbeit mit einfachsten, auf Tabellen basierenden Kosinus- und Umkehrfunktion liefert diese Ergebnisse mit meistens nicht einmal 2 % Abweichung. Der Ablauf:&lt;br /&gt;
# Breitendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Längendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Nach dem Satz des Pythagoras den Abstand der Punkte bestimmen, Länge und Breite stehen dabei für orthogonale Vektoren, somit haben wir ein rechtwinkliges Dreieck&lt;br /&gt;
# Da wir hier gleich alle Seiten berechnet haben, kann einfach der Winkel zwischen Ankathete und Hypothenuse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
Der Winkel muss zum Schluss noch korrigiert werden, jenachdem, in welchem Quadranten (Koordinate a als Ursprung und b als Punkt im 2 dimensionalen Koordinatensystem betrachtet) wir uns befinden.&lt;br /&gt;
Diese Funktion liefert für alle Punkte, die nicht mehr als 65535 Meter auseinander liegen korrekte Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variabel, bis zu 5).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 5 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;0 - allgemeine GPS Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;1 - GPS Logging Funktionen&#039;&#039;&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1 16 128 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;2 - Wegpunkt Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei (Erneuter Aufruf: Nächste Wegpunkt Datei öffnen)&lt;br /&gt;
** 1* - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 = 1 sind es 2048 Meter Schritte.&lt;br /&gt;
** 2* - Erster Aufruf: Anzeige des Kurses zum Wegpunkt. LED 0 ist dabei die Bewegungsrichtung.&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der jetzige weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
** LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
     * Für 1 und 2 gilt: Erneuter Aufruf navigiert den nachfolgenden Wegpunkt an.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;3 - Wegpunkte einspeichern&#039;&#039;&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkte Datei und gibt die Nummer binär aus. Diese Schreibzugriffe können parallel zum GPS Log durchgeführt werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;4 - Allgemeine Optionen&#039;&#039;&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 700 ms muss sie losgelassen und nach weiteren 400 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt.&lt;br /&gt;
** (LED 5 und 6 geben den Batteriestatus wieder. 6 ist voll, 5 ist fast leer und garnichts steht für leer)&lt;br /&gt;
&lt;br /&gt;
== PC Interaktion ==&lt;br /&gt;
Für den PC habe ich bereits einfachste Übertragungsprogramme geschrieben, welche jedoch zur Zeit noch ungetestet und stark aufs Debugging ausgelegt sind. Diese werden erst zu späterer Zeit veröffentlicht.&lt;br /&gt;
[[http://www.gpsbabel.org/ GPS Babel]] eignet sich wunderbar, um ausgelesene Daten in ein Google Earth kompatibles Format umzuwandeln, um sich z.B. die GPS Logs anzusehen. Auch können in Google Earth erstellte Pfade so als Waylist für den Mini Navigator umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;br /&gt;
[[Category:GPS|G]]&lt;br /&gt;
[[Category:Projekte|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:GPSMiniNavigatorb0.2.zip&amp;diff=30936</id>
		<title>Datei:GPSMiniNavigatorb0.2.zip</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:GPSMiniNavigatorb0.2.zip&amp;diff=30936"/>
		<updated>2008-09-09T09:01:21Z</updated>

		<summary type="html">&lt;p&gt;Matze88: GPS Mini Navigator Version b0.2. Lizenz: GPLv2, Changelog liegt bei.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GPS Mini Navigator Version b0.2. Lizenz: GPLv2, Changelog liegt bei.&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30912</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30912"/>
		<updated>2008-09-08T10:42:15Z</updated>

		<summary type="html">&lt;p&gt;Matze88: /* Software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(Achtung: Diesen Artikel habe ich nach Wettbewerbsschluss noch bearbeitet, bitte beachtet beim Bewerten, dass ihr euch die alte Version anschaut. Danke)&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, in dem die meiste Arbeit steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts:&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.2.zip| GPS Mini Navigator Version beta 0.2]]&lt;br /&gt;
&lt;br /&gt;
Behobene Fehler:&lt;br /&gt;
* Wiedereinschalten aus dem Standby wurde nicht ausreichend überprüft.&lt;br /&gt;
* Fehler beim Laden der nächsten Waypoint Datei, sofern rückwärts navigieren aktiviert und zuvor die letzte Waypoint Datei geladen war führte zu einer Endlosschleife.&lt;br /&gt;
&lt;br /&gt;
Bekannte Fehler:&lt;br /&gt;
* Race Condition: Mit einer SEHR geringen Wahrscheinlichkeit wird beim Wegpunkte abspeichern ein völlig falscher Wert gespeichert, falls der GPS Interrupt gerade die Positionsdaten aktualisiert UND dabei gerade eine Wertänderung stattfindet, die nicht nur das letzte Byte betrifft. Die Wahrscheinlichkeit ist so enorm gering (Ich habs noch nicht ausgerechnet, aber sie dürfte weit unter 1:1 Million liegen), dass ein Fix (-&amp;gt; Zugriffssperre) zur Zeit noch nicht lohnt, erstmal sind wichtigere Sachen (z.B. PC Software) dran.&lt;br /&gt;
* Nach der letzten Wegpunktdatei wird die Datei 0xFF geöffnet als Schutz vor einer Endlosschleife (falls keine Wegpunktdatei existiert). Weitere Überprüfungen notwendig, sodass wieder bei der ersten Wegpunktdatei begonnen wird.&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Achtung:&#039;&#039; Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
Für das Rechnen mit Koordinaten benutze ich hauptsächlich eine Funktion:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t calculate_distance (gps_coords *a, gps_coords *b)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t latstate = 0;&lt;br /&gt;
  uint32_t lat_distance;&lt;br /&gt;
  if(a-&amp;gt;lat &amp;gt; b-&amp;gt;lat)&lt;br /&gt;
  {&lt;br /&gt;
    latstate = 1;&lt;br /&gt;
    lat_distance = a-&amp;gt;lat - b-&amp;gt; lat;&lt;br /&gt;
  }&lt;br /&gt;
  else lat_distance = b-&amp;gt;lat - a-&amp;gt;lat;&lt;br /&gt;
  lat_distance = mul32_16u(div32u(lat_distance,100),11112);	// * 10^7 * 10^-2 *10^-1= *10^4 meters&lt;br /&gt;
  lat_distance = div32u(lat_distance, 10000);&lt;br /&gt;
  uint16_t distance_cache = lat_distance;			&lt;br /&gt;
  lat_distance = mul32_16u(lat_distance, lat_distance);		// square of lat_distance&lt;br /&gt;
&lt;br /&gt;
  uint8_t lonstate = 0;&lt;br /&gt;
  uint32_t lon_distance;&lt;br /&gt;
  if(a-&amp;gt;lon &amp;gt; b-&amp;gt;lon)&lt;br /&gt;
  {&lt;br /&gt;
    lonstate = 1;&lt;br /&gt;
    lon_distance = a-&amp;gt;lon - b-&amp;gt;lon;&lt;br /&gt;
  }&lt;br /&gt;
  else lon_distance = b-&amp;gt;lon - a-&amp;gt;lon;&lt;br /&gt;
  /* square(((lon_diff / 1000) * cos_val * 1113) / 10000) = lon_diff * 111,3 * cos(angle)*/&lt;br /&gt;
  lon_distance = mul32_16u(div32u(lon_distance, 1000), my_cos(div32u(labs(a-&amp;gt;lat),10000000)));  //-&amp;gt;10^6  // simplification:&lt;br /&gt;
                                              //a-&amp;gt;lat instead of a-&amp;gt;lat+b-&amp;gt;lat/2&lt;br /&gt;
  lon_distance = div32u(mul32_16u(lon_distance, 1113),10000); // -&amp;gt;meters&lt;br /&gt;
  lon_distance = isqrt32(mul32_16u(lon_distance, lon_distance) + lat_distance);&lt;br /&gt;
  uint8_t temp_angle = (my_acos(div32u(mul32_16u(distance_cache,100),lon_distance)) * 100) &amp;gt;&amp;gt; 8;	// 0-90 deg. angle&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  if(latstate)&lt;br /&gt;
  {&lt;br /&gt;
    if(lonstate) temp_angle +=70;&lt;br /&gt;
    else temp_angle = 70 - temp_angle;&lt;br /&gt;
  }&lt;br /&gt;
  else if(lonstate)&lt;br /&gt;
    temp_angle = 140 - temp_angle;&lt;br /&gt;
  &lt;br /&gt;
 return (lon_distance) | ((uint32_t)temp_angle &amp;lt;&amp;lt; 16);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Zusammenarbeit mit einfachsten, auf Tabellen basierenden Kosinus- und Umkehrfunktion liefert diese Ergebnisse mit meistens nicht einmal 2 % Abweichung. Der Ablauf:&lt;br /&gt;
# Breitendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Längendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Nach dem Satz des Pythagoras den Abstand der Punkte bestimmen, Länge und Breite stehen dabei für orthogonale Vektoren, somit haben wir ein rechtwinkliges Dreieck&lt;br /&gt;
# Da wir hier gleich alle Seiten berechnet haben, kann einfach der Winkel zwischen Ankathete und Hypothenuse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
Der Winkel muss zum Schluss noch korrigiert werden, jenachdem, in welchem Quadranten (Koordinate a als Ursprung und b als Punkt im 2 dimensionalen Koordinatensystem betrachtet) wir uns befinden.&lt;br /&gt;
Diese Funktion liefert für alle Punkte, die nicht mehr als 65535 Meter auseinander liegen korrekte Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variabel, bis zu 5).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 5 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;0 - allgemeine GPS Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;1 - GPS Logging Funktionen&#039;&#039;&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1 16 128 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;2 - Wegpunkt Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei (Erneuter Aufruf: Nächste Wegpunkt Datei öffnen)&lt;br /&gt;
** 1* - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 = 1 sind es 2048 Meter Schritte.&lt;br /&gt;
** 2* - Erster Aufruf: Anzeige des Kurses zum Wegpunkt. LED 0 ist dabei die Bewegungsrichtung.&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der jetzige weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
** LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
     * Für 1 und 2 gilt: Erneuter Aufruf navigiert den nachfolgenden Wegpunkt an.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;3 - Wegpunkte einspeichern&#039;&#039;&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkte Datei und gibt die Nummer binär aus. Diese Schreibzugriffe können parallel zum GPS Log durchgeführt werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;4 - Allgemeine Optionen&#039;&#039;&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 700 ms muss sie losgelassen und nach weiteren 400 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt.&lt;br /&gt;
** (LED 5 und 6 geben den Batteriestatus wieder. 6 ist voll, 5 ist fast leer und garnichts steht für leer)&lt;br /&gt;
&lt;br /&gt;
== PC Interaktion ==&lt;br /&gt;
Für den PC habe ich bereits einfachste Übertragungsprogramme geschrieben, welche jedoch zur Zeit noch ungetestet und stark aufs Debugging ausgelegt sind. Diese werden erst zu späterer Zeit veröffentlicht.&lt;br /&gt;
[[http://www.gpsbabel.org/ GPS Babel]] eignet sich wunderbar, um ausgelesene Daten in ein Google Earth kompatibles Format umzuwandeln, um sich z.B. die GPS Logs anzusehen. Auch können in Google Earth erstellte Pfade so als Waylist für den Mini Navigator umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;br /&gt;
[[Category:GPS|G]]&lt;br /&gt;
[[Category:Projekte|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30911</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30911"/>
		<updated>2008-09-08T10:41:48Z</updated>

		<summary type="html">&lt;p&gt;Matze88: /* Software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(Achtung: Diesen Artikel habe ich nach Wettbewerbsschluss noch bearbeitet, bitte beachtet beim Bewerten, dass ihr euch die alte Version anschaut. Danke)&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, in dem die meiste Arbeit steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts:&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.2.zip| GPS Mini Navigator Version beta 0.2]]&lt;br /&gt;
&lt;br /&gt;
Behobene Fehler:&lt;br /&gt;
* Wiedereinschalten aus den Standby wurde nicht ausreichend überprüft&lt;br /&gt;
* Fehler beim Laden der nächsten Waypoint Datei, sofern rückwärts navigieren aktiviert und zuvor die letzte Waypoint Datei geladen war führte zu einer Endlosschleife&lt;br /&gt;
&lt;br /&gt;
Bekannte Fehler:&lt;br /&gt;
* Race Condition: Mit einer SEHR geringen Wahrscheinlichkeit wird beim Wegpunkte abspeichern ein völlig falscher Wert gespeichert, falls der GPS Interrupt gerade die Positionsdaten aktualisiert UND dabei gerade eine Wertänderung stattfindet, die nicht nur das letzte Byte betrifft. Die Wahrscheinlichkeit ist so enorm gering (Ich habs noch nicht ausgerechnet, aber sie dürfte weit unter 1:1 Million liegen), dass ein Fix (-&amp;gt; Zugriffssperre) zur Zeit noch nicht lohnt, erstmal sind wichtigere Sachen (z.B. PC Software) dran.&lt;br /&gt;
* Nach der letzten Wegpunktdatei wird die Datei 0xFF geöffnet als Schutz vor einer Endlosschleife (falls keine Wegpunktdatei existiert). Weitere Überprüfungen notwendig, sodass wieder bei der ersten Wegpunktdatei begonnen wird.&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Achtung:&#039;&#039; Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
Für das Rechnen mit Koordinaten benutze ich hauptsächlich eine Funktion:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t calculate_distance (gps_coords *a, gps_coords *b)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t latstate = 0;&lt;br /&gt;
  uint32_t lat_distance;&lt;br /&gt;
  if(a-&amp;gt;lat &amp;gt; b-&amp;gt;lat)&lt;br /&gt;
  {&lt;br /&gt;
    latstate = 1;&lt;br /&gt;
    lat_distance = a-&amp;gt;lat - b-&amp;gt; lat;&lt;br /&gt;
  }&lt;br /&gt;
  else lat_distance = b-&amp;gt;lat - a-&amp;gt;lat;&lt;br /&gt;
  lat_distance = mul32_16u(div32u(lat_distance,100),11112);	// * 10^7 * 10^-2 *10^-1= *10^4 meters&lt;br /&gt;
  lat_distance = div32u(lat_distance, 10000);&lt;br /&gt;
  uint16_t distance_cache = lat_distance;			&lt;br /&gt;
  lat_distance = mul32_16u(lat_distance, lat_distance);		// square of lat_distance&lt;br /&gt;
&lt;br /&gt;
  uint8_t lonstate = 0;&lt;br /&gt;
  uint32_t lon_distance;&lt;br /&gt;
  if(a-&amp;gt;lon &amp;gt; b-&amp;gt;lon)&lt;br /&gt;
  {&lt;br /&gt;
    lonstate = 1;&lt;br /&gt;
    lon_distance = a-&amp;gt;lon - b-&amp;gt;lon;&lt;br /&gt;
  }&lt;br /&gt;
  else lon_distance = b-&amp;gt;lon - a-&amp;gt;lon;&lt;br /&gt;
  /* square(((lon_diff / 1000) * cos_val * 1113) / 10000) = lon_diff * 111,3 * cos(angle)*/&lt;br /&gt;
  lon_distance = mul32_16u(div32u(lon_distance, 1000), my_cos(div32u(labs(a-&amp;gt;lat),10000000)));  //-&amp;gt;10^6  // simplification:&lt;br /&gt;
                                              //a-&amp;gt;lat instead of a-&amp;gt;lat+b-&amp;gt;lat/2&lt;br /&gt;
  lon_distance = div32u(mul32_16u(lon_distance, 1113),10000); // -&amp;gt;meters&lt;br /&gt;
  lon_distance = isqrt32(mul32_16u(lon_distance, lon_distance) + lat_distance);&lt;br /&gt;
  uint8_t temp_angle = (my_acos(div32u(mul32_16u(distance_cache,100),lon_distance)) * 100) &amp;gt;&amp;gt; 8;	// 0-90 deg. angle&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  if(latstate)&lt;br /&gt;
  {&lt;br /&gt;
    if(lonstate) temp_angle +=70;&lt;br /&gt;
    else temp_angle = 70 - temp_angle;&lt;br /&gt;
  }&lt;br /&gt;
  else if(lonstate)&lt;br /&gt;
    temp_angle = 140 - temp_angle;&lt;br /&gt;
  &lt;br /&gt;
 return (lon_distance) | ((uint32_t)temp_angle &amp;lt;&amp;lt; 16);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Zusammenarbeit mit einfachsten, auf Tabellen basierenden Kosinus- und Umkehrfunktion liefert diese Ergebnisse mit meistens nicht einmal 2 % Abweichung. Der Ablauf:&lt;br /&gt;
# Breitendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Längendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Nach dem Satz des Pythagoras den Abstand der Punkte bestimmen, Länge und Breite stehen dabei für orthogonale Vektoren, somit haben wir ein rechtwinkliges Dreieck&lt;br /&gt;
# Da wir hier gleich alle Seiten berechnet haben, kann einfach der Winkel zwischen Ankathete und Hypothenuse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
Der Winkel muss zum Schluss noch korrigiert werden, jenachdem, in welchem Quadranten (Koordinate a als Ursprung und b als Punkt im 2 dimensionalen Koordinatensystem betrachtet) wir uns befinden.&lt;br /&gt;
Diese Funktion liefert für alle Punkte, die nicht mehr als 65535 Meter auseinander liegen korrekte Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variabel, bis zu 5).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 5 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;0 - allgemeine GPS Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;1 - GPS Logging Funktionen&#039;&#039;&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1 16 128 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;2 - Wegpunkt Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei (Erneuter Aufruf: Nächste Wegpunkt Datei öffnen)&lt;br /&gt;
** 1* - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 = 1 sind es 2048 Meter Schritte.&lt;br /&gt;
** 2* - Erster Aufruf: Anzeige des Kurses zum Wegpunkt. LED 0 ist dabei die Bewegungsrichtung.&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der jetzige weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
** LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
     * Für 1 und 2 gilt: Erneuter Aufruf navigiert den nachfolgenden Wegpunkt an.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;3 - Wegpunkte einspeichern&#039;&#039;&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkte Datei und gibt die Nummer binär aus. Diese Schreibzugriffe können parallel zum GPS Log durchgeführt werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;4 - Allgemeine Optionen&#039;&#039;&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 700 ms muss sie losgelassen und nach weiteren 400 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt.&lt;br /&gt;
** (LED 5 und 6 geben den Batteriestatus wieder. 6 ist voll, 5 ist fast leer und garnichts steht für leer)&lt;br /&gt;
&lt;br /&gt;
== PC Interaktion ==&lt;br /&gt;
Für den PC habe ich bereits einfachste Übertragungsprogramme geschrieben, welche jedoch zur Zeit noch ungetestet und stark aufs Debugging ausgelegt sind. Diese werden erst zu späterer Zeit veröffentlicht.&lt;br /&gt;
[[http://www.gpsbabel.org/ GPS Babel]] eignet sich wunderbar, um ausgelesene Daten in ein Google Earth kompatibles Format umzuwandeln, um sich z.B. die GPS Logs anzusehen. Auch können in Google Earth erstellte Pfade so als Waylist für den Mini Navigator umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;br /&gt;
[[Category:GPS|G]]&lt;br /&gt;
[[Category:Projekte|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30910</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30910"/>
		<updated>2008-09-08T10:41:10Z</updated>

		<summary type="html">&lt;p&gt;Matze88: Software Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(Achtung: Diesen Artikel habe ich nach Wettbewerbsschluss noch bearbeitet, bitte beachtet beim Bewerten, dass ihr euch die alte Version anschaut. Danke)&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, in dem die meiste Arbeit steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts: &lt;br /&gt;
[[Media:GPSMiniNavigatorb0.2.zip| GPS Mini Navigator Version beta 0.2]]&lt;br /&gt;
Behobene Fehler:&lt;br /&gt;
* Wiedereinschalten aus den Standby wurde nicht ausreichend überprüft&lt;br /&gt;
* Fehler beim Laden der nächsten Waypoint Datei, sofern rückwärts navigieren aktiviert und zuvor die letzte Waypoint Datei geladen war führte zu einer Endlosschleife&lt;br /&gt;
&lt;br /&gt;
Bekannte Fehler:&lt;br /&gt;
* Race Condition: Mit einer SEHR geringen Wahrscheinlichkeit wird beim Wegpunkte abspeichern ein völlig falscher Wert gespeichert, falls der GPS Interrupt gerade die Positionsdaten aktualisiert UND dabei gerade eine Wertänderung stattfindet, die nicht nur das letzte Byte betrifft. Die Wahrscheinlichkeit ist so enorm gering (Ich habs noch nicht ausgerechnet, aber sie dürfte weit unter 1:1 Million liegen), dass ein Fix (-&amp;gt; Zugriffssperre) zur Zeit noch nicht lohnt, erstmal sind wichtigere Sachen (z.B. PC Software) dran.&lt;br /&gt;
* Nach der letzten Wegpunktdatei wird die Datei 0xFF geöffnet als Schutz vor einer Endlosschleife (falls keine Wegpunktdatei existiert). Weitere Überprüfungen notwendig, sodass wieder bei der ersten Wegpunktdatei begonnen wird.&lt;br /&gt;
&lt;br /&gt;
[[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Achtung:&#039;&#039; Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
Für das Rechnen mit Koordinaten benutze ich hauptsächlich eine Funktion:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t calculate_distance (gps_coords *a, gps_coords *b)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t latstate = 0;&lt;br /&gt;
  uint32_t lat_distance;&lt;br /&gt;
  if(a-&amp;gt;lat &amp;gt; b-&amp;gt;lat)&lt;br /&gt;
  {&lt;br /&gt;
    latstate = 1;&lt;br /&gt;
    lat_distance = a-&amp;gt;lat - b-&amp;gt; lat;&lt;br /&gt;
  }&lt;br /&gt;
  else lat_distance = b-&amp;gt;lat - a-&amp;gt;lat;&lt;br /&gt;
  lat_distance = mul32_16u(div32u(lat_distance,100),11112);	// * 10^7 * 10^-2 *10^-1= *10^4 meters&lt;br /&gt;
  lat_distance = div32u(lat_distance, 10000);&lt;br /&gt;
  uint16_t distance_cache = lat_distance;			&lt;br /&gt;
  lat_distance = mul32_16u(lat_distance, lat_distance);		// square of lat_distance&lt;br /&gt;
&lt;br /&gt;
  uint8_t lonstate = 0;&lt;br /&gt;
  uint32_t lon_distance;&lt;br /&gt;
  if(a-&amp;gt;lon &amp;gt; b-&amp;gt;lon)&lt;br /&gt;
  {&lt;br /&gt;
    lonstate = 1;&lt;br /&gt;
    lon_distance = a-&amp;gt;lon - b-&amp;gt;lon;&lt;br /&gt;
  }&lt;br /&gt;
  else lon_distance = b-&amp;gt;lon - a-&amp;gt;lon;&lt;br /&gt;
  /* square(((lon_diff / 1000) * cos_val * 1113) / 10000) = lon_diff * 111,3 * cos(angle)*/&lt;br /&gt;
  lon_distance = mul32_16u(div32u(lon_distance, 1000), my_cos(div32u(labs(a-&amp;gt;lat),10000000)));  //-&amp;gt;10^6  // simplification:&lt;br /&gt;
                                              //a-&amp;gt;lat instead of a-&amp;gt;lat+b-&amp;gt;lat/2&lt;br /&gt;
  lon_distance = div32u(mul32_16u(lon_distance, 1113),10000); // -&amp;gt;meters&lt;br /&gt;
  lon_distance = isqrt32(mul32_16u(lon_distance, lon_distance) + lat_distance);&lt;br /&gt;
  uint8_t temp_angle = (my_acos(div32u(mul32_16u(distance_cache,100),lon_distance)) * 100) &amp;gt;&amp;gt; 8;	// 0-90 deg. angle&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  if(latstate)&lt;br /&gt;
  {&lt;br /&gt;
    if(lonstate) temp_angle +=70;&lt;br /&gt;
    else temp_angle = 70 - temp_angle;&lt;br /&gt;
  }&lt;br /&gt;
  else if(lonstate)&lt;br /&gt;
    temp_angle = 140 - temp_angle;&lt;br /&gt;
  &lt;br /&gt;
 return (lon_distance) | ((uint32_t)temp_angle &amp;lt;&amp;lt; 16);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Zusammenarbeit mit einfachsten, auf Tabellen basierenden Kosinus- und Umkehrfunktion liefert diese Ergebnisse mit meistens nicht einmal 2 % Abweichung. Der Ablauf:&lt;br /&gt;
# Breitendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Längendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Nach dem Satz des Pythagoras den Abstand der Punkte bestimmen, Länge und Breite stehen dabei für orthogonale Vektoren, somit haben wir ein rechtwinkliges Dreieck&lt;br /&gt;
# Da wir hier gleich alle Seiten berechnet haben, kann einfach der Winkel zwischen Ankathete und Hypothenuse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
Der Winkel muss zum Schluss noch korrigiert werden, jenachdem, in welchem Quadranten (Koordinate a als Ursprung und b als Punkt im 2 dimensionalen Koordinatensystem betrachtet) wir uns befinden.&lt;br /&gt;
Diese Funktion liefert für alle Punkte, die nicht mehr als 65535 Meter auseinander liegen korrekte Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variabel, bis zu 5).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 5 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;0 - allgemeine GPS Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;1 - GPS Logging Funktionen&#039;&#039;&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1 16 128 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;2 - Wegpunkt Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei (Erneuter Aufruf: Nächste Wegpunkt Datei öffnen)&lt;br /&gt;
** 1* - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 = 1 sind es 2048 Meter Schritte.&lt;br /&gt;
** 2* - Erster Aufruf: Anzeige des Kurses zum Wegpunkt. LED 0 ist dabei die Bewegungsrichtung.&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der jetzige weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
** LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
     * Für 1 und 2 gilt: Erneuter Aufruf navigiert den nachfolgenden Wegpunkt an.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;3 - Wegpunkte einspeichern&#039;&#039;&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkte Datei und gibt die Nummer binär aus. Diese Schreibzugriffe können parallel zum GPS Log durchgeführt werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;4 - Allgemeine Optionen&#039;&#039;&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 700 ms muss sie losgelassen und nach weiteren 400 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt.&lt;br /&gt;
** (LED 5 und 6 geben den Batteriestatus wieder. 6 ist voll, 5 ist fast leer und garnichts steht für leer)&lt;br /&gt;
&lt;br /&gt;
== PC Interaktion ==&lt;br /&gt;
Für den PC habe ich bereits einfachste Übertragungsprogramme geschrieben, welche jedoch zur Zeit noch ungetestet und stark aufs Debugging ausgelegt sind. Diese werden erst zu späterer Zeit veröffentlicht.&lt;br /&gt;
[[http://www.gpsbabel.org/ GPS Babel]] eignet sich wunderbar, um ausgelesene Daten in ein Google Earth kompatibles Format umzuwandeln, um sich z.B. die GPS Logs anzusehen. Auch können in Google Earth erstellte Pfade so als Waylist für den Mini Navigator umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;br /&gt;
[[Category:GPS|G]]&lt;br /&gt;
[[Category:Projekte|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30901</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30901"/>
		<updated>2008-09-07T15:26:09Z</updated>

		<summary type="html">&lt;p&gt;Matze88: Kategorien erweitert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, in dem die meiste Arbeit steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts: [[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Achtung:&#039;&#039; Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
Für das Rechnen mit Koordinaten benutze ich hauptsächlich eine Funktion:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t calculate_distance (gps_coords *a, gps_coords *b)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t latstate = 0;&lt;br /&gt;
  uint32_t lat_distance;&lt;br /&gt;
  if(a-&amp;gt;lat &amp;gt; b-&amp;gt;lat)&lt;br /&gt;
  {&lt;br /&gt;
    latstate = 1;&lt;br /&gt;
    lat_distance = a-&amp;gt;lat - b-&amp;gt; lat;&lt;br /&gt;
  }&lt;br /&gt;
  else lat_distance = b-&amp;gt;lat - a-&amp;gt;lat;&lt;br /&gt;
  lat_distance = mul32_16u(div32u(lat_distance,100),11112);	// * 10^7 * 10^-2 *10^-1= *10^4 meters&lt;br /&gt;
  lat_distance = div32u(lat_distance, 10000);&lt;br /&gt;
  uint16_t distance_cache = lat_distance;			&lt;br /&gt;
  lat_distance = mul32_16u(lat_distance, lat_distance);		// square of lat_distance&lt;br /&gt;
&lt;br /&gt;
  uint8_t lonstate = 0;&lt;br /&gt;
  uint32_t lon_distance;&lt;br /&gt;
  if(a-&amp;gt;lon &amp;gt; b-&amp;gt;lon)&lt;br /&gt;
  {&lt;br /&gt;
    lonstate = 1;&lt;br /&gt;
    lon_distance = a-&amp;gt;lon - b-&amp;gt;lon;&lt;br /&gt;
  }&lt;br /&gt;
  else lon_distance = b-&amp;gt;lon - a-&amp;gt;lon;&lt;br /&gt;
  /* square(((lon_diff / 1000) * cos_val * 1113) / 10000) = lon_diff * 111,3 * cos(angle)*/&lt;br /&gt;
  lon_distance = mul32_16u(div32u(lon_distance, 1000), my_cos(div32u(labs(a-&amp;gt;lat),10000000)));  //-&amp;gt;10^6  // simplification:&lt;br /&gt;
                                              //a-&amp;gt;lat instead of a-&amp;gt;lat+b-&amp;gt;lat/2&lt;br /&gt;
  lon_distance = div32u(mul32_16u(lon_distance, 1113),10000); // -&amp;gt;meters&lt;br /&gt;
  lon_distance = isqrt32(mul32_16u(lon_distance, lon_distance) + lat_distance);&lt;br /&gt;
  uint8_t temp_angle = (my_acos(div32u(mul32_16u(distance_cache,100),lon_distance)) * 100) &amp;gt;&amp;gt; 8;	// 0-90 deg. angle&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  if(latstate)&lt;br /&gt;
  {&lt;br /&gt;
    if(lonstate) temp_angle +=70;&lt;br /&gt;
    else temp_angle = 70 - temp_angle;&lt;br /&gt;
  }&lt;br /&gt;
  else if(lonstate)&lt;br /&gt;
    temp_angle = 140 - temp_angle;&lt;br /&gt;
  &lt;br /&gt;
 return (lon_distance) | ((uint32_t)temp_angle &amp;lt;&amp;lt; 16);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Zusammenarbeit mit einfachsten, auf Tabellen basierenden Kosinus- und Umkehrfunktion liefert diese Ergebnisse mit meistens nicht einmal 2 % Abweichung. Der Ablauf:&lt;br /&gt;
# Breitendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Längendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Nach dem Satz des Pythagoras den Abstand der Punkte bestimmen, Länge und Breite stehen dabei für orthogonale Vektoren, somit haben wir ein rechtwinkliges Dreieck&lt;br /&gt;
# Da wir hier gleich alle Seiten berechnet haben, kann einfach der Winkel zwischen Ankathete und Hypothenuse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
Der Winkel muss zum Schluss noch korrigiert werden, jenachdem, in welchem Quadranten (Koordinate a als Ursprung und b als Punkt im 2 dimensionalen Koordinatensystem betrachtet) wir uns befinden.&lt;br /&gt;
Diese Funktion liefert für alle Punkte, die nicht mehr als 65535 Meter auseinander liegen korrekte Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variabel, bis zu 5).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 5 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;0 - allgemeine GPS Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;1 - GPS Logging Funktionen&#039;&#039;&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1 16 128 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;2 - Wegpunkt Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei (Erneuter Aufruf: Nächste Wegpunkt Datei öffnen)&lt;br /&gt;
** 1* - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 = 1 sind es 2048 Meter Schritte.&lt;br /&gt;
** 2* - Erster Aufruf: Anzeige des Kurses zum Wegpunkt. LED 0 ist dabei die Bewegungsrichtung.&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der jetzige weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
** LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
     * Für 1 und 2 gilt: Erneuter Aufruf navigiert den nachfolgenden Wegpunkt an.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;3 - Wegpunkte einspeichern&#039;&#039;&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkte Datei und gibt die Nummer binär aus. Diese Schreibzugriffe können parallel zum GPS Log durchgeführt werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;4 - Allgemeine Optionen&#039;&#039;&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 700 ms muss sie losgelassen und nach weiteren 400 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt.&lt;br /&gt;
** (LED 5 und 6 geben den Batteriestatus wieder. 6 ist voll, 5 ist fast leer und garnichts steht für leer)&lt;br /&gt;
&lt;br /&gt;
== PC Interaktion ==&lt;br /&gt;
Für den PC habe ich bereits einfachste Übertragungsprogramme geschrieben, welche jedoch zur Zeit noch ungetestet und stark aufs Debugging ausgelegt sind. Diese werden erst zu späterer Zeit veröffentlicht.&lt;br /&gt;
[[http://www.gpsbabel.org/ GPS Babel]] eignet sich wunderbar, um ausgelesene Daten in ein Google Earth kompatibles Format umzuwandeln, um sich z.B. die GPS Logs anzusehen. Auch können in Google Earth erstellte Pfade so als Waylist für den Mini Navigator umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;br /&gt;
[[Category:GPS|G]]&lt;br /&gt;
[[Category:Projekte|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30809</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30809"/>
		<updated>2008-08-31T22:26:41Z</updated>

		<summary type="html">&lt;p&gt;Matze88: /* PC Interaktion */ Link angepasst&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, in dem die meiste Arbeit steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts: [[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Achtung:&#039;&#039; Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
Für das Rechnen mit Koordinaten benutze ich hauptsächlich eine Funktion:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t calculate_distance (gps_coords *a, gps_coords *b)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t latstate = 0;&lt;br /&gt;
  uint32_t lat_distance;&lt;br /&gt;
  if(a-&amp;gt;lat &amp;gt; b-&amp;gt;lat)&lt;br /&gt;
  {&lt;br /&gt;
    latstate = 1;&lt;br /&gt;
    lat_distance = a-&amp;gt;lat - b-&amp;gt; lat;&lt;br /&gt;
  }&lt;br /&gt;
  else lat_distance = b-&amp;gt;lat - a-&amp;gt;lat;&lt;br /&gt;
  lat_distance = mul32_16u(div32u(lat_distance,100),11112);	// * 10^7 * 10^-2 *10^-1= *10^4 meters&lt;br /&gt;
  lat_distance = div32u(lat_distance, 10000);&lt;br /&gt;
  uint16_t distance_cache = lat_distance;			&lt;br /&gt;
  lat_distance = mul32_16u(lat_distance, lat_distance);		// square of lat_distance&lt;br /&gt;
&lt;br /&gt;
  uint8_t lonstate = 0;&lt;br /&gt;
  uint32_t lon_distance;&lt;br /&gt;
  if(a-&amp;gt;lon &amp;gt; b-&amp;gt;lon)&lt;br /&gt;
  {&lt;br /&gt;
    lonstate = 1;&lt;br /&gt;
    lon_distance = a-&amp;gt;lon - b-&amp;gt;lon;&lt;br /&gt;
  }&lt;br /&gt;
  else lon_distance = b-&amp;gt;lon - a-&amp;gt;lon;&lt;br /&gt;
  /* square(((lon_diff / 1000) * cos_val * 1113) / 10000) = lon_diff * 111,3 * cos(angle)*/&lt;br /&gt;
  lon_distance = mul32_16u(div32u(lon_distance, 1000), my_cos(div32u(labs(a-&amp;gt;lat),10000000)));  //-&amp;gt;10^6  // simplification:&lt;br /&gt;
                                              //a-&amp;gt;lat instead of a-&amp;gt;lat+b-&amp;gt;lat/2&lt;br /&gt;
  lon_distance = div32u(mul32_16u(lon_distance, 1113),10000); // -&amp;gt;meters&lt;br /&gt;
  lon_distance = isqrt32(mul32_16u(lon_distance, lon_distance) + lat_distance);&lt;br /&gt;
  uint8_t temp_angle = (my_acos(div32u(mul32_16u(distance_cache,100),lon_distance)) * 100) &amp;gt;&amp;gt; 8;	// 0-90 deg. angle&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  if(latstate)&lt;br /&gt;
  {&lt;br /&gt;
    if(lonstate) temp_angle +=70;&lt;br /&gt;
    else temp_angle = 70 - temp_angle;&lt;br /&gt;
  }&lt;br /&gt;
  else if(lonstate)&lt;br /&gt;
    temp_angle = 140 - temp_angle;&lt;br /&gt;
  &lt;br /&gt;
 return (lon_distance) | ((uint32_t)temp_angle &amp;lt;&amp;lt; 16);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Zusammenarbeit mit einfachsten, auf Tabellen basierenden Kosinus- und Umkehrfunktion liefert diese Ergebnisse mit meistens nicht einmal 2 % Abweichung. Der Ablauf:&lt;br /&gt;
# Breitendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Längendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Nach dem Satz des Pythagoras den Abstand der Punkte bestimmen, Länge und Breite stehen dabei für orthogonale Vektoren, somit haben wir ein rechtwinkliges Dreieck&lt;br /&gt;
# Da wir hier gleich alle Seiten berechnet haben, kann einfach der Winkel zwischen Ankathete und Hypothenuse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
Der Winkel muss zum Schluss noch korrigiert werden, jenachdem, in welchem Quadranten (Koordinate a als Ursprung und b als Punkt im 2 dimensionalen Koordinatensystem betrachtet) wir uns befinden.&lt;br /&gt;
Diese Funktion liefert für alle Punkte, die nicht mehr als 65535 Meter auseinander liegen korrekte Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variabel, bis zu 5).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 5 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;0 - allgemeine GPS Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;1 - GPS Logging Funktionen&#039;&#039;&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1 16 128 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;2 - Wegpunkt Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei (Erneuter Aufruf: Nächste Wegpunkt Datei öffnen)&lt;br /&gt;
** 1* - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 = 1 sind es 2048 Meter Schritte.&lt;br /&gt;
** 2* - Erster Aufruf: Anzeige des Kurses zum Wegpunkt. LED 0 ist dabei die Bewegungsrichtung.&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der jetzige weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
** LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
     * Für 1 und 2 gilt: Erneuter Aufruf navigiert den nachfolgenden Wegpunkt an.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;3 - Wegpunkte einspeichern&#039;&#039;&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkte Datei und gibt die Nummer binär aus. Diese Schreibzugriffe können parallel zum GPS Log durchgeführt werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;4 - Allgemeine Optionen&#039;&#039;&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 700 ms muss sie losgelassen und nach weiteren 400 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt.&lt;br /&gt;
** (LED 5 und 6 geben den Batteriestatus wieder. 6 ist voll, 5 ist fast leer und garnichts steht für leer)&lt;br /&gt;
&lt;br /&gt;
== PC Interaktion ==&lt;br /&gt;
Für den PC habe ich bereits einfachste Übertragungsprogramme geschrieben, welche jedoch zur Zeit noch ungetestet und stark aufs Debugging ausgelegt sind. Diese werden erst zu späterer Zeit veröffentlicht.&lt;br /&gt;
[[http://www.gpsbabel.org/ GPS Babel]] eignet sich wunderbar, um ausgelesene Daten in ein Google Earth kompatibles Format umzuwandeln, um sich z.B. die GPS Logs anzusehen. Auch können in Google Earth erstellte Pfade so als Waylist für den Mini Navigator umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30808</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30808"/>
		<updated>2008-08-31T22:07:39Z</updated>

		<summary type="html">&lt;p&gt;Matze88: /* GPS Zugriff */ Minimale Formatanpassungen&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, in dem die meiste Arbeit steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts: [[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Achtung:&#039;&#039; Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
Für das Rechnen mit Koordinaten benutze ich hauptsächlich eine Funktion:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t calculate_distance (gps_coords *a, gps_coords *b)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t latstate = 0;&lt;br /&gt;
  uint32_t lat_distance;&lt;br /&gt;
  if(a-&amp;gt;lat &amp;gt; b-&amp;gt;lat)&lt;br /&gt;
  {&lt;br /&gt;
    latstate = 1;&lt;br /&gt;
    lat_distance = a-&amp;gt;lat - b-&amp;gt; lat;&lt;br /&gt;
  }&lt;br /&gt;
  else lat_distance = b-&amp;gt;lat - a-&amp;gt;lat;&lt;br /&gt;
  lat_distance = mul32_16u(div32u(lat_distance,100),11112);	// * 10^7 * 10^-2 *10^-1= *10^4 meters&lt;br /&gt;
  lat_distance = div32u(lat_distance, 10000);&lt;br /&gt;
  uint16_t distance_cache = lat_distance;			&lt;br /&gt;
  lat_distance = mul32_16u(lat_distance, lat_distance);		// square of lat_distance&lt;br /&gt;
&lt;br /&gt;
  uint8_t lonstate = 0;&lt;br /&gt;
  uint32_t lon_distance;&lt;br /&gt;
  if(a-&amp;gt;lon &amp;gt; b-&amp;gt;lon)&lt;br /&gt;
  {&lt;br /&gt;
    lonstate = 1;&lt;br /&gt;
    lon_distance = a-&amp;gt;lon - b-&amp;gt;lon;&lt;br /&gt;
  }&lt;br /&gt;
  else lon_distance = b-&amp;gt;lon - a-&amp;gt;lon;&lt;br /&gt;
  /* square(((lon_diff / 1000) * cos_val * 1113) / 10000) = lon_diff * 111,3 * cos(angle)*/&lt;br /&gt;
  lon_distance = mul32_16u(div32u(lon_distance, 1000), my_cos(div32u(labs(a-&amp;gt;lat),10000000)));  //-&amp;gt;10^6  // simplification:&lt;br /&gt;
                                              //a-&amp;gt;lat instead of a-&amp;gt;lat+b-&amp;gt;lat/2&lt;br /&gt;
  lon_distance = div32u(mul32_16u(lon_distance, 1113),10000); // -&amp;gt;meters&lt;br /&gt;
  lon_distance = isqrt32(mul32_16u(lon_distance, lon_distance) + lat_distance);&lt;br /&gt;
  uint8_t temp_angle = (my_acos(div32u(mul32_16u(distance_cache,100),lon_distance)) * 100) &amp;gt;&amp;gt; 8;	// 0-90 deg. angle&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  if(latstate)&lt;br /&gt;
  {&lt;br /&gt;
    if(lonstate) temp_angle +=70;&lt;br /&gt;
    else temp_angle = 70 - temp_angle;&lt;br /&gt;
  }&lt;br /&gt;
  else if(lonstate)&lt;br /&gt;
    temp_angle = 140 - temp_angle;&lt;br /&gt;
  &lt;br /&gt;
 return (lon_distance) | ((uint32_t)temp_angle &amp;lt;&amp;lt; 16);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Zusammenarbeit mit einfachsten, auf Tabellen basierenden Kosinus- und Umkehrfunktion liefert diese Ergebnisse mit meistens nicht einmal 2 % Abweichung. Der Ablauf:&lt;br /&gt;
# Breitendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Längendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
# Nach dem Satz des Pythagoras den Abstand der Punkte bestimmen, Länge und Breite stehen dabei für orthogonale Vektoren, somit haben wir ein rechtwinkliges Dreieck&lt;br /&gt;
# Da wir hier gleich alle Seiten berechnet haben, kann einfach der Winkel zwischen Ankathete und Hypothenuse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
Der Winkel muss zum Schluss noch korrigiert werden, jenachdem, in welchem Quadranten (Koordinate a als Ursprung und b als Punkt im 2 dimensionalen Koordinatensystem betrachtet) wir uns befinden.&lt;br /&gt;
Diese Funktion liefert für alle Punkte, die nicht mehr als 65535 Meter auseinander liegen korrekte Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variabel, bis zu 5).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 5 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;0 - allgemeine GPS Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;1 - GPS Logging Funktionen&#039;&#039;&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1 16 128 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;2 - Wegpunkt Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei (Erneuter Aufruf: Nächste Wegpunkt Datei öffnen)&lt;br /&gt;
** 1* - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 = 1 sind es 2048 Meter Schritte.&lt;br /&gt;
** 2* - Erster Aufruf: Anzeige des Kurses zum Wegpunkt. LED 0 ist dabei die Bewegungsrichtung.&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der jetzige weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
** LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
     * Für 1 und 2 gilt: Erneuter Aufruf navigiert den nachfolgenden Wegpunkt an.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;3 - Wegpunkte einspeichern&#039;&#039;&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkte Datei und gibt die Nummer binär aus. Diese Schreibzugriffe können parallel zum GPS Log durchgeführt werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;4 - Allgemeine Optionen&#039;&#039;&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 700 ms muss sie losgelassen und nach weiteren 400 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt.&lt;br /&gt;
** (LED 5 und 6 geben den Batteriestatus wieder. 6 ist voll, 5 ist fast leer und garnichts steht für leer)&lt;br /&gt;
&lt;br /&gt;
== PC Interaktion ==&lt;br /&gt;
Für den PC habe ich bereits einfachste Übertragungsprogramme geschrieben, welche jedoch zur Zeit noch ungetestet und stark aufs Debugging ausgelegt sind. Diese werden erst zu späterer Zeit veröffentlicht.&lt;br /&gt;
[[http://www.gpsbabel.org/|GPS Babel]] eignet sich wunderbar, um ausgelesene Daten in ein Google Earth kompatibles Format umzuwandeln, um sich z.B. die GPS Logs anzusehen. Auch können in Google Earth erstellte Pfade so als Waylist für den Mini Navigator umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:GpsMiniNavigatorSchaltplan.png&amp;diff=30807</id>
		<title>Datei:GpsMiniNavigatorSchaltplan.png</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:GpsMiniNavigatorSchaltplan.png&amp;diff=30807"/>
		<updated>2008-08-31T22:00:28Z</updated>

		<summary type="html">&lt;p&gt;Matze88: hat eine neue Version von „Bild:GpsMiniNavigatorSchaltplan.png“ hochgeladen: Aktualisierter Schaltplan&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Schaltplan zur GPS Mini Navigator Platine.&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30804</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30804"/>
		<updated>2008-08-31T21:58:38Z</updated>

		<summary type="html">&lt;p&gt;Matze88: Letzte Änderungen&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, in dem die meiste Arbeit steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts: [[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Achtung:&#039;&#039; Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
Für das Rechnen mit Koordinaten benutze ich hauptsächlich eine Funktion:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t calculate_distance (gps_coords *a, gps_coords *b)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t latstate = 0;&lt;br /&gt;
  uint32_t lat_distance;&lt;br /&gt;
  if(a-&amp;gt;lat &amp;gt; b-&amp;gt;lat)&lt;br /&gt;
  {&lt;br /&gt;
    latstate = 1;&lt;br /&gt;
    lat_distance = a-&amp;gt;lat - b-&amp;gt; lat;&lt;br /&gt;
  }&lt;br /&gt;
  else lat_distance = b-&amp;gt;lat - a-&amp;gt;lat;&lt;br /&gt;
  lat_distance = mul32_16u(div32u(lat_distance,100),11112);	// * 10^7 * 10^-2 *10^-1= *10^4 meters&lt;br /&gt;
  lat_distance = div32u(lat_distance, 10000);&lt;br /&gt;
  uint16_t distance_cache = lat_distance;			&lt;br /&gt;
  lat_distance = mul32_16u(lat_distance, lat_distance);		// square of lat_distance&lt;br /&gt;
&lt;br /&gt;
  uint8_t lonstate = 0;&lt;br /&gt;
  uint32_t lon_distance;&lt;br /&gt;
  if(a-&amp;gt;lon &amp;gt; b-&amp;gt;lon)&lt;br /&gt;
  {&lt;br /&gt;
    lonstate = 1;&lt;br /&gt;
    lon_distance = a-&amp;gt;lon - b-&amp;gt;lon;&lt;br /&gt;
  }&lt;br /&gt;
  else lon_distance = b-&amp;gt;lon - a-&amp;gt;lon;&lt;br /&gt;
  /* square(((lon_diff / 1000) * cos_val * 1113) / 10000) = lon_diff * 111,3 * cos(angle)*/&lt;br /&gt;
  lon_distance = mul32_16u(div32u(lon_distance, 1000), my_cos(div32u(labs(a-&amp;gt;lat),10000000)));  //-&amp;gt;10^6  // simplification:&lt;br /&gt;
                                              //a-&amp;gt;lat instead of a-&amp;gt;lat+b-&amp;gt;lat/2&lt;br /&gt;
  lon_distance = div32u(mul32_16u(lon_distance, 1113),10000); // -&amp;gt;meters&lt;br /&gt;
  lon_distance = isqrt32(mul32_16u(lon_distance, lon_distance) + lat_distance);&lt;br /&gt;
  uint8_t temp_angle = (my_acos(div32u(mul32_16u(distance_cache,100),lon_distance)) * 100) &amp;gt;&amp;gt; 8;	// 0-90 deg. angle&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  if(latstate)&lt;br /&gt;
  {&lt;br /&gt;
    if(lonstate) temp_angle +=70;&lt;br /&gt;
    else temp_angle = 70 - temp_angle;&lt;br /&gt;
  }&lt;br /&gt;
  else if(lonstate)&lt;br /&gt;
    temp_angle = 140 - temp_angle;&lt;br /&gt;
  &lt;br /&gt;
 return (lon_distance) | ((uint32_t)temp_angle &amp;lt;&amp;lt; 16);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Zusammenarbeit mit einfachsten, auf Tabellen basierenden Kosinus- und Umkehrfunktion liefert diese Ergebnisse mit meistens nicht einmal 2 % Abweichung. Der Ablauf:&lt;br /&gt;
a) Breitendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
b) Längendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
c) Nach dem Satz des Pythagoras den Abstand der Punkte bestimmen, Länge und Breite stehen dabei für orthogonale Vektoren, somit haben wir ein rechtwinkliges Dreieck&lt;br /&gt;
d) Da wir hier gleich alle Seiten berechnet haben, kann einfach der Winkel zwischen Ankathete und Hypothenuse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
Der Winkel muss zum Schluss noch korrigiert werden, jenachdem, in welchem Quadranten (Koordinate a als Ursprung und b als Punkt im 2 dimensionalen Koordinatensystem betrachtet) wir uns befinden.&lt;br /&gt;
Diese Funktion liefert für alle Punkte, die nicht mehr als 65535 Meter auseinander liegen korrekte Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variabel, bis zu 5).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 5 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;0 - allgemeine GPS Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;1 - GPS Logging Funktionen&#039;&#039;&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1 16 128 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;2 - Wegpunkt Funktionen&#039;&#039;&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei (Erneuter Aufruf: Nächste Wegpunkt Datei öffnen)&lt;br /&gt;
** 1* - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 = 1 sind es 2048 Meter Schritte.&lt;br /&gt;
** 2* - Erster Aufruf: Anzeige des Kurses zum Wegpunkt. LED 0 ist dabei die Bewegungsrichtung.&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der jetzige weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
** LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
     * Für 1 und 2 gilt: Erneuter Aufruf navigiert den nachfolgenden Wegpunkt an.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;3 - Wegpunkte einspeichern&#039;&#039;&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkte Datei und gibt die Nummer binär aus. Diese Schreibzugriffe können parallel zum GPS Log durchgeführt werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;4 - Allgemeine Optionen&#039;&#039;&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 700 ms muss sie losgelassen und nach weiteren 400 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt.&lt;br /&gt;
** (LED 5 und 6 geben den Batteriestatus wieder. 6 ist voll, 5 ist fast leer und garnichts steht für leer)&lt;br /&gt;
&lt;br /&gt;
== PC Interaktion ==&lt;br /&gt;
Für den PC habe ich bereits einfachste Übertragungsprogramme geschrieben, welche jedoch zur Zeit noch ungetestet und stark aufs Debugging ausgelegt sind. Diese werden erst zu späterer Zeit veröffentlicht.&lt;br /&gt;
[[http://www.gpsbabel.org/|GPS Babel]] eignet sich wunderbar, um ausgelesene Daten in ein Google Earth kompatibles Format umzuwandeln, um sich z.B. die GPS Logs anzusehen. Auch können in Google Earth erstellte Pfade so als Waylist für den Mini Navigator umgewandelt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30793</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30793"/>
		<updated>2008-08-31T21:49:37Z</updated>

		<summary type="html">&lt;p&gt;Matze88: /* GPS Zugriff */ Funktionen erläutert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, in dem die meiste Arbeit steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts: [[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei. Achtung: Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
Für das Rechnen mit Koordinaten benutze ich hauptsächlich eine Funktion:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t calculate_distance (gps_coords *a, gps_coords *b)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t latstate = 0;&lt;br /&gt;
  uint32_t lat_distance;&lt;br /&gt;
  if(a-&amp;gt;lat &amp;gt; b-&amp;gt;lat)&lt;br /&gt;
  {&lt;br /&gt;
    latstate = 1;&lt;br /&gt;
    lat_distance = a-&amp;gt;lat - b-&amp;gt; lat;&lt;br /&gt;
  }&lt;br /&gt;
  else lat_distance = b-&amp;gt;lat - a-&amp;gt;lat;&lt;br /&gt;
  lat_distance = mul32_16u(div32u(lat_distance,100),11112);	// * 10^7 * 10^-2 *10^-1= *10^4 meters&lt;br /&gt;
  lat_distance = div32u(lat_distance, 10000);&lt;br /&gt;
  uint16_t distance_cache = lat_distance;			&lt;br /&gt;
  lat_distance = mul32_16u(lat_distance, lat_distance);		// square of lat_distance&lt;br /&gt;
&lt;br /&gt;
  uint8_t lonstate = 0;&lt;br /&gt;
  uint32_t lon_distance;&lt;br /&gt;
  if(a-&amp;gt;lon &amp;gt; b-&amp;gt;lon)&lt;br /&gt;
  {&lt;br /&gt;
    lonstate = 1;&lt;br /&gt;
    lon_distance = a-&amp;gt;lon - b-&amp;gt;lon;&lt;br /&gt;
  }&lt;br /&gt;
  else lon_distance = b-&amp;gt;lon - a-&amp;gt;lon;&lt;br /&gt;
  /* square(((lon_diff / 1000) * cos_val * 1113) / 10000) = lon_diff * 111,3 * cos(angle)*/&lt;br /&gt;
  lon_distance = mul32_16u(div32u(lon_distance, 1000), my_cos(div32u(labs(a-&amp;gt;lat),10000000)));  //-&amp;gt;10^6  // simplification:&lt;br /&gt;
                                              //a-&amp;gt;lat instead of a-&amp;gt;lat+b-&amp;gt;lat/2&lt;br /&gt;
  lon_distance = div32u(mul32_16u(lon_distance, 1113),10000); // -&amp;gt;meters&lt;br /&gt;
  lon_distance = isqrt32(mul32_16u(lon_distance, lon_distance) + lat_distance);&lt;br /&gt;
  uint8_t temp_angle = (my_acos(div32u(mul32_16u(distance_cache,100),lon_distance)) * 100) &amp;gt;&amp;gt; 8;	// 0-90 deg. angle&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  if(latstate)&lt;br /&gt;
  {&lt;br /&gt;
    if(lonstate) temp_angle +=70;&lt;br /&gt;
    else temp_angle = 70 - temp_angle;&lt;br /&gt;
  }&lt;br /&gt;
  else if(lonstate)&lt;br /&gt;
    temp_angle = 140 - temp_angle;&lt;br /&gt;
  &lt;br /&gt;
 return (lon_distance) | ((uint32_t)temp_angle &amp;lt;&amp;lt; 16);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Zusammenarbeit mit einfachsten, auf Tabellen basierenden Kosinus und Umkehrfunktion liefert diese Ergebnisse mit meistens nicht einmal 2 % Abweichung. Der Ablauf:&lt;br /&gt;
a) Breitendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
b) Längendifferenz der Punkte nach Meter umrechnen&lt;br /&gt;
c) Nach dem Satz des Pythagoras den Abstand der Punkte bestimmen, Länge und Breite stehen dabei für orthogonale Vektoren, somit haben wir ein rechtwinkliges Dreieck&lt;br /&gt;
d) Da wir hier gleich alle Seiten berechnet haben, kann einfach der Winkel zwischen Ankathete und Hypothenuse berechnet werden.&lt;br /&gt;
&lt;br /&gt;
Der Winkel muss zum Schluss noch korrigiert werden, jenachdem, in welchem Quadranten (Koordinate a als Ursprung und b als Punkt im 2 dimensionalen Koordinatensystem betrachtet) wir uns befinden.&lt;br /&gt;
Diese Funktion liefert für alle Punkte, die nicht mehr als 65535 Meter auseinander liegen korrekte Ergebnisse.&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variabel, bis zu 5).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 5 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert:&lt;br /&gt;
* 0 - allgemeine GPS Funktionen&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
* 1 - GPS Logging Funktionen&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1 16 128 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
* 2 - Wegpunkt Funktionen&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei&lt;br /&gt;
Erneuter Aufruf: Nächste Wegpunkt Datei öffnen&lt;br /&gt;
** 1 - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 = 1 sind es 2048 Meter Schritte.&lt;br /&gt;
** 2 - Erster Aufruf: Anzeige des Kurses zum Wegpunkt. LED 0 ist dabei die Bewegungsrichtung.&lt;br /&gt;
Für 1 und 2 gilt: Erneuter Aufruf navigiert den nachfolgenden Wegpunkt an.&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der jetzige weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
* 3 - Wegpunkte einspeichern&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkte Datei und gibt die Nummer binär aus. Diese Schreibzugriffe können parallel zum GPS Log durchgeführt werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
* 4 - Allgemeine Optionen (LED 5 und 6 geben den Batteriestatus wieder. 6 ist voll, 5 ist fast leer und garnichts steht für leer)&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 700 ms muss sie losgelassen und nach weiteren 400 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30792</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30792"/>
		<updated>2008-08-31T21:40:49Z</updated>

		<summary type="html">&lt;p&gt;Matze88: /* Software */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, in dem die meiste Arbeit steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts: [[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei. Achtung: Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variabel, bis zu 5).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 5 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert:&lt;br /&gt;
* 0 - allgemeine GPS Funktionen&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
* 1 - GPS Logging Funktionen&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1 16 128 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
* 2 - Wegpunkt Funktionen&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei&lt;br /&gt;
Erneuter Aufruf: Nächste Wegpunkt Datei öffnen&lt;br /&gt;
** 1 - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 = 1 sind es 2048 Meter Schritte.&lt;br /&gt;
** 2 - Erster Aufruf: Anzeige des Kurses zum Wegpunkt. LED 0 ist dabei die Bewegungsrichtung.&lt;br /&gt;
Für 1 und 2 gilt: Erneuter Aufruf navigiert den nachfolgenden Wegpunkt an.&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der jetzige weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
* 3 - Wegpunkte einspeichern&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkte Datei und gibt die Nummer binär aus. Diese Schreibzugriffe können parallel zum GPS Log durchgeführt werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
* 4 - Allgemeine Optionen (LED 5 und 6 geben den Batteriestatus wieder. 6 ist voll, 5 ist fast leer und garnichts steht für leer)&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 700 ms muss sie losgelassen und nach weiteren 400 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30791</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30791"/>
		<updated>2008-08-31T21:39:23Z</updated>

		<summary type="html">&lt;p&gt;Matze88: /* SD-Karte und Dateisystem */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, wo die meiste Arbeit drin steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts: [[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei. Achtung: Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variabel, bis zu 5).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 5 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert:&lt;br /&gt;
* 0 - allgemeine GPS Funktionen&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
* 1 - GPS Logging Funktionen&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1 16 128 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
* 2 - Wegpunkt Funktionen&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei&lt;br /&gt;
Erneuter Aufruf: Nächste Wegpunkt Datei öffnen&lt;br /&gt;
** 1 - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 = 1 sind es 2048 Meter Schritte.&lt;br /&gt;
** 2 - Erster Aufruf: Anzeige des Kurses zum Wegpunkt. LED 0 ist dabei die Bewegungsrichtung.&lt;br /&gt;
Für 1 und 2 gilt: Erneuter Aufruf navigiert den nachfolgenden Wegpunkt an.&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der jetzige weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
* 3 - Wegpunkte einspeichern&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkte Datei und gibt die Nummer binär aus. Diese Schreibzugriffe können parallel zum GPS Log durchgeführt werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
* 4 - Allgemeine Optionen (LED 5 und 6 geben den Batteriestatus wieder. 6 ist voll, 5 ist fast leer und garnichts steht für leer)&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 700 ms muss sie losgelassen und nach weiteren 400 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30790</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30790"/>
		<updated>2008-08-31T21:38:48Z</updated>

		<summary type="html">&lt;p&gt;Matze88: Vervollständigung&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, wo die meiste Arbeit drin steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts: [[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist noch der Bootloader von Peter Danneger zu erwähnen, welcher bei so einem Projekt sehr hilfreich ist. Auf der Platine gibt es wenig Platz für einen ISP Anschluss, sodass die Firmware anderweitig auf den µC gespielt werden muss. Der Bootloader benötigt nur 512 Byte und bringt ein Software Uart mit. Das Bluetooth-Modul eignet sich somit auch für Firmware Updates, das Beschreiben des kompletten Flashs dauert bei mir 3,78 Sekunden.&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
=== SD-Karte und Dateisystem ===&lt;br /&gt;
&lt;br /&gt;
Ulrich Radigs MMC/SD Library eignet sich für kleine bis mittelgroße Mikrocontroller Projekte aufgrund seiner Einfachheit sehr gut. Die Bibliothek unterstützt hauptsächlich das Schreiben und Lesen von ganzen Blöcken, neben dem Lesen von CID und CSD Register. Ich habe dabei die Block-Lese Funktion erweitert, sodass man auch Teile von Blöcken lesen kann. Dabei wird der Takt zur SD-Karte während einem Block Read einfach angehalten und an späterer Stelle fortgesetzt. Dies ist auf einem System mit 1 kByte Ram sehr praktisch, da man Lesevorgänge nicht zwischenspeichern muss. Der Nachteil ist allerdings, dass die SD-Karte und der SPI Bus bis zum Abschluss des Lesevorgangs blockiert sind.&lt;br /&gt;
&lt;br /&gt;
Dafür ergeben sich dann folgende Funktionen:&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_start (uint32_t addr);&amp;lt;/c&amp;gt;&lt;br /&gt;
Initialisiert den Lesevorgang ab Sektor addr.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t mmc_read_sector_continue(uint8_t *Buffer, uint16_t count);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (count) Bytes in den übergebenen Puffer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void mmc_read_sector_finish(uint8_t *Buffer, uint8_t discard_bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Schließt den Lesevorgang ab, wobei man die restlichen Bytes entweder in den übergebenen Puffer speichern oder aber verwerfen (discard_bytes = 1) kann.&lt;br /&gt;
&lt;br /&gt;
Das Dateisystem ist möglichst einfach gestrikt und baut auf Sektoradressierung auf. Dabei gibt es maximal 256 Dateieinträge, jede Datei kann beliebig lang sein. Es unterstützt das Anlegen &amp;amp; Schreiben in neue Dateien, das Öffnen &amp;amp; Lesen bestehender Dateien, das Löschen von Dateien und das Leeren des gesamten Speichermediums. Löschen (großer Dateien) und Formatieren dauert aufgrund des sektorbasierenden Aufbaus sehr lange. Ein für dieses Projekt wichtiges Feature ist die Möglichkeit, zwei Dateien parallel zu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Der Aufbau aller Sektoren ist wie folgt:&lt;br /&gt;
Byte 0: Dateityp. Bisher implementiert: 0 - FT_NONE, 1 - FT_LOG (GPS Aufzeichnung, 2 - FT_WAY (Liste von Wegpunkten zur Navigation)&lt;br /&gt;
&lt;br /&gt;
Byte 1 - 507: Nutzdaten&lt;br /&gt;
&lt;br /&gt;
Byte 508 - 511: Adresse des nächsten Sektors.&lt;br /&gt;
&lt;br /&gt;
Dabei werden lediglich die ersten 256 Sektoren als Dateitabelle angesehen, obwohl eine Datei theoretisch an jeder Stelle des Datenträgers anfangen könnte.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t create_file (uint8_t filetype);&amp;lt;/c&amp;gt;&lt;br /&gt;
Erstellt eine Datei des angegebenen Typs. Rückgabewert ist die Dateinummer&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t write_file (uint8_t *Buffer, uint8_t count);&amp;lt;c&amp;gt;&lt;br /&gt;
Schreibt in die zuvor mit create_file angelegte Datei, dabei maximal 255 Bytes am Stück. Rückgabewerte können Fehlermeldungen (-&amp;gt;filesystem_simple.h) sein.&lt;br /&gt;
Zum Schreiben wird ein 512 Byte großer Puffer benutzt, welcher beim Eintreffen des 508. Nutzdatenbytes auf die SD-Karte geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t close_write_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Füllt den Rest des Sektors mit Nullen auf und beendet den Schreibvorgang auf die Datei. Achtung: Die genaue Länge der Nutzdaten kann später nicht festgestellt werden, sie ist für dieses Projekt auch uninteressant. Die Restbytes bis zur nächsten Sektorgrenze sind immer 0, eine ungültige Adresse zum nächsten Sektor wird als End of File interpretiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t open_file (uint8_t filenumber);&amp;lt;/c&amp;gt;&lt;br /&gt;
Öffnet die angegebene Datei und gibt den Dateityp zurück. Diese Funktion lässt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;uint8_t read_file (uint8_t *Buffer, uint16_t bytes);&amp;lt;/c&amp;gt;&lt;br /&gt;
Liest (bytes) Bytes aus der geöffneten Datei in den Puffer. Auch hier bleibt die SD-Übertragung offen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void close_read_file ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion beendet den aktuellen Lesevorgang und beendet den SD-Zugriff.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;void swap_write_files ();&amp;lt;/c&amp;gt;&lt;br /&gt;
Diese Funktion sichert alle für den Schreibzugriff nötigen Variablen und schreibt den nicht vollständig gefüllten Schreibpuffer temporär auf die SD Karte. Danach wird ein vorher gesichertes Set von Variablen geladen und der Puffer von der SD Karte gelesen. Somit kann man zwei Dateien gleichzeitig zum Schreiben geöffnet haben und abwechselnd beschreiben.&lt;br /&gt;
&lt;br /&gt;
=== GPS Zugriff ===&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird nach dem einschalten mit&lt;br /&gt;
&amp;lt;c&amp;gt;void gps_enable(uint8_t enable_interrupt);&amp;lt;/c&amp;gt;&lt;br /&gt;
in den Sirf Modus initialisiert und je nach Parameter der USART RX Interrupt aktiviert. Alle Daten vom GPS-Modul werden dann im Interrupt ausgewertet und entsprechend in eine Struktur geschrieben:&lt;br /&gt;
&amp;lt;c&amp;gt;typedef struct&lt;br /&gt;
{&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      int32_t lat;&lt;br /&gt;
      int32_t lon;&lt;br /&gt;
      int32_t alt;&lt;br /&gt;
    };&lt;br /&gt;
    uint8_t coords[12];&lt;br /&gt;
  };&lt;br /&gt;
  union&lt;br /&gt;
  {&lt;br /&gt;
    uint32_t dword;&lt;br /&gt;
    struct&lt;br /&gt;
    {&lt;br /&gt;
      unsigned second:6;&lt;br /&gt;
      unsigned minute:6;&lt;br /&gt;
      unsigned hour:5;&lt;br /&gt;
      unsigned day:5;&lt;br /&gt;
      unsigned month:4;&lt;br /&gt;
      unsigned year:6;	  &lt;br /&gt;
    } s;&lt;br /&gt;
  } date;&lt;br /&gt;
  uint16_t sog;		// bit 0-2 is nav type&lt;br /&gt;
  uint8_t sv;&lt;br /&gt;
  uint8_t hdop;		// bit 7 is trickle power indicator (not used in current version)&lt;br /&gt;
} gps_log_entry_t;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es werden also Länge, Breite, Höhe, das aktuelle Datum, die Geschwindigkeit, die Anzahl der Satelliten, der Typ des Sat-Fixes (3D, 2D, etc.) und der HDOP geloggt. Außerdem wird der aktuelle Kurs in eine globale Variable geschrieben, sodass dieser im Programm zur Verfügung steht.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== LED und Tastenhandling ===&lt;br /&gt;
&lt;br /&gt;
Über einen Timer werden alle 2 ms die Tasten abgefragt und nach der Entprellroutine von Peter Danneger bearbeitet. Außerdem werden die LEDs gemäß der globalen Variable&lt;br /&gt;
&amp;lt;c&amp;gt;volatile uint8_t led;&amp;lt;/c&amp;gt;&lt;br /&gt;
gesetzt. Zusätzlich findet im Timerinterrupt noch eine Überprüfung statt, ob das Bluetooth-Modul aktiviert ist, indem der RX Pin vom Software Uart auf High-Pegel geprüft wird. Ist das Modul aktiviert, so wird auch das Software Uart aktiviert.&lt;br /&gt;
&lt;br /&gt;
=== Software Uart Handling ===&lt;br /&gt;
&lt;br /&gt;
In der Hauptschleife wird überprüft, ob das Software Uart aktiviert ist. Ist dies der Fall, so wird die Empfangsfunktion aufgerufen, welche für die Kommunikation mit dem PC zuständig ist. Das Protokoll sieht vor, dass alle eingehenden Bytes als Kommando interpretiert werden, bis ein gültiges Kommando empfangen wurde. Per switch Anweisung wird dann für jedes Kommando eigenständig Code ausgeführt. Die wichtigsten Funktionen dienen zum Lesen und Schreiben aus dem Dateisystem:&lt;br /&gt;
&lt;br /&gt;
SUART_CREATE_FILE gibt nach Aufruf direkt ein SUART_SUCCESS zurück und erwartet daraufhin den Dateitypen. Nach Ausgabe der Dateinummer folgt ein SUART_COMPLETED.&lt;br /&gt;
&lt;br /&gt;
SUART_WRITE_FILE gibt SUART_SUCCESS zurück, erwartet in 2 Bytes (Low Byte zuerst) die zu schreibende Dateilänge und interpretiert alle Folgedaten als Datenbytes, bis der Bytezähler auf 0 ist. Da der SD Kartenzugriff hier länger dauern kann, muss der PC alle (n*507)+1 Bytes warten, bis ein SUART_NEXT_SECTOR empfangen wird. Zusätzlich muss an dieser Stelle der Timer Interrupt deaktiviert werden, da sonst die 8 MHz des AVRs nicht mehr für 38400 bps Software Uart mit durchlaufenden Daten ausreicht.&lt;br /&gt;
&lt;br /&gt;
SUART_READ_FILE öffnet die übergebene Dateinummer, gibt den Dateityp zurück und schreibt dann jeweils 507 Bytes zum PC, bis ein SUART_STOP_COMMAND empfangen wurde oder die Datei zu Ende ist.&lt;br /&gt;
&lt;br /&gt;
SUART_CALL_BOOTLOADER stellt eine Sonderfunktion dar, welche auf die Erkennungsbytes von Peter Dannegers Bootloader reagiert und dann den Mikrocontroller per Watchdog reseted. Dies ermöglicht ein ganz einfaches Programmieren mit der zugehörigen Software direkt aus der laufenden Applikation.&lt;br /&gt;
&lt;br /&gt;
=== Menü ===&lt;br /&gt;
&lt;br /&gt;
Die Menüsteuerung ist sehr umfangreich, aber dennoch so einfach wie möglich gehalten. 8 LEDs und 2 Taster bieten nicht sehr viele Möglichkeiten.&lt;br /&gt;
Grundsätzlich sieht die Struktur wie folgt aus:&lt;br /&gt;
Es gibt Obermenüs (0-4) und Untermenüs (variabel, bis zu 5).&lt;br /&gt;
Die Tasten links und rechts kurz gedrückt schalten jeweils einen Menüpunkt/Untermenüpunkt weiter oder zurück.&lt;br /&gt;
Drückt man lange links, so wird ein Menüpunkt aufgerufen, also ein Untermenü betreten oder eine Aktion ausgeführt.&lt;br /&gt;
Lange rechts hingegen geht grundsätzlich zurück in das Wurzelmenü.&lt;br /&gt;
&lt;br /&gt;
Die LEDs 0 und 1 zeigen dabei die Menünummer an (Menü 5 wird ebenso wie 0 als 0 angezeigt, was aber aufgrund der Steuerung in beide Richtungen dennoch kein Problem darstellt), LEDs 2-4 die Untermenünummer. Leider muss sich der Anwender hier minimal mit Binärcode rumschlagen, aber für uns ist das kein Problem :-).&lt;br /&gt;
&lt;br /&gt;
Die LEDs 5-7 können je nach Menüpunkt Zusatzinformationen anzeigen. Außerdem blenden einige Untermenüs die Menüanzeige aus und nutzen alle 8 LEDs für ihre eigene Anzeige. Dies passiert aber erst nach einmaligem Aufruf, erst ein zweiter Aufruf durch Taste links lang führt dann die jeweilige Aktion aus.&lt;br /&gt;
&lt;br /&gt;
Das Menü ist zur Zeit wie folgt gegliedert:&lt;br /&gt;
* 0 - allgemeine GPS Funktionen&lt;br /&gt;
** 0 - Ausgabe der Breite als 7 stellige Dezimalzahl, jede Stelle wird dabei einzeln für eine Sekunde angezeigt, Nullen werden als LED 7 0 1 dargestellt, die 9 wird als LED 7 und LED 6 dargestellt.&lt;br /&gt;
** 1 - Ausgabe der Länge als 7 stellige Dezimalzahl&lt;br /&gt;
** 2 - Ausgabe der Höhe als 7 stellige Dezimalzahl&lt;br /&gt;
** 3 - Ausgabe der Geschwindigkeit, binär in km / h&lt;br /&gt;
** 4 - Ausgabe des aktuellen Kurses, LED 0 ist dabei Nord.&lt;br /&gt;
* 1 - GPS Logging Funktionen&lt;br /&gt;
** 0 - GPS Log starten und stoppen&lt;br /&gt;
** 1 - Einstellen eines GPS Log Intervals in Sekunden (1 16 128 1024)&lt;br /&gt;
** 2 - Einstellen eines GPS Log Intervals in Metern (Aus, 50, 400, 2000)&lt;br /&gt;
* 2 - Wegpunkt Funktionen&lt;br /&gt;
** 0 - Erster Aufruf: Anzeige aktuell geöffneter Wegpunkt Datei&lt;br /&gt;
Erneuter Aufruf: Nächste Wegpunkt Datei öffnen&lt;br /&gt;
** 1 - Erster Aufruf: Anzeige der Entfernung zum Wegpunkt in 16 Meter Schritten binär, falls LED 7 = 1 sind es 2048 Meter Schritte.&lt;br /&gt;
** 2 - Erster Aufruf: Anzeige des Kurses zum Wegpunkt. LED 0 ist dabei die Bewegungsrichtung.&lt;br /&gt;
Für 1 und 2 gilt: Erneuter Aufruf navigiert den nachfolgenden Wegpunkt an.&lt;br /&gt;
** 3 - Sucht automatisch den nächsten Wegpunkt aus der Wegpunktdatei. Sucht dabei nur vorwärts in der Datei, sodass alle bereits zurückgelegten Wegpunkte nicht mit einbezogen werden.&lt;br /&gt;
** 4 - Optionen: Aufruf erhöht Optionen um 1. LED 6 (Bit 0) steht für automatisches Weiterspringen zum nächsten Wegpunkt, sofern der jetzige weniger als 20 Meter der aktuellen Position entfernt ist.&lt;br /&gt;
LED 7 (Bit 1) aktiviert bedeutet, dass alle Wegpunkte in umgekehrter Reihenfolge annavigiert werden.&lt;br /&gt;
* 3 - Wegpunkte einspeichern&lt;br /&gt;
** 0 - Erstellt eine neue Wegpunkte Datei und gibt die Nummer binär aus. Diese Schreibzugriffe können parallel zum GPS Log durchgeführt werden!&lt;br /&gt;
** 1 - Speichert den aktuellen Punkt als Wegpunkt ab&lt;br /&gt;
** 2 - Beendet die Wegpunkte Datei&lt;br /&gt;
* 4 - Allgemeine Optionen (LED 5 und 6 geben den Batteriestatus wieder. 6 ist voll, 5 ist fast leer und garnichts steht für leer)&lt;br /&gt;
** 0 - Ausschalten / Standby. Zum Wiedereinschalten die rechte Taste anklicken, nach rund 700 ms muss sie losgelassen und nach weiteren 400 ms müssen beide Tasten gedrückt sein.&lt;br /&gt;
** 1 - GPS Modul ein und Ausschalten. Der Status wird auf LED 7 dargestellt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30776</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30776"/>
		<updated>2008-08-31T20:33:13Z</updated>

		<summary type="html">&lt;p&gt;Matze88: Teil Software, allgemein&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Die Software ist der eigentliche Schwerpunkt dieses Projekts, wo die meiste Arbeit drin steckt. Bis heute habe ich etwa 45 Tage, mal mehr mal weniger, insgesamt etwa 200 Stunden mit dem Quelltext oder Informationen dazu gearbeitet.&lt;br /&gt;
Die aktuelle Version ist nicht als fertig zu bezeichnen, es wird immer jemanden geben, der tolle Ideen einbringen oder Funktionen verbessern kann. Für mich persönlich ist der jetzige Stand brauchbar und ausreichend, weshalb ich mich an dieser Stelle für eine Veröffentlichung entschieden habe. Der Quelltext ist weder ausführlich überarbeitet noch lange Zeit debuggt worden, hat aber im Alltag bereits ohne auffällige Fehler funktioniert. Sollte dennoch ein Bug auftreten, so fühl dich frei, ihn zu beheben und deine Veränderungen zu veröffentlichen.&lt;br /&gt;
&lt;br /&gt;
Download des kompletten Quelltexts: [[Media:GPSMiniNavigatorb0.1.zip| GPS Mini Navigator Version beta 0.1]]&lt;br /&gt;
&lt;br /&gt;
=== Aufbau ===&lt;br /&gt;
Das Programm besteht aus mehreren Einzelkomponenten, welche größtenteils Zentral aus der Hauptschleife gesteuert werden.&lt;br /&gt;
Zum Einsatz kommen folgende Komponenten:&lt;br /&gt;
* Software Uart von Peter Danneger (suart.c/suart.h)&lt;br /&gt;
* Tastenentprellung von Peter Danneger (keys.c)&lt;br /&gt;
* Angepasste MMC/SD Library von Ulrich Radig (mmc.c/mmc.h)&lt;br /&gt;
* diverse Rechenalgorithmen in Assembler von elm-chan (sqrt32.S)&lt;br /&gt;
* ein einfach gestriktes eigenes Dateisystem (filesystem_simple.c)&lt;br /&gt;
&lt;br /&gt;
Außerdem existieren noch folgende Sourcefiles bzw. Module:&lt;br /&gt;
* Hauptschleife, Interruptcodes, kleine Funktionen, die kein eigenes Sourcefile haben (egl.c/egl.h)&lt;br /&gt;
* GPS Uart Handling (gps_uart.c/gps_uart.h)&lt;br /&gt;
* &amp;quot;User Interface&amp;quot; bzw. Menü (ui.c)&lt;br /&gt;
* erste Version des Dateisystems auf Clusterbasis. Verworfen aufgrund zu großer Komplexität ohne Nutzen (filesystem.c/filesystem.h)&lt;br /&gt;
&lt;br /&gt;
Im folgenden werde ich auf die einzelnen Module und das Programm als ganzes näher eingehen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:GPSMiniNavigatorb0.1.zip&amp;diff=30775</id>
		<title>Datei:GPSMiniNavigatorb0.1.zip</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:GPSMiniNavigatorb0.1.zip&amp;diff=30775"/>
		<updated>2008-08-31T20:27:39Z</updated>

		<summary type="html">&lt;p&gt;Matze88: Quellcode mit Hex-File für Mega88 des GPS Mini Navigators von Matthias Larisch. Der Code unterliegt der GPL v2 oder höher.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Quellcode mit Hex-File für Mega88 des GPS Mini Navigators von Matthias Larisch. Der Code unterliegt der GPL v2 oder höher.&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30774</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30774"/>
		<updated>2008-08-31T20:15:46Z</updated>

		<summary type="html">&lt;p&gt;Matze88: Korrektur des ersten Teils&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Auf der Suche nach einem passenden Projekt hat mir eines meiner Hobbies, das Fahrrad fahren, sehr geholfen: Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger für knapp 30 €. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch der Schwerpunkt des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Ephemeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Neben den Standardkomponenten wie Quarz, Blockkondensatoren, Pullups gibt es eine (Mikro-)SD Karte, 8 LEDs, 2 Taster und 2 P-Fets. Die LEDs sind in einer Art Matrix angeschlossen: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe Osram SMD-LEDs in rot verwendet, welche mit etwa 0,7 mA betrieben werden. Die Lichtausbeute ist allerdings für Sonnenlichtbedingungen zu schwach. Als Taster bieten sich SMD Miniaturhub Taster an, welche günstig zu beziehen und optimal durch Gehäusebohrungen bedienbar sind. P-Kanal Logic-Level Fets gibts mit dem IRF7314 gleich als Doppelpack im SO8 Gehäuse, 20 V, ~5 A bei nur 0,06 Ohm RdsOn @ 3,3 V Vgs. Alle von mir ausgesuchten Komponenten sind preiswert beim großen R zu beziehen.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, sie funktioniert aber. Für alle Drahtbrücken und Verbindungen habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas Dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Aufgrund geringer mechanischer Last im fertigen Gehäuse funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
* ~4 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
* ~70-75 mA GPS Tracking&lt;br /&gt;
* ~10 mA Bluetooth Modul an&lt;br /&gt;
* ~50 mA Bluetooth Modul verbunden&lt;br /&gt;
* ~30 mA Bluetooth Modul ohne Verbindung, nachdem es einmal verbunden war (wohl ein Bug)&lt;br /&gt;
* ~35 µA für die komplette Schaltung im Standby (µC Powerdown)&lt;br /&gt;
* ~10 µA Transcend Mikro-SD Karte 512 MB, wenn CS auf high&lt;br /&gt;
* ~30 mA Mikro-SD Karte schreiben/lesen&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30581</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30581"/>
		<updated>2008-08-27T23:59:08Z</updated>

		<summary type="html">&lt;p&gt;Matze88: Änderung 30579 von 85.182.121.200 (Diskussion) wurde rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Mit ein Hauptauslöser für dieses Projekt ist dann außerdem meine Leidenschaft zum Fahrrad fahren. Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger, der hat knapp 30 € gekostet. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch das Hauptmerkmal des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Epiphmeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nur noch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zur Grundbeschaltung wird an das Hardware SPI Interface eine SD-Karte angeschlossen. Außerdem hängt an Port C eine Art LED Matrix: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, ich habe die Platine versehentlich einige Minuten nach dem Entwickeln nochmal in den Entwickler gelegt. Zum Verbinden habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie einfach nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Da die mechanische Last im fertigen Gehäuse sehr gering ist, funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
-3,5 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
-~70-75 mA GPS Tracking&lt;br /&gt;
-~30 mA Bluetooth Modul an&lt;br /&gt;
-~60 mA Bluetooth Modul verbunden&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30578</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30578"/>
		<updated>2008-08-27T23:38:47Z</updated>

		<summary type="html">&lt;p&gt;Matze88: Kategorie falsch&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Mit ein Hauptauslöser für dieses Projekt ist dann außerdem meine Leidenschaft zum Fahrrad fahren. Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger, der hat knapp 30 € gekostet. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch das Hauptmerkmal des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Epiphmeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nurnoch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zur Grundbeschaltung wird an das Hardware SPI Interface eine SD-Karte angeschlossen. Außerdem hängt an Port C eine Art LED Matrix: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, ich habe die Platine versehentlich einige Minuten nach dem Entwickeln nochmal in den Entwickler gelegt. Zum Verbinden habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie einfach nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Da die mechanische Last im fertigen Gehäuse sehr gering ist, funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
-3,5 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
-~70-75 mA GPS Tracking&lt;br /&gt;
-~30 mA Bluetooth Modul an&lt;br /&gt;
-~60 mA Bluetooth Modul verbunden&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
[[Category:Wettbewerb|G]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30569</id>
		<title>GPS Mini Navigator</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPS_Mini_Navigator&amp;diff=30569"/>
		<updated>2008-08-27T16:06:34Z</updated>

		<summary type="html">&lt;p&gt;Matze88: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Matthias Larisch&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Seit einiger Zeit schwirrte mir im Kopf die Idee herum, einen GPS Empfänger zum Basteln zu kaufen. Mit ein Hauptauslöser für dieses Projekt ist dann außerdem meine Leidenschaft zum Fahrrad fahren. Ich habe mir häufig bei Google Earth Strecken angeschaut, die ich dann nachfahren wollte. Wie toll wäre es, einen Richtungsweiser auf dem Fahrrad dabei zu haben, um nicht immer auf der ausgedruckten Karte nachzuschauen, wo es weitergeht? Das Projekt sollte beginnen!&lt;br /&gt;
&lt;br /&gt;
Zuerst kaufte ich mir bei Ebay einen SysOnChip Smart Blue GPS Bluetooth Empfänger, der hat knapp 30 € gekostet. Der Vorteil ist hierbei, dass ein GPS Empfänger, ein Bluetooth Modul und ein Akku in einem schönen kleinen Gehäuse zusammengefasst sind.&lt;br /&gt;
&lt;br /&gt;
Danach begann ich mit der Entwicklung einer kleinen Schaltung für einen Mega88, welche 8 LEDs, 2 Taster, 2 Fets zum Steuern von Peripherie, den Quarz sowie ein paar Widerstände/Kondensatoren enthält.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung war schnell geätzt und die Platine in Form gesägt, langwierig wurde es dann, sie in das Originalgehäuse vom Bluetooth GPS zu integrieren.&lt;br /&gt;
&lt;br /&gt;
Damit war der Grundstein für die Softwareentwicklung gelegt, auf welcher auch das Hauptmerkmal des Projektes liegt.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== GPS/Bluetooth Modul ===&lt;br /&gt;
Mein Modul ist ein SysOnChip Smart Blue, welches ein Samsung SIRF III GPS-Modul und ein Samsung BTPZ5002OA Bluetooth-Modul enthält. Der Lithium Ionen Akku mit 1100 mAh ist ein Standard Modell, der EL-EN5.&lt;br /&gt;
Am Innenaufbau erkennt man schnell, dass eine Erweiterung sehr einfach von statten geht:&lt;br /&gt;
&lt;br /&gt;
[[Bild:SysOnChipSmartBluePlatineoben.jpg‎|300px]]&lt;br /&gt;
&lt;br /&gt;
Links das GPS-Modul, oben gehen die Uart RX/TX Pins ab zum Bluetooth-Modul. Die untere Verbindung ist ein GPS Signalindikator. Ganz unten ist die 5 V Versorgungsbuchse, mit der der Akku geladen werden kann. Dadrüber befindet sich der Ladecontroller, links vom Ladecontroller ein 3,3 V Low-Drop Regler, welcher im Standby nur rund 20 µA Strom aufnimmt. Der Schalter oben trennt die komplette Schaltung hinter dem 3,3 V Regler.&lt;br /&gt;
&lt;br /&gt;
Um eine Schaltung auf diese Platine aufzubauen, können die Uart-Leitungen durchtrennt werden. Die Baudrate beträgt sowohl für das GPS-Modul als auch für das Bluetooth Modul unveränderbar 38400 bps, ohne Parität und mindestens 1 Stoppbit.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird über 2 Quellen mit Strom versorgt: Einmal erkennt man im Bild links einen größeren Kondensator, rechts daneben und ein Stück nach unten ist eine Leiterbahn zur Durchkontaktierung zum 3,3 V Layer, welche durchtrennt werden kann.&lt;br /&gt;
&lt;br /&gt;
Außerdem wird das Modul jedoch noch anderweitig mit 3,3 V versorgt, um Almanach &amp;amp; Epiphmeriden Daten auch nach Ausschalten der Hauptversorgung zu behalten. Das geschieht über den Pin, an dem der Kondensator DC2 nach Masse führt.&lt;br /&gt;
Anmerkung: Ich habe diesen Kondensator bei weiteren Arbeiten abgerissen, das GPS Modul macht nach längeren Standby Phasen nun Probleme beim Einschalten, welche eventuell auf eine unsaubere Standby Versorgung zurückzuführen sind. Dies wird weiter untersucht.&lt;br /&gt;
&lt;br /&gt;
Auf der Rückseite der Platine ist nurnoch die GPS-Antenne verbaut, die über das abgeschirmte Kabel, welches man oben neben der Bluetooth-Antenne sehen kann, mit dem GPS-Modul verbunden ist.&lt;br /&gt;
=== µC Platine ===&lt;br /&gt;
[[Bild:GpsMiniNavigatorSchaltplan.png|300px]]&lt;br /&gt;
&lt;br /&gt;
Das Herzstück der Schaltung ist ein AT Mega88. Ich empfehle für den Nachbau allerdings eine Version mit mehr Flash und eventuell sogar 2 Uarts zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich zur Grundbeschaltung wird an das Hardware SPI Interface eine SD-Karte angeschlossen. Außerdem hängt an Port C eine Art LED Matrix: Alle LEDs haben einen gemeinsamen Pin (PC1), welcher bei 4 LEDs an der Anode und bei den anderen 4 an der Kathode hängt. Jeweils 2 LEDs kommen dann zusammen an einen weiteren Pin des Controllers, sodass eine LED bei PC1 Low und z.B. PC0 High und die andere bei PC1 High und PC0 Low leuchtet. Somit kann man mit 5 Pins 8 LEDs anschließen und hat dabei einen vertretbaren Softwareaufwand bei relativ geringem Layoutaufwand. Der Grund für die Verwendung dieser Methode war bei mir auch der Platzmangel, welcher es mir nicht ermöglicht, mehr als 3 Leiterbahnen zu den LEDs auf der Unterseite des Controllerboards zu führen (siehe unten).&lt;br /&gt;
&lt;br /&gt;
Durch 2 P-Kanal Mosfets kann die SD Karte und das GPS-Modul vom Strom getrennt werden.&lt;br /&gt;
&lt;br /&gt;
Das GPS-Modul wird mit dem Hardware-Uart des µCs verbunden, da dies hauptsächlich benutzt wird, wohingegen für das Bluetooth-Modul ein Software-Uart ausreichen muss.&lt;br /&gt;
&lt;br /&gt;
=== Verbindung beider Platinen ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:GpsMiniNavigatorPlatinenUnten.jpg|300px]] [[Bild:GpsMiniNavigatorPlatinenOben.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Zusatzplatine habe ich so zugeschnitten, dass man sie einfach auf die Oberseite, also die Seite mit der GPS Antenne, aufsetzen kann. Hier wird nun auch klar, warum ich sehr platzsparend arbeiten musste. Leider ist meine selbstgeätzte Platine nicht besonders gut geworden, ich habe die Platine versehentlich einige Minuten nach dem Entwickeln nochmal in den Entwickler gelegt. Zum Verbinden habe ich 0,3 mm Kupferlackdraht verwendet, empfehlen würde ich etwas dünneren, z.B. 0,2 mm. Es ist außerdem nicht ratsam, Drähte direkt an die Pins vom TQFP Mega anzulöten, dort halten sie einfach nicht so gut wie auf einem Lötpad. Da ich keine Lust habe, die Platine noch einmal neu zu layouten, zu sägen und zu löten bleibt das allerdings bei meinem Aufbau so. Da die mechanische Last im fertigen Gehäuse sehr gering ist, funktioniert das bisher auch fehlerfrei.&lt;br /&gt;
&lt;br /&gt;
Die Mikro-SD Karte findet auf der anderen Seite der Platine ihren Platz. Der 100 nF Kondensator zwischen Vcc und GND sollte so dicht wie möglich an der Karte platziert werden. Die Uart Leitungen der Originalplatine habe ich durchtrennt und je 2 Drähte direkt am GPS- und am Bluetooth-Modul angeschlossen. Das GPS-Modul wird vom Dual-Fet versorgt, meine Schaltung bekommt ihren Strom direkt vom Ausgang des 3,3 V Reglers, deshalb ist die Implementierung eines Zustands mit extrem niedriger Stromaufnahme wichtig. Der Originalschalter auf der Platine schaltet in diesem Zustand nur noch das Bluetooth Modul Ein und Aus.&lt;br /&gt;
&lt;br /&gt;
Die Stromaufnahme der einzelnen Module beträgt im Übrigen:&lt;br /&gt;
-3,5 mA AT Mega 88, aktiv, 8 MHz, PRR = 0xFF&lt;br /&gt;
-~70-75 mA GPS Tracking&lt;br /&gt;
-~30 mA Bluetooth Modul an&lt;br /&gt;
-~60 mA Bluetooth Modul verbunden&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
[[Category:Wettbewerb|P]]&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:GpsMiniNavigatorPlatinenOben.jpg&amp;diff=30568</id>
		<title>Datei:GpsMiniNavigatorPlatinenOben.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:GpsMiniNavigatorPlatinenOben.jpg&amp;diff=30568"/>
		<updated>2008-08-27T15:55:49Z</updated>

		<summary type="html">&lt;p&gt;Matze88: GPS Mini Navigator auf SysOnChip Smart Blue Platinenoberseite&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GPS Mini Navigator auf SysOnChip Smart Blue Platinenoberseite&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:GpsMiniNavigatorPlatinenUnten.jpg&amp;diff=30567</id>
		<title>Datei:GpsMiniNavigatorPlatinenUnten.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:GpsMiniNavigatorPlatinenUnten.jpg&amp;diff=30567"/>
		<updated>2008-08-27T15:54:56Z</updated>

		<summary type="html">&lt;p&gt;Matze88: GPS Mini Navigator auf SysOnChip Smart Blue Unterseite&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;GPS Mini Navigator auf SysOnChip Smart Blue Unterseite&lt;/div&gt;</summary>
		<author><name>Matze88</name></author>
	</entry>
</feed>