Ultraschallentfernungsmessung mittels FPGA
von Thomas Eichstetter, Nicole Elsner ; Mentor: Dr.Ing. MBA Thomas Fuhrmann
Dieser Artikel ist ein Anfängerprojekt.
Einleitung
Zugegeben, das Projekt „Ultraschall-Entfernungsmessung“ findet sich in diversen Variationen an einigen Stellen im Netz. Warum haben wir nun das gleiche Ziel, aber wollen es wieder in einer abgewandelten Form vorstellen? Als Studenten im Bereich Elektro- und Informationstechnik ist es uns besonders wichtig, die teilweise sehr theoretisch aufgebauten Vorlesungen durch praktische Aufgaben zu vertiefen. Neben den grundsätzlichen Dingen wie Erstellen einer Platine und Anwendung deren Bausteine, lag es uns auch am Herzen die bisher sehr rudimentären VHDL-Kenntnisse auszubauen und in einem praktischen Projekt anzuwenden. Damit ist ein neues Projekt geboren, das zwar ähnlich bereits existiert, aber nur in unserer Form angemessen auf unser Studium eingeht.
Eine gewisse Grundausrüstung ist Voraussetzung für das Gelingen des
Projektes. So gehört ein Oszilloskop ebenso zum Equipment wie die Materialen
zum Herstellen einer Platine und Programme zum Erstellen von Schaltnetzen
und Simulationen. Diese Programme stehen im Internet teilweise kostenlos zur
verfügung. Als kostspieligerer Bestandteil ist das FPGA (Field Programmable
Gate Array) zu nennen, welches auf einem Evaluationsboard angebracht und
mit entsprechender Entwicklungsumgebung für das folgende Projekt geeignet
ist.
Um das hier beschriebene Projekt nachzustellen, wird folgende Ausrüstung benötigt:
- SwitcherCAD IV LTSpice
- EAGLE Layout Editor
- Xilinx 9.1 ISE
- Xilinx Spartan – 3
- diverse Bauteile (darunter Z-Diode, Operationsverstärker, Transistoren)
- Ultraschallsender und -empfänger
- Spannungsversorgung
- analoges oder digitales Oszilloskop
Als besonders nützlich hat sich ein Multimeter und Funktionsgenerator gezeigt.
Grundkenntnisse in Schaltungstechnik, Berechnungen in elektrischer
Netzwerke, Bauelemente und VHDL sind hilfreich.
Präbeginn
Idee
Eine Sendekapsel erzeugt Schall, der an einem beliebigen Objekt reflektiert und von einer Empfängerkapsel aufgenommen wird. Durch Messung der Laufzeit, Dauer von Senden bis zum Empfangen, kann unter Berücksichtigung der Schallgeschwindigkeit die Entfernung des Objektes bestimmt werden. Diese zeitliche Differenz wird durch das FPGA und die selbst erstellte Platine aufgenommen und weiterverarbeitet.
Schnittstellen festlegen
Um verschiedene Teilprojekte erfolgreich miteinander zu verknüpfen, wird zu Anfang die Schnittstelle festgelegt, die sich hier zwischen der selbsterstellten Platine und dem FPGA befindet. An der Schnittstelle liegen zwei zu definierende Signale an, Sendeimpuls und Empfangssignal, die wie folgt aus Sicht des FPGAs festgelegt sind:
Signalart | Eigenschaft | |
---|---|---|
Sendeimpulse | 1 Ausgangssignal mit CMOS-Pegel Positive Logik | 7 Rechteckimpulse auf 3,3V mit f=40kHz ungefähr alle 30ms |
Empfangssignal | 1 Eingangssingal mit CMOS-Pegel Positive Logik | Highimpuls erst bei Erhalten des Echos, spätere Impulse zwischen dem ersten
Highimpuls und der nächsten Sendesequenz haben keinen Einfluss |
Essentielle Bausteine
Sender-, Empfängerkapsel
Bei dem Ultraschallempfänger bzw. -sender wird der piezoelektrische Effekt genutzt. Der sogenannte Piezokristall wechselwirkt mit Spannung, beginnt dadurch seine Form zu ändern und sende Schallwellen aus. Wird hingegen Schall empfangen, so tritt eine Änderung der elektrischen Polarisation auf und Spannung wird erzeugt.
Bei der Ultraschallentfernungsmessung benötigen wir beide Fälle, sowohl die
Erzeugung von Schall, als auch Detektion.
FPGA
Die CMOS Komponenten im konfigurierbaren Logikbaustein erhalten durch das Programm den Befehl sich auf bestimmte Weise zu verschalten. Damit werden unterschiedliche Gatter (AND, NOR, usw.) realisiert, die zusammen die Hardware des Programmes darstellen.
Ein großer Vorteil des FPGA gegenüber Mikrocontrollern ist die Unabhängigkeit der Anzahl der Messungen vom Timer, da im mehrere Messungen parallel laufen können. Dadurch ist es einfacher das Projekt weiter auszubauen.
Operationsverstärker
Dieses Bauteil kann auf simple Weise sämtliche Verstärkungseigenschaften entwickeln. So ist eine Verwendung als Komparator, Filter, Verstärker, Integrator usw. möglich. Im vorgestellten Projekt werden invertierende Verstärker und Komparatoren benötigt.
Aufteilung in Module - Baukastenprinzip
Um die Übersicht besonders bei großen Projekten nicht zu verlieren, ist es ratsam das Netzwerk in einzelne Module zu unterteilen und diese Stück für Stück zu entwickeln. Erst wenn das einzelne Teilprojekt einsatzbereit ist, wird es mit den Übrigen verknüpft. So wird gewährleistet, dass Fehler im Modul nicht in andere Bereiche einfließen und damit schwer festzustellende Störungen verursacht.
Spannungsversorgung
Diese Schaltungsteile sind zuständig für die Spannungsversorgung der Bauteile. Mit den Kondensatoren C5 und C6 wird sichergestellt, dass die Betriebsspannung durch kurze Stromimpulse nicht zusammenbricht. Als Ursache dieses Problems ist ein evtl. hoher Innenwiderstand der Spannungsversorgung zu nennen. Die Diode D2 schützt die Schaltung vor falscher Polung.
Mit den zwei Widerständen R7 und R8 wird die Versorgungsspannung VCC halbiert und als neues Bezugspotential VCC/2 verwendet. Die Schwingung der Eingangssignale bewegt sich damit um dieses Potential. Der damit entstandene Offset von VCC/2 kann später durch den Kondensator C3 wieder entfernt werden.
Nachdem die Versorgungsspannung festgelegt ist, wird der Komparator IC2A (vgl. Bild 12) als Ausgangsbauteil für die Funktionalität verwendet. Mit dem korrekten Verlauf der RC-Kurve werden die unerwünschten Signale gefiltert und das auszuwertende Signal weitergeleitet. Im Folgenden werden die beiden Signale getrennt betrachtet.
Verstärkung des Senders
Prinzip des Moduls
Mehrere kurz aufeinander folgende Impulse gewährleisten ein ausreichendes Aufladen des Kondensators. Da das FPGA aber nur mit 3,3 V und kleinen Strömen arbeitet, werden die Impulse mit Transistoren verstärkt um die Sendekapsel ausreichend versorgen zu können.
Realisierung im Schaltplan
Es werden pro Entfernungsmessung sieben Sendeimpulse vom FPGA geliefert und mit den beiden Transistoren T1 und Q1 verstärkt. Damit ist gewährleistet, dass die Intensität ausreicht um die Senderkapsel zum Senden zu bewegen. Außerdem wird der Kondensator C1 geladen. Weil nur Impulse verstärkt werden, können die Transistoren im Sättigungsbereich betrieben werden, um die größtmögliche Verstärkung zu erreichen. Nachdem aus dem Datenblatt der Transistoren die Stromverstärkungsfaktoren entnommen sind, wird der Basisstrom so dimensioniert, dass die Transistoren im übersteuerten Bereich arbeiten. Es hat sich gezeigt, dass durch die Diffusionskapazitäten der Transistoren jeder Impuls verlängert wird. Um diesen Effekt zu verringern, werden die Transistoren nicht zu weit im Sättigungsbereich betrieben.
Verstärkung des Empfängers
Prinzip des Moduls
Erste Probemessungen an der Empfängerkapsel zeigen am Oszilloskop nur sehr geringe Ausschläge. Da es während der Signalverarbeitung zum Rauschen durch besonders hochohmige Widerstände innerhalb der Schaltung kommt, wird das Signal verstärkt um es in einen Spannungsbereich zu bringen, der sich deutlich von ungewollten Nebeneffekten abhebt. Zur Veranschaulichung einer weiteren Variante zur Verstärkung, wird am Empfänger ein Operationsverstärker, statt eines einfachen Transistors, verwendet.
Realisierung im Schaltplan
Trotz dem optimalisierten Sender-Empfangssystem mit gleicher Resonanzfrequenz von 40 kHz muss das nach der Reflexion des Ultraschalls nur schwache Echo verstärkt werden, um weiterverarbeitet werden zu können.
Die Ersatzschaltbilder von Ultraschallsender und –empfänger sind identisch. Die Stromquelle des Senders bleibt jedoch auf Null, während die des Empfängers bei Empfang aktiv wird. Um Störungen durch Rauschen am hohen Innenwiderstand der Ultraschallkapsel zu vermeiden, wird an beiden Anschlüssen des Empfängers das gleiche Potential angelegt.
Der Operationsverstärker IC1A dient als Vorverstärker und Filter. In dieser invertierenden Beschaltung verstärkt er die Eingangssignale um das zehnfache und filtert alle Schwingungen ab 48 kHz. heraus. Um die empfangenen Signale weiterzugeben und gleichzeitig jeden Gleichanteil abzutrennen wird der Kondensator C3 eingesetzt.
Die zweite Stufe mit IC1B ist ebenfalls als invertierender Verstärker aufgebaut und kann erneut um Faktor zehn verstärken. Dies läst sich über das Potentiometer R12 stufenlos einstellen. Zudem lässt sich der Gleichanteil mit R14 in geringen Bereichen um VCC/2 variieren, um die Empfangskurve exakt mit der RC-Kurve abzugleichen. Das Audio-Signal am Ausgang des Operationsverstärkers IC1B, schwingt um nahezu dasselbe Potential, wie das Signal am nichtinvertierenden Eingang.
Erzeugung einer RC-Kurve zur Filterung
Prinzip des Moduls
Aus der Richtcharakteristik ist zu entnehmen, wie stark der Ultraschall neben der Hauptrichtung auch in andere Richtungen abstrahlt. Auf ähnliche Weise empfängt auch der Empfänger aus dem gesamten Raum Signale. Da Sender- und Empfängerkapsel dicht nebeneinander verbaut sind und der ausgesendete Schall nicht nur durch Reflexion zum Empfänger gelangt, sondern auch auf direktem Wege durch seitliche Abstrahlung während der Messung, ist es notwendig die bei der Sendung seitlich abgestrahlten Impulse herauszufiltern. Das wird durch den Vergleich mit einer RC-Entladungskurve erreicht. Während die Senderkapsel die Impulse erhält, wird parallel dazu ein Kondensator aufgeladen. Ist der Sendevorgang abgeschlossen, entlädt sich dieser Kondensator über einen Widerstand. In einem Operationsverstärker wird diese Entladekurve mit dem Signal des verstärkten Ultraschalleingangs verglichen. Seitlich emittierter Ultraschall fällt beim Empfangen unter die RC-Kurve und wird dadurch nicht verwertet. Beim Auftreffen des senkrecht reflektierten Schalls ist die RC-Kurve ausreichend abgefallen um einer komplikationslosen Messung nicht mehr im Wege zu stehen.
Realisierung im Schaltplan
Der Fluss der Ladung in den Kondensator legt die Spannungserhöhung gegenüber der anderen Kondensatorplatte fest. Wie viel Ladung in den Kondensator fließt wird mit dem Potentiometer R5 eingestellt. Das Potential an der unteren Kondensatorseite liegt bei der halben Betriebsspannung. Beim Entladevorgang, also nach den 7 Sendeimpulsen, wird die erhöhte Ladungsansammlung auf der oberen Kondensatorplatte über den Widerstand R6 zur unteren Platte geleitet. Die Diode D1 verhindert ein zusätzliches Entladen durch R4 und den Ultraschallsender. Da der Eingangswiderstand des Operationsverstärkers sehr groß ist, findet auch darüber kaum eine Entladung statt. Dadurch ergibt sich eine typische Entladekurve mit der Zeitkonstante τ=R6*C1. Diese Kurve nähert sich asymptotisch der halben Betriebsspannung an.
Der Operationsverstärker IC2A dient als Komparator zwischen RC-Kurve und dem Audio-Signal. Sobald das Potential des Audio-Singals höher ist als das der RC-Kurve, schaltet der Ausgang nahezu auf Betriebsspannung.
Anpassung der Spannung für das FPGA
Prinzip des Moduls
Da das FPGA im CMOS-Pegel von 0 – 3,3 V arbeitet und im Normalfall eine
höhere Spannung am Ausgang es Komparators anliegt, ist eine Reduzierung
der Spannung nötig. Eine parallel zum FPGA - Eingang geschaltete Z-Diode
reduziert die Spannung auf die gewünschten 3,3 V.
Realisierung im Schaltplan
Die Spannung am FPGA muss auf 3,3 V reguliert werden. Deshalb wird das
Ausgabepotential des Operationsverstärkers verwendet, um einen PNP-
Transistor zu schalten. Der Operationsverstärker IC2A kann nicht bis zur
oberen und unteren Betriebsspannung (0V und VCC) aussteuern. Hat der
Operationsverstärker auf maximales positives Potential geschalten, kann der
Transistor BC328 noch teilweise Strom durchlassen. Um den Transistor sicher
zu sperren, wird mit dem Widerstand R16 das Potential auf nahezu VCC
gebracht. Der andere Fall, dass der Operationsverstärker gegen GND schaltet,
veranlasst das Öffnen des PNP-Transistors und lässt damit genügend Strom
durch die Zener-Diode fließen, welche das Potential am FPGA_EINGANG auf
3,3V beschränkt.
Gesamter Schaltplan und Aufbau
Hardwarebeschreibungssprache VHDL
VHDL Einleitung
VHDL ist eine hardwarebeschreibende Sprache. Damit wird dem FPGA vorgegeben, welche Verkettung der CMOS Bauteile freigegeben wird um die in VHDL eingegebenen Befehle in Hardware umzusetzen. Alle Signaldurchläufe durch das FPGA werden parallel ausgeführt, das macht das FPGA sehr leistungsstark. Es ist jedoch auch möglich Prozesse mit sequenzieller Struktur in VHDL zu realisieren. In unserem Fall wurden beide Arten der Signallaufstrukur gewählt. Um verschiedene externe Signale miteinander zu verbinden, werden interne Signale definiert.
VHDL Moduleinteilung
Ein komplettes VHDL-Programm setzt sich aus einzelnen Modulen zusammen, welche miteinander verknüpft sind. Diese Art von Programm ist für Teamarbeiten sehr gut geeignet, da die Aufteilung von Modulen an verschiedene Entwickler einfach möglich ist. Ein besonderes Augenmerk sollte dabei auf die Festlegung der Schnittstellen und Übergabewerte gelegt werden. Für das Ultraschallprojekt wurden die Module wie folgt festgelegt:
Die externen Signale sind blau markiert und wurden schon beschrieben.
VHDL Modulschnitstellen
Signalart | Eigenschaft | |
---|---|---|
clk2 | 10Bit-Block, STD_LOGIC_VECTOR | Zählt mit 25MHz hoch bis „1011011000“ und wirdanschließend auf „0000000000“ zurückgesetzt |
startzähler | 11Bit-Block, STD_LOGIC_VECTOR | Zählt für Schallgeschwindigkeit alle 5mm um eine Stelle hoch |
einaus | 4Bit-Block, STD_LOGIC_VECTOR | Enthält die Flankenwechsel der Ultraschallimpulse |
sender_ein | 1Bit-Wert, STD_LOGIC | Wenn 1 dann soll der Ultraschallsender die 7 Sendeimpulse bekommen |
wegzähler1 | 10Bit-Block, STD_LOGIC_VECTOR | Zählt nach Offsetkorrektur für Schallgeschwindigkeit in 1 cm Schritten |
mm | 1Bit-Wert, STD_LOGIC | Wechselt für Schallgeschwindigkeit in 5mm Schritten seinen Wert |
seg1 - seg4 | jeweils 8Bit-Wert, STD_LOGIC_VECTOR | Gibt den BCD-Wert jeder Anzeigestelle an; seg1 für Meter, seg2 für Dezimeter, seg3 für Zentimeter |
VHDL-CODE
----------------------------------------------------------------------------------
-- Company: FH-Regensburg
-- Azubi-Engineer: Thomas Eichstetter
--
-- Create Date: 2011-06-28
-- Design Name:
-- Module Name: ultraschall_1.1
-- Project Name:
-- Target Devices: Spartan 3
-- Tool versions:
-- Description: Mittels Ultraschallimpuls und Laufzeitmessung über Reflexion
-- wird die Entfernung zu einem Objekt bestimmt
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ultraschall is
Port ( clk : IN std_logic;
stopp : IN std_logic;
ultraschall : OUT std_logic;
lampe : OUT std_logic;
seg1 : out STD_LOGIC_VECTOR (7 downto 0);
seg2 : out STD_LOGIC_VECTOR (7 downto 0);
seg3 : out STD_LOGIC_VECTOR (7 downto 0);
seg4 : out STD_LOGIC_VECTOR (7 downto 0));
end ultraschall;
architecture Behavioral of ultraschall is
signal wegzaehler1 : STD_LOGIC_VECTOR (9 downto 0) :="0000000000";
signal senderein : STD_LOGIC := '0';
signal ultra : STD_LOGIC_VECTOR (9 downto 0) :="0000000000";
signal einaus: STD_LOGIC_VECTOR (3 downto 0) :="0000";
signal startzaehler : STD_LOGIC_VECTOR (10 downto 0) :="00000000000";
signal clk2 : STD_LOGIC_VECTOR (11 downto 0) := "000000000000";
signal fivemm : STD_LOGIC_VECTOR (11 downto 0) := "000000000000";
signal mm: STD_LOGIC := '0';
signal flag: STD_LOGIC := '0';
begin
lampe <= not stopp;
ultraschall <= einaus(0);
process ( clk) --Timer wird auf 5mm Weg/Periode gesetzt """"Zähler1""""
begin
if clk'event and clk='1' then
clk2 <= clk2+1; --clk2 Zähl-Periode jetzt auf 50MHz
if (clk2=728) then --auf 5mm einstellen: 0,005m * 50e6 Hz/ (343 m/s) = 729
clk2 <= "000000000000"; --doppelter Laufweg noch nicht berücksichtigt
end if; --und 1011011000=728 weil er von 0 anfängt zu zählen
end if;
end process;
process ( clk ) --Ultraschallimpuls wird erzeugt (7 Impulse bei 40kHz)""""Zähler2""""
begin
if clk'event and clk='1' then
if einaus >= 14 then --14 da HIGH und LOW gezählt werden
senderein <= '0';
end if;
if clk2 = 728 then
startzaehler <= startzaehler+1; --Zähler der jeweils in 5mm-Steps zählt
end if;
if (startzaehler=2047) then --Periode der Messung (ca 30ms)
startzaehler <= "00000000000";
senderein <= '1';
end if;
end if;
end process;
process ( clk )
begin
if clk'event and clk='0' then
if (senderein = '1' ) then
ultra <= ultra+1;
if (ultra=625) then -- 50MHz/40kHz/2= 625 Takte [2mal wegen ein/aus für Ultraschallkapsel 40kHz]
einaus <= einaus + 1; -- hier auch wirklich 625 Takte, weil er danach sofort eins dazuzählt
ultra <="0000000000";
end if;
if einaus = 14 then -- Rücksetzten
einaus <= "0000";
end if;
end if;
end if;
end process;
process (clk)
begin
if clk'event and clk='1' then
if (startzaehler=8) then -- setzt alle ~30ms Zähler auf 0 zurück,1110 zusätzlich Trägheitsausgleich der Senderkapsel (offset)
fivemm <= "000000000000"; -- muss angepasst werden auf die jeweilige Spannung
end if;
if (clk2 = 0) then -- erhöht jeden bestimmten Zeitabschnitt um 5mm
fivemm <= fivemm + 1; -- eigentliche Wegzählung
end if;
if (senderein='1') then -- Bereit machen für Wertänderung
flag <= '1'; -- zeigt das Ultraschallimpuls unterwegs ist
end if;
if (stopp='1' and flag='1') then --Wertänderung der zuletzt gemessenen Länge
if (fivemm(10 downto 2) < 500) then -- Zu weit weg -> alter Wert bleibt
if (fivemm(10 downto 2) > 2) then -- Zu nah dran -> alter Wert bleibt
wegzaehler1(8 downto 0) <= fivemm(10 downto 2); -- geteilt durch 2 wegen hin/zurück und 5mm extra
mm <= fivemm(1); -- 5mm
wegzaehler1(9) <='0';
flag <= '0'; -- Impuls angekommen
end if;
end if;
end if;
if (fivemm=4095) then
fivemm <= "000000000000";
wegzaehler1(8 downto 0) <="111111111";
end if;
end if;
end process;
PROCESS ( wegzaehler1 , mm)
variable wegzaehler2 : STD_LOGIC_VECTOR (9 downto 0) := "0000000000";
variable wegzaehler3 : STD_LOGIC_VECTOR (9 downto 0) := "0000000000";
variable m , dm , cm : STD_LOGIC_VECTOR (3 downto 0) := "0000";
BEGIN
wegzaehler2 := "1111111111";
wegzaehler3 := "1111111111";
m := "0000";
dm := "0000";
cm := "0000";
--Meterberechnung
if ((wegzaehler1(8 downto 0) > 399) and (wegzaehler1(8 downto 0) < 500)) then
m := "0100";
wegzaehler2:= wegzaehler1 - 400;
elsif ((wegzaehler1(8 downto 0) > 299) and (wegzaehler1(8 downto 0) < 400)) then
m := "0011";
wegzaehler2 := wegzaehler1 - 300;
elsif ((wegzaehler1(8 downto 0) > 199) and (wegzaehler1(8 downto 0) < 300)) then
m := "0010";
wegzaehler2 := wegzaehler1 - 200;
elsif ((wegzaehler1(8 downto 0) > 99) and (wegzaehler1(8 downto 0) < 200)) then
m := "0001";
wegzaehler2 := wegzaehler1 - 100;
elsif (wegzaehler1(8 downto 0) < 100) then
m := "0000";
wegzaehler2 := wegzaehler1;
else
m := "1111";
wegzaehler2 := "1111111111";
end if;
--Dezimeterberechnung
if ((wegzaehler2(8 downto 0) > 89)and(wegzaehler2(8 downto 0) < 100)) then
dm := "1001";
wegzaehler3 := wegzaehler2 -90;
elsif ((wegzaehler2(8 downto 0) > 79)and(wegzaehler2(8 downto 0) < 90)) then
dm := "1000";
wegzaehler3 := wegzaehler2 -80;
elsif ((wegzaehler2(8 downto 0) > 69)and(wegzaehler2(8 downto 0) < 80)) then
dm := "0111";
wegzaehler3 := wegzaehler2 -70;
elsif ((wegzaehler2(8 downto 0) > 59)and(wegzaehler2(8 downto 0) < 70)) then
dm := "0110";
wegzaehler3 := wegzaehler2 -60;
elsif ((wegzaehler2(8 downto 0) > 49)and(wegzaehler2(8 downto 0) < 60)) then
dm := "0101";
wegzaehler3 := wegzaehler2 -50;
elsif ((wegzaehler2(8 downto 0) > 39)and(wegzaehler2(8 downto 0) < 50)) then
dm := "0100";
wegzaehler3 := wegzaehler2 -40;
elsif ((wegzaehler2(8 downto 0) > 29)and(wegzaehler2(8 downto 0) < 40)) then
dm := "0011";
wegzaehler3 := wegzaehler2 -30;
elsif ((wegzaehler2(8 downto 0) > 19)and(wegzaehler2(8 downto 0) < 30)) then
dm := "0010";
wegzaehler3 := wegzaehler2 -20;
elsif ((wegzaehler2(8 downto 0) > 9)and(wegzaehler2(8 downto 0) < 20)) then
dm := "0001";
wegzaehler3 := wegzaehler2 -10;
elsif (wegzaehler2(8 downto 0) < 10) then
dm := "0000";
wegzaehler3 := wegzaehler2;
else
dm := "1111";
wegzaehler3 := "1111111111";
end if;
--Zentimeterberechnung
if (wegzaehler3 < 10) then
cm := wegzaehler3(3 downto 0);
else
cm := "1111";
end if;
--Millimeterberechnung
CASE mm IS
WHEN '0' => seg4 <= "00111111";
WHEN OTHERS => seg4 <= "01101101";
END CASE;
if (cm="1111") then --falls Falscher Wert mm auf nichts
seg4 <="00000000";
end if;
CASE cm IS
WHEN "0000" => seg3 <= "00111111";
WHEN "0001" => seg3 <= "00000110";
WHEN "0010" => seg3 <= "01011011";
WHEN "0011" => seg3 <= "01001111";
WHEN "0100" => seg3 <= "01100110";
WHEN "0101" => seg3 <= "01101101";
WHEN "0110" => seg3 <= "01111101";
WHEN "0111" => seg3 <= "00000111";
WHEN "1000" => seg3 <= "01111111";
WHEN "1001" => seg3 <= "01101111";
WHEN OTHERS => seg3 <= "00000000";
END CASE;
CASE dm IS
WHEN "0000" => seg2 <= "00111111";
WHEN "0001" => seg2 <= "00000110";
WHEN "0010" => seg2 <= "01011011";
WHEN "0011" => seg2 <= "01001111";
WHEN "0100" => seg2 <= "01100110";
WHEN "0101" => seg2 <= "01101101";
WHEN "0110" => seg2 <= "01111101";
WHEN "0111" => seg2 <= "00000111";
WHEN "1000" => seg2 <= "01111111";
WHEN "1001" => seg2 <= "01101111";
WHEN OTHERS => seg2 <= "00000000";
END CASE;
CASE m IS
WHEN "0000" => seg1 <= "10111111";
WHEN "0001" => seg1 <= "10000110";
WHEN "0010" => seg1 <= "11011011";
WHEN "0011" => seg1 <= "11001111";
WHEN "0100" => seg1 <= "11100110";
WHEN "0101" => seg1 <= "11101101";
WHEN "0110" => seg1 <= "11111101";
WHEN "0111" => seg1 <= "10000111";
WHEN "1000" => seg1 <= "11111111";
WHEN "1001" => seg1 <= "11101111";
WHEN OTHERS => seg1 <= "00000000";
END CASE;
END PROCESS ;
-------------------------------------------------------------------------
end Behavioral;
Pinbelegung
NET "clk" LOC = AA12;
NET "seg1[0]" LOC = E15;
NET "seg1[1]" LOC = E16;
NET "seg1[2]" LOC = A14;
NET "seg1[3]" LOC = D14;
NET "seg1[4]" LOC = D13;
NET "seg1[5]" LOC = B13;
NET "seg1[6]" LOC = E13;
NET "seg1[7]" LOC = D15;
NET "seg2[0]" LOC = B17;
NET "seg2[1]" LOC = B18;
NET "seg2[2]" LOC = A18;
NET "seg2[3]" LOC = B15;
NET "seg2[4]" LOC = D17;
NET "seg2[5]" LOC = C17;
NET "seg2[6]" LOC = E17;
NET "seg2[7]" LOC = A19;
NET "seg3[0]" LOC = D19;
NET "seg3[1]" LOC = F18;
NET "seg3[2]" LOC = C20;
NET "seg3[3]" LOC = C19;
NET "seg3[4]" LOC = C18;
NET "seg3[5]" LOC = B19;
NET "seg3[6]" LOC = D18;
NET "seg3[7]" LOC = F17;
NET "seg4[0]" LOC = F19;
NET "seg4[1]" LOC = G17;
NET "seg4[2]" LOC = E19;
NET "seg4[3]" LOC = D21;
NET "seg4[4]" LOC = D20;
NET "seg4[5]" LOC = E18;
NET "seg4[6]" LOC = C22;
NET "stopp" LOC = V10;
NET "seg4[7]" LOC = E20;
NET "ultraschall" LOC = AB13;
NET "lampe" LOC = W2;
Funktionstest
Natürlich ist es am einfachsten die Einstellung des Ultraschallsenders mit dem Oszilloskop nachzuvollziehen. Diese Anleitung soll aber vor allem dazu dienen, den Leuten eine Inbetriebnahme zu ermöglichen, die kein Oszilloskop zur Hand haben.
Ganz allgemein ist jedem anzuraten, der Geräte neu einstellen will, wie auch bei der Modulentwicklung eine Reihenfolge zu verfolgen und Schritt für Schritt vorzugehen. Zur Vorbereitung sollten die Sensoren einigermaßen frei liegen und in ca. 30 cm Abstand ein flacher, parallel zu den Sensoren liegende Fläche stehen. Zu Anfang alle drei Potentiometer gegen den Uhrzeigersinn auf Anschlag drehen. Anschließend wird die Quelle (Netzgerät oder Batterien sind möglich) angeschlossen. Um die Bauteile nicht zu stark zu belasten und sie damit zu zerstören, ist eine Spannung von 5-20 V empfehlenswert. In der Testphase wurden 10 V verwendet, damit der Ultraschallimpuls ausreichend stark war.
Die Potentiale am Eingang des Verstärkers IC2A liegen nah beieinander. Deshalb verändert man das Potentiometer R14 so lange, bis das FPGA das erste Mal einen Wert anzeigt. Damit ist der Offset des Signals knapp unterhalb des Spannungsendwertes der RC-Kurve. Vorsicht: Bitte darauf achten, dass man nicht zu weit dreht, denn das System ist diesbezüglich sehr empfindlich und größere Entfernungen nicht mehr einwandfrei gemessen werden können.
Dann Poti R5 langsam im Uhrzeigersinn drehen, bis der zu erwartende Messwert stabil angezeigt wird. Nun sollte der Ultraschallentfernungsmesser eingestellt sein um Entfernung messen zu können. Jetzt kann der Ultraschallentfernungsmesser auf ein zu messendes Objekt ausgerichtet werden. Mit R12 lässt sich die Verstärkung von um Faktor 10 variieren. Das ermöglicht es Hindernisse, welche neben der Messstrecke sind und schwache Signale zurücklaufen lassen, auszublenden.
Fazit
Dieses Projekt der Ultraschallentfernungsmessung eignet sich hervorragend um verschiedene Grundschaltungen innerhalb eines Netzwerkes besser zu verstehen. Auch erste Schritte mit VHDL sind hiermit leicht zu realisieren. Erfolge sind bereits während dem Projekt nach den einzelnen Abschnitten zu erkennen. Durch die 7-Segment-Anzeigen ist die Funktionalität auch für Anfänger leicht ersichtlich und der Ultraschallentfernungsmesser eignet sich deshalb hervorragend als Vorführprojekt. Die Entfernungsmessung funktioniert bis zu 4 m zuverlässig.
Siehe auch
- Diskussion zu diesem Projekt: http://www.mikrocontroller.net/topic/200976