Académique Documents
Professionnel Documents
Culture Documents
Features
Simple ambient light sensor
Convert light to digital data with 8-bit resolution
6-pin Pmod port with SPI interface
Functional Description
The PmodALS utilizes a single ambient light sensor (ALS) for user input. The amount of light the ALS is exposed
to determines the voltage level passed into the ADC, which converts it to 8-bits of data. A value of 0 indicates a
low light level and a value of 255 indicates a high light level.
The PmodALS reports to the host board when the ADC081S021 is placed in normal mode by bringing the CS pin
low, and delivers a single reading in 16 SCLK clock cycles. The PmodALS requires the frequency of the SCLK
to be between 1 MHz and 4 MHz. The bits of information, placed on the falling edge of the SCLK and valid on
the subsequent rising edge of SCLK, consist of three leading zeroes, the eight bits of information with the MSB
first, and four trailing zeroes.
Any external power applied to the PmodALS must be within 2.7V and 5.25V; however, it is recommended that
Pmod is operated at 3.3V.
Physical Dimensions
The pins on the pin header are spaced 100 mil apart. The PCB is 0.8 inches long on the sides parallel to the pins
on the pin header and 0.8 inches long on the sides perpendicular to the pin header.
Additional Information
The schematics of the PmodALS are available here. Additional information about the ADC including
communication modes and specific timings of the chip can be found by checking out its datasheet here. Similarly,
the datasheet for the ambient light sensor can be found here.
More specific information about how to use the PmodALS can be found by checking out our user guide. Example
code demonstrating how to get information from the PmodALS can be found here.
If you have any questions or comments about the PmodALS, feel free to post them under the appropriate section
(“Add-on Boards”) of the Digilent Forum.
The ADC081S021 operates with a single supply that can range from 2.7 V to 5.25 V. Normal power
consumption using a 3.6-V or 5.25-V supply is 1.3 mW and 7.7 mW, respectively. The power-down
feature reduces the power consumption to as low as 2.6 µW using a 5.25-V supply.
Feature Description
The serial interface timing diagram for the ADC is shown in Timing Requirements. CS is chip select, which
initiates conversions on the ADC and frames the serial data transfers. SCLK (serial clock) controls both the
conversion process and the timing of serial data. SDATA is the serial data out pin, where a conversion result is
found as a serial data stream.
Basic operation of the ADC begins with CS going low, which initiates a conversion process and data transfer.
Subsequent rising and falling edges of SCLK are labelled with reference to the falling edge of CS; for example,
the third falling edge of SCLK shall refer to the third falling edge of SCLK after CS goes low. At the fall of CS,
the SDATA pin comes out of TRI-STATE and the converter moves from track mode to hold mode. The input
signal is sampled and held for conversion on the falling edge of CS. The converter moves from hold mode to
track mode on the 13th rising edge of SCLK (see Timing Requirements). It is at this point that the interval for the
TACQ specification begins. At least 350 ns must pass between the 13th rising edge of SCLK and the next falling
edge of CS. The SDATA pin is placed back into TRI-STATE after the 16th falling edge of SCLK, or at the rising
edge of CS, whichever occurs first. After a conversion is completed, the quiet time (tQUIET) must
be satisfied before bringing CS low again to begin another conversion. Sixteen SCLK cycles are required to read
a complete sample from the ADC. The sample bits (including leading or trailing zeroes) are clocked out on falling
edges of SCLK, and are intended to be clocked in by a receiver on subsequent rising edges of SCLK. The ADC
produces three leading zero bits on SDATA, followed by eight data bits, most significant first. After the data bits,
the ADC clocks out four trailing zeros. If CS goes low before the rising edge of SCLK, an additional (fourth) zero
bit may be captured by the next falling edge of SCLK.
Determining Throughput
Throughput depends on the frequency of SCLK and how much time is allowed to elapse between the end of one
conversion and the start of another. At the maximum specified SCLK frequency, the maximum ensured
throughput is obtained by using a 20 SCLK frame. As shown in Timing Requirements, the minimum allowed
time between CS falling edges is determined by:
1. 12.5 SCLKs for Hold mode.
2. The larger of two quantities: either the minimum required time for Track mode (tACQ) or 2.5 SCLKs to finish
reading the result.
Código VHDL
------------------------------------------------------------------------------------------
-- PmodALS (Ambient Light Sensor)
-- SPI CONTROLLER
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity SPI_ctrl_ALS is
generic(
N : integer := 8; -- number of bit to serialize
MAX : integer := 333_333 -- number of us to sample
);
port (
--FPGA clock and button
clk : in std_logic; -- 50MHz
rst : in std_logic; -- reset
--PmodALS
CS : out std_logic; -- Pmod chip selec
SDO : in std_logic; -- Pmod Serial Data Output
SCK : out std_logic; -- Pmod Serial Clock
-- led output
data : out std_logic_vector(N-1 downto 0):=x"00"; -- received data
-- Display "abcdefgP"
DISPLAY: out STD_LOGIC_VECTOR(7 DOWNTO 0); -- segments
AN: out STD_LOGIC_VECTOR(3 DOWNTO 0):="0111" -- ánodes
);
end SPI_ctrl_ALS;
begin
-----------------------------------------------------
div : process(rst,clk,clkdiv,counter)
begin
-- divisor 1MHz (1us)
if(rst='1') then clkdiv <= '0';
elsif(rising_edge(clk)) then
if cnt = "11000" then cnt <= "00000"; --24
clkdiv <= not clkdiv;
else cnt <= cnt + '1';
end if;
end if;
SCK <= clkdiv;
end process div;
-----------------------------------------------------
cnter : process(rst,counter,clkdiv)
begin
-- divisor 1MHz (1us)
if(rst='1' or counter = MAX) then counter <= 0;
elsif(rising_edge(clkdiv)) then counter <= counter + 1 ;
end if;
end process cnter;
-----------------------------------------------------
receive : process(clkdiv,counter,tempo,SDO,rst)
begin
--
if(rst='1') then tempo <= (others => '0');
elsif(rising_edge(clkdiv)) then
case counter is
when 0 => CS <= '1';
when 1 => CS <= '1';
when 2 => CS <= '0';
when 3 => tempo(0) <= SDO; --0
when 4 => tempo(1) <= SDO; --0
when 5 => tempo(2) <= SDO; --0
when 6 => tempo(3) <= SDO; --DB7
when 7 => tempo(4) <= SDO; --DB6
when 8 => tempo(5) <= SDO; --DB5
when 9 => tempo(6) <= SDO; --DB4
when 10 => tempo(7) <= SDO; --DB3
when 11 => tempo(8) <= SDO; --DB2
when 12 => tempo(9) <= SDO; --DB1
when 13 => tempo(10) <= SDO; --DB0
when 14 => tempo(11) <= SDO; --0
when 15 => tempo(12) <= SDO; --0
when 16 => tempo(13) <= SDO; --0
when 17 => tempo(14) <= SDO; --0
when 18 => tempo(15) <= SDO; --tri state
when 19 => CS <= '1'; --
when others => CS <= '1'; --
end case;
end if;
data <= tempo (3 to 10);
end process receive;
-- realiza el corrimiento
C_D_U(17 DOWNTO 1):= C_D_U(16 DOWNTO 0);
END LOOP;
END PROCESS;
--UNIDADES
UNI<=P(3 DOWNTO 0);
--DECENAS
DEC<=P(7 DOWNTO 4);
--CENTENAS
CEN<="00"&P(9 DOWNTO 8);
-------------------DIVISOR ÁNODOS-------------------
process (CLK) begin
if rising_edge(CLK) then
if (contadors = 6250) then --cuenta 0.125ms (50MHz=6250)
-- if (contadors = 12500) then --cuenta 0.125ms (100MHz=12500)
SAL_250us <= NOT(SAL_250us); --genera un barrido de 0.25ms
contadors <= 1;
else
contadors <= contadors+1;
end if;
end if;
end process; -- fin del proceso Divisor Ánodos
--------------------MULTIPLEXOR---------------------
PROCESS(SAL_250us, sel, UNI, DEC,CEN)
BEGIN
IF SAL_250us'EVENT and SAL_250us='1' THEN SEL <= SEL+'1';
CASE(SEL) IS
when "00" => AN <="0111"; D <= UNI; -- UNIDADES
when "01" => AN <="1011"; D <= DEC; -- DECENAS
when "10" => AN <="1101"; D <= CEN; -- CENTENAS
-- when "11" => AN <="1111"; --D <= MIL; -- UNIDAD DE MILLAR
when OTHERS=>AN <="1111"; --D <= MIL; -- UNIDAD DE MILLAR
END CASE;
end if;
END PROCESS; -- fin del proceso Multiplexor
--------------------DISPLAY---------------------
PROCESS(D)
Begin
case(D) is -- abcdefgP
WHEN "0000" => DISPLAY <= "00000011"; --0
WHEN "0001" => DISPLAY <= "10011111"; --1
WHEN "0010" => DISPLAY <= "00100101"; --2
WHEN "0011" => DISPLAY <= "00001101"; --3
WHEN "0100" => DISPLAY <= "10011001"; --4
WHEN "0101" => DISPLAY <= "01001001"; --5
WHEN "0110" => DISPLAY <= "01000001"; --6
WHEN "0111" => DISPLAY <= "00011111"; --7
WHEN "1000" => DISPLAY <= "00000001"; --8
WHEN "1001" => DISPLAY <= "00001001"; --9
WHEN OTHERS => DISPLAY <= "11111111"; --apagado
END CASE;
END PROCESS; -- fin del proceso Display
------------------------------------------------
Código UCF
// Archivo de restricciones de usuario (UCF) Nexys 2//
//reset
NET "RST" LOC = "H13"; // btn3 RST
// Pmod ALS en JA
NET "CS" LOC = "L15"; // JA1
#NET "NC" LOC = "K12"; // JA2
NET "SDO" LOC = "L17"; // JA3
NET "SCK" LOC = "M15"; // JA4
//DISPLAYS
NET "DISPLAY(7)" LOC = "L18"; // a
NET "DISPLAY(6)" LOC = "F18"; // b
NET "DISPLAY(5)" LOC = "D17"; // c
NET "DISPLAY(4)" LOC = "D16"; // d
NET "DISPLAY(3)" LOC = "G14"; // e
NET "DISPLAY(2)" LOC = "J17"; // f
NET "DISPLAY(1)" LOC = "H14"; // g
NET "DISPLAY(0)" LOC = "C17"; // P
//ANODOS
NET "AN(3)" LOC = "F17"; // AN0
NET "AN(2)" LOC = "H17"; // AN1
NET "AN(1)" LOC = "C18"; // AN2
NET "AN(0)" LOC = "F15"; // AN3
References.
ADC081S021 Single-Channel, 50-ksps to 200-ksps, 8-Bit A/D Converter, consultado en febrero-2018, disponible
en: http://www.ti.com/lit/ds/symlink/adc081s021.pdf
Design and implementation (in VHDL) of a VGA Display and Light Sensor to run on the Nexys4DDR board
Report and Signoff due Week 6 (October 4), ECE 574: Modeling and synthesis of digital systems using Verilog
and VHDL Fall Semester 2017, consultado en febrero-2018, disponible en:
http://artsdocbox.com/Television/70952295-Design-and-implementation-in-vhdl-of-a-vga-display-and-light-
sensor-to-run-on-the-nexys4ddr-board-report-and-signoff-due-week-6-october-4.html