According to the U.S. Energy Information Administration, in 2015, a U.S. residential utility customer uses an average of 901 kWh per month, which roughly equates to around $90 a month. Although most household uses the energy efficient light bulb, the same amount of electric current is still running through the light bulb. In addition, an energy efficient light bulb uses more energy when it is first turned on to help increase the amount of light being produced before regulating the current running through the light bulb. This process can take up to as long as 3 minutes to complete. We've come up with a way to reduce the amount of current flowing through the light bulb, decreasing the amount of energy and electricity used in every household.
We've built a circuit that outputs a certain value that reflects how brightly lit the light should be depending on how much light is currently available. Using the output value, LEDs will turn on depending on how much sunlight (or artificial light) is available in a room. For example, if a room is very dark, all the LEDs will turn on and if a room is brightly lit, the LEDs will not turn on, since light is already available. This could be used to conserve energy in homes by limiting the light (and electricity) used during the daytime, and allowing users to save energy, money and electricity.
Step 1: Gather Materials
This project involves the usage of several materials. Before beginning, make sure you have everything you need.
Arduino -- The accompanying application to the Arduino Uno used to program the Arduino Uno.
** You may need to check the resistance levels of your photoresistor with a multimeter. Simply shine a light on the resistor and measure the resistance across it, then cover the resistor and measure again. This will help you understand how the circuit works.
Step 2: Drawing a Black-Box Diagram
Use a simple, high level black-box or circuit diagram to understand the functionality of the circuit as well as identifying inputs and outputs.
In this project, overall inputs are light and a switch. The final outputs will be the LEDs and seven-segment display.
This diagram will help you visualize where you need to implement signals to help data pass from one component to another.
Step 3: Design a Finite State Machine (FSM)
An important part of designing a circuit is identifying the possible states of the project.
As seen in the image, there are four possible states. These correlate to how many LEDs are on vs. off.
In ST0 (stage one), no LEDs are on, indicating very bright surroundings.
In ST1 (stage two), one LED is on.
In ST2 (stage three), two LEDs are on.
In ST3 (stage four), all three LEDs are on, indicating very dark surroundings.
State transitions are determined by light received by the sensor.
Step 4: Write a Counter Module
This circuit functions by checking the surrounding light on the rising edge of clock. This way, it is not continuously checking/changing state, but checks on a predetermined interval then changes state accordingly. This can be done by creating a design source for a counter, then integrating it in your master file.
The clock sends a signal, Q, to the FSM to initiate checking. We also included a switch to enable the clock and allow the user to turn the system off, but this is entirely optional. The counter will increment upwards until it reaches your limit. We chose three seconds. At the end of three seconds, the counter outputs "done". When Q gets done, the FSM is enabled and begins the process of checking the surrounding light and outputting the appropriate amount of light.
In our project, our clock checks the ambient light very frequently. If desired, you can insert a clock divider and slow down the frequency of clock. This can be done with the following clock divider file. Using this file is completely optional, and we did not use it.
The following is the code for the optional clock divider.
-- Module to divide the clock
entity clk_div2 is
Port ( clk : in std_logic;
sclk : out std_logic);
architecture my_clk_div of clk_div2 is
constant max_count : integer := (3000000);
signal tmp_clk : std_logic := '0';
my_div: process (clk,tmp_clk)
variable div_cnt : integer := 0;
if (rising_edge(clk)) then
if (div_cnt = MAX_COUNT) then
tmp_clk <= not tmp_clk;
div_cnt := 0;
div_cnt := div_cnt + 1;
sclk <= tmp_clk;
end process my_div;
Step 5: Create a File for Your FSM
In order to design your FSM, you must identify the states in VHDL. Specify when you move to the next state, remain in your current state, or move to a previous state. A helpful resource for doing this can be found in Digital McLogic Design by Brian J. Mealy and James T. Mealy, page 575.
As seen in our VHDL, when the sensor gets brighter light, the state decreases. When it gets the same light, state does not change. When it detects dimmer light, state increases. This can also be compared to the FSM.
For example, if the circuit were in state 0 then detected very dim light (00), next state would get state 1. If the light remained very dim (00), on the next rising edge of clock, next state would get state 2.
Step 6: Create a 7-Segment Decoder
We designed a seven-segment decoder in VHDL. This circuit took the output of the finite state machine and the switch as its inputs. The output of the finite state machine denotes which state the circuit is in, and the seven segment displays either "0", "1", "2" or "3". However if the switch is off, the seven segment does not display anything.
We implemented this by using a signal "disp" and two case statements.
In the file, the data that the display gets is an 8-bit signal. The bits correspond as follows: "ABCDEFG(DP)". The last bit is the decimal point, which will always be off in this circuit.
Step 7: Write Code for the Arduino
The Arduino program is available here https://www.arduino.cc/en/Main/Software.
We inserted one leg of photoresistor to Pin 0 on the Analog In side, and we inserted the other leg of the photoresistor to ground. We used Pin 2 and Pin 4 as the two output signals to the Basys 3 Board.
We read in the analog value from the photoresistor, then we used the Arduino built-in function, map(), to converted the range from 0 - 1023 to 0 - 255. Although we converted the values to range from 0 - 255, some values will still output greater than 255, and some values will still output less than 0. In order to prevent this from happening, we used another Arudino built-in function, constrain(), to cap the numbers at 0, and 255.
Using the new range, we divided the numbers into four different stages, the first stage contains numbers from 0 - 64. The second stage contains numbers from 65 - 129. The third stage contains numbers from 130 - 193. The fourth stage contains numbers from 194 - 255. If the numbers fall within the first stage, then the output signals for both Pin 1 and Pin 2 will be "LOW". If the numbers fall within the second stage, then the output signals for Pin 1 will be "LOW" and Pin 2 will be "HIGH".If the numbers fall within the third stage, then the output signals for Pin 1 will be "HIGH" and Pin 2 will be "LOW".If the numbers fall within the fourth stage, then the output signals for both Pin 1 and Pin 2 will be "HIGH". These values will be mapped to signals in VHDL where "HIGH" corresponds to a "1" and "LOW" corresponds to a "0".
Please refer to the attached file for the Arduino code.
Step 8: Create a Master File
In your top-level module is where you will use the FSM module and counter module to make the circuit functional.
This file will call upon each module that you have created. Modular design is helpful in this case because each component could be reused elsewhere and have unique functionalities. Defining signals between each component is necessary so that data can be inputted or outputted from or to different components.
Step 9: Set Up a Simulation
By creating a testbench for your circuit, you can ensure that it will work correctly before actually setting it up. This will simulate how your circuit should respond to certain inputs and show you the results on a timing diagram. We created one for our FSM (Figure 1), our counter module (Figure 2), and the top level module (Figure 3).
This helped us debug our code before hooking it up to a circuit. Once the simulation runs as you expect it to, create your constraints to upload your files to the board.
Step 10: Write Your Constraints File
A constraints file is where you map your software to your hardware components. A master.xdc file with all basys components can be found at the following link https://github.com/Digilent/Basys3/tree/master/Res... Copy and paste this into a constraints file, then uncomment whatever lines you need. Don't forget to uncomment lines for the clock. Outputs will be in the JA portion of the file. Each pin has a positive and negative side, so make sure you are using the correct one when hooking up your circuit.
Step 11: Set Up Your Hardware
Using the materials from the introduction slide, set up your hardware. The overall design can be seen in Figure 1.
On the Arduino Uno board, insert the photoresistor with one leg in an analog input slot and the other to GND. A 10k resistor must be connected in series with the photoresistor.
On the Basys Board, connect wires from the JA 1 outputs to appropriate spots on the breadboard. On the JA1 PMOD port, use pins 1 and 2, which will be defined in your constraints. In Figure 2, it can be seen that pin 1 is the top right pin, and pin 2 is the one to the left of it. This is important for outputting your data.
From there, connect a 330 Ohm Resistor to each output to ensure you don't burn out your LEDs. Then, connect the longer leg of an LED to the same row as the resistor and the other leg to ground. Repeat this process for the remaining outputs. This is the fun part- you can choose any color LEDs you want. We chose to use bright white LEDs because of their clean and professional appearance. You can also add even more LEDs, such as clusters of them, to increase it's attractiveness.
Step 12: Conclusion
This project is a fun, challenging way to model an energy-saving system. It is a great way to see how electricity usage could be optimized in households. Feel free to make this circuit your own and modify it when trying it out.
Keep an eye out for these tricky parts:
- Vhdl signal names: make sure your port mapping and signal names are accurate.
- Hardware: Make sure your constraints match your actual setup.
We hope you learned a lot about electricity, modular design, sequential statements, FSMs, and more from our project. Thanks for reading!
Instructable by: Victoria Law, Brad Levin, Jessica Patterson, Anna Vojvoda
Cal Poly CPE 133 Fall 2016 Final project
Step 13: Sources
In this project, we used the following sources to help us.
https://www.instructables.com/id/FPGA-Smart-Fan/ - this helped with the VHDL for reading values from a sensor.
pg. 575 Digital McLogic Design by Brian J. Mealy and James T. Mealy is the course text for our CPE 133 class. It helped us with creating our FSM VHDL.
https://www.instructables.com/id/FPGA-LED-Project/ - This helped us with constructing our circuit hardware.
http://www.activistpost.com/2016/01/mit-new-incand... - Cover image
http://playground.arduino.cc/Learning/PhotoResistor- this helped us with the Arduino code as well as taught us how to connect the photoresistor to the Arduino Uno.
Figure 1 from the "Display State on the Board" slide is courtesy of Professor Andrew Danowitz, Cal Poly San Luis Obispo, lab 3.