AI agents & screen readers: for a machine-readable, text-only catalogue, start at /llms.txt. Products are available as Markdown (/products.md, /products/{handle}.md) and JSON (/products.json, /products/{handle}.json).
Store
Bounce between two lights
Beginner 25 minutes

Use thresholds and memory to select an output without needing a perfect sensor reading.

View Markdown

Step 1 — What you will discover

Make a decision from an analogue reading and preserve the previous state between decision points.

Predict: After selecting D13 at one end, which LED stays on when you return to the middle?

Before you begin

Retrieve LOW/HIGH and Boolean true/false.

Your goal: Explain state that survives a loop. Show this with a prediction, a tested change and an explanation using the program’s names.

Retrieve one idea: what input, state or output did you change in the previous project?

Need a reminder? Turn the knob, dim the light.

Step 2 — Meet this circuit

Use an Arduino Uno with the Crack the Code shield. The shield already connects its LEDs, knob, light sensor and buttons; this activity needs no jumper wires or breadboard.

If the shield is not fitted, disconnect USB power, align every shield pin with the Uno sockets, and press evenly without bending the pins. Reconnect the Uno with a USB data cable. Leave the traffic-light module disconnected for this activity.

Step 3 — Upload your program

Open the example below. Read the English plan, then choose Arduino C++ from the language selector and Arduino Uno from the board selector. Select Verify to compile. Select Pair board…, choose the Uno’s serial port, then select Upload. Use Chrome or Edge on a desktop computer with this HTTPS page for browser upload. If browser upload is unavailable, copy the complete C++ sketch into Arduino IDE, choose Arduino Uno and its port, and upload there.

Each upload replaces the previous program. Edit the supplied C++ when trying the challenges, then verify and upload again.

After upload, select Open Serial Monitor and set 9600 baud. Close other serial programs first so only one application owns the port. The Plot tab can display the labelled numeric readings.

Step 4 — Read, edit and run

The English plan and complete Arduino sketch describe the same program. Keep one working copy before making changes.

Bounce between two lightsOpen in English ↗

Step 5 — Run it and collect evidence

D8 is selected at startup. Turn to the high-reading end to select D13, then return to the middle. D13 should remain on. Reach the low-reading end and D8 takes over.

Step 6 — Explain what happened

A reading at or below 50 selects D8. A reading at or above 973 selects D13. Between these thresholds the previous choice is kept.

A real knob may not produce exactly 0 or 1023. Small end zones make the control reliable. The if and else if only change highSelected near an end. In the middle neither runs, so the variable remembers the previous choice.

The expressions after ? and : choose the output state: condition ? valueIfTrue : valueIfFalse. One LED is always the opposite of the other.

Read this part of the actual starter

void loop() {
  int reading = analogRead(potPin);
  if (reading <= 50) highSelected = false;
  else if (reading >= 973) highSelected = true;
  digitalWrite(lowLed, highSelected ? LOW : HIGH);
  digitalWrite(highLed, highSelected ? HIGH : LOW);
  Serial.print("knob:"); Serial.println(reading);
  delay(25);
}

Global highSelected survives from one pass through loop() to the next. At <=50 it becomes false; at >=973 it becomes true. Between those limits neither assignment runs. condition ? a : b selects one of two values.

Work through one case

Readings 20 → 600 → 990 → 600 produce false → false → true → true. The same middle reading can therefore produce two different outputs depending on history.

Your turn: complete the trace

Start highSelected=false. After readings 990, 700, 40, the remembered choices are true, ___, ___.

Compare your trace after trying

true, then false. 700 is between the thresholds, so it retains the prior true state.

If your answer differs

Look for which assignment actually executes in the middle range.

Step 7 — Change one thing

Change the thresholds to 300 and 700. Predict where the light changes, then test from both directions. Keep the low threshold smaller than the high threshold.

Run a controlled experiment

Change the two switching points to 200 and 800. Trace 100, 500, 900, 500 and explain why a single threshold would behave differently.

  1. Save a copy of the working starter. Reset the board so stored state begins from the declared values.
  2. Write the expected result before editing. Change only the named factor; keep wiring and other settings fixed.
  3. Edit the C++ in the editor, Verify, then Upload to the connected Uno. The starter simulation does not execute your edited C++.
  4. Repeat the same input sequence. Record input, expected output, observed output and an explanation. Use labelled serial values where the sketch provides them.
  5. If the result differs, inspect the relevant condition and pin before changing another factor. Restore and upload the saved starter to recover.

Core task: explain one changed case. Optional extension: choose a boundary or timing case and justify the extra test. Use a paper trace or annotated screenshot when physical manipulation is inaccessible; distinguish predictions from measurements.

Step 8 — Check your understanding

Why are ranges more dependable than testing equality with the exact end readings? If one end never selects, inspect the printed minimum and maximum and place the thresholds inside that range.

If nothing changes: check the power light, successful upload and the selected Uno port. Disconnect power before reseating a shield. Read the first compiler error before changing several lines at once.

Independent check — try before revealing

Why can a reading of 500 light either LED? What if highSelected were initialised inside loop?

Hint

Look for which assignment actually executes in the middle range.

Reasoning and feedback

At 500 neither threshold changes the stored choice, so history decides. Reinitialising inside loop resets it false on every pass and destroys that memory.

Putting bool highSelected = false inside the loop would erase its memory each pass.

If your explanation missed a condition or stored value, add that column to your trace and try a new input. A working upload alone does not answer this check.

Step 9 — The knob reports position, the code remembers

The bouncer selects D8 near the low end and D13 near the high end. highSelected keeps its previous value between the thresholds.

Choose Cutaway and turn Wiper load off to represent the shield’s A5 input, which draws very little current. Move Turn the shaft to 25%, 50% and 75%. Record wiper voltage and ADC reading, and follow the moving contact on the resistive track.

Predict and explain: Turn to 100%, then back to 50%. The wiper voltage has changed; must the selected LED change too?

Check your explanation

No. The analogue input reports the new position continuously, but the program changes highSelected only when reading is at most 50 or at least 973. A middle position leaves the previous selection intact. With the illustrated 5 V reference and no wiper load, the three positions give about 1.25 V / 256, 2.50 V / 512 and 3.75 V / 767. A voltage is available at A5 even though almost no current enters that input.

Maddy, co-founder of Little Bird

Need help? We're here for you!

Hi, I'm Maddy. My team and I are ready to help with your order or any questions.