ROBOTICS · LEVEL 1 · ARDUINO FOUNDATIONS · LESSON 06

Build an Arduino Smart Night-Light

Teach an Arduino to notice darkness, then decide when a room needs light.

A regular night-light has no idea whether the room is bright or dark. Yours will notice.

You will give the Arduino a phototransistor, a tiny light-sensitive electronic switch. First, you will make the Arduino report what the sensor sees. Then you will use real evidence from your own room to teach it when to turn an LED on. This is your first project in which the computer makes a decision about the world around it.

At a glance

Age range10–13
Estimated time60–80 minutes
DifficultyBeginner-plus
Parent involvementMedium for the first sensor-orientation check; light afterward
Major conceptsPhototransistor, voltage divider, analog input, calibration, threshold, if/else, serial evidence

What you will learn

  • How a phototransistor changes an electrical signal when light changes.
  • How Arduino reads that changing signal on A0 as a number from 0 to 1023.
  • How to collect bright and dark readings before choosing a threshold.
  • How an if/else statement lets code make a decision.
  • Why a useful sensor project needs calibration in the real place where it will be used.
  • How to use the Serial Monitor as a window into the Arduino’s evidence.

Before you begin

Complete Lesson 5: Build a Dial-a-Signal Controller. You already know that A0 can read a changing voltage and that the Serial Monitor can show the number. This lesson, the changing voltage comes from light instead of your hand turning a knob.

Have the Components guide and the Debugging Ladder open or printed. This lesson uses the phototransistor in the Arduino Student Kit—not a round photoresistor/LDR. If you are using a compatible substitute, check its collector/emitter pinout before wiring it.

Do not simulate this lesson first. A simulated room has simulated light values, so it cannot teach your family how to calibrate a sensor in your actual room. Build the physical circuit after the parent completes the quick orientation check in Step 2.

For technical background, read SparkFun’s phototransistor voltage-divider guide. The pictured sensor is a different model, but the input idea is the same: light changes the signal sent to an Arduino analog pin.

What you need

Required components

QuantityItemCompatible substitute
1Arduino Uno from the Arduino Student KitGenuine Uno R3 or Uno R3 SMD
1Solderless breadboardStandard half-size breadboard
1Two-lead phototransistor from the Student KitNPN phototransistor with verified collector/emitter pinout
110 kΩ resistor4.7 kΩ–22 kΩ resistor; 10 kΩ is the planned value
1LED, any colorAny ordinary 3–5 mm LED
1220 Ω resistor330 Ω or 560 Ω resistor; do not omit it
7–10Male-to-male jumper wiresSolid-core breadboard wires
1USB-A to USB-B data cableArduino-branded USB-A-to-B data cable

Optional components

  • Cardboard, tape, and markers to turn the LED into a small lamp or a room-status sign.
  • A black cup or box to make a repeatable “dark” test.
  • Your maker notebook and pencil.

Tools

None. This project is solderless.

Computer/software requirements

  • Arduino IDE 2 with Arduino Uno and its port selected.
  • A Mac running macOS 10.15 or later, or Windows 10 64-bit or newer.
  • Serial Monitor, set to 9600 baud.

Safety and setup notes

  • Unplug the USB cable before you move wires. Connect it only after the parent and student have traced the circuit once.
  • This is a low-voltage, USB-powered project. It must not connect to wall power, batteries larger than the Uno’s USB supply, water, or anything hot.
  • Do not stare into a very bright light source to test the sensor. A lamp across the room, a window, your hand, or a cup over the sensor is enough.
  • The phototransistor has a direction. In this lesson, its collector/longer lead goes to 5V and its emitter/shorter lead goes to the A0 signal row. Check the actual part against the labeled diagram before power-up; a compatible replacement may use different lead lengths.
  • Keep 5V and ground on separate breadboard rails. The 10 kΩ resistor belongs between the A0 signal row and ground; it is not optional.
  • The adult should inspect the first sensor wiring and any uncertainty about the component’s leads. Let the student choose the threshold, test the code, and own normal software mistakes. Step in immediately for a warm part, a possible 5V-to-ground short, smoke, or a board that repeatedly disconnects.

Build overview

The phototransistor and resistor make a voltage divider. More light lets more electrical current flow through the sensor. In the planned orientation, bright light makes A0 read a bigger number; shading the sensor makes A0 read a smaller number.

Room light → phototransistor + resistor make a changing voltage → A0 reads 0–1023
           → code compares that number with your dark threshold → D9 turns LED off or on

First, you will only read and record the sensor. That is calibration: gathering facts before asking the Arduino to make a rule. Then you will add the rule: if the room is darker than our chosen threshold, turn on the night-light. Otherwise, turn it off.

