DESIGNING DIGITAL CONTROLLER FOR ELECTRONIC DUMBWAITER LIFT (EDL) SYSTEM
For this Design Project, I had to design a digital controller for a Electronic Dumbwaiter Lift(EDL) for a hotel. The typical view of EDL controller as below,

And the given specifications are,
1. The hotel owner initially plan’s to implements the system for three stories (ground floor, first floor, and second floor).
2. Push buttons are used for selecting the appropriate floor to move the lift from the default location (ground floor kitchen).
3. Limit Switches will be used for identifying the floor when the lift reaches.
4. Return switches are used for sending the EDL to the default location.
5. RESET can be used to reset the EDL system.
For implement this designed controller, I used a mealy machine with a encoder, In my design have 7 inputs and 2 output to control the motor direction.
With this controller, There are two control panel required to located in a kitchen and on EDL as below.

1st panel is for kitchen and 2nd panel is for EDL. I made following initial assumptions for continue the deign tasks
· EDL can transport goods between floors from/to kitchen and a floor only. It can’t go intermediate floors.(Ex. It can’t go from 1st floor to 2nd )
· When start the system (Powered up),EDL went to ground floor.
· If press the reset, controller goes to initial state.(If system not work properly, can press ‘reset’).
· Assume initially not pressed any button.
· After start the transition, Buttons can’t change the destination, other than with press reset.

This controller has two components known as, priority encoder and a controller. Priority encoders reduce the number of inputs to the controller, and it maintain the input priority. Controllers hold the current state and make decisions according to the inputs.
Inputs
| # | Input | Encoder Output Code | Description |
|---|---|---|---|
| 1 | CLK | - | Synchronize Clock |
| 2 | RST | 000 | Reset - reset the EDL system. |
| 3 | P[0] | 001 | 1st push button. Use to select 1st floor |
| 4 | P[1] | 010 | 2nd push button. Use to select 2nd floor |
| 5 | L[0] | 011 | Ground Limit switch – activated when Lift reaches the kitchen |
| 6 | L[1] | 100 | 1st Limit switch – activated when Lift reaches 1st Floor |
| 7 | L[2] | 101 | 2nd Limit switch – activated when Lift reaches 2nd Floor |
| 8 | RET | 110 | Return – use to return lift to the kitchen |
| 9 | RUN | 111 | Nothing (Implement at the hardware level by using a push-up resistors) |
Outputs
| # | Output | Code | Function |
|---|---|---|---|
| 1 | M[1],M[0] | 00 | Stop Motor |
| 2 | M[1],M[0] | 01 | Start Motor Upward |
| 3 | M[1],M[0] | 10 | Start Motor Downward |
| 4 | M[1],M[0] | 11 | Stop Motor |


States before Minimizing
| State | Description |
|---|---|
| II | Initial State |
| GG | Ground Floor State |
| F1 | 1st Floor State |
| F2 | 2nd Floor State |
| TG | Go to Ground Floor State |
| T1 | Go to 1st Floor State |
| T2 | Go to 2nd Floor State |
State Table before minimizing
| Present State | Next State, Output | |||||||
|---|---|---|---|---|---|---|---|---|
| RST | P [0] | P [1] | L [0] | L [1] | L [2] | RET | RUN * | |
| II | II,00 | -,- | -,- | GG,00 | II,10 | II,10 | -,- | II,10 |
| GG | II,00 | T1,01 | T2,01 | GG,00 | -,- | -,- | GG,00 | GG,00 |
| F1 | II,00 | F1,00 | F1,00 | -,- | F1,00 | -,- | TG,10 | F1,00 |
| F2 | II,00 | F2,00 | F2,00 | -,- | -,- | F2,00 | TG,10 | F2,00 |
| TG | II,00 | TG,10 | TG,10 | GG,00 | TG,10 | TG,10 | TG,10 | TG,10 |
| T1 | II,00 | T1,01 | T1,01 | T1,01 | F1,00 | -,- | T1,01 | T1,01 |
| T2 | II,00 | T2,01 | T2,01 | T2,01 | T2,01 | F2,00 | T2,01 | T2,01 |
| NO* | II,10 | II,10 | II,10 | GG,00 | II,10 | II,10 | II,00 | II,00 |


