The Uncertain Sensor Detective
Change the slider level and observe the 5x5 LED display.
- Web browser (Chrome, Edge, Firefox)
- Internet connection
- MakeCode (micro:bit) online editor
🔧 Build Your Hysteresis Controller
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 / Action | Expected Result |
|---|---|
| Light drops to 45 | Lamp 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 60 | Lamp cleanly switches OFF |
Log relay switching events to the serial monitor to prove zero chattering occurred during sunset transitions!
📖 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 / Action | Expected Result |
|---|---|
| Light drops to 45 | Lamp 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 60 | Lamp cleanly switches OFF |
⚑ Extension Challenges & Blueprints
- 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.