Forum: FPGA, VHDL & Co. Hall Sensor in VHDL/FPGA


von Wolfgang (Gast)


Lesenswert?

Hallo alle,

mein Name ist Wolfgang und ich wollte in meiner Freizeit an einem 
Privaten Projekt Arbeiten.

Ich habe mir in meinem Garten eine kleine Windmühle aufgestellt, von der 
würde ich gerne die Geschwindigkeit messen.

Ich habe mir schon einen Sensor geholt und denn an meinem FPGA 
angeschlossen.

Ich bin schon so weit gekommen, das er mir, wenn der Sensor denn 
Magneten entdeckt, mir auf den 7-Seg Display eine 1 anzeigt.

Nun komme ich nicht weiter, ich weiss das ein Aduiono oder andere Boards 
einfacher wären, aber ich möchte meine Kenntnisse in VHDL/FPGA 
verbessern.

Hat jemand schon mal ein ähnliches Projekt gemacht oder hätte jemand 
Quellen für mich?

von Cartman (Gast)


Lesenswert?

Schreib dir noch einen Zaehler fuer deinen Sensor und
eine Uhr mit 7 Segmentanzeige.
Dann brauchst du nur noch die Differenz des Zaehlers
zwischen den Sekunden zu bilden, mit 60 zu multiplizieren
und hast "Rotations per Minute"!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Wolfgang schrieb:
> von der würde ich gerne die Geschwindigkeit messen.
In welcher Einheit?
Flügelspitzengeschwindigkeit in m/s?
Oder einfach nur U/min?

> Ich bin schon so weit gekommen, das er mir, wenn der Sensor denn
> Magneten entdeckt, mir auf den 7-Seg Display eine 1 anzeigt.
Dann solltest du dich noch zum Thema "Eintakten" bzw. 
"Einsynchronisieren" schlau machen, denn sonst wird dein Messwert dann 
und wann "spinnen".

Cartman schrieb:
> Dann brauchst du nur noch die Differenz des Zaehlers
> zwischen den Sekunden zu bilden
Das ist natürlich nur sinnvoll, wenn innerhalb 1s genug Impulse 
anfallen.

> mit 60 zu multiplizieren und hast "Rotations per Minute"!
Einfacher wäre es, pro Impuls 60 auf einen Zähler draufzuaddieren.

Aber weil ein FPGA verglichen mit der Aufgabe dermaßen schnell ist, 
würde ich die Zeit zwischen 2 Impulsen ermitteln (also us/U), dann den 
Kehrwert bilden und mit 60000000 multiplizieren und hätte dann U/min. 
Diese Rechungen könnte man in einer Tabelle abbilden und mit 
Interpolation die Zwischenwerte ermitteln. Nette Fingerübung zum selber 
Lernen.

von Cartman (Gast)


Lesenswert?

> den Kehrwert bilden
ist fuer ein FPGA immer Schwerstarbeit.
Und nicht unbedingt Anfaengertauglich.
Damit verkomplizierst du ihm den Einstieg voellig unnoetig.

> genug Impulse anfallen
Er kann ja Anzahl der Hallsensoren ja vergroessern :-).
Oder ein paar Ausloesemagnete dazutun.

Ein "genauen" Wert wie 55.5 rpm ist sowieso nur bedingt
aussagekraeftig. Wind ist keine Konstante.
Nicht mal innerhalb einer Umdrehung.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Cartman schrieb:
> den Kehrwert bilden ist fuer ein FPGA immer Schwerstarbeit.
Die Anzeige muss ja nicht 1 Mio mal pro Sekunde aktualisiert werden.

> den Kehrwert bilden ist fuer ein FPGA immer Schwerstarbeit.
Deshalb hatte ich ja vorgeschlagen, dass man diesen Kehrwert samt 
Skalierung mit dem Ansatz über eine per Excel berechnete Tabelle auch 
hinbekommt. Die weiters vorgeschlagene lineare Interpolation ist dabei 
ja vorerst mal optional.

> Und nicht unbedingt Anfaengertauglich.
Die Schwachpunkte der Anfängerlösung wurden ja schon angesprochen.

>> genug Impulse anfallen
> Er kann ja Anzahl der Hallsensoren ja vergroessern :-).
> Oder ein paar Ausloesemagnete dazutun.
Auf jeden Fall sollte auch eine Mittelwertbildung rein, die länger als 
nur über 1 Sekunde geht, damit man auch bei 10 U/min noch was Sinnvolles 
sieht. Wenn man es schlau macht, läuft der Mittelwert über 1 Minute im 
"Hintergrund", während im Vordergrund die Anzeige im Sekundentakt 
aktualisiert wird. Auch das ist eine nette Aufgabe.

