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.
Key Components:
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.
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.
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.
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.
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.
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.
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.
Project Wiring Diagram
Workflow:
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.
from smd.red import*import timeimport tkinter as tkfrom tkinter import messagebox # Uyarı mesajları içinfrom threading import Threadimport json # To handle saving and loading from JSONimport os # To check if the JSON file existsfrom serial.tools.list_ports import comportsfrom platform import systemdefUSB_Port():""" Detects and returns the USB serial port for the SMD module on the current operating system. Returns: str or None: The USB serial port for the SMD module, or None if no suitable port is found. """ifsystem()=="Windows": ports =list(comports())if ports:for port, desc, hwid insorted(ports):if'USB Serial Port'in desc: SMD_Port = portreturn SMD_Portelse: SMD_Port =Nonereturn SMD_Portelifsystem()=="Linux": ports =list(serial.tools.list_ports.comports())if ports:for port, desc, hwid insorted(ports):if'/dev/ttyUSB'in port: SMD_Port = portreturn SMD_Portelifsystem()=="Darwin":# macOS ports =list(serial.tools.list_ports.comports())if ports:for port, desc, hwid insorted(ports):if'/dev/tty.usbserial'in port or'/dev/tty.usbmodem'in port: SMD_Port = portreturn SMD_Portelse: SMD_Port =Nonereturn SMD_Portport =USB_Port()m =Master(port)m.attach(Red(0))defload_colors_from_json():""" Loads the list of colors from a JSON file named "rgbsetting.json". If the file does not exist or the "colors" key is not present in the JSON data, an empty list is returned. Returns: list: A list of RGB color tuples, or an empty list if the JSON file does not exist or does not contain the "colors" key.
"""if os.path.exists("rgbsetting.json"):withopen("rgbsetting.json", "r")as f: data = json.load(f)return data.get("colors", [])return []# Predefined default colors in RGB formatdefault_colors = [(255,0,0), (0,255,0), (0,0,255), (255,255,0), (255,0,255), (0,255,255)]# Load colors from JSON file if available, otherwise use default colorscolors =load_colors_from_json()or default_colorscolor_index =0# Index for the order of colorsprint(m.scan_modules(0))# Scans the Red SMD module connected to the COM6 serial port and prints the result.# Create a Tkinter windowwindow = tk.Tk()window.title("LED Color Controller")window.geometry("400x300")defvalidate_rgb_value(value):""" Validates an RGB value to ensure it is an integer between 0 and 255 (inclusive). Args: value (str): The RGB value to validate as a string. Returns: bool: True if the value is a valid RGB value, False otherwise. """try: value =int(value)if0<= value <=255:returnTrueelse:returnFalseexceptValueError:returnFalsedefsave_color_to_json():""" Saves the current list of colors to a JSON file named "rgbsetting.json". This function is called when the "Save color to file" checkbox is checked after adding a new color. It creates a dictionary with the "colors" key and assigns the current `colors` list as its value. The dictionary is then written to the "rgbsetting.json" file using the `json.dump()` function. Args: None Returns: None """ data ={"colors": colors}withopen("rgbsetting.json", "w")as f: json.dump(data, f, indent=4)print(f"Colors saved to rgbsetting.json")defadd_color():""" Adds a new color to the list of colors based on the RGB values entered in the GUI. This function is called when the "Add Color" button is clicked in the GUI. It retrieves the RGB values from the corresponding text fields, validates them, and adds the new color to the `colors` list. If the "Save color to file" checkbox is checked, it also saves the updated list of colors to a JSON file. Args: None Returns: None """ r = r_entry.get() g = g_entry.get() b = b_entry.get()ifvalidate_rgb_value(r)andvalidate_rgb_value(g)andvalidate_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}")update_gui("On", "Added", (r, g, b))if save_var.get():save_color_to_json()else: messagebox.showerror("Invalid Input", "RGB values must be integers between 0 and 255.")# Create labels to display light status and button statelight_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)# RGB input fields and button to add new colorr_label = tk.Label(window, text="R:", font=("Helvetica", 12))r_label.pack(pady=5, side=tk.LEFT, padx=(10, 0))r_entry = tk.Entry(window, width=5)r_entry.pack(pady=5, side=tk.LEFT)g_label = tk.Label(window, text="G:", font=("Helvetica", 12))g_label.pack(pady=5, side=tk.LEFT, padx=(10, 0))g_entry = tk.Entry(window, width=5)g_entry.pack(pady=5, side=tk.LEFT)b_label = tk.Label(window, text="B:", font=("Helvetica", 12))b_label.pack(pady=5, side=tk.LEFT, padx=(10, 0))b_entry = tk.Entry(window, width=5)b_entry.pack(pady=5, side=tk.LEFT)# Checkbox for saving the color to JSONsave_var = tk.BooleanVar()save_checkbox = tk.Checkbutton(window, text="Save color to file", variable=save_var)save_checkbox.pack(pady=5)# Button to trigger adding the new coloradd_button = tk.Button(window, text="Add Color", command=add_color)add_button.pack(pady=10)defupdate_gui(light_status,button_status,current_color):""" Updates the GUI to reflect the current light status, button state, and LED color. This function is responsible for updating the labels and background color of the GUI to match the current state of the RGB LED light.
It is called whenever the light status, button state, or LED color changes. Args: light_status (str): The current status of the light, either "On" or "Off". button_status (str): The current state of the button, either "Pressed" or "Released". current_color (tuple): A tuple containing the current RGB values of the LED light. """ 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}')defchange_color(index):""" Changes the color of the RGB LED light. This function is responsible for turning off the LED, then turning on the next color in the `colors` list. It also updates the GUI to reflect the new color.
Args: index (int): The index of the color to change to in the `colors` list. """ m.set_rgb(0, 1, 0, 0, 0) time.sleep(0.1) r, g, b = colors[index %len(colors)] m.set_rgb(0, 1, r, g, b)update_gui("On", "Pressed", (r, g, b))button_held =Falselight_status ='Off'defcontrol_loop():""" The `control_loop()` function is the main control loop for the RGB LED light. It performs the following tasks: 1. Checks the ambient light level and turns the LED on or off accordingly. 2. Monitors the button state and changes the LED color when the button is pressed. 3. Updates the GUI to reflect the current light status, button state, and LED color. 4. Ensures the LED stays on the last selected color when the button is released. 5. Provides a short delay to control the loop rate. This function runs in a separate thread to allow the Tkinter main loop to run concurrently. """global color_index, button_held,light_statuswhileTrue: light = m.get_light(0, 1)if light isnotNone: light_status ="Off"if light >=100else"On"if m.get_button(0, 1)==1:ifnot button_held: button_held =Truechange_color(color_index+1) color_index +=1 time.sleep(0.5)else:if button_held: button_held =Falseif light isnotNone:if light<100: r, g, b = colors[color_index %len(colors)] m.set_rgb(0, 1, r, g, b)update_gui(light_status, "Released", (r, g, b))else: m.set_rgb(0, 1, 0, 0, 0)update_gui("Off", "N/A", (0, 0, 0)) update_gui(light_status, "Pressed" if button_held else "Released", ((r, g, b) if light < 100 else (0, 0, 0)) if light is not None else((0, 0, 0)))
time.sleep(0.01)control_thread =Thread(target=control_loop)control_thread.daemon =Truecontrol_thread.start()window.mainloop()
#include<Acrome-SMD.h>#defineID0 // ID of the SMD#defineBAUDRATE115200 // Baud rate of the communicationRedmaster(ID,Serial,BAUDRATE); // Defines the Arduino gateway moduleconstint rgb_module_id =1; // ID of the RGB LED moduleconstint button_module_id =1; // ID of the button module (assuming it's the same as RGB module)constint light_sensor_module_id =1; // ID of the light sensor module (assuming it's the same as RGB module)// Renk dizisiconstint COLOR_Counts =6;int colors[][3] = { {255,0,0}, // Kırmızı {0,255,0}, // Yeşil {0,0,255}, // Mavi {255,255,0}, // Sarı {255,0,255}, // Magenta {0,255,255} // Cyan};int colorIndex =0;bool currentButtonState=false;voidsetup() {master.begin(); // Starts the communicationmaster.scanModules(); // Scans for the connected modulesSerial.begin(BAUDRATE);}voidloop() { // Ortam ışığını kontrol etint lightLevel =master.getLight(light_sensor_module_id);Serial.println(lightLevel);bool shouldLightBeOn = (lightLevel >100); // Düğme durumunu kontrol etbool currentButtonState =master.getButton(button_module_id); // Düğmeye basıldığında rengi değiştirif (currentButtonState) { colorIndex = (colorIndex +1) % COLOR_Counts; } // LED'i güncelleif (shouldLightBeOn) {master.setRGB(rgb_module_id,colors[colorIndex][0],colors[colorIndex][1],colors[colorIndex][2]); } else {master.setRGB(rgb_module_id,0,0,0); }delay(100); // Kısa bir gecikme ekleyerek döngü hızını kontrol et}
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.