Step-by-step build instructions

Step 1: Set up the power rails and LED output

  1. Place the breadboard with its center trench running left to right.
  2. Use a red jumper to connect Arduino 5V to one breadboard rail. This is the 5V rail.
  3. Use a black jumper to connect Arduino GND to a different breadboard rail. This is the ground rail.
  4. Place the LED so its legs are in different connected rows. Connect its short leg (flat-side leg) to ground.
  5. Put one end of the 220 Ω resistor in the LED’s long-leg row. Put the resistor’s other end in a new row and connect that row to Arduino D9.

Checkpoint: trace the LED path aloud: D9 → 220 Ω resistor → LED long leg → LED short leg → ground. Keep the Uno unplugged.

Step 2: Wire the light sensor divider

  1. Put the phototransistor’s two legs into two different, unconnected rows of the main breadboard area. Do not put it in the same row as an LED leg.
  2. Identify its collector (C) and emitter (E) using the labeled visual. For the supplied kit part, start with the longer collector lead to 5V and the shorter emitter lead as the signal lead. If your substitute labels its leads differently, follow that label instead.
  3. Connect the collector row to the 5V rail.
  4. Connect the emitter row to Arduino analog pin A0. This is the signal row.
  5. Place the 10 kΩ resistor with one end in that same signal row and its other end in the ground rail.
Sensor connectionDestinationJob
Collector / longer lead5V railProvides the high side of the sensor circuit
Emitter / shorter leadA0 signal rowSends a changing voltage to the Arduino
10 kΩ resistor, first endA0 signal rowHelps turn light changes into a readable voltage
10 kΩ resistor, second endGround railCompletes the divider path

Checkpoint: with USB still unplugged, have the parent and student trace two separate paths: 5V → sensor → A0 signal row and A0 signal row → 10 kΩ resistor → ground. Confirm that the 5V rail and ground rail never share a row.

Step 3: Upload the calibration sketch

  1. Connect the Uno with the USB data cable.
  2. In Arduino IDE, confirm that Arduino Uno and the correct port are selected.
  3. Create a new sketch and upload this calibration code first.
  4. Open Tools → Serial Monitor and set the speed to 9600 baud.
  5. Watch the numbers with normal room light. Then cover the sensor with your hand or a cup without touching the wires.
const int LIGHT_SENSOR_PIN = A0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  int lightValue = analogRead(LIGHT_SENSOR_PIN);
  Serial.println(lightValue);
  delay(250);
}

Checkpoint: write down at least three readings: bright room, normal room, and sensor covered. In the planned circuit, the covered value should be lower than the bright-room value. The LED is not meant to react yet.

Step 4: Choose a threshold from evidence

  1. Find a number halfway between your normal-room value and covered-sensor value. That is a sensible first dark threshold.
  2. Example only: if normal room is about 780 and covered is about 180, halfway is about 480. Your room will probably make different numbers.
  3. Write your own number in the notebook, along with this sentence: “When I shaded the sensor, the number went up/down.”
  4. Replace the example value in the final code below with your evidence-based threshold.

Checkpoint: predict the result before uploading: if your covered reading is lower than the threshold, should the night-light turn on or off?

Step 5: Upload the smart night-light code

  1. Replace the calibration sketch with the complete program in the next section.
  2. Change DARK_THRESHOLD to your own chosen value before you upload.
  3. Upload, then leave the Serial Monitor open.
  4. Test in normal room light and then shade the sensor. Adjust only DARK_THRESHOLD after each test; write down the new value and what changed.

Checkpoint: you have a successful first night-light when the LED is off in your chosen bright condition and turns on when the sensor is covered or the room is dark enough for your stated rule.

Code

const int LIGHT_SENSOR_PIN = A0;
const int NIGHT_LIGHT_PIN = 9;

// Replace 480 with a threshold based on your own recorded readings.
const int DARK_THRESHOLD = 480;

