Smart Light Control

This project focuses on creating an interactive lighting system using the ACROME SMD platform, incorporating an Ambient Light Sensor, an RGB LED Module, and a Button Module. The system allows for automatic lighting control based on ambient light conditions and provides user interactivity to change the LED color. Additionally, the Button Module allows the user to cycle through colors, and when held down, it will quickly transition between colors. The LED will retain the last selected color after the button is released.

About Tools and Materials:

SMD Red (Purchase Here)

SMD USB Gateway (Purchase Here)

Arduino Gateway Module (Purchase Here)

RGB LED Module (Purchase Here)

Button Module (Purchase Here)

Ambient Light Sensor Module (Purchase Here)

Step 1: Hardware & Software Overview

Key Components:

  1. SMD The SMD serves as the central communication hub between the different modules. It manages the interaction between the Ambient Light Sensor, RGB LED Module, and Button Module, executing the logic as defined in the script.

  2. RGB LED Module The RGB LED Module emits light in different colors by mixing red, green, and blue channels. This allows users to create a variety of lighting effects, controlled via the Button Module.

  3. Button Module The Button Module serves as a physical interface for user input. Users can press the button to cycle through different colors for the RGB LED Module, and if the button is held down, the system will rapidly cycle through colors, allowing for faster color selection.

  4. Ambient Light Sensor Module The Ambient Light Sensor detects the intensity of the surrounding light and allows the system to decide when to automatically turn on or off the RGB LED Module, depending on the environment’s lighting conditions.

Project Key Features:

  1. Automatic Light Sensing The Ambient Light Sensor Module continuously monitors the environmental light levels. When the light intensity falls below a predefined threshold, the system automatically activates the RGB LED Module. This ensures that the light is only turned on when needed, enhancing energy efficiency and creating an adaptive lighting environment.

  2. Manual Color Control The user can interact with the Button Module to manually change the color of the RGB LED Module. Each button press cycles through a preset list of colors (e.g., red, green, blue, yellow, magenta, cyan). Additionally, holding the button down accelerates the color transitions, allowing users to quickly move between colors.

  3. Energy-Efficient Operation The Ambient Light Sensor Module makes the system more energy-efficient by turning the light off when ambient light levels are sufficient. This feature ensures that the RGB LED Module operates only in low-light conditions, minimizing unnecessary energy usage.

  4. Seamless Module Communication The SMD ensures seamless communication between all components. It reads the ambient light data from the Ambient Light Sensor, controls the color output of the RGB LED, and processes user input from the Button Module. This integration allows the project to react dynamically to both environmental changes and user commands.

Step 2: Assemble

Getting Started

  1. Hardware Setup

Project Wiring Diagram

Step 3: Run & Test

  • Light Monitoring: The system constantly reads ambient light data using the Ambient Light Sensor.

  • Automatic Light Control: If the environment is too dark, the RGB LED Module is automatically turned on, and if the environment is bright, the RGB LED Module turns off.

  • User Interaction: The Button Module allows the user to cycle through colors manually. A single press changes the color, and holding the button down rapidly switches between the colors.

  • Color Retention: When the button is released, the LED remains on the last selected color until further interaction.

Project Codes

from smd.red import *
import time
import tkinter as tk
from tkinter import messagebox
from threading import Thread
import json
import os
from serial.tools.list_ports import comports
from platform import system


# Serial Communication Settings
baudrate = 115200          # Baud rate of communication
ID = 0                     # ID of the SMD module
button_module_id = 5       # ID of the button module
light_sensor_id = 5        # ID of the light sensor module
rgb_led_id = 5             # ID of the RGB LED module


def USB_Port():
    """
    Scans and identifies a compatible USB port for the current operating system.

    Returns:
        str: The detected USB port or None if no suitable port is found.
    """
    ports = list(comports())

    usb_names = {
        "Windows": ["USB Serial Port"],
        "Linux": ["/dev/ttyUSB"],
        "Darwin": [
            "/dev/tty.usbserial",
            "/dev/tty.usbmodem",
            "/dev/tty.SLAB_USBtoUART",
            "/dev/tty.wchusbserial",
            "/dev/cu.usbserial",
            "/dev/cu.usbmodem",
            "/dev/cu.SLAB_USBtoUART",
            "/dev/cu.wchusbserial",
        ]
    }

    # Detect the operating system
    os_name = system()
    print(f"Operating System: {os_name}")

    if ports:
        for port in ports:
            if any(name in port.device or name in port.description for name in usb_names.get(os_name, [])):
                print(f"USB device detected on port: {port.device}")
                return port.device
        print("No suitable USB device found. Available ports:")
        for port in ports:
            print(f"Port: {port.device}, Description: {port.description}, HWID: {port.hwid}")
    else:
        print("No ports detected!")
    return None


# Initialize the USB port and SMD module
SerialPort = USB_Port()
if not SerialPort:
    raise Exception("No compatible USB port found. Please check your connection.")

master = Master(SerialPort, baudrate)
master.attach(Red(ID))
print("Connected Modules:", master.scan_modules(ID))


