The Uncertain Sensor Detective

JSS 2 MakeCode micro:bit Simulation first Deadbands and Boundary States
Simulation lab
Board: BBC micro:bit
Open MakeCode ↗
Simulator preview
☀️ 80

Change the slider level and observe the 5x5 LED display.

📁 Tools ▴
  • Web browser (Chrome, Edge, Firefox)
  • Internet connection
  • MakeCode (micro:bit) online editor

🔧 Build Your Hysteresis Controller

1 Wire an analog photoresistor (LDR) voltage divider to analog pin A0.
2 Connect an output relay module controlling an AC/DC lamp to digital pin 8.
3 Implement hysteresis thresholds: Turn ON when light drops below 40; Turn OFF when light rises above 60.
4 Define the 40 to 60 zone as a stable deadband where current output state is strictly preserved!
🧩 Block plan / Starter code ▴
const int LDR_PIN = A0;
const int RELAY_PIN = 8;
const int LOW_THRESHOLD = 40;  // Turn ON below 40
const int HIGH_THRESHOLD = 60; // Turn OFF above 60

bool lampState = false;

void setup() {
  pinMode(RELAY_PIN, OUTPUT);
  Serial.begin(9600);
  Serial.println("Hysteresis Controller Initialized.");
}

void loop() {
  int sensorVal = map(analogRead(LDR_PIN), 0, 1023, 0, 100);

  if (sensorVal < LOW_THRESHOLD && !lampState) {
    lampState = true;
    digitalWrite(RELAY_PIN, HIGH);
    Serial.println("Night confirmed: Lamp ON");
  } else if (sensorVal > HIGH_THRESHOLD && lampState) {
    lampState = false;
    digitalWrite(RELAY_PIN, LOW);
    Serial.println("Daylight confirmed: Lamp OFF");
  }
  // Between 40 and 60: Hysteresis deadband preserves stability
  delay(200);
}

Dual thresholds create a deadband buffer that eliminates relay chattering caused by sensor noise.

⚗️ Test your model

Test Condition / ActionExpected Result
Light drops to 45Lamp remains OFF; does not trigger prematurely
Light drops to 35 (below 40)Lamp cleanly switches ON
Light hovers at 50 (in deadband)Lamp remains ON without flickering
Light exceeds 60Lamp cleanly switches OFF
⚑ Try a challenge

Log relay switching events to the serial monitor to prove zero chattering occurred during sunset transitions!

❓ Quick check
Why does an automated cooling fan rapidly turn on and off (chatter) if controlled by a single rigid temperature threshold?

📖 Our Story & Concepts

In naive software, beginners often write single-threshold rules: if (light < 50) turn_lamp_on() else turn_lamp_off(). What happens when sunset arrives and ambient light naturally hovers between 49.9 and 50.1? The relay chatters violently on and off dozens of times per second!

Actuator chattering sparks electrical arcs that weld relay contacts shut and burn out bulbs. Engineers solve this using hysteresis: establishing an asymmetrical deadband where turning ON requires dropping below a low threshold, while turning OFF requires climbing above a higher threshold.

</> Full Annotated Code Walkthrough

// Complete Hysteresis Engine with Boundary Diagnostics
const int LDR_PIN = A0;
const int RELAY_PIN = 8;
const int STATUS_LED = 13;

const int TURN_ON_THRESHOLD = 35;
const int TURN_OFF_THRESHOLD = 65;

bool relayActive = false;
unsigned int switchCount = 0;

void setup() {
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(STATUS_LED, OUTPUT);
  Serial.begin(115200);
  Serial.println("Hysteresis Controller Online");
}

void loop() {
  int rawADC = analogRead(LDR_PIN);
  int lightPercent = map(rawADC, 0, 1023, 0, 100);

  if (lightPercent < TURN_ON_THRESHOLD && !relayActive) {
    relayActive = true;
    switchCount++;
    digitalWrite(RELAY_PIN, HIGH);
    digitalWrite(STATUS_LED, HIGH);
    Serial.print("Actuator Switch #"); Serial.print(switchCount);
    Serial.println(" -> STATE: ON");
  } 
  else if (lightPercent > TURN_OFF_THRESHOLD && relayActive) {
    relayActive = false;
    switchCount++;
    digitalWrite(RELAY_PIN, LOW);
    digitalWrite(STATUS_LED, LOW);
    Serial.print("Actuator Switch #"); Serial.print(switchCount);
    Serial.println(" -> STATE: OFF");
  }
  delay(250);
}

Dual thresholds create a deadband buffer that eliminates relay chattering caused by sensor noise.

▷ Expected Results & Troubleshooting

Test Condition / ActionExpected Result
Light drops to 45Lamp remains OFF; does not trigger prematurely
Light drops to 35 (below 40)Lamp cleanly switches ON
Light hovers at 50 (in deadband)Lamp remains ON without flickering
Light exceeds 60Lamp cleanly switches OFF

⚑ Extension Challenges & Blueprints

⚑ Extension Challenges
  • Level 1: Adjust threshold gap from 30 points to 10 points and test with a torch.
  • Level 2: Implement an 'Uncertain State' indicator LED that lights up whenever light is inside the deadband.
  • Level 3: Add a time-delay requirement: condition must persist for 3 continuous seconds before switching.

❓ Check Your Understanding

Question 1: Why does an automated cooling fan rapidly turn on and off (chatter) if controlled by a single rigid temperature threshold?

Question 2: What is a 'Deadband' (or Hysteresis) in control engineering?

Question 3: Instead of guessing a false state when a sensor reading fluctuates near the boundary, what does our Detective model report?

Question 4: In MakeCode, what built-in environmental sensor can be simulated on the micro:bit to test this concept?

Feedback appears after you check your answer.