void setup() {
  pinMode(NIGHT_LIGHT_PIN, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int lightValue = analogRead(LIGHT_SENSOR_PIN);

  Serial.print("Light value: ");
  Serial.print(lightValue);
  Serial.print(" | Threshold: ");
  Serial.println(DARK_THRESHOLD);

  if (lightValue < DARK_THRESHOLD) {
    analogWrite(NIGHT_LIGHT_PIN, 255);
  } else {
    analogWrite(NIGHT_LIGHT_PIN, 0);
  }

  delay(100);
}

What the important code means

  • Variables and constants: LIGHT_SENSOR_PIN and NIGHT_LIGHT_PIN give useful names to A0 and D9. DARK_THRESHOLD is a named rule value you choose from real readings. lightValue holds the latest number from the sensor.
  • setup(): this runs once. It prepares D9 as an output and starts the Serial Monitor connection.
  • loop(): this repeats: read the room, show the evidence, make a decision, change the LED, and wait briefly.
  • Inputs and outputs: analogRead(LIGHT_SENSOR_PIN) is the input. analogWrite(NIGHT_LIGHT_PIN, ...) is the output. Here, 255 means fully on and 0 means off.
  • New condition: if (lightValue < DARK_THRESHOLD) asks a true-or-false question. If the reading is lower than your dark line, the Arduino turns the LED on. else handles every other reading.
  • Why calibration matters: 480 is not a magic correct number. A sunny window, a dark basement, and a hand over the sensor make different readings. Your notebook values are the evidence for your rule.

If your verified sensor circuit consistently produces higher numbers in darkness, reverse only the comparison to if (lightValue > DARK_THRESHOLD), then write a comment explaining why. Do not change the comparison just to hide a loose wire: first use the calibration sketch to prove what the sensor is reporting.

Arduino’s analog input reference explains the 0–1023 reading range. SparkFun’s phototransistor guide explains why a phototransistor needs a voltage-divider circuit to make a useful analog signal.

Make it work

The first version works when all of these are true:

  1. Arduino IDE says Done uploading.
  2. Serial Monitor values change noticeably when you shade and uncover the sensor.
  3. You recorded bright, normal, and covered readings before choosing a threshold.
  4. The LED is off in your chosen bright condition and on in your chosen dark condition.
  5. You can point to A0 and name it the input, then point to D9 and name it the output.
  6. You can explain, in your own words, what the if condition is deciding.

Understand it

  1. Why does this project need both a phototransistor and a 10 kΩ resistor?
  2. What number does analogRead(A0) give your code, and what real-world thing changes that number?
  3. Why should you record readings before choosing DARK_THRESHOLD?
  4. Predict what happens if you make DARK_THRESHOLD much smaller than your covered reading.
  5. In the planned circuit, why does lightValue < DARK_THRESHOLD mean “it is dark enough”?

Required “change it” challenge

Desired outcome: upgrade the on/off night-light into a fade-in night-light. It should glow a little in a dim room, grow brighter as the sensor is more covered, and flash when the sensor reaches your chosen “emergency dark” level.

Constraints: keep the sensor on A0 and LED on D9; use two named constants based on recorded data, such as DARK_THRESHOLD and EMERGENCY_DARK_THRESHOLD; use if, else if, and else; use map() to choose a brightness between 30 and 255; add one code comment explaining which readings mean darker in your circuit. Save a copy of the working on/off sketch before starting.

Hints:

  1. Record a value when the sensor is very dark. In the planned circuit, that value should be lower than your normal dark threshold. Give it the name EMERGENCY_DARK_THRESHOLD.
  2. Start your decision chain with the emergency case. There, make the LED flash: full brightness, short delay, off, short delay.
  3. The middle case is “dark but not emergency dark.” Map the range from your emergency-dark reading to your normal dark threshold into an LED-brightness range from 255 down to about 30. In the bright case, turn the LED off.
  4. Test one condition at a time: bright room, shaded sensor, then cup-covered sensor. Change a threshold only after you can name the reading that caused the surprise.

Parent guidance: the student should choose the two thresholds and wrestle with the order of the if / else if / else rules. A useful struggle is 10–15 minutes of testing values, writing a three-row rule table, and making one small code change at a time. Ask, “Which range should this reading belong to?” Do not write the decision chain for him. Step in if he changes many things at once, if the circuit’s 5V/ground path is uncertain, or if 15–20 minutes pass without a fresh, specific test. Return to the saved working sketch before continuing.

Optional enhancements

Try this

Make the Serial Monitor print a word as well as a number: BRIGHT, DIM, or DARK. Hint: put the matching Serial.println() inside each branch of your decision chain. Confirm that the word matches the LED before you decorate anything.

Challenge

Use the Lesson 5 potentiometer as an adjustable darkness setting. The sensor still goes to A0; connect the knob’s center pin to A1, read it, and map it to a useful threshold range. Add a paper dial labeled “turn toward more sensitive.”

Stretch

Build a cardboard bedside lamp, creature eye, hallway sentinel, or “do-not-enter” sign around the LED and sensor. Your enclosure must leave the sensor uncovered and let someone reach the USB cable. Write a one-sentence test: “In ___ light, it should ___.”

Debugging guide

What you noticeLikely causeSmallest next diagnostic step
The Uno is not detected or does not uploadComputer/cable/port problem, not the light circuitRemove the breadboard wires and run Lesson 1’s built-in Blink check. Then use the Debugging Ladder.
Serial Monitor always shows 0 or nearly 0A0 signal row is not connected, sensor emitter is loose, or the resistor is in the wrong rowTrace only A0 → signal row → emitter and signal row → 10 kΩ → GND; then run the calibration sketch.
Serial Monitor always shows 1023 or nearly 1023Signal row is tied to 5V or the resistor’s ground path is missingWith USB unplugged, confirm 5V goes to the collector only and the 10 kΩ resistor ends at ground.
Covering the sensor barely changes the numberSensor is backward, not exposed to light, or placed with both legs in one breadboard rowMove a lamp or hand close to the sensor, confirm its legs are in separate rows, then check collector/emitter orientation against the diagram.
The LED is on in a bright room and off when coveredThreshold is outside the recorded range, or the comparator direction is wrong after a verified reading testRead the bright and covered values aloud. First adjust the threshold between them; reverse </> only if the readings are consistently opposite the planned circuit.
The LED never turns on or never turns offDARK_THRESHOLD was guessed or has a typoPrint the current value and threshold; choose a new threshold halfway between actual bright and dark readings.
The LED is dark even when code says it should be onLED polarity, resistor path, or D9 connection errorTest the LED circuit alone with Lesson 5’s simple brightness code, then trace D9 → resistor → LED long leg → LED short leg → GND.
Custom fade/flash works strangelyThe three conditions overlap or are in the wrong orderMake a three-row table: bright, dim, emergency dark. Test one recorded value per row before changing code.

When a small test does not answer the question, return to the Debugging Ladder: power, data cable, board/port, loose wires, component direction, pin numbers, upload, then code logic. Take an overhead wiring photo and keep the working on/off sketch safe before trying a custom rule.

Recap

You built a physical sensor circuit, used A0 to turn light into numbers, calibrated a threshold with evidence from your room, and used an if/else decision to control an LED. The important new habit is not “remember 480.” It is: measure first, choose a rule, test the rule, then improve it.

Show what you learned

In your maker notebook, answer these in complete sentences or draw-and-label answers:

  • What three light readings did you record, and which threshold did you choose?
  • What did you change in the project?
  • What failed, and how did you diagnose it?
  • What would you improve next time?
  • Explain either the 10 kΩ resistor’s connection or the if (lightValue < DARK_THRESHOLD) line in your own words.

What’s next

Next, in Lesson 7: Become a Temperature Detective, you will use another analog sensor—but the number will need math before it becomes useful information. The habits carry forward: read the evidence, calibrate or verify it, name a clear rule, and test one change at a time. Lesson 7 also gives you another possible input for the capstone you will choose in Lesson 8.

NEXT · LESSON 07

Lesson 7: Become a Temperature Detective

Parent guide

What to prepare in advance

  • Confirm Arduino IDE can upload a simple sketch to the Uno before the session.
  • Put out one phototransistor, one 10 kΩ resistor, one LED, one 220 Ω resistor, jumpers, breadboard, USB data cable, and notebook.
  • Open the Components guide, the Debugging Ladder, and Serial Monitor at 9600 baud.
  • Look at the actual phototransistor beside the labeled wiring visual. If you substituted a part, verify its collector/emitter pinout before the child wires it.

Where the child should work independently

Let the child place the parts, trace the input and output paths, upload both sketches, collect readings, calculate a midpoint threshold, and decide what counts as “dark enough.” He should make the first one-change-at-a-time threshold adjustment and write the evidence down.

Moments when the parent should resist taking over

Do not supply a magic threshold. Do not reverse the if comparison before the child has shown you the Serial Monitor evidence. Do not turn a wrong prediction into a rescue; ask, “What value did it actually read?” Let the student make a three-row bright/dim/dark rule table for the required challenge before offering a hint.

When the parent should step in

Step in for a suspected 5V/ground short, component heat, uncertain sensor orientation, board/cable/port failure, or after 15–20 minutes of honest ladder-based diagnosis without a new test. Ask the child to save the working sketch before custom changes. If requesting outside help, collect: an overhead wiring photo, board model, operating system, exact upload/error text, selected port, full code, recorded values, and expected versus actual behavior.

A simple understanding-based assessment

Ask the student to point and explain: “Where does the room enter the project? Where does the decision happen? Where does the answer come out?” Then ask him to predict whether the LED will turn on for one real Serial Monitor value and justify the answer using his threshold. Assess four things equally: a safe circuit, a correct explanation, recorded evidence, and persistence through at least one intentional test or revision—not merely whether the LED happens to light.

Further resource: SparkFun: TEMT6000 Ambient Light Sensor Hookup Guide