+ Post New Thread
Results 1 to 4 of 4
  1. #1
    Member level 2
    Points: 332, Level: 3

    Join Date
    Dec 2017
    Location
    Bydgoszcz - Poland
    Posts
    42
    Helped
    8 / 8
    Points
    332
    Level
    3

    My VHDL code -Controller for roller-blinds DC motor

    Hello Everybody,

    I am new to this forum and to "programmable logic" so I would like to say Hello to forum members and ask for indulgence. I am learning VHDL and FPGA's for about a half of year. I had finished only one my own project - "Controller for roller-blinds with 12V DC motor". Project is written in VHDL for Xilinx Spartan3A
    (for synthesis I am using ISE Webpack 14.7) - more precisely for "Elbert V2" board (and MOSFET bridge as a driver for 12V DC motor). Here is link to this board:

    https://numato.com/product/elbert-v2...elopment-board

    There is three buttons:

    - one for starting closing of rollers
    - one for starting opening for rollers
    - reset (for reseting error state - for example overloading of motor)

    There are also few sensors:

    - analog comparator for detecting to much current of motor
    - two final sensor (position of rollers: end position and start position)

    I am using pwm generator (core from opencores.org) for generating of 'soft-start' and 'soft-stop' of DC motor for avoiding overvoltage of motor. The major component is a state-machine steering most of others components. The project is practically deployed in my flat and is working OK (before I had write bench-tests for veryfiing the correctness of project). I also have simple one way comunication from controller (FPGA) over RS-485 protocol and converters UART-RS485. The FPGA controller is sending status vector (4 bit of his internal state) to Arduino UNO with small OLED display.

    Here is my major project entity:

    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    
    entity Project is
        Port ( CLK : in  STD_LOGIC;
               RST : in  STD_LOGIC;
               b1 : in  STD_LOGIC;--button zamykaj
               b2 : in  STD_LOGIC;--button otwieraj
               krancEND : in  STD_LOGIC;--wyłącznik krancow 
               krancPOC : in  STD_LOGIC;--wyłącznik krancow 
               OVERLOAD : in  STD_LOGIC;--z komparatora (za duży prąd płynie przez silnik)
                  brakZasilaniaCz : in  STD_LOGIC;--Brak zasilania czujnikow (aktywne 0)
                  zdalneZamykanie : in  STD_LOGIC;--Zdalne zamykanie drzwi(aktywne 0)
               DIRPIN : inout  STD_LOGIC;
               SLPPIN : out  STD_LOGIC;
               AWARIA : out  STD_LOGIC;--Aktywne 1
                  STATUS : out STD_LOGIC_VECTOR (3 downto 0);--Opis stanu ukladu (Praca/Awaria)
               LEDOTWARTE : out  STD_LOGIC;
               LEDZAMKNIETE : out  STD_LOGIC;
               LEDPRACA : out  STD_LOGIC;
               LEDAWARIA : out  STD_LOGIC;
                  WyjPWM : out  STD_LOGIC_VECTOR (0 downto 0)
                  );--wyjscie pwm na mostek MOSFET
    end Project;
    
    architecture Behavioral of Project is
        component divider is
           Port ( clk : in  STD_LOGIC;
                  clk_out : inout  STD_LOGIC := '0');--clk_out 1MHZ
       end component;
    
       component debounce is
           port (   clk    : IN  STD_LOGIC;  --input clock
                        button  : IN  STD_LOGIC;  --input signal to be debounced
                        result  : OUT STD_LOGIC); --debounced signal
       end component;    
        
       component DMASM is
        Port ( CLK : in  STD_LOGIC;
               RST : in  STD_LOGIC;
               bt1 : in  STD_LOGIC;--btn zamykanie
               bt2 : in  STD_LOGIC;--btn otwieranie
                  krancEND : in  STD_LOGIC;--active 0
                  krancPOC : in  STD_LOGIC;--active 0
                  OVERLOAD : in  STD_LOGIC;--active 0 (przeciazenie silnika)
                  TIM2LONGZ : in  STD_LOGIC;--Timer operacja trwa za dlugo(zamykanie)
                  TIM2LONGO : in  STD_LOGIC;--Timer operacja trwa za dlugo(otwieranie)
                  NoPowerSensors : in  STD_LOGIC;--Brak zasilania czujnikow (aktywne 0)
                  RemoteZamykanie : in  STD_LOGIC;--Zdalne zamykanie drzwi(aktywne 0)
               DIRPIN : out  STD_LOGIC;--Direction Motor ( 0 - FORWARD)
               SLPPIN : out  STD_LOGIC;--SLEEP PIN Mostek (0 - mostek zablokowany)
               pb1_Zam : out  STD_LOGIC;--gdy 0 zamykanie
               pb2_Otw : out  STD_LOGIC;--gdy 0 otwieranie
                  blokada_Zam : out  STD_LOGIC;--gdy 0 blokada
               blokada_Otw : out  STD_LOGIC;--gdy 0 blokada
                  SELO : out STD_LOGIC_VECTOR (1 downto 0);--wybor pwm dla multiplexera
                  AWARIA : out  STD_LOGIC;--gdy 1 awaria ukladu
                  STATUSO : out STD_LOGIC_VECTOR (3 downto 0);--Opis stanu ukladu (Praca/Awaria)
                  LEDZAMKNIETE : out  STD_LOGIC;--gdy 1 LED zamkniete
                  LEDOTWARTE : out  STD_LOGIC;--gdy 1 LED otwarte
                  LEDPRACA : out  STD_LOGIC;--gdy 1 LED Zamykanie/otwieranie
                  LEDAWARIA : out  STD_LOGIC);--gdy 1 LED awaria;
      end component;
    
     component WEKTORY_WYPELNIEN is
           port ( clk :in std_logic;
             pushB :in std_logic;
                blokada :in std_logic;
                rst : in  STD_LOGIC; --aktywne 0
                timerO : out std_logic;
             data : out std_logic_vector(7 downto 0) );
     end component; 
       
     component WEKTORY_REVERSE is
           port ( clk :in std_logic;
             pushB :in std_logic;
             data : out std_logic_vector(7 downto 0) );
     end component;
    
       component pwm is
          Port (  clk : in  STD_LOGIC;
               reset_n : in  STD_LOGIC;
               ena : in  STD_LOGIC;
               duty : in  STD_LOGIC_VECTOR (7 downto 0);
               pwm_out : out  STD_LOGIC_VECTOR (0 downto 0);
               pwm_n_out : out  STD_LOGIC_VECTOR (0 downto 0));
      end component;  
    
     component mux4to1 is
                Port ( SEL : in  STD_LOGIC_VECTOR (1 downto 0); -- select input
               A   : in  STD_LOGIC_VECTOR (0 downto 0);  -- inputs
                  B   : in  STD_LOGIC_VECTOR (0 downto 0);
                  C   : in  STD_LOGIC_VECTOR (0 downto 0);
                  D   : in  STD_LOGIC_VECTOR (0 downto 0);
               X   : out STD_LOGIC_VECTOR (0 downto 0)); -- output
     end component;  
     
      
       signal data1_signal :STD_LOGIC_VECTOR (7 downto 0);
        signal data2_signal :STD_LOGIC_VECTOR (7 downto 0);
        signal data3_signal :STD_LOGIC_VECTOR (7 downto 0);
        signal data4_signal :STD_LOGIC_VECTOR (7 downto 0);
        signal b1_DB :STD_LOGIC;
        signal b2_DB :STD_LOGIC;
        signal clk_1MHz :STD_LOGIC;
        signal pwm1_out :STD_LOGIC_VECTOR (0 downto 0);
        signal pwm2_out :STD_LOGIC_VECTOR (0 downto 0);
        signal pwm3_out :STD_LOGIC_VECTOR (0 downto 0);
        signal pwm4_out :STD_LOGIC_VECTOR (0 downto 0);
        signal pwm1_n_out :STD_LOGIC_VECTOR (0 downto 0);
        signal pwm2_n_out :STD_LOGIC_VECTOR (0 downto 0);
        signal pwm3_n_out :STD_LOGIC_VECTOR (0 downto 0);
        signal pwm4_n_out :STD_LOGIC_VECTOR (0 downto 0);
        --signal WyjPWM :STD_LOGIC_VECTOR (0 downto 0);
        signal pb1_Zam :STD_LOGIC;
        signal pb2_Otw :STD_LOGIC;
        signal blokada_Zam :STD_LOGIC;
        signal blokada_Otw :STD_LOGIC;
        signal SELO :STD_LOGIC_VECTOR (1 downto 0);
        signal TIM2LONGZ :STD_LOGIC;
        signal TIM2LONGO :STD_LOGIC;
        --signal brakZasilaniaCz :STD_LOGIC;    
        --signal zdalneZamykanie :STD_LOGIC;
        
    begin
        C1: divider port map (CLK, clk_1MHz);
        C2: debounce port map (clk_1MHz, b1, b1_DB);
        C3: debounce port map (clk_1MHz, b2, b2_DB);
        
        C4: WEKTORY_WYPELNIEN port map (clk_1MHz, pb1_Zam, blokada_Zam, RST, TIM2LONGZ, data1_signal);
        C5: WEKTORY_WYPELNIEN port map (clk_1MHz, pb2_Otw, blokada_Otw, RST, TIM2LONGO, data2_signal);
        C6: DMASM  port map   (clk_1MHz,
                                      RST,
                                      b1_DB, 
                                      b2_DB,
                                      krancEND,
                                      krancPOC,
                                      OVERLOAD,
                                      TIM2LONGZ,
                                      TIM2LONGO,
                                      brakZasilaniaCz,
                                      zdalneZamykanie,
                                      DIRPIN, 
                                      SLPPIN, 
                                      pb1_Zam, 
                                      pb2_Otw,
                                      blokada_Zam,
                                      blokada_Otw,
                                      SELO,
                                      AWARIA,
                                      STATUS,
                                      LEDZAMKNIETE, 
                                      LEDOTWARTE, 
                                      LEDPRACA, 
                                      LEDAWARIA);
            
        
        C7: pwm port map (clk_1MHz, RST, '1', data1_signal, pwm1_out, pwm1_n_out);
       C8: pwm port map (clk_1MHz, RST, '1', data2_signal, pwm2_out, pwm2_n_out);
        
        C9: WEKTORY_REVERSE port map (clk_1MHz, blokada_Zam, data3_signal);
        C10: WEKTORY_REVERSE port map (clk_1MHz, blokada_Otw, data4_signal);
        C11: pwm port map (clk_1MHz, RST, '1', data3_signal, pwm3_out, pwm3_n_out);
       C12: pwm port map (clk_1MHz, RST, '1', data4_signal, pwm4_out, pwm4_n_out);
        C13: mux4to1 port map (SELO, pwm1_out, pwm2_out, pwm3_out, pwm4_out, WyjPWM);
            
    end Behavioral;
    Below entity WEKTORY_WYPELNIEN for generating changing PWM signal (soft-start for example):

    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    use ieee.numeric_std.all;
    
    entity WEKTORY_WYPELNIEN is
      generic (
            NBit : natural := 30;
            Div : natural := 3_000_000 --3s
            );
      port ( clk :in std_logic;
             pushB :in std_logic;
                blokada :in std_logic;
                rst : in  STD_LOGIC; --aktywne 0
                timerO : out std_logic;
             data : out std_logic_vector(7 downto 0) );
    end WEKTORY_WYPELNIEN;
    
     architecture BEHAVE of WEKTORY_WYPELNIEN is
    
      signal ADDRESS :integer range 0 to 32 :=0;
       signal TEMP :integer range 0 to 10_000_000 :=0; -- liczba impulsów
       -- jaka ma minąć zanim dojdzie do zmiany adresu
    
          signal GENERACJA_SERII_WEKTOROW : std_logic :='0'; 
       -- okreslanie kiedy ma sie zaczac generacja serii wektorow
        signal GENERACJA2_SERII_WEKTOROW : std_logic :='0'; 
    
       signal KONIEC_GENERACJI_WEKTOROW : std_logic :='0'; 
       -- okreslenie kiedy koniec generacji serii wektorow
    
       signal OPOZNIENIE_BUTTONA :integer range 0 to 1_000_000 :=0;
        
        signal cnt: std_logic_vector(Nbit -1 downto 0) := (others=>'0'); --licznik timera czasu otwarcia
        
        type mem is array ( 0 to 2**5 - 1) of std_logic_vector(7 downto 0);
      constant my_Rom : mem := (
        0  => "00000011",
        1  => "00000111",
        2  => "00001110",
        3  => "00001111",
        4  => "00010101",
        5  => "00011100",
        6  => "00100011",
        7  => "00010000",
        8  => "00101010",
        9  => "00110001",
        10 => "00111000",
        11 => "00111111",
        12 => "01000110",
        13 => "01001101",
        14 => "01010100",
        15 => "01011011",
        16 => "01100010",
        17 => "01101001",
        18 => "01110000",
        19 => "01110111",
        20 => "01111110",
        21 => "10000101",
        22 => "10001100",
        23 => "10010011",
        24 => "10011010",
        25 => "10100001",
        26 => "10101000",
        27 => "10010111",
        28 => "10110110",
        29 => "11011001",
        30 => "11100000",
        31 => "11111111"
         );
    
    begin
    
        --  ZWIEKSZANIE ADRESU KOLEJNYCH WEKTOROW WYPELNIEN
       process (CLK)
       begin
          if rising_edge(CLK) then
             if (rst= '0') then
                   ADDRESS <= 0;
                    TEMP <= 0; -- liczba impulsów
                   GENERACJA_SERII_WEKTOROW <= '0'; 
                 GENERACJA2_SERII_WEKTOROW <= '0'; 
                KONIEC_GENERACJI_WEKTOROW <= '0'; 
                OPOZNIENIE_BUTTONA <= 0;    
                else    
                  -- SPRAWDZENIE CZY PRZYCISK JEST NACISNIETY CZY NIE
                  if (pushB = '0') then -- lub '0' gdy po nacisnieciu
                  -- przycisku generowane jest przerwanie
                      if (OPOZNIENIE_BUTTONA < 10_000) then
                      -- opoznienie dzialania przycisku, aby za szybko 
                      -- nie szla generacja po nacisnieciu
                         OPOZNIENIE_BUTTONA <= OPOZNIENIE_BUTTONA + 1;
                      else
                         if (KONIEC_GENERACJI_WEKTOROW = '0') then  
                         -- jesli jest koniec to nie wznawiaj generacji
                             GENERACJA_SERII_WEKTOROW <= '1';
                                     GENERACJA2_SERII_WEKTOROW <= '0';
                         end if;
                      end if;
                  else
                      KONIEC_GENERACJI_WEKTOROW <= '0';  
                       OPOZNIENIE_BUTTONA <= 0;
                      -- zeruj  koniec, gdy przycisk jest puszczony
                      -- zeruj opoznienie przycisku
                  end if;             
    
                  -- GENERACJA SERII WEKTOROW PO NACISNIECIU PRZYCISKU 
                  -- ORAZ OKRESLENIE JEJ KONCA PO JEJ WYKONANIU
                  if (GENERACJA_SERII_WEKTOROW = '1') then
                            if (TEMP < 20_000) then --okolo 0,02 s : 0,64 s calosc
                          TEMP <= TEMP + 1;
                            else 
                          TEMP <= 0;
                          if (ADDRESS < 31) then
                             ADDRESS <= ADDRESS + 1;
                         else
                             KONIEC_GENERACJI_WEKTOROW <= '1';
                             GENERACJA_SERII_WEKTOROW <= '0';
                                     GENERACJA2_SERII_WEKTOROW <= '1';
                             ADDRESS <= 0;
                         end if;
                            end if;
                  else
                          
                     TEMP <= 0;
                  end if;
                  end if;      
          end if;
       end process;
    
    
          -- GENEROWANIE WEKTOROW WYPELNIEN
       process (CLK)
       begin
          if rising_edge(CLK)  then
            if (rst= '0') then
                DATA <= "00000000";
            elsif (blokada = '0') then
                DATA <= "00000000";
            else
            if (GENERACJA_SERII_WEKTOROW = '1') and (GENERACJA2_SERII_WEKTOROW = '0')  then-- gdy trwa generacja             -- wektorow
                   DATA <= my_rom(ADDRESS);
             else if     (GENERACJA2_SERII_WEKTOROW = '1') then
                        DATA <= "11100000";
            else  -- gdy generacja nie trwa
              DATA <= "00000000";
                 end if;
             end if;
        end if;
        end if;
       end process;
        
           -- Timer do odliczania czasu otwierania
            
        process(CLK)
        begin
            if (CLK'event and CLK='1') then
              if ((rst = '0') or (blokada = '0')) then 
                    cnt <= (others => '0');
                    timerO  <= '0';
              else
                if ((GENERACJA_SERII_WEKTOROW = '1') or (GENERACJA2_SERII_WEKTOROW = '1')) then          
                    if cnt < Div then
                        --timerO <= '0';--Check this
                        cnt <= cnt+1;
                    else
                        cnt <= (others=>'0');
                        timerO <= '1';
                    end if;
                end if;
              end if;
            end if;
       end process;            
        
    end BEHAVE;
    And last example: state-machine:

    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;
     
    
    entity DMASM is
        Port ( CLK : in  STD_LOGIC;--Zegar
               RST : in  STD_LOGIC;--Reset
               bt1 : in  STD_LOGIC;--btn zamykanie
               bt2 : in  STD_LOGIC;--btn otwieranie
                  krancEND : in  STD_LOGIC;--active 0
                  krancPOC : in  STD_LOGIC;--active 0
                  OVERLOAD : in  STD_LOGIC;--active 0 (przeciazenie silnika)
                  TIM2LONGZ : in  STD_LOGIC;--Timer operacja trwa za dlugo(zamykanie)
                  TIM2LONGO : in  STD_LOGIC;--Timer operacja trwa za dlugo(otwieranie)
                  NoPowerSensors : in  STD_LOGIC;--Brak zasilania czujnikow (aktywne 0)
                  RemoteZamykanie : in  STD_LOGIC;--Zdalne zamykanie drzwi(aktywne 0)
               DIRPIN : out  STD_LOGIC;--Direction Motor ( 0 - FORWARD)
               SLPPIN : out  STD_LOGIC;--SLEEP PIN Mostek (0 - mostek zablokowany)
               pb1_Zam : out  STD_LOGIC;--gdy 0 zamykanie
               pb2_Otw : out  STD_LOGIC;--gdy 0 otwieranie
                  blokada_Zam : out  STD_LOGIC;--gdy 0 blokada
               blokada_Otw : out  STD_LOGIC;--gdy 0 blokada
                  SELO : out STD_LOGIC_VECTOR (1 downto 0);--wybor pwm dla multiplexera
                  AWARIA : out  STD_LOGIC;--gdy 0 awaria ukladu
                  STATUSO : out STD_LOGIC_VECTOR (3 downto 0);--Opis stanu ukladu (Praca/Awaria)
                  LEDZAMKNIETE : out  STD_LOGIC;--gdy 1 LED zamkniete
                  LEDOTWARTE : out  STD_LOGIC;--gdy 1 LED otwarte
                  LEDPRACA : out  STD_LOGIC;--gdy 1 LED Zamykanie/otwieranie
                  LEDAWARIA : out  STD_LOGIC);--gdy 1 LED awaria;
    end DMASM;
    
    architecture BEHAVE of DMASM is
            type STATE is (S0Otwarte, S1ZamykanieLocal, S2Zamkniete, S3OtwieranieLocal, S4ZamykanieRemote, 
                                  S5Overload, S6TooLongOper, S7NoPowerSensors, S8PositionError,
                                  S9UnknowError, S10Awaria, S11DomkZamykanie, S12DomkOtwieranie,
                                  S13BetweenEdges);
           signal CURRENT_STATE, NEXT_STATE: STATE;
              
             constant LICZNIK_LIMIT : integer := 2_000_000; -- 2s deklaracja stalej z max wart licznika
             
             signal licznik : unsigned(24 downto 0); -- definicja syg lokalnego          
              
    begin
    
    SEQ: process (RST, CLK, krancPOC, krancEND, OVERLOAD, NoPowerSensors, RemoteZamykanie)
    begin
            if (RST = '0') then
                 licznik <= b"0000000000000000000000000";
                 if ((krancPOC = '0') and (krancEND = '1')) then
                 CURRENT_STATE <= S0Otwarte; 
               else if ((krancPOC = '1') and (krancEND = '0')) then
                 CURRENT_STATE <= S2Zamkniete;
                    elsif ((krancPOC = '1') and (krancEND = '1')) then
                 CURRENT_STATE <= S13BetweenEdges; 
                    end if;   
               end if;     
            elsif (CLK' event and CLK = '1' ) then
                    if (CURRENT_STATE = S11DomkZamykanie) and (NEXT_STATE = S11DomkZamykanie) then
                        licznik <= licznik + 1;
                         if licznik = LICZNIK_LIMIT then 
                            licznik <= b"0000000000000000000000000";
                             CURRENT_STATE <= S2Zamkniete;
                         end if;
                    elsif (CURRENT_STATE = S12DomkOtwieranie) and (NEXT_STATE = S12DomkOtwieranie) then
                         licznik <= licznik + 1;
                         if licznik = LICZNIK_LIMIT then 
                            licznik <= b"0000000000000000000000000";
                             CURRENT_STATE <= S0Otwarte;
                         end if;
                    elsif (OVERLOAD = '0') then--tu obsluga bledow dla all states
                         CURRENT_STATE <= S5Overload;
                    elsif (NoPowerSensors = '0') then
                         CURRENT_STATE <= S7NoPowerSensors;
                    elsif ((krancEND = '0') and (krancPOC = '0')) then
                         CURRENT_STATE <= S8PositionError;      
                    else     
                    CURRENT_STATE <= NEXT_STATE;
                    end if;
            end if;
    end process;
    
    COMB: process (CURRENT_STATE, RST, bt1, bt2, krancEND, KrancPOC,
                       TIM2LONGZ, TIM2LONGO)
    begin 
    case CURRENT_STATE is
        when S0Otwarte => DIRPin <= '0';
                SLPPin <= '0';--mostek zablokowany
                pb1_Zam <= '1';
                pb2_Otw <= '1';--blokada ALL
                blokada_Zam <= '0';
                blokada_Otw <= '0';
                SELO <= "11";
                AWARIA <= '0'; --klawisz nieaktywny
                LEDZAMKNIETE <= '0';
                LEDOTWARTE <= '1';
                LEDPRACA <= '0';
                LEDAWARIA  <= '0';
                STATUSO <= "0000";            
                if (bt1 = '0') then
                     NEXT_STATE <= S1ZamykanieLocal;
                  elsif  (RemoteZamykanie = '0') then 
                      NEXT_STATE <= S4ZamykanieRemote;
               elsif ((krancPOC = '0') and (krancEND = '1')) then
                 NEXT_STATE <= S0Otwarte; 
               elsif ((krancPOC = '1') and (krancEND = '0')) then
                 NEXT_STATE <= S2Zamkniete;
                  elsif ((krancPOC = '1') and (krancEND = '1')) then
                    NEXT_STATE <= S13BetweenEdges;
               end if;                                                             
        when S1ZamykanieLocal => DIRPin <= '0';
                SLPPin <= '1';--FORWARD,MOSTEK OTWARTY
                pb1_Zam <= '0';
                pb2_Otw <= '1';
                blokada_Zam <= '1';
                blokada_Otw <= '0';
                SELO <= "00";
                AWARIA <= '0'; --klawisz nieaktywny
                LEDZAMKNIETE <= '0';
                LEDOTWARTE <= '1';
                LEDPRACA <= '1';
                LEDAWARIA  <= '0';
                STATUSO <= "0001";
             if (bt2 = '0')    then
               NEXT_STATE <= S3OtwieranieLocal;                        
               else 
                  if ((krancEND = '0') and (krancPOC = '1')) then 
                      NEXT_STATE <= S11DomkZamykanie;                  
                 elsif (TIM2LONGZ = '1') then
                   NEXT_STATE <= S6TooLongOper;
               else
                  NEXT_STATE <= S1ZamykanieLocal; 
               end if;                                                                    
               end if;
        when S2Zamkniete => DIRPin <= '1';
                SLPPin <= '0';
                pb1_Zam <= '1';
                pb2_Otw <= '1';--blokada ALL
                blokada_Zam <= '0';
                blokada_Otw <= '0';
                SELO <= "10";
                AWARIA <= '0'; --klawisz nieaktywny
                LEDZAMKNIETE <= '1';
                LEDOTWARTE <= '0';
                LEDPRACA <= '0';
                LEDAWARIA  <= '0'; 
                STATUSO <= "0010";
            if (bt2 = '0')then --Button otwieranie
                  NEXT_STATE <= S3OtwieranieLocal;
            else
                  if ((krancPOC = '0') and (krancEND = '1')) then
                 NEXT_STATE <= S0Otwarte; 
               elsif ((krancPOC = '1') and (krancEND = '0')) then
                 NEXT_STATE <= S2Zamkniete;
                  elsif ((krancPOC = '1') and (krancEND = '1')) then
                    NEXT_STATE <= S13BetweenEdges;
                  end if;     
            end if;
        when S3OtwieranieLocal => DIRPin <= '1';
                SLPPin <= '1';
                pb1_Zam <= '1';
                pb2_Otw <= '0';--BACKWARD,MOSTEK OTWARTY
                blokada_Zam <= '0';
                blokada_Otw <= '1';
                SELO <= "01";
                AWARIA <= '0'; --klawisz nieaktywny
                LEDZAMKNIETE <= '1';
                LEDOTWARTE <= '0';
                LEDPRACA <= '1';
                LEDAWARIA  <= '0';
                STATUSO <= "0011";
              if (bt1 = '0') then --Button zamykanie
                   NEXT_STATE <= S1ZamykanieLocal;
              elsif ((krancPOC = '0') and (krancEND = '1')) then  -- zmiana stanu czuj. krancowych
                  NEXT_STATE <= S12DomkOtwieranie;     
              else -- gdy nie ma awarii
                 if (TIM2LONGO = '1') then  -- gdy jest awaria
                   NEXT_STATE <= S6TooLongOper;
               else
                  NEXT_STATE <= S3OtwieranieLocal; 
              end if;                                                                    
              end if;            
        when S4ZamykanieRemote => DIRPin <= '0';
                SLPPin <= '1';--FORWARD,MOSTEK OTWARTY
                pb1_Zam <= '0';
                pb2_Otw <= '1';
                blokada_Zam <= '1';
                blokada_Otw <= '0';
                SELO <= "00";
                AWARIA <= '0'; --klawisz nieaktywny
                LEDZAMKNIETE <= '0';
                LEDOTWARTE <= '1';
                LEDPRACA <= '1';
                LEDAWARIA  <= '0';
                STATUSO <= "0100";
               
                if (bt2 = '0') then --klawisz otwieranie
                      NEXT_STATE <= S3OtwieranieLocal;
               elsif ((krancEND = '0') and (krancPOC = '1')) then
                   NEXT_STATE <= S11DomkZamykanie;                                 
               else 
                 if (TIM2LONGZ = '1') then  -- gdy jest awaria
                  NEXT_STATE <= S6TooLongOper; 
               else
                  NEXT_STATE <= S4ZamykanieRemote;
               end if;                                                                        
            end if;            
         when S5Overload => DIRPin <= '1';--stan S4Awaria
                SLPPin <= '0';--blokada mostka
                pb1_Zam <= '1';
                pb2_Otw <= '1';--klawisze nieaktywne
                blokada_Zam <= '0';
                blokada_Otw <= '0';
                AWARIA <= '1'; --sygnal aktywny
                LEDZAMKNIETE <= '0';
                LEDOTWARTE <= '0';
                LEDPRACA <= '0';
                LEDAWARIA  <= '1';
                STATUSO <= "1000";
                NEXT_STATE <= S10Awaria;
         when S6TooLongOper => DIRPin <= '1';--stan S4Awaria
                SLPPin <= '0';--blokada mostka
                pb1_Zam <= '1';
                pb2_Otw <= '1';--klawisze nieaktywne
                blokada_Zam <= '0';
                blokada_Otw <= '0';
                AWARIA <= '1'; --sygnal aktywny
                LEDZAMKNIETE <= '0';
                LEDOTWARTE <= '0';
                LEDPRACA <= '0';
                LEDAWARIA  <= '1';
                STATUSO <= "1010";
                NEXT_STATE <= S10Awaria;
         when S7NoPowerSensors => DIRPin <= '1';--stan S4Awaria
                SLPPin <= '0';--blokada mostka
                pb1_Zam <= '1';
                pb2_Otw <= '1';--klawisze nieaktywne
                blokada_Zam <= '0';
                blokada_Otw <= '0';
                AWARIA <= '1'; --sygnal aktywny
                LEDZAMKNIETE <= '0';
                LEDOTWARTE <= '0';
                LEDPRACA <= '0';
                LEDAWARIA  <= '1';
                STATUSO <= "1001";
                NEXT_STATE <= S10Awaria;
         when S8PositionError => DIRPin <= '1';--stan S4Awaria
                SLPPin <= '0';--blokada mostka
                pb1_Zam <= '1';
                pb2_Otw <= '1';--klawisze nieaktywne
                blokada_Zam <= '0';
                blokada_Otw <= '0';
                AWARIA <= '1'; --sygnal aktywny
                LEDZAMKNIETE <= '0';
                LEDOTWARTE <= '0';
                LEDPRACA <= '0';
                LEDAWARIA  <= '1';
                STATUSO <= "1011";
             NEXT_STATE <= S10Awaria;            
         when S9UnknowError => DIRPin <= '1';--stan S4Awaria
                SLPPin <= '0';--blokada mostka
                pb1_Zam <= '1';
                pb2_Otw <= '1';--klawisze nieaktywne
                blokada_Zam <= '0';
                blokada_Otw <= '0';
                AWARIA <= '1'; --sygnal aktywny
                LEDZAMKNIETE <= '0';
                LEDOTWARTE <= '0';
                LEDPRACA <= '0';
                LEDAWARIA  <= '1';
                STATUSO <= "1100";
             NEXT_STATE <= S10Awaria;            
         when S10Awaria => DIRPin <= '1';--stan S10Awaria
                SLPPin <= '0';--blokada mostka
                pb1_Zam <= '1';
                pb2_Otw <= '1';--klawisze nieaktywne
                blokada_Zam <= '0';
                blokada_Otw <= '0';
                AWARIA <= '1'; --sygnal aktywny
                LEDZAMKNIETE <= '0';
                LEDOTWARTE <= '0';
                LEDPRACA <= '0';
                LEDAWARIA  <= '1';
       when S11DomkZamykanie => DIRPin <= '0';
                SLPPin <= '1';
                pb1_Zam <= '1';
                pb2_Otw <= '1';--blokada ALL
                blokada_Zam <= '0';
                blokada_Otw <= '0';
                SELO <= "10";
                AWARIA <= '0'; --klawisz nieaktywny
                LEDZAMKNIETE <= '0';
                LEDOTWARTE <= '1';
                LEDPRACA <= '1';
                LEDAWARIA  <= '0'; 
                STATUSO <= "0101";
                if (bt2 = '0') then --klawisz otwieranie
                    NEXT_STATE <= S3OtwieranieLocal;
                else        
                    NEXT_STATE <= S11DomkZamykanie;
                end if;     
      when S12DomkOtwieranie => DIRPin <= '1';
                SLPPin <= '1';
                pb1_Zam <= '1';
                pb2_Otw <= '1';--blokada ALL
                blokada_Zam <= '0';
                blokada_Otw <= '0';
                SELO <= "11";
                AWARIA <= '0'; --klawisz nieaktywny
                LEDZAMKNIETE <= '1';
                LEDOTWARTE <= '0';
                LEDPRACA <= '1';
                LEDAWARIA  <= '0'; 
                STATUSO <= "0110";
                if (bt1 = '0') then --Button zamykanie
                    NEXT_STATE <= S1ZamykanieLocal;
                else    
                    NEXT_STATE <= S12DomkOtwieranie;
                end if;     
       when S13BetweenEdges => DIRPin <= '0';
                SLPPin <= '0';--mostek zablokowany
                pb1_Zam <= '1';
                pb2_Otw <= '1';--blokada ALL
                blokada_Zam <= '0';
                blokada_Otw <= '0';
                SELO <= "11";
                AWARIA <= '0'; --klawisz nieaktywny
                LEDZAMKNIETE <= '0';
                LEDOTWARTE <= '0';
                LEDPRACA <= '0';
                LEDAWARIA  <= '0';
                STATUSO <= "0111";            
                if (bt2 = '0') then --Button otwieranie
                     NEXT_STATE <= S3OtwieranieLocal;             
                  elsif (bt1 = '0') then --Button zamykanie
                     NEXT_STATE <= S1ZamykanieLocal;
                  elsif  (RemoteZamykanie = '0') then 
                      NEXT_STATE <= S4ZamykanieRemote;
               else
                 if ((krancPOC = '0') and (krancEND = '1')) then
                    NEXT_STATE <= S0Otwarte; 
                 elsif ((krancPOC = '1') and (krancEND = '0')) then
                    NEXT_STATE <= S2Zamkniete;
                    elsif ((krancPOC = '1') and (krancEND = '1')) then
                       NEXT_STATE <= S13BetweenEdges;
                  end if;     
               end if;              
        when others => STATUSO <= "1010";--sygnalizacja TooLongOper
              NEXT_STATE <= S10Awaria;
        end case;
      end process;
    end BEHAVE;
    For last month I had started to learn myself Xilinx Vivado. I also had purchased a 'larger' FPGA board - "Digilent Cmod-A7' board:

    https://reference.digilentinc.com/re...1id=cmod_a7/cm

    with Xilinx Artix-7 FPGA

    and I would like to experiment with Xilinx soft-CPU Microblaze.

    I am also interested with HLS (High Level Synthesis) and "Vivado HLS".

    Best Regards

    •   Alt16th December 2017, 18:47

      advertising

        
       

  2. #2
    Super Moderator
    Points: 47,651, Level: 53

    Join Date
    Apr 2011
    Location
    Minneapolis, Minnesota, USA
    Posts
    11,852
    Helped
    2339 / 2339
    Points
    47,651
    Level
    53

    Re: My VHDL code -Controller for roller-blinds DC motor

    Your post was moved to the Do-it-yourself section, in case readers wish to generate discussion.
    We invite you to create your own blog page. (Edaboard provides each member with his individual blog area.)
    Sorry, your weblinks are not working correctly.
    Schematics, photographs, etc., can be uploaded as Edaboard attachments, in normal circumstances. Click the Rules tab to find more information.

    •   Alt16th December 2017, 20:28

      advertising

        
       

  3. #3
    Full Member level 4
    Points: 1,828, Level: 9

    Join Date
    May 2014
    Posts
    221
    Helped
    22 / 22
    Points
    1,828
    Level
    9

    Re: My VHDL code -Controller for roller-blinds DC motor

    Well done on your project.

    If I may ask, what is it you're after? Project resources/templates or ideas? Project collaboration?

    Regards,

    •   Alt12th January 2018, 11:18

      advertising

        
       

  4. #4
    Member level 2
    Points: 332, Level: 3

    Join Date
    Dec 2017
    Location
    Bydgoszcz - Poland
    Posts
    42
    Helped
    8 / 8
    Points
    332
    Level
    3

    Re: My VHDL code -Controller for roller-blinds DC motor

    Hi,

    thanks ;)

    I haven't any precised plans on future. I wolud like to develop my skills regarding PLDs, next step are Soft-CPU and SoCs with FPGAs.

    Kind Regards

--[[ ]]--