You are on page 1of 8

FPGA based Temperature Sensor and Control

A
Project Report
Submitted
As Essential Part of the Course

Hardware Design Methodology


(M. Tech. MI)

Submitted by

ANKITA VERMA (IMI2012003)


RAJAN BHARTI (IMI2012018)

Under the Guidance of:


Dr. Satish Kumar Singh
Assistant Professor

INDIAN INSTITUTE OF INFORMATION TECHNOLOGY


ALLAHABAD-211 012 (INDIA)
May-2013
Abstract: We need temperature control in various concurrent processes to compare user and sensor value
places . It can be used to control the temperature of furnaces
and take suitable actions, to convert decimal to BCD
which is further displayed on a seven segment display.
or also room temperature.We have used LM35 as
temperature sensor whose output is compared to the user
input desired value, the resulting signal is used to control the
temperature.

Introduction: Field programmable gate arrays (FPGAs)


are extensively used in rapid prototyping and verification
of a conceptual design and also used in electronic
systems when the mask-production of a custom IC
becomes prohibitively expensive due to the small
quantity. Many system designs that used to be built in
custom silicon VLSI are now implemented in Field
Programmable Gate Arrays. This is because of the high
cost of building a mask production of a custom VLSI
especially for small quantity.
In this the main objective is to design a FPGA based
temperature sensor and control. We are using LM35
temperature sensor IC. The LM35 series are precision
integrated-circuit temperature sensors, whose output
voltage is linearly proportional to the Celsius
(Centigrade) temperature. The LM35 thus has an
advantage over linear temperature sensors calibrated in ˚
Kelvin, as the user is not required to subtract a large
constant voltage from its output to obtain convenient
Centigrade scaling.Its analog output is given to the
analog to digital module converter board (AD7476). Its
digital output can be read using FPGA.

Block diagram:

The LM35 is rated to operate over a −55˚ to +150˚C


temperature range. Calibrated directly in ˚ Celsius
(Centigrade). It has Linear scale factor of +10.0mV/˚C.
Its output is given to 12 bit A/D converter.

Methodology and Modeling: We have divided the