# Color Management Functions
def load_colors_from_json():
    """
    Load colors from a JSON file. If the file doesn't exist, return an empty list.

    Returns:
        list: A list of RGB color tuples, or an empty list if the file is not found.
    """
    if os.path.exists("rgbsetting.json"):
        with open("rgbsetting.json", "r") as f:
            data = json.load(f)
            return data.get("colors", [])
    return []


def save_color_to_json():
    """
    Save the current list of colors to a JSON file.
    """
    data = {"colors": colors}
    with open("rgbsetting.json", "w") as f:
        json.dump(data, f, indent=4)
    print("Colors saved to rgbsetting.json")


# Default Colors
default_colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (255, 0, 255), (0, 255, 255)]
colors = load_colors_from_json() or default_colors
color_index = 0  # Tracks the current color index


# GUI Setup
window = tk.Tk()
window.title("LED Color Controller")
window.geometry("400x300")


# GUI Widgets
light_label = tk.Label(window, text="Light Status: ", font=("Helvetica", 14))
light_label.pack(pady=10)

button_label = tk.Label(window, text="Button State: ", font=("Helvetica", 14))
button_label.pack(pady=10)

color_label = tk.Label(window, text="Current Color: ", font=("Helvetica", 14))
color_label.pack(pady=10)

r_label = tk.Label(window, text="R:", font=("Helvetica", 12))
r_label.pack(side=tk.LEFT, padx=(10, 0))
r_entry = tk.Entry(window, width=5)
r_entry.pack(side=tk.LEFT)

g_label = tk.Label(window, text="G:", font=("Helvetica", 12))
g_label.pack(side=tk.LEFT, padx=(10, 0))
g_entry = tk.Entry(window, width=5)
g_entry.pack(side=tk.LEFT)

b_label = tk.Label(window, text="B:", font=("Helvetica", 12))
b_label.pack(side=tk.LEFT, padx=(10, 0))
b_entry = tk.Entry(window, width=5)
b_entry.pack(side=tk.LEFT)

save_var = tk.BooleanVar()
save_checkbox = tk.Checkbutton(window, text="Save color to file", variable=save_var)
save_checkbox.pack(pady=5)

add_button = tk.Button(window, text="Add Color", command=lambda: add_color())
add_button.pack(pady=10)


# Helper Functions
def validate_rgb_value(value):
    """
    Validates whether the given value is an integer between 0 and 255.

    Args:
        value (str): RGB value as string.
    Returns:
        bool: True if valid, False otherwise.
    """
    try:
        value = int(value)
        return 0 <= value <= 255
    except ValueError:
        return False


def add_color():
    """
    Adds a new color to the colors list and saves it to a JSON file if required.
    """
    r, g, b = r_entry.get(), g_entry.get(), b_entry.get()
    if validate_rgb_value(r) and validate_rgb_value(g) and validate_rgb_value(b):
        r, g, b = int(r), int(g), int(b)
        colors.append((r, g, b))
        print(f"New color added: R={r}, G={g}, B={b}")
        if save_var.get():
            save_color_to_json()
    else:
        messagebox.showerror("Invalid Input", "RGB values must be integers between 0 and 255.")


def update_gui(light_status, button_status, current_color):
    """
    Updates the GUI labels and background color based on the current state.

    Args:
        light_status (str): Current status of the light (On/Off).
        button_status (str): Current state of the button (Pressed/Released).
        current_color (tuple): RGB values of the current LED color.
    """
    light_label.config(text=f"Light Status: {light_status}")
    button_label.config(text=f"Button State: {button_status}")
    color_label.config(text=f"Current Color: R={current_color[0]}, G={current_color[1]}, B={current_color[2]}")
    window.configure(bg=f'#{current_color[0]:02x}{current_color[1]:02x}{current_color[2]:02x}')


# Main Control Loop
def control_loop():
    """
    Main control loop for managing the RGB LED light and updating GUI elements.
    """
    global color_index
    button_held = False

    while True:
        light = master.get_light(ID, light_sensor_id)
        button_pressed = master.get_button(ID, button_module_id)

        # Determine light status based on sensor reading
        if light is not None and light < 100:
            light_status = "On"
        else:
            light_status = "Off"

        # Handle button press to change colors
        if button_pressed == 1 and not button_held:
            button_held = True
            color_index = (color_index + 1) % len(colors)
            r, g, b = colors[color_index]
            master.set_rgb(ID, rgb_led_id, r, g, b)
        elif button_pressed == 0:
            button_held = False

        # Update GUI with the current state
        r, g, b = colors[color_index] if light_status == "On" else (0, 0, 0)
        update_gui(light_status, "Pressed" if button_pressed else "Released", (r, g, b))
        time.sleep(0.1)


# Start control loop in a separate thread
control_thread = Thread(target=control_loop)
control_thread.daemon = True
control_thread.start()

# Run the GUI main loop
window.mainloop()

Conclusion:

This project exemplifies how the ACROME SMD platform can integrate with various modules to create a smart lighting solution that is both interactive and energy-efficient. By using the Ambient Light Sensor, RGB LED, and Button Module, the system combines automatic control with manual user inputs, providing a flexible and customizable lighting experience.

Last updated