due at the start class on Wednesday, Jan. 29th

Assignment: a reasonable nightlight

You’re hired to help build a prototype nightlight. Your bill of materials includes:

  • Inputs
  • 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.

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:

  • Working nightlight, as described above, ready to present at the start of class
  • Working serial feedback, as described above
  • Electrical schematic of the circuit you built, with your name and date at the top, to be handed in on an unlined sheet of 8-1/2”×11” paper
  • Code submission to this homework’s Canvas 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.

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.)

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(A0); // the pin the photoresistor is plugged into
int potVal = analogRead(A1);        // the pin the potentiometer is plugged into
int switchVal = digitalRead(7);     // the pin the switch is plugged into

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!

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 there’s a data type called String which can hold words, etc., which can be put 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.

Remember to use the built-in reference system in the Arduino software if you’re confused about how to use any functions, or do web searches if you’re not getting the answers you’d like.

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:

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: while the bloat button is presssed, that activates “robot mode”—the servo motor turns its position to match the rotation of the setpoint potentiometer. (I.e. turning the potentiometer through its ~270º travel makes the servo motor drive through its 180º travel in sync.) While the additional momentary pushbutton is not held, the servo sits at 90º.
  • 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.

Feedback

points assignment
2 inputs wired properly (with pull-down resistors for button/switch)
1 outputs wired properly (current-limiting ≥270Ω resistor in series with LED)
2 serial feedback formatted properly and working
4 code written cleanly, clearly, and with appropriate commenting practice
6 device functions to spec
3 schematic clear and correct
2 bonus (all or none): additional bloat features work to spec
18 (plus 2 bonus points available)