> Damit verkomplizierst du ihm den Einstieg voellig unnoetig.
Ich zeige nur auf, wie es weitergehen könnte und wie ich es machen 
würde. Dabei muss korrekterweise durchaus bedacht werden, dass ich 
deutlich mehr Erfahrung habe. Aber auch ich war mal in der Situation des 
TO und von nix kommt nix:
https://www.gutefrage.net/frage/genaue-bedeutung-vom-spruch--von-nix-kommt-nix-

Wolfgang schrieb:
> Ich bin schon so weit gekommen, das er mir, wenn der Sensor denn
> Magneten entdeckt, mir auf den 7-Seg Display eine 1 anzeigt.
Da würde ich erst mal gar nichts am FPGA machen, sondern das Allermeiste 
im Simulator. Geht viel schneller und ist reproduzierbar...

von Wolfgang (Gast)


Lesenswert?

Hallo Danke für die Ganzen Antworten, ich habe einen Counter 
geschrieben, nun bekomme ich auf allen Segmenten einen Error angezeigt 
obwohl ich nur eins anspreche, dass macht für mich keinen Sinn.

von Wolfgang (Gast)


Lesenswert?

Ich will es in km/h abbilden.

von Gustl B. (-gb-)


Lesenswert?

Ohne deinen Code zu kennen können wir dir nicht helfen.

Wolfgang schrieb:
> Error

Etwas mehr Details wären auch sinnvoll.

Noch besser wäre dazu der Name der Hardware oder der Schaltplan.

von Cartman (Gast)


Lesenswert?

> auf allen Segmenten einen Error angezeigt

Ich weiss gar nicht, ob ich da noch an mehr Details ueberhaupt
interessiert bin.

Bis zu
> Ich will es in km/h abbilden.
wird es wohl noch eine Weile brauchen.

von Weltbester FPGA-Pongo (Gast)


Lesenswert?

Wolfgang schrieb:
> mein Name ist Wolfgang und ich wollte in meiner Freizeit an einem
> Privaten Projekt Arbeiten.
die scheinen sehr wichtig zu sein, wenn du sie groß schreibst

> Ich habe mir in meinem Garten eine kleine Windmühle aufgestellt, von der
> würde ich gerne die Geschwindigkeit messen.
du würdest gerne die Drehzahl messen

> Ich habe mir schon einen Sensor geholt und denn an meinem FPGA
> angeschlossen.
du hast "den" angeschlossen, denn "denn" wäre das falsche Wort

> Ich bin schon so weit gekommen, das er mir, wenn der Sensor denn
> Magneten entdeckt, mir auf den 7-Seg Display eine 1 anzeigt.
s.o.

Was soll das werden? Wie man eine Drehzahl (= Impulse je Zeit) berechnet 
ist klar?

> Nun komme ich nicht weiter, ich weiss das ein Aduiono oder andere Boards
> einfacher wären,
das glaube ich nicht

> Quellen für mich?
Die Quellen bringen dir gar nichts, weil die meistens nicht dokumentiert 
sind und von ähnlic begabten Menschen wie dir verfasst wurden.

Du musst zunächst eine Schaltung hinmalen, die deine Funktion leistet.

von Wolfgang (Gast)


Lesenswert?

mein Problem ist, dass es in ModelSim alles Funktioniert, wie es 
Funktionieren soll.

Sobald ich es auf das Board ziehe, bekomme ich einen Error, und ich 
weiss nicht wie ich das Debuggen kann.
Da ich in der Simulation alles Funktioniert.

von Wolfgang (Gast)


Lesenswert?

Da in der*

von Gustl B. (-gb-)


Lesenswert?

Und ohne Details können wir dir nicht helfen. Auch nicht wenn du weiter 
detailfreie Beiträge schreibst. Also was wäre sinnvoll?

Name der beteiligten Boards
Bilder vom Aufbau
Schaltpläne
Code
Alles was du noch bieten kannst damit wir dir helfen können.

Wolfgang schrieb:
> einen Error