| State | Description | Code | |
|---|---|---|---|
| 1 | II | Initial State | 000 |
| 2 | GG | Ground Floor State | 100 |
| 3 | FF | NOT Ground Floor State | 011 |
| 4 | T1 | Go to 1st Floor State | 001 |
| 5 | T2 | Go to 2nd Floor State | 010 |




Minimizing P:
P = RST’ . P0’ . P1’.L0’ [L1 + L1’.L2+L1’.L2’.RET]
P = RST’ . P0’ . P1’.L0’[L1+L2+ L1’.L2’.RET]
Minimizing Q:
Q = RST’ . P0’ . P1 + RET’ . P0’ . P1’ . L0 + RST’ . P0’. P1’.L0’.L1’.L2’
Minimizing R:
R = RST’ [P0 + P0’.P1’.L0 + P0’.P1’.L0’.L1’.L2 + P0’ P1’ L0’ L1’ L2’ RET]
R = RST’ [P0 + P1’.L0’ + P0’.P1’.L0’.L1’ [L2+RET]]



· Controller has 5 states and developed by using D Flip flop.
· Output also depended on the current states and input (Merely machine).
· Included Power-on-reset circuit. So, when power up the system, system goes to initial state.

library IEEE; --Not a Picture
use IEEE.STD_LOGIC_1164.ALL;
use ieee.NUMERIC_STD.all;
entity Encorder is
Port ( BUT1 : in STD_LOGIC;
BUT2 : in STD_LOGIC;
G_lmt : in STD_LOGIC;
lmt_1 : in STD_LOGIC;
lmt_2 : in STD_LOGIC;
ret : in STD_LOGIC;
reset : in STD_LOGIC;
Y : out STD_LOGIC_VECTOR (2 downto 0));
end Encorder;
architecture Behavioral of Encorder is
begin
process(BUT1,BUT2,G_lmt,lmt_1,lmt_2,ret,reset)
begin
if (reset = '1') then Y <= "000";
elsif (ret = '1') then Y <= "001";
elsif (BUT1 = '1') then Y<="010";
elsif (BUT2 = '1') then Y<="011";
elsif (G_lmt = '1') then Y<="100";
elsif (lmt_1 = '1') then Y<="101";
elsif (lmt_2 = '1') then Y<="110";
else Y<="111";
end if;
end process;
library ieee; -- Not a picture
use IEEE.STD_LOGIC_1164.ALL;
entity EDL_2 is
port(
clk: in std_logic;
encod : in std_logic_vector(2 downto 0);
M :out std_logic_vector(1 downto 0)
);
end EDL_2;
architecture arch_EDL_2 of EDL_2 is
type state_type is (II,GG,FF,T1,T2);
signal state_reg, state_next : state_type;
begin
process(clk)
begin
if encod = "000" then state_reg <=II;
elsif (rising_edge(clk)) then state_reg <= state_next;
end if;
end process;
process(encod,state_reg)
begin
state_next <= state_reg;
M <= "00";
case state_reg is
when II =>
if (encod = "100") then M <= "00";
state_next <= GG;
else
M <= "10";
state_next <= II;
end if;
when GG =>
if (encod = "010") then M <= "01";
state_next <= T1;
elsif (encod = "011") then M <= "01";
state_next <= T2;
else
M <= "00";
state_next <= GG;
end if;
when FF =>
if(encod = "001") then M <= "10";
state_next <= II;
else
M <= "00";
state_next <= FF;
end if;
when T1 =>
if(encod = "101") then M <= "00";
state_next <= FF;
else
M <= "01";
state_n
when T2 =>
if(encod = "110") then M <= "00";
state_next <= FF;
else
M <= "01";
state_next <= T2;
end if;
end case;
end process;
end arch_EDL_2;
use ieee.std_logic_1164.all;
entity EDL is
port(
clk, reset :in std_logic;
BUT1,BUT2,G_lmt,lmt_1,lmt_2,RET :in std_logic; -- p - push button , l - limit
switch , -M motor, ret-return
M : out std_logic_vector(1 downto 0)
);
end EDL;
architecture arch_EDL of EDL is
signal P : std_logic_vector(2 downto 0); -- internal signals
component EDL_2 is
port(
clk: in std_logic;
encod : in std_logic_vector(2 downto 0);
M :out std_logic_vector(1 downto 0)
);
end component;
component Encorder is
Port ( BUT1 : in STD_LOGIC;
BUT2 : in STD_LOGIC;
G_lmt : in STD_LOGIC;
lmt_1 : in STD_LOGIC;
lmt_2 : in STD_LOGIC;
ret : in STD_LOGIC;
reset : in STD_LOGIC;
Y : out STD_LOGIC_VECTOR (2 downto 0));
end component;
-- port map
begin
controller : EDL_2 port map (encod => P, M =>M, clk =>clk);
encod: Encorder port map (BUT1 => BUT1,BUT2 => BUT2,G_lmt => G_lmt, lmt_1 =>
lmt_1,
lmt_2 =>lmt_2, ret => ret, reset => reset, Y => P);
end arch_EDL;
library ieee;
use ieee.std_logic_1164.all;
use ieee.NUMERIC_STD.all;
-- Add your library and packages declaration here ...
entity encorder_tb is
end encorder_tb;
architecture TB_ARCHITECTURE of encorder_tb is
-- Component declaration of the tested unit
component encorder
port(
BUT1 : in STD_LOGIC;
BUT2 : in STD_LOGIC;
G_lmt : in STD_LOGIC;
lmt_1 : in STD_LOGIC;
lmt_2 : in STD_LOGIC;
ret : in STD_LOGIC;
reset : in STD_LOGIC;
Y : out STD_LOGIC_VECTOR(2 downto 0) );
end component;
-- Stimulus signals - signals mapped to the input and inout ports of tested entity
signal BUT1 : STD_LOGIC;
signal BUT2 : STD_LOGIC;
signal G_lmt : STD_LOGIC;
signal lmt_1 : STD_LOGIC;
signal lmt_2 : STD_LOGIC;
signal ret : STD_LOGIC;
signal reset : STD_LOGIC;
-- Observed signals - signals mapped to the output ports of tested entity
signal Y : STD_LOGIC_VECTOR(2 downto 0);
begin
-- Unit Under Test port map
UUT : encorder
port map (
BUT1 => BUT1,
BUT2 => BUT2,
G_lmt => G_lmt,
lmt_1 => lmt_1,
lmt_2 => lmt_2,
ret => ret,
reset => reset,
Y => Y
);
reset <= '1', '0' after 50ns;
BUT1 <= '0', '1' after 100 ns, '0' after 150ns;
BUT2 <= '0', '1' after 200 ns, '0' after 250ns; -- G_lmt <= '0', '1' after 100ns , '0' after 150ns;
end TB_ARCHITECTURE;
configuration TESTBENCH_FOR_encorder of encorder_tb is
for TB_ARCHITECTURE
for UUT : encorder
use entity work.encorder(behavioral);
end for;
end for;
end TESTBENCH_FOR_encorder;
o 0) );
end component;
-- Stimulus signals - signals mapped to the input and inout ports of tested entity
signal clk : STD_LOGIC;
signal encod : STD_LOGIC_VECTOR(2 downto 0);
-- Observed signals - signals mapped to the output ports of tested entity
signal M : STD_LOGIC_VECTOR(1 downto 0);
-- Add your code here ...
begin
-- Unit Under Test port map
UUT : edl_2
port map (
clk => clk,
encod => encod,
M => M
);
clock_process: process
begin
clk <='0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
encod <= "000", "100" after 100ns, "110" after 200ns;
end TB_ARCHITECTURE;
configuration TESTBENCH_FOR_edl_2 of edl_2_tb is
for TB_ARCHITECTURE
for UUT : edl_2
use entity work.edl_2(arch_edl_2);
end for;
end for;
end TESTBENCH_FOR_edl_2;
library ieee;
use ieee.std_logic_1164.all;
-- Add your library and packages declaration here ...
entity edl_tb is
end edl_tb;
architecture TB_ARCHITECTURE of edl_tb is -- Component declaration of the tested unit
constant clk_period : time := 10 ns; --defining clock
component edl
port(
clk : in STD_LOGIC;
reset : in STD_LOGIC;
BUT1 : in STD_LOGIC;
BUT2 : in STD_LOGIC;
G_lmt : in STD_LOGIC;
lmt_1 : in STD_LOGIC;
lmt_2 : in STD_LOGIC;
RET : in STD_LOGIC;
M : out STD_LOGIC_VECTOR(1 downto 0) );
end component;
-- Stimulus signals - signals mapped to the input and inout ports of tested entity
signal clk : STD_LOGIC;
signal reset : STD_LOGIC;
signal BUT1 : STD_LOGIC;
signal BUT2 : STD_LOGIC;
signal G_lmt : STD_LOGIC;
signal lmt_1 : STD_LOGIC;
signal lmt_2 : STD_LOGIC;
signal RET : STD_LOGIC;
-- Observed signals - signals mapped to the output ports of tested entity
signal M : STD_LOGIC_VECTOR(1 downto 0);
-- Add your code here ...
begin
-- Unit Under Test port map
UUT : edl
port map (
clk => clk,
reset => reset,
BUT1 => BUT1,
BUT2 => BUT2,
G_lmt => G_lmt,
lmt_1 => lmt_1,
lmt_2 => lmt_2,
RET => RET,
M => M
);
-- Add your stimulus here ...
clock_process: process
begin
clk <='0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
17
stim: process
begin
----------------Case 00------------------------------
reset <= '1'; --Initially reset occur at hardware
wait for 200ns;
reset <='0';
wait for 300ns; -- Initillay find lift go to kitchen
G_lmt <= '1'; --Lift reach the Ground Floor
wait for 100ns;
assert M = "00" report "Check Case 00 - 1" severity error;
wait for 400ns; -- Remain at kitchen
-----------------------Case 01------------------------
BUT1 <= '1'; --Press 1st button
wait for 100ns;
BUT1 <='0';
G_lmt <= '0';
wait for 100ns;
assert M = "01" report "Check Case 01 - 1" severity error;
wait for 300ns;
lmt_1 <= '1'; --Reach 1st floor
wait for 500ns;
assert M = "00" report "Check Case 01 - 2" severity error;
RET <= '1'; --press return button
wait for 100ns;
RET <= '0';
lmt_1 <='0';
wait for 400ns;
assert M = "10" report "Check Case 01 - 3" severity error;
G_lmt <= '1'; -- Reach kitchen
assert M = "00" report "Check Case 01 - 4" severity error;
wait;
end process;
end TB_ARCHITECTURE;
configuration TESTBENCH_FOR_edl of edl_tb is
for TB_ARCHITECTURE
for UUT : edl
use entity work.edl(arch_edl);
end for;
end for;
end TESTBENCH_FOR_edl;

Initially reset is hold sometimes trough hardware (Included it in the circuit diagram). Then the motor output provided as downward (M[]=2) until reach the kitchen (G_lmt). Then motor was stopped. Then press 1st floor button (BUT1). Then motor was start to upward direction (M[]=1). The ground limit went to zero. When reach 1st floor 1st limit switch(lmt_1) turn on. Then Motor was stopped. Finally press the return button(RET), Then motor goes to downward until reach the ground limit.
Blue color indicate the user pressing buttons. Red color indicates the system inputs such as limit switches. Green color indicates the motor output.