Homework 4: Nightlights
due at the start class on Tuesday, Sept. 15th
Assignment: a reasonable nightlight
You’re hired to help build a prototype nightlight. Your bill of materials includes:
- Inputs
- a single-pole double-throw switch (tutorial link) (note: this part is called a “slideswitch” in Tinkercad)
- a momentary pushbutton (tutorial link) (note: this is called a “pushbutton” in Tinkercad, unsurprisingly)
- a potentiometer
- a photoresistor, a type of light sensor (tutorial link)
- Outputs
- an LED
Serial
monitor feedback
Nightlight operation
When it gets darker in the room (less light falling on the light sensor), the illumination LED should turn on. When it gets brighter in the room, the LED should turn off.
Turning the potentiometer adjusts the “setpoint,” i.e. the threshold at which the illumination LED turns on/off.
- To change the potentiometer’s knob position in Tinkercad, while the simulation is running, click and drag the knob around.
- To change the amount of simulated light hitting the photoresistor, while the simulation is running, click on the photoresistor and use the little slider that appears above it, like so:
Mode switch
The single-pole double-throw switch changes the nightlight into a daylight. That is to say, when that switch is in “daylight” position, the light turns on when it’s bright out, and off when it’s dark out. (The switch can be flipped to “daylight” or “nightlight” mode whenever the user wants.) The potentiometer still adjusts the setpoint just as it did before.
Flashlight button
While the momentary pushbutton is pressed, the LED turns on. (If it was already on, it remains on.) When the button is released, the LED goes back to its regular functioning. This is meant as a flashlight function for a user who, for instance, needs to see something on the nighstand for a moment, but doesn’t want to leave the nightlight on.
Serial
feedback
In order to help understand what calculations the nightlight is making, and how bright the room is, add some Serial
feedback in this format:
room brightness: 320; setpoint: 300; mode: NIGHTLIGHT; flashlight mode: FALSE; LED: OFF room brightness: 290; setpoint: 300; mode: NIGHTLIGHT; flashlight mode: FALSE; LED: ON room brightness: 290; setpoint: 305; mode: DAYLIGHT; flashlight mode: FALSE; LED: OFF room brightness: 290; setpoint: 305; mode: DAYLIGHT; flashlight mode: TRUE; LED: ON
The Serial
feedback should print no more than twice per second.
Deliverables:
- Tinkercad share link submitted to this Canvas assignment
- Please look at the “Feedback” section at the bottom of the page to be sure that you know all the standards you’ll be graded on. Note that you can get lots of points just from good wiring, even if the thing doesn’t work!
- Arduino code (
.ino
) and schematic submitted to this Canvas assignment- Specific information about expected code formatting is below.
Recommended general approaches for this assignment
Begin by writing pseudocode, i.e. a summary of the basic logic that will underlie the sketch. This is just meant as an organizational step for your own thinking; it should not be included in the final sketch you submit for the assignment. You may wish to diagram out the logic with bubbles and arrows, etc., instead of putting it into words; whatever works for you is fine. Also draw your schematic (or aspects of your schematic) before beginning wiring: using it as a planning document will be very helpful as more and more wires and components start to crowd your breadboard.
When you’re ready, add only one component at a time. Maybe start with only the photosensor (tutorial link), make sure it’s working (the Serial
feedback will help a lot with that), then add the switch, make sure it’s working, etc. At the same time you’re adding a component and confirming that it’s working electrically, you can start to write the relevant parts of the code that interact with that component.
Rather than writing complete code that totally works and covers all cases, begin by writing code that covers only a portion of what you’ll ultimately need—for instance, get the nightlight working before worrying about getting the daylight working, and get both of those working before worrying about the flashlight button. (You don’t need to follow that order of development; it’s just an example.)
Build towards the goal, and stop at ~4 hours (only optionally pushing beyond that time limit). If you complete the assignment, great, and if not, get as far as you can in ~4 hours. We’re at the learning-a-lot-very-quickly stage of the course, which is coincidentally sometimes also the this-is-too-much-at-once stage.
Code formatting notes
Use a standard comment block at the top of the code as specified in the syllabus.
Use single-line comments in your code to explain anything not obvious. These aren’t only notes for other people—they’re notes for you when you look at the code next month and are trying to figure it out!
Example of a good single-line comment:
// switch is in DAYLIGHT position
if (switchState == HIGH){
The above comment is useful and helps the reader quickly scan the code with understanding.
Example of an gratuitous (unnecessary) single-line comment:
// test the position of the switch and load it into the switchState variable
switchState = digitalRead(SWITCHPIN);
This comment is just spelling out the obvious and you shouldn’t write it.
Write constant variable names like pin designations (see next section) in ALL_CAPS
and changeable variable names like sensor values in camelCase
.
Pin designations
As we discussed in class, it’s preferred to use variable names, rather than numbers, to refer to input and output pins.
Using the same order as your pin mapping section of the comment block, add a section at the top of your code to give clear ALL_CAPS
constant variable names for all of your inputs and output pins. For instance:
[code above this point not shown]
/*
* Pin mapping:
*
* pin | mode | description
* ------|--------|------------
* A2 input potentiometer for setpoint
* A4 input photoresistor
* 6 output nightlight/daylight LED
*
*/
const int POTPIN = A2;
const int PHOTOPIN = A4;
const int LEDPIN = 6;
[code below this point not shown]
(Note that this sample does not include the total list of inputs and outputs you’ll need to complete this assignment.)
String formatting
A reminder from the prior homework is that you can build long Serial
strings like so:
Serial.println((String)"This first variable's value is " + varOne + ", and the second one's is " + varTwo);
Another useful thing to know is that you can use theString
data type to hold words, etc., and then put them right into the Serial
commands, like so:
String modeName = "DAYLIGHT";
Serial.println("the current mode is: " + modeName);
In this case modeName
is a variable just like any other, and you can change its value any time you’d like.
Code structure notes
First, begin by gathering data about the world. In the setup()
, use the pinMode()
commands to tell the Arduino where everything is plugged in, and what things are inputs and what things are outputs. Also, in the setup()
, don’t forget to add the command to begin Serial
communication.
Then, in the loop()
, begin by gathering information like this:
int brightnessVal = analogRead(PHOTOPIN);
int potVal = analogRead(POTPIN);
int switchVal = digitalRead(SWITCHPIN);
Now you have to write the instructions that will turn the LED on or off. It’s a simple question that the code needs to run: is the brightness value lower than the potentiometer value? If so, turn on the LED. If not, turn off the LED.
if (brightnessVal < potVal){
// turn on the LED in here
}
This will set you on your way, but there’s things I left out. For instance, I haven’t told you how to add the logic to make it so that the switch reverses the behavior of the LED to make it into a daylight, or how to implement the flashlight button. The exercise is left to the reader!
Bonus: a nightlight with feature bloat
Do this part of the assignment only if you were able to successfully do the “Reasonable Nightlight” first!
- Inputs are same as above, plus:
- an additional momentary pushbutton, referred to below as the “bloat button”
- Outputs are same as above, plus:
- an additional LED (yellow in color)
The engineers at the nightlight company must have gotten real bored because they started to add features that no reasonable consumer would want. Specifically:
- When in DAYLIGHT mode: if the bloat button is presssed:
- The additional yellow LED will dim up from off, to full brightness, then back down to off. The whole process (off→partial brightness→full brightness→partial brightness→off) takes one second, and it smoothly goes from off, to on, and back to off. (Use
analogWrite
!) - Additionally, the
Serial
output prints:
That's a sick fade, broseph
- The additional yellow LED will dim up from off, to full brightness, then back down to off. The whole process (off→partial brightness→full brightness→partial brightness→off) takes one second, and it smoothly goes from off, to on, and back to off. (Use
- When in NIGHTLIGHT mode: while the bloat button is pressed, the
Serial
monitor output changes from the previous useful diagnostic information. Instead, it helps the user sleep by printing one more Z per line, like so:
Z ZZ ZZZ ZZZZ ZZZZZ ZZZZZZ ZZZZZZZ
It continues printing longer and longer lines of Zs until the bloat button is no longer held. The next time it’s pressed, it begins again with one Z.
Collaboration and help
Limited collaboration with your classmates is permitted. You must build your own circuit and write your own code, but you can talk with other students to get advice and reason through the problem together. You are not permitted to copy somebody else’s code, nor are you permitted to look at someone else’s schematic or breadboard and simply reproduce what you see there. You are permitted to use any internet/book/etc. resource you’d like.
As always, you must note all of your collaboration in the appropriate section of the opening comment block.
Feedback
points | assignment |
---|---|
Tinkercad/breadboard | |
2 | inputs wired properly (with 10kΩ pull-down resistors for button/switch) |
1 | outputs wired properly (current-limiting ≥270Ω resistor in series with LED) |
1 | proper wire colors used (red for power, black for ground, your choice for others) |
1 | wires routed with 90º turns |
2 | serial feedback formatted properly and working |
6 | device functions to spec |
Code | |
4 | code written cleanly, clearly, and with appropriate commenting practice |
Schematic | |
3 | schematic clear and correct |
Bonus | |
2 | bonus (all or none): additional bloat features work to spec |
Total | |
20 | overall points, plus 2 bonus points available |