Auch hier wäre es sinnvoll gewesen zu schreiben was für ein Fehler genau 
kommt mit vollständiger Fehlermeldung. Gerne auch Screenshot.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Wolfgang schrieb:
> mein Problem ist, dass es in ModelSim alles Funktioniert, wie es
> Funktionieren soll.
In der Simulation blikt sogar eine LED, wenn wenn ich schreibe
1
LED <= not LED after 500 ms;
Auf realer Hardware funktioniert das nicht.

> Sobald ich es
Was denn? Zeig mal deinen Code und sag, was der machen soll.
> auf das Board ziehe
Auf welches? Mit welcher Toolchain?
> bekomme ich einen Error
Und der ist geheim?

Wolfgang schrieb:
> Hat jemand schon mal ein ähnliches Projekt gemacht
Du solltest mal die Fragen zu deiner Aufgabe lesen und beantworten. Denn 
du hast ein Problem und mit den grausam schlechten Informationen, die du 
dazu gibst kann dir keiner helfen.

: Bearbeitet durch Moderator
von Wolfgang (Gast)


Angehängte Dateien:

Lesenswert?

Hallo danke erstmal,
Quartus 2
FPGA: DE10-Lite
Ich will, wenn der Sensor was entdeckt, das auf der 7-Seg. anzeige 
hochgezählt wird (x++).
ich habe hier denn ganzen code gepostet.
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
entity count is
5
    port
6
    (
7
        clk        : in std_logic;
8
        reset    : in std_logic;
9
        S_1     : std_logic; --sensor signal
10
        q        : out integer range 0 to 2147483647; --32bit    -- 16 bit 65535
11
      y : out std_logic
12
    );
13
end entity;
14
architecture rtl of count is
15
begin
16
    process (S_1, clk,reset)
17
        variable   cnt    : integer range 0 to 2147483647;  
18
    begin
19
 
20
21
  --  IF (S_1 = '1') THEN 
22
      --Y   <= '1'; --led leuchten 
23
    --  cnt := cnt + 1;
24
    --ELSE 
25
  --    Y   <= '0';
26
  --  END IF;
27
--q <= cnt;
28
29
30
 if (rising_edge(clk)) then
31
            if (reset = '1') then
32
                 --Reset counter 0
33
                cnt := 0;
34
            elsif (S_1 = '1') then
35
              --   count ++ y
36
                cnt := cnt + 1;
37
           y <= '0';
38
           
39
            end if;
40
     end if;
41
        
42
        -- Output count
43
  q <= cnt;
44
    end process;
45
end rtl;
1
LIBRARY IEEE;
2
USE IEEE.STD_LOGIC_1164.ALL;
3
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
4
5
ENTITY INT_TO_BCD IS
6
  
7
  PORT
8
  (
9
    q        : in integer range 0 to 2147483647;
10
    
11
     BCD_OUT : out STD_LOGIC_VECTOR (3 DOWNTO 0)--:= (others => '0')
12
  );
13
    
14
END INT_TO_BCD;
15
16
17
ARCHITECTURE arch OF INT_TO_BCD IS
18
--signal count_out            : integer range 0 to 65535;
19
20
  begin
21
 -- count_out <= 8;
22
23
        process (q) --q
24
       
25
26
          begin
27
    
28
            case q is
29
              when 0 => BCD_OUT <= "0000";
30
              when 1 => BCD_OUT <= "0001";
31
              when 2 => BCD_OUT <= "0010";
32
              when 3 => BCD_OUT <= "0011";
33
              when 4 => BCD_OUT <= "0100";
34
              when 5 => BCD_OUT <= "0101";
35
              when 6 => BCD_OUT <= "0110";
36
              when 7 => BCD_OUT <= "0111";
37
              when 8 => BCD_OUT <= "1000";
38
          when 9 => BCD_OUT <= "1001";
39
              when others => BCD_OUT <= "1110";
40
            end case;
41
  
42
    end process;
43
end arch;
1
LIBRARY IEEE;
2
USE IEEE.STD_LOGIC_1164.ALL;
3
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
4
5
ENTITY BCD_TO_7SEG IS
6
  
7
  PORT
8
  (
9
    BCD_IN : IN   STD_LOGIC_VECTOR (3 DOWNTO 0); -- nur fuer simmulation stdlogic  ueberall
10
    
11
    
12
     a, b, c, d, e, f, g : out std_logic
13
  );
14
    
15
END BCD_TO_7SEG;
16
17
ARCHITECTURE arch OF BCD_TO_7SEG IS
18
--signal cyd : STD_LOGIC_VECTOR (3 DOWNTO 0);
19
20
21
  begin
