03 - Lab Light Sensor LED

Video

# Lab: Light Sensor LED Light - Automatic Lighting Control ## Objective Build an automatic lighting system using the TinkerBlock TK20 Ambient Light Sensor to control the TinkerBlock TK01 LED. The LED automatically turns on when the environment is dark (sensor value below 10) and turns off when there is sufficient light (sensor value above 20). This creates a practical automatic night light or security light system. ## Learning Outcomes - Understand automatic lighting control systems - Learn threshold-based sensor control - Master conditional logic for sensor input - Create practical automation systems - Use Serial communication for system monitoring - Understand hysteresis and threshold design ## Required Components ![](https://cdn.shopify.com/s/files/1/0331/9994/7908/files/Pasted_image_20250722154230.png?v=1753824009) 1. **Lonely Binary UNO R3** - Main Arduino board 2. **TinkerBlock UNO R3 Shield** - Expansion shield that plugs onto the UNO R3 3. **TinkerBlock TK20 - Ambient Light Sensor** - Light sensor module with 4-pin connector 4. **TinkerBlock TK01 - XL LED** - LED module with 4-pin connector ## Theory ### Automatic Lighting Control - **Threshold-Based Control**: Using sensor values to trigger actions - **Hysteresis**: Different on/off thresholds to prevent flickering - **Darkness Detection**: Low light sensor values indicate darkness - **Brightness Detection**: High light sensor values indicate sufficient light - **Automatic Response**: System responds to environmental changes ### Threshold Design Principles - **On Threshold**: Sensor value below 10 triggers LED ON - **Off Threshold**: Sensor value above 20 triggers LED OFF - **Hysteresis Band**: Values 10-20 create a stable transition zone - **Flicker Prevention**: Different thresholds prevent rapid switching - **Reliable Operation**: Stable operation in varying light conditions ### Light Sensor Behavior - **Dark Conditions**: High resistance, low voltage, low ADC values (0-10) - **Bright Conditions**: Low resistance, high voltage, high ADC values (20+) - **Transition Zone**: Values 10-20 provide stable operation - **Response Time**: Sensor responds to light changes in 10-100ms ### System States 1. **Dark State**: Sensor < 10, LED ON 2. **Transition State**: Sensor 10-20, LED maintains previous state 3. **Bright State**: Sensor > 20, LED OFF 4. **Monitoring State**: Continuous sensor reading and state evaluation ### Key Functions Used - `pinMode(pin, mode)`: Configures pins as input or output - `analogRead(pin)`: Reads analog value from specified pin (0-1023) - `digitalWrite(pin, value)`: Sets a digital pin HIGH or LOW - `Serial.begin(baud)`: Initializes serial communication - `Serial.print()` and `Serial.println()`: Outputs data to Serial Monitor - `delay(milliseconds)`: Pauses the program for a specified time ## Circuit Diagram ![](https://cdn.shopify.com/s/files/1/0331/9994/7908/files/Pasted_image_20250722154445.png?v=1753824014) ## Connection Instructions 1. **Assemble the Hardware:** - Place the TinkerBlock UNO R3 Shield onto the Lonely Binary UNO R3 - Ensure all pins are properly aligned and seated - The shield should fit snugly on top of the Arduino board 2. **Connect the Light Sensor Module:** - Take the TinkerBlock TK20 - Ambient Light Sensor module - Align the 4-pin connector with any available 4-pin slot on the shield - Gently push the module into the slot until it clicks into place - The module will automatically connect: - **GND** pin to ground - **VCC** pin to 5V power - **NC** pin remains unconnected - **Signal** pin to analog pin A3 3. **Connect the LED Module:** - Take the TinkerBlock TK01 - XL LED module - Align the 4-pin connector with another available 4-pin slot on the shield - Gently push the module into the slot until it clicks into place - The module will automatically connect: - **GND** pin to ground - **VCC** pin to 5V power - **NC** pin remains unconnected - **D3** pin to digital pin D3 4. **Important Notes:** - No breadboard or jumper wires required - Both modules have built-in current limiting resistors - The TK20 sensor has a built-in voltage divider circuit - Pin D3 is used for digital LED control (ON/OFF) - Multiple 4-pin slots are available on the shield for expansion ## Code ```cpp // Lab: Light Sensor LED Light - Automatic Lighting Control // Light sensor connected to analog pin A3 // LED connected to digital pin D3 // Define the pins const int lightSensorPin = A3; // Light sensor input pin const int ledPin = 3; // LED output pin // Threshold values for light control const int DARK_THRESHOLD = 50; // LED turns ON when sensor value < 10 const int BRIGHT_THRESHOLD = 200; // LED turns OFF when sensor value > 20 // Variables for reading and processing int lightValue = 0; // Raw analog value (0-1023) bool ledState = false; // Current LED state (true = ON, false = OFF) bool lastLedState = false; // Previous LED state for change detection // Smoothing variables const int numReadings = 5; int readings[numReadings]; int readIndex = 0; int total = 0; void setup() { // Configure light sensor pin as input (optional for analog pins) pinMode(lightSensorPin, INPUT); // Configure LED pin as output pinMode(ledPin, OUTPUT); // Initialize serial communication for monitoring Serial.begin(9600); Serial.println("Light Sensor LED Light System Started"); Serial.println("Automatic lighting control based on ambient light"); Serial.println("----------------------------------------"); Serial.println("Thresholds: ON < 50, OFF > 200"); Serial.println("Format: Light Value | LED State | Action"); Serial.println("----------------------------------------"); // Initialize LED to off digitalWrite(ledPin, LOW); ledState = false; // Initialize smoothing array for (int i = 0; i < numReadings; i++) { readings[i] = 0; } } void loop() { // Read the analog value from the light sensor lightValue = analogRead(lightSensorPin); // Apply smoothing to reduce noise lightValue = smoothReading(lightValue); // Store previous LED state lastLedState = ledState; // Determine LED state based on light sensor value if (lightValue < DARK_THRESHOLD) { // Dark conditions - turn LED ON if (!ledState) { digitalWrite(ledPin, HIGH); ledState = true; Serial.print("Light: "); Serial.print(lightValue); Serial.print(" | LED: ON | Action: LED turned ON (Dark detected)"); Serial.println(); } } else if (lightValue > BRIGHT_THRESHOLD) { // Bright conditions - turn LED OFF if (ledState) { digitalWrite(ledPin, LOW); ledState = false; Serial.print("Light: "); Serial.print(lightValue); Serial.print(" | LED: OFF | Action: LED turned OFF (Bright detected)"); Serial.println(); } } // If light value is between thresholds (10-20), maintain current state // Display current status (only when state changes or periodically) if (ledState != lastLedState) { // State changed, already printed above } else { // Periodic status update (every 1 seconds) static unsigned long lastStatusTime = 0; if (millis() - lastStatusTime > 1000) { Serial.print("Light: "); Serial.print(lightValue); Serial.print(" | LED: "); Serial.print(ledState ? "ON" : "OFF"); Serial.print(" | Status: "); if (lightValue < DARK_THRESHOLD) { Serial.println("Dark - LED should be ON"); } else if (lightValue > BRIGHT_THRESHOLD) { Serial.println("Bright - LED should be OFF"); } else { Serial.println("Transition zone - LED maintaining state"); } lastStatusTime = millis(); } } // Small delay to prevent too rapid reading delay(100); } // Function to smooth analog readings int smoothReading(int newReading) { // Subtract the last reading total = total - readings[readIndex]; // Read from the sensor readings[readIndex] = newReading; // Add the reading to the total total = total + readings[readIndex]; // Advance to the next position in the array readIndex = (readIndex + 1) % numReadings; // Return the average return total / numReadings; } ``` ## Code Explanation ### Setup Function ```cpp void setup() { pinMode(lightSensorPin, INPUT); pinMode(ledPin, OUTPUT); Serial.begin(9600); digitalWrite(ledPin, LOW); } ``` - Configures analog pin A3 as input for light sensor - Configures digital pin D3 as output for LED control - Initializes serial communication for monitoring - Sets LED to off initially ### Main Loop Logic ```cpp void loop() { lightValue = analogRead(lightSensorPin); lightValue = smoothReading(lightValue); if (lightValue < DARK_THRESHOLD) { // Turn LED ON } else if (lightValue > BRIGHT_THRESHOLD) { // Turn LED OFF } } ``` **Light Sensor Reading:** - `analogRead(lightSensorPin)`: Reads raw light sensor value (0-1023) - **Smoothing**: 5-point moving average reduces noise - **Real-time**: Continuous monitoring of light conditions **Threshold Control:** - **Dark Threshold (10)**: LED turns ON when sensor < 50 - **Bright Threshold (20)**: LED turns OFF when sensor > 200 - **Hysteresis Zone (10-20)**: LED maintains current state ### Control Logic ```cpp if (lightValue < DARK_THRESHOLD) { // Dark conditions - turn LED ON if (!ledState) { digitalWrite(ledPin, HIGH); ledState = true; } } else if (lightValue > BRIGHT_THRESHOLD) { // Bright conditions - turn LED OFF if (ledState) { digitalWrite(ledPin, LOW); ledState = false; } } ``` **State Management:** - **State Tracking**: Monitors current and previous LED states - **Change Detection**: Only updates when state actually changes - **Flicker Prevention**: Hysteresis prevents rapid switching ### Smoothing Function ```cpp int smoothReading(int newReading) { total = total - readings[readIndex]; readings[readIndex] = newReading; total = total + readings[readIndex]; readIndex = (readIndex + 1) % numReadings; return total / numReadings; } ``` - **5-point moving average**: Reduces noise and fluctuations - **Stable readings**: Prevents false triggers from noise - **Responsive**: Still responds to actual light changes ### Key Variables - **lightValue**: Raw light sensor reading (0-1023) - **ledState**: Current LED state (true = ON, false = OFF) - **lastLedState**: Previous LED state for change detection - **DARK_THRESHOLD**: Value below which LED turns ON (50) - **BRIGHT_THRESHOLD**: Value above which LED turns OFF (200) ### System Behavior - **Dark Conditions (< 50)**: LED turns ON - **Bright Conditions (> 200)**: LED turns OFF - **Transition Zone (50-200)**: LED maintains current state - **Hysteresis**: Prevents flickering at threshold boundaries ## Testing and Verification 1. **Upload the code to Lonely Binary UNO R3** 2. **Open Serial Monitor** in Arduino IDE (Tools → Serial Monitor) 3. **Test automatic lighting control:** - **Dark test**: Cover sensor completely, LED should turn ON - **Bright test**: Expose to bright light, LED should turn OFF - **Transition test**: Move between dark and bright, LED should respond - **Stability test**: LED should not flicker at threshold boundaries 4. **Verify threshold behavior:** - **Below 10**: LED should be ON - **Above 20**: LED should be OFF - **10-20 range**: LED maintains previous state 5. **Verify connections:** - Ensure both modules are firmly connected to the shield - Check that the shield is properly seated on the Arduino - Confirm the sensor responds to light changes - Verify the LED responds to sensor readings ## Troubleshooting ### LED doesn't respond to light changes: - Check if the TinkerBlock shield is properly seated on the Arduino - Ensure both TK01 and TK20 modules are firmly connected to the shield - Verify the modules are connected to slots that use A3 and D3 pins - Check if code uploaded successfully to the Lonely Binary UNO R3 - Open Serial Monitor to see if sensor values are being read ### LED flickers or switches rapidly: - Check if the modules are properly seated in the shield - Verify all pins are making good contact - Try reconnecting the modules to different 4-pin slots - Check for loose connections or bent pins - Increase smoothing by changing `numReadings` to a higher value - Adjust threshold values to create a larger hysteresis zone ### LED doesn't turn on in darkness: - Check if the sensor is properly covered or in dark conditions - Verify the sensor is connected to analog pin A3 - Check Serial Monitor output to see actual sensor values - Ensure the sensor surface is clean and unobstructed - Try adjusting the `DARK_THRESHOLD` to a higher value ### LED doesn't turn off in bright light: - Check if the sensor is exposed to sufficient light - Verify the sensor is connected to analog pin A3 - Check Serial Monitor output to see actual sensor values - Try adjusting the `BRIGHT_THRESHOLD` to a lower value - Ensure the light source is bright enough ### Serial Monitor shows no output: - Ensure Serial Monitor is set to 9600 baud rate - Check that Serial.begin(9600) is in setup() - Verify the correct COM port is selected in Arduino IDE ## Experiment Variations ### 1. Adjustable Thresholds Make thresholds configurable: ```cpp // Add these variables at the top int darkThreshold = 10; int brightThreshold = 20; // Add threshold adjustment in loop if (Serial.available() > 0) { char command = Serial.read(); if (command == 'd') { darkThreshold = Serial.parseInt(); Serial.print("Dark threshold set to: "); Serial.println(darkThreshold); } else if (command == 'b') { brightThreshold = Serial.parseInt(); Serial.print("Bright threshold set to: "); Serial.println(brightThreshold); } } ``` ### 2. PWM Brightness Control Use PWM for variable brightness instead of on/off: ```cpp void loop() { int lightValue = analogRead(lightSensorPin); lightValue = smoothReading(lightValue); if (lightValue < DARK_THRESHOLD) { // Dark - full brightness analogWrite(ledPin, 255); } else if (lightValue > BRIGHT_THRESHOLD) { // Bright - off analogWrite(ledPin, 0); } else { // Transition zone - proportional brightness int brightness = map(lightValue, DARK_THRESHOLD, BRIGHT_THRESHOLD, 255, 0); analogWrite(ledPin, brightness); } delay(100); } ``` ### 3. Multiple Light Levels Add multiple brightness levels: ```cpp void loop() { int lightValue = analogRead(lightSensorPin); lightValue = smoothReading(lightValue); if (lightValue < 5) { analogWrite(ledPin, 255); // Very dark - full brightness } else if (lightValue < 10) { analogWrite(ledPin, 128); // Dark - half brightness } else if (lightValue < 20) { analogWrite(ledPin, 64); // Low light - quarter brightness } else { analogWrite(ledPin, 0); // Bright - off } delay(100); } ``` ### 4. Time-Based Control Add time-based features: ```cpp unsigned long lastChangeTime = 0; const unsigned long MIN_ON_TIME = 5000; // Minimum 5 seconds ON void loop() { int lightValue = analogRead(lightSensorPin); lightValue = smoothReading(lightValue); if (lightValue < DARK_THRESHOLD) { if (!ledState) { digitalWrite(ledPin, HIGH); ledState = true; lastChangeTime = millis(); } } else if (lightValue > BRIGHT_THRESHOLD) { if (ledState && (millis() - lastChangeTime > MIN_ON_TIME)) { digitalWrite(ledPin, LOW); ledState = false; } } delay(100); } ``` ## Questions for Understanding 1. What is hysteresis and why is it important in this system? 2. How do the threshold values (10 and 20) prevent LED flickering? 3. What happens if both thresholds are set to the same value? 4. Why do we use smoothing for the light sensor readings? 5. How would you modify the system to work in reverse (LED ON in bright light)? 6. What are the advantages of using different on/off thresholds? 7. How could you add a manual override to the automatic system? ## Next Steps - Try connecting multiple LEDs for area lighting control - Experiment with different threshold values for your environment - Learn about other environmental sensors (temperature, humidity) - Explore other TinkerBlock sensor modules for different automation systems - Try creating more complex lighting control systems - Implement time-based or motion-based lighting control ## Safety Notes - Always disconnect power before connecting or disconnecting modules - Handle the TinkerBlock shield and modules carefully to avoid bending pins - Ensure proper alignment when connecting modules to prevent damage - The built-in resistors in the modules prevent component damage - Keep the Lonely Binary UNO R3 and shield in a stable position during operation - Do not apply voltages higher than 5V to analog inputs - Consider power consumption for long-term operation --- **Lab Completion Checklist:** - [ ] TinkerBlock shield properly seated on Lonely Binary UNO R3 - [ ] TK20 Ambient Light Sensor module connected to shield (A3) - [ ] TK01 LED module connected to shield (D3) - [ ] Code uploaded successfully to Lonely Binary UNO R3 - [ ] LED turns ON when sensor value < 10 - [ ] LED turns OFF when sensor value > 20 - [ ] LED maintains state in transition zone (10-20) - [ ] No flickering at threshold boundaries - [ ] Serial Monitor displays system status correctly - [ ] System responds to light changes smoothly - [ ] Troubleshooting completed (if needed) - [ ] Experiment variations tried - [ ] Questions answered