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