problem into submodules.In the first module we are
reading the data from the sensor output, which is a FSM
according to three state. In second module, we are
converting the read data to BCD format , which is further
displayed on seven segment display. It contains
Implementation:
clock_divide : process(rst,clk)
begin
(A) RTL Description(VHDL Code): if rst = '1' then
To read data from ADC clk_counter <= "00";
library IEEE; elsif (clk = '1' and clk'event) then
use IEEE.STD_LOGIC_1164.ALL; count:=count+1;
use IEEE.STD_LOGIC_ARITH.ALL; if (count="11") then
use IEEE.STD_LOGIC_UNSIGNED.ALL; clk_div1:=not clk_div1;
count:="00";
end if;
entity AD1 is end if;
Port ( clk_div<=clk_div1;
--General usage end process;
CLK : in std_logic;
RST : in std_logic; SCLK <= not clk_div;

--Pmod interface signals


SDATA1 : in std_logic; counter : process(clk_div, enParalelLoad,
SCLK : out std_logic; enShiftCounter)
nCS : out std_logic; begin
if (clk_div = '1' and clk_div'event) then
--User interface signals
DATA1 : out std_logic_vector(11 downto 0); if (enShiftCounter = '1') then
START : in std_logic; temp1 <= temp1(14 downto 0) &
DONE : out std_logic SDATA1;
);
shiftCounter <= shiftCounter + '1';
end AD1 ; elsif (enParalelLoad = '1') then
shiftCounter <= "0000";
architecture AD1 of AD1 is DATA1 <= temp1(11 downto 0);

type states is (Idle, end if;


ShiftIn, end if;
SyncData); end process;
signal current_state : states;
signal next_state : states; ---------------------------------------------------------------------
signal clk_div:std_logic; ------------
signal temp1 : std_logic_vector(15 --
downto 0); SYNC_PROC: process (clk_div, rst)
shared variable clk_div1: std_logic:='0'; begin
signal clk_counter : std_logic_vector(1 if (clk_div'event and clk_div = '1') then
downto 0); if (rst = '1') then
signal shiftCounter : std_logic_vector(3 current_state <= Idle;
downto 0) := x"0"; else
signal enShiftCounter: std_logic; current_state <= next_state;
signal enParalelLoad : std_logic; end if;
shared variable count:std_logic_vector(1 downto end if;
0):="00"; end process;

OUTPUT_DECODE: process (current_state)


begin begin
if current_state = Idle then use IEEE.numeric_std.all;
enShiftCounter <='0';
DONE <='1';
nCS <='1'; entity BCD12SEVSEG is
enParalelLoad <= '0'; Port ( u_data:in std_logic_vector(7 downto
elsif current_state = ShiftIn then 0);d_in : in STD_LOGIC_VECTOR (11 downto
enShiftCounter <='1'; 0);clk,done: in std_logic;
DONE <='0'; d_o : out STD_LOGIC_VECTOR (10 downto
nCS <='0'; 0),control:out std_logic);
enParalelLoad <= '0'; end BCD12SEVSEG;
else --if current_state = SyncData then architecture Behavioral of BCD12SEVSEG is
enShiftCounter <='0';
DONE <='0'; signal temp: std_logic_vector(11 downto
nCS <='1'; 0):="000000000000";
enParalelLoad <= '1'; signal temp1: std_logic_vector(15 downto
0):="0000000000000000";
end if; signal shcntr: integer:=0;
end process; signal i1,i2,i3,i4: std_logic_vector(3 downto 0);
signal state: integer range 0 to 5;
NEXT_STATE_DECODE: process (current_state, shared variable d_out1,d_out2,d_out3,d_out4:
START, shiftCounter) std_logic_vector(10 downto 0);
begin shared variable c:std_logic_vector(1 downto
0):="00";
next_state <= current_state; -- default is to stay shared variable cld: integer:=0;
in current state signal clk_t:std_logic;
shared variable clkt: std_logic:='0';
case (current_state) is begin
when Idle => --
if START = '1' then process
next_state <= ShiftIn; begin
end if; wait until rising_edge(clk);
when ShiftIn =>
if shiftCounter = x"F" then case state is
next_state <= SyncData;
end if; when 0 =>
when SyncData => if(done='1') then
if START = '0' then temp<=d_in;
next_state <= Idle; shcntr<=0;
end if; temp1<=(others =>'0');
when others => state<=1;
next_state <= Idle; end if;
end case;
end process;
when 1 => if shcntr/=12 then
end AD1; temp1<=temp1(14 downto 0) & temp(11);
temp<=temp(10 downto 0) & '0';
12 bit binary to 7 segment display shcntr<=shcntr+1;
state<=2;
library IEEE; end if;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL; when 2=> if shcntr<12 then
use IEEE.STD_LOGIC_UNSIGNED.ALL; if temp1(3 downto 0)>="0101" then
state<=3;
elsif temp1(7 downto 4)>="0101" then process(u_data,temp1)
state<=4; begin
elsif temp1(11 downto 8) >="0101" then if(udata>temp(11 downto 4)) then
state<=5; control<='1';
else else
state<=1; control<='0';
end if; end if;
else end process;
state<=0;
end if; end case;
end process;
process(shcntr,clk)
when 3=> temp1(3 downto 0)<=temp1(3 downto begin
0)+"0011"; if shcntr=12 then
if temp1(7 downto 4)>="0101" then if clk'event and clk='1' then
temp1(7 downto 4)<=temp1(7 downto 4)+"0011"; i1<=temp1(3 downto 0);
state<=1; i2<=temp1(7 downto 4);
elsif temp1(11 downto 8) >="0101" then i3<=temp1(11 downto 8);
temp1(11 downto 8) <=temp1(11 downto 8) i4<=temp1(15 downto 12);
+"0011"; end if;
state<=1; end if;
else end process;
state<=1;
end if; process(i1,clk)
begin
when 4=> temp1(7 downto 4)<=temp1(7 downto case i1 is
4)+"0011"; when "0000"=> d_out1:="11100000001";
if temp1(11 downto 8) >="0101" then when "0001"=> d_out1:="11101001111";
temp1(11 downto 8) <=temp1(11 downto 8) when "0010"=> d_out1:="11100010010";
+"0011"; when "0011"=> d_out1:="11100000110";
state<=1; when "0100"=> d_out1:="11101001100";
elsif temp1(3 downto 0)>="0101" then when "0101"=> d_out1:="11100100100";
temp1(3 downto 0)<=temp1(3 downto 0)+"0011"; when "0111"=> d_out1:="11100001111";
state<=1; when "1000"=> d_out1:="11100000000";
else when "1001"=> d_out1:="11100000100";
state<=1; when others => d_out1:="11100110000";
end if; end case;
end process;

when 5=> temp1(11 downto 8) <=temp1(11 process(i2,clk)


downto 8) +"0011"; begin
if temp1(3 downto 0)>="0101" then case i2 is
temp1(3 downto 0)<=temp1(3 downto 0)+"0011"; when "0000"=> d_out2:="11010000001";
state<=1; when "0001"=> d_out2:="11011001111";
elsif temp1(7 downto 4)>="0101" then when "0010"=> d_out2:="11010010010";
temp1(7 downto 4)<=temp1(7 downto 4)+"0011"; when "0011"=> d_out2:="11010000110";
state<=1; when "0100"=> d_out2:="11011001100";
else when "0101"=> d_out2:="11010100100";
state<=1; when "0111"=> d_out2:="11010001111";
end if; when "1000"=> d_out2:="11010000000";
when "1001"=> d_out2:="11010000100"; end process;
when others => d_out2:="11010110000"; ---------------------------------------------
end case; process(clk_t)
end process;
begin
if (rising_edge(clk_t)) then
process(i3,clk) if( c="00") then
begin d_o<=d_out1;
case i3 is c:=c+1;
when "0000"=> d_out3:="10110000001"; elsif (c="01") then
when "0001"=> d_out3:="10111001111"; d_o<=d_out2;
when "0010"=> d_out3:="10110010010"; c:=c+1;
when "0011"=> d_out3:="10110000110"; elsif (c="10") then
when "0100"=> d_out3:="10111001100"; d_o<=d_out3;
when "0101"=> d_out3:="10110100100"; c:=c+1;
when "0111"=> d_out3:="10110001111"; elsif (c="11") then
when "1000"=> d_out3:="10110000000"; d_o<=d_out4;
when "1001"=> d_out3:="10110000100"; c:="00";
when others => d_out3:="10110110000"; else null;
end case; end if;
else null;
end process; end if;
end process;
end Behavioral;
process(i4,clk)
begin Top Module to interconnect two modules
case i4 is library IEEE;
when "0000"=> d_out4:="01110000001"; use IEEE.STD_LOGIC_1164.ALL;
when "0001"=> d_out4:="01111001111";
when "0010"=> d_out4:="01110010010"; entity top is
when "0011"=> d_out4:="01110000110"; Port ( clk_i,sdata,start,rst : in
when "0100"=> d_out4:="01111001100"; STD_LOGIC;u_data:in std_logic_vector(7 downto 0);
when "0101"=> d_out4:="01110100100"; ncs,sclk,control : out STD_LOGIC;
when "0111"=> d_out4:="01110001111"; d1_out : out STD_LOGIC_VECTOR (10
when "1000"=> d_out4:="01110000000"; downto 0));
when "1001"=> d_out4:="01110000100"; end top;
when others => d_out4:="01110110000"; architecture Behavioral of top is
end case;

end process; component AD1 is


--------------------------------------------- Port(CLK : in std_logic;
process(clk) RST : in std_logic;
SDATA1 : in std_logic;
begin SCLK : out std_logic;
if(rising_edge(clk)) then nCS : out std_logic;
cld:=cld+1; DATA1 : out std_logic_vector(11 downto 0);
if (cld=50000) then START : in std_logic;
clkt:=not clkt; DONE : out std_logic
cld:=0; );
end if;
end if; end component AD1 ;
clk_t<=clkt;
component BCD12SEVSEG is
Port ( u_data:in std_logic_vector(7 downto
0);d_in : in STD_LOGIC_VECTOR (11 downto
0);clk,done: in std_logic;
d_o : out STD_LOGIC_VECTOR (10 downto 0);
control:out std_logic);
end component BCD12SEVSEG;

signal data:std_logic_vector(11 downto 0);


signal done:std_logic;
begin
ad: AD1 port
map(clk=>clk_i,RST=>rst,SDATA1=>sdata,SCLK=>scl
k,nCS=>ncs,DATA1=>data,START=>start,DONE=>do
ne);
bcd: BCD12SEVSEG port
map(u_data=>u_data,d_in=>data,clk=>clk_i,done=>
done,d_o=>d1_out, control=>control);

end Behavioral;

Applications and related modifications:


This can be applied to many industrial application
as well as in some home appliances also.

Reference:
[1] Nexys 2 reference manual
[2] AD7476 datasheet
[3] Pmod AD1 reference sheet
[4] LM 35 datasheet

You might also like