Step 1: Hardware Setup
Install the RGB LED following the wiring diagram.
Identify the Pins: Find the longest pin (Common Cathode); this goes to GND (number 6). Connect the other three pins to the designated GPIOs using resistors if necessary.
Step 2: Basic Control (Switching Colors)
Copy and Paste the code into Thonny.
Run the program to test the Red, Green, and Blue buttons. This confirms your wiring is correct.
import network
import socket
from machine import Pin, PWM
import time
import gc
# 1. 設定學生 ID
student_id = "01"
# 2. 設定 RGB 燈腳位 (使用 PWM 才能控制亮度)
red = PWM(Pin(13), freq=1000)
green = PWM(Pin(12), freq=1000)
blue = PWM(Pin(14), freq=1000)
# 初始關閉所有燈 (0 為熄滅,1023 為最亮)
def set_color(r, g, b):
red.duty(r)
green.duty(g)
blue.duty(b)
set_color(0, 0, 0)
# 3. 啟動 Wi-Fi AP
ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid="RGB_Control_" + student_id, password="password123")
# 4. 網頁 HTML
def web_page():
html = """<html><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body { font-family: Arial; text-align: center; padding-top: 30px; }
.btn { display: block; width: 80%; padding: 20px; margin: 10px auto;
font-size: 24px; color: white; border-radius: 10px; text-decoration: none; }
.red { background: red; } .green { background: green; } .blue { background: blue; } .off { background: black; }
</style></head>
<body>
<h1>RGB Controller #""" + student_id + """</h1>
<a href="/red" class="btn red">RED</a>
<a href="/green" class="btn green">GREEN</a>
<a href="/blue" class="btn blue">BLUE</a>
<a href="/off" class="btn off">OFF</a>
</body></html>"""
return html
# 5. 啟動伺服器
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 80))
s.listen(5)
print("RGB Server Ready: http://192.168.4.1")
while True:
try:
gc.collect()
conn, addr = s.accept()
request = conn.recv(1024).decode()
if '/red' in request: set_color(1023, 0, 0)
if '/green' in request: set_color(0, 1023, 0)
if '/blue' in request: set_color(0, 0, 1023)
if '/off' in request: set_color(0, 0, 0)
response = web_page()
conn.send('HTTP/1.1 200 OK\nContent-Type: text/html\n\n' + response)
conn.close()
except:
if 'conn' in locals(): conn.close()
Step 3: Advanced Control (Color Mixing)
Use the Sliders on the webpage to adjust the intensity of each color.
Observe the result: See how combining Red, Green, and Blue light creates new colors like Yellow, Cyan, or White.
import network
import socket
from machine import Pin, PWM
import time
import gc
# 1. Student ID Configuration
student_id = "01"
# 2. RGB LED Setup (PWM)
# Range: 0 to 1023
red = PWM(Pin(13), freq=1000)
green = PWM(Pin(12), freq=1000)
blue = PWM(Pin(14), freq=1000)
# Global variables to track current color states (0-255)
r_val, g_val, b_val = 0, 0, 0
def update_hardware():
# Map 0-255 to 0-1023
red.duty(r_val * 4)
green.duty(g_val * 4)
blue.duty(b_val * 4)
# Initial: Off
update_hardware()
# 3. Start Wi-Fi AP
ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid="RGB_Mixer_ID_" + student_id, password="password123")
# 4. Web Interface (HTML + CSS + JS)
def web_page():
html = """<html><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>RGB Mixer</title>
<style>
body { font-family: Arial, sans-serif; text-align: center; background: #f0f0f0; padding: 20px; }
.card { background: white; padding: 20px; border-radius: 15px; box-shadow: 0 4px 8px rgba(0,0,0,0.2); max-width: 400px; margin: auto; }
.slider-group { margin: 25px 0; text-align: left; }
input[type=range] { width: 100%; height: 15px; border-radius: 5px; outline: none; -webkit-appearance: none; }
#r-slider { background: #ffcccc; } #g-slider { background: #ccffcc; } #b-slider { background: #ccccff; }
.btn-group { display: flex; justify-content: space-between; margin-bottom: 20px; }
.btn { padding: 15px; width: 30%; border-radius: 8px; color: white; text-decoration: none; font-weight: bold; border: none; cursor: pointer; }
.red { background: #e74c3c; } .green { background: #2ecc71; } .blue { background: #3498db; }
.off { background: #34495e; width: 100%; margin-top: 10px; }
h1 { color: #2c3e50; margin-bottom: 5px; }
span { font-weight: bold; float: right; }
</style>
<script>
function updateColor() {
let r = document.getElementById('r-slider').value;
let g = document.getElementById('g-slider').value;
let b = document.getElementById('b-slider').value;
// Send parameters to ESP32: /set?r=255&g=0&b=128
window.location.href = `/set?r=${r}&g=${g}&b=${b}`;
}
</script>
</head>
<body>
<div class="card">
<h1>RGB Mixer #""" + student_id + """</h1>
<p>Quick Presets:</p>
<div class="btn-group">
<a href="/set?r=255&g=0&b=0" class="btn red">RED</a>
<a href="/set?r=0&g=255&b=0" class="btn green">GREEN</a>
<a href="/set?r=0&g=0&b=255" class="btn blue">BLUE</a>
</div>
<div class="slider-group">
<label>Red Intensity: <span id="rv">""" + str(r_val) + """</span></label>
<input type="range" id="r-slider" min="0" max="255" value='""" + str(r_val) + """' onchange="updateColor()">
</div>
<div class="slider-group">
<label>Green Intensity: <span id="gv">""" + str(g_val) + """</span></label>
<input type="range" id="g-slider" min="0" max="255" value='""" + str(g_val) + """' onchange="updateColor()">
</div>
<div class="slider-group">
<label>Blue Intensity: <span id="bv">""" + str(b_val) + """</span></label>
<input type="range" id="b-slider" min="0" max="255" value='""" + str(b_val) + """' onchange="updateColor()">
</div>
<a href="/set?r=0&g=0&b=0" class="btn off">ALL OFF</a>
</div>
</body></html>"""
return html
# 5. Main Server Loop
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 80))
s.listen(5)
print("Mixer Ready: http://192.168.4.1")
while True:
try:
gc.collect()
conn, addr = s.accept()
request = conn.recv(1024).decode()
# Parse URL: /set?r=255&g=100&b=50
if '/set?' in request:
try:
# Simple string parsing to find r, g, b values
r_val = int(request.split('r=')[1].split('&')[0])
g_val = int(request.split('g=')[1].split('&')[0])
b_val = int(request.split('b=')[1].split(' ')[0])
update_hardware()
print("Hardware: R:%d G:%d B:%d" % (r_val, g_val, b_val))
except:
pass
response = web_page()
conn.send('HTTP/1.1 200 OK\nContent-Type: text/html\n\n' + response)
conn.close()
except Exception as e:
if 'conn' in locals(): conn.close()