22
  --cyd <= "0011";
23
          process (BCD_IN)
24
25
          begin
26
27
            case BCD_IN is
28
              when "0000" => a <= '0'; b <= '0'; c <= '0'; d <= '0'; e <= '0'; f <= '0'; g <= '1';
29
              when "0001" => a <= '1'; b <= '0'; c <= '0'; d <= '1'; e <= '1'; f <= '1'; g <= '1'; 
30
              when "0010" => a <= '0'; b <= '0'; c <= '1'; d <= '0'; e <= '0'; f <= '1'; g <= '0';
31
              when "0011" =>  a <= '0'; b <= '0'; c <= '0'; d <= '0'; e <= '1'; f <= '1'; g <= '0';
32
              when "0100" =>  a <= '1'; b <= '0'; c <= '0'; d <= '1'; e <= '1'; f <= '0'; g <= '0';
33
              when "0101" => a <= '0'; b <= '1'; c <= '0'; d <= '0'; e <= '1'; f <= '0'; g <= '0';
34
              when "0110" => a <= '0'; b <= '1'; c <= '0'; d <= '0'; e <= '0'; f <= '0'; g <= '0';
35
              when "0111" => a <= '0'; b <= '0'; c <= '0'; d <= '1'; e <= '1'; f <= '1'; g <= '1';
36
              when "1000" =>  a <= '0'; b <= '0'; c <= '0'; d <= '0'; e <= '0'; f <= '0'; g <= '0';
37
              when "1001" => a <= '0'; b <= '0'; c <= '0'; d <= '0'; e <= '1'; f <= '0'; g <= '0';
38
              when others => a <= '1'; b <= '1'; c <= '1'; d <= '1'; e <= '1'; f <= '1'; g <= '0';
39
            end case;
40
    end process;
41
end arch;
1
library ieee;
2
use ieee.std_logic_1164.all;
3
4
entity tb_Seg7_Comp is
5
end tb_Seg7_Comp;
6
7
architecture tb of tb_Seg7_Comp is
8
9
    component Seg7_Comp
10
        port (S_1    : in std_logic;
11
              led_o  : out std_logic_vector (6 downto 0);
12
              reset  : in std_logic;
13
              areset : in std_logic;
14
              inclk0 : in std_logic;
15
              y      : out std_logic;
16
              locked : out std_logic);
17
    end component;
18
19
    signal S_1    : std_logic;
20
    signal led_o  : std_logic_vector (6 downto 0);
21
    signal reset  : std_logic;
22
    signal areset : std_logic;
23
    signal inclk0 : std_logic;
24
    signal y      : std_logic;
25
    signal locked : std_logic;
26
27
    constant TbPeriod : time := 1000 ns; -- EDIT Put right period here
28
    signal TbClock : std_logic := '0';
29
    signal TbSimEnded : std_logic := '0';
30
31
begin
32
33
    dut : Seg7_Comp
34
    port map (S_1    => S_1,
35
              led_o  => led_o,
36
              reset  => reset,
37
              areset => areset,
38
              inclk0 => inclk0,
39
              y      => y,
40
              locked => locked);
41
42
    -- Clock generation
43
    TbClock <= not TbClock after TbPeriod/2 when TbSimEnded /= '1' else '0';
44
45
    -- EDIT: Check that inclk0 is really your main clock signal
46
    inclk0 <= TbClock;
47
48
    stimuli : process
49
    begin
50
        -- EDIT Adapt initialization as needed
51
        S_1 <= '1' AFTER 0ps,'1' AFTER 10ps,'0' AFTER 20ps,'1' AFTER 30ps,'0' AFTER 40ps, '1' AFTER 50ps,'0' AFTER 60ps,'1' AFTER 70ps;
52
        areset <= '0';
53
54
        -- Reset generation
55
        -- EDIT: Check that reset is really your reset signal
56
        reset <= '0';
57
        wait for 100 ns;
58
        reset <= '0';
59
        wait for 100 ns;
60
61
        -- EDIT Add stimuli here
62
        wait for 100 * TbPeriod;
63
64
        -- Stop the clock and hence terminate the simulation
65
        TbSimEnded <= '1';
66
        wait;
67
    end process;
68
69
end tb;
70
71
72
73
configuration cfg_tb_Seg7_Comp of tb_Seg7_Comp is
74
    for tb
75
    end for;
76
end cfg_tb_Seg7_Comp;

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Wolfgang schrieb:
> elsif (S_1 = '1') then
Wie ich gleich zu Anfang schrieb:
>>>> Dann solltest du dich noch zum Thema "Eintakten" bzw.
>>>> "Einsynchronisieren" schlau machen, denn sonst wird dein Messwert dann
>>>> und wann "spinnen".

>        variable   cnt    : integer range 0 to 2147483647;
Warum verwendest du da völlig unnötigerweise eine Variable statt eines 
Signals?
Siehe Beitrag "Variable vs Signal"

> Ich will, wenn der Sensor was entdeckt, das auf der 7-Seg. anzeige
> hochgezählt wird (x++).
Und das funktioniert in der Testbench?
Was passiert damit auf der Hardware? Welche Fehlermeldung bekommst du 
von welchem Teil welcher Toolchain?

> ich habe hier denn ganzen code gepostet.
Häng das doch besser als *.vhdl Dateien an, wie über jedem 
Texteingabefeld hier steht:
1
Antwort schreiben
2
Wichtige Regeln - erst lesen, dann posten!
3
   * Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
In dem "ganzen Code" fehlt die Entity Seg7_Comp, das sollte vermutlich 
das Toplevel-Modul sein.
Was hat das gepostete Bild mit der Aufgabe zu tun? Zeigt das Bild die 
Module, die du implementieren und verdrahten sollst?

: Bearbeitet durch Moderator
von -gb- (Gast)


Lesenswert?

Lothar M. schrieb:
> unnötigerweise ein Signal?

Eine Variable. Und genau das ist auch das Problem. cnt ist 0 und wird in 
dem Takt maximal 1. Also ist auch q nur ab und zu mal für einen Takt 
lang 1.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

-gb- schrieb:
> Lothar M. schrieb:
>> unnötigerweise ein Signal?
> Eine Variable.
Aaargh... ich habs korrigiert.
Für Anfänger gilt: man benutzt keine Variable, wenn man nicht unbedingt 
eine braucht.

-gb- schrieb:
> Eine Variable. Und genau das ist auch das Problem. cnt ist 0 und wird in
> dem Takt maximal 1. Also ist auch q nur ab und zu mal für einen Takt
> lang 1.
cnt ist eine speichernde Variable (das ist fast schon ein 
Kündigungsgrund!) und zählt mangels Flankenerkennung bei Betätigung von 
S1 mit der Taktgeschwindigkeit hoch.
Also mal angenommen, der clk ist 50MHz und der Sensor belegt den S1 für 
1 ms, dann hat der cnt schon auf 50000 hochgezählt...

Darüber hinaus ist auch die Sensitivliste des Prozesses überdefiniert, 
denn Wolfgang schrieb:
> process (S_1, clk,reset)
Der Prozess ist vollkommen synchron zum clk und deshalb ausschließlich 
auf clk sensitv. Aus diesem Grund gehört auch nur clk in die Liste.

Beitrag #6907977 wurde vom Autor gelöscht.
von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

Wolfgang schrieb:
> Quartus 2
> FPGA: DE10-Lite
> Ich will, wenn der Sensor was entdeckt, das auf der 7-Seg. anzeige
> hochgezählt wird (x++).
> ich habe hier denn ganzen code gepostet.

Und die restlichen Details? Inhalt der Fehlermeldung? Beim Code fehlt
das Toplevel "Seg7_Comp".

Edith hat gerade

S_1 <= '1' AFTER 0ps,'1' AFTER 10ps,'0' AFTER 20ps,'1' AFTER 30ps,'0'
AFTER 40ps, '1' AFTER 50ps,'0' AFTER 60ps,'1' AFTER 70ps;

in der Testbench gefunden. Das sind eben echt kleine Zeiten. In der
Simulation geht das, aber das was dann auf der Hardware gemacht wird
wird sich von der Simulation deutlich unterscheiden. Daher: Simuliere
immer möglichst so wie du es auch auf der Hardware erwarten würdest.
Miss mit dem Oszi wie lange S_1 high und low ist und dann beschreibe das
so in deiner Testbench.

Edith hat hier
S_1     : std_logic; --sensor signal
noch ein fehlendes in oder out gefunden.

Lothar M. schrieb:
> cnt ist eine speichernde Variable

Jap tatsächlich.

Jetzt mit Bildchen sim.png man sieht schön, dass ein zweiter Puls
an S_1 nichts mehr an der Anzeige ändert.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.