a project based on a smart power switch that detects changes in light using a Raspberry Pi Pico:
Approximate time to do this tutorial: 1 hours
The purpose of this project is to create a smart power switch that can turn on or off an appliance based on the ambient light level. The project will use a Raspberry Pi Pico, a photoresistor, a relay module, and an LED to sense and control the power switch. The project will also use a web app to display the light level and the switch status on a web page.
The hardware components required for this project are:
- Raspberry Pi Pico
- Photoresistor x2
- Relay module
- LED
- Breadboard
- Jumper wires
- Power supply
The software components required for this project are:
- MicroPython
- Thonny IDE
- Flask web framework
- Socket.IO library
The implementation steps for this project are:
- Connect the photoresistor, the relay module, and the LED to the Raspberry Pi Pico using the breadboard and the jumper wires. The photoresistor will be connected to GPIO pin 26 (ADC0), the relay module will be connected to GPIO pin 15, and the LED will be connected to GPIO pin 14.
- Install MicroPython on the Raspberry Pi Pico using the Thonny IDE following the instructions from [this guide].
- Create a MicroPython script named
main.py
that will read the light level from the photoresistor, write it to a global variable namedlight
, and compare it with a predefined threshold namedthreshold
. If the light level is below the threshold, the script will turn on the relay module and the LED, otherwise it will turn them off. The script will also use Socket.IO to communicate with the web app and send or receive messages. The script will look something like this:
import machine
import utime
import socketio
# Set up GPIO pins
adc = machine.ADC(26) # photoresistor pin
relay = machine.Pin(15, machine.Pin.OUT) # relay module pin
led = machine.Pin(14, machine.Pin.OUT) # LED pin
# Set up global variables for light level and threshold
light = 0 # light level in percentage (0% = dark, 100% = bright)
threshold = 50 # threshold in percentage
# Set up Socket.IO client
sio = socketio.Client()
# Define callback function for Socket.IO connection
def on_connect():
print("Connected to web app")
# Define callback function for Socket.IO disconnection
def on_disconnect():
print("Disconnected from web app")
# Define callback function for Socket.IO messages
def on_message(data):
# Get message as string
message = data.decode("utf-8")
# Check if message is "ON" or "OFF"
if message == "ON":
# Turn on relay module and LED
relay.value(1)
led.value(1)
elif message == "OFF":
# Turn off relay module and LED
relay.value(0)
led.value(0)
# Register callback functions for Socket.IO events
sio.on("connect", on_connect)
sio.on("disconnect", on_disconnect)
sio.on("message", on_message)
# Connect to web app using Socket.IO
sio.connect("http://localhost:5000")
# Main loop
while True:
# Read light level from photoresistor (0 - 65535)
value = adc.read_u16()
# Convert light level to percentage (0% - 100%)
light = value / 655.35
# Send light level to web app using Socket.IO
sio.emit("light", light)
# Check if light level is below threshold
if light < threshold:
# Turn on relay module and LED if not already on
if relay.value() == 0:
relay.value(1)
led.value(1)
else:
# Turn off relay module and LED if not already off
if relay.value() == 1:
relay.value(0)
led.value(0)
# Wait for 1 second before next iteration
utime.sleep(1)
# Disconnect from web app using Socket.IO
sio.disconnect()
- Create a web app using Flask and Socket.IO that will display the light level and the switch status on a web page. The web app will also allow the user to manually control the switch by sending “ON” or “OFF” messages to the Raspberry Pi Pico. The web app will look something like this:
from flask import Flask, render_template
from flask_socketio import SocketIO
# Set up Flask app and Socket.IO server
app = Flask(__name__)
socketio = SocketIO(app)
# Set up global variable for switch status
switch = "OFF"
# Define route for home page
@app.route("/")
def index():
# Render index.html template with switch variable
return render_template("index.html", switch=switch)
# Define event handler for Socket.IO connection
@socketio.on("connect")
def on_connect():
print("Connected to Raspberry Pi Pico")
# Define event handler for Socket.IO disconnection
@socketio.on("disconnect")
def on_disconnect():
print("Disconnected from Raspberry Pi Pico")
# Define event handler for Socket.IO light event
@socketio.on("light")
def on_light(data):
# Get light level as float
light = float(data)
# Emit light level to web page using Socket.IO
socketio.emit("light", light)
# Define event handler for Socket.IO message event
@socketio.on("message")
def on_message(data):
# Get message as string
message = data.decode("utf-8")
# Update global switch variable
global switch
switch = message
# Emit switch status to web page using Socket.IO
socketio.emit("switch", switch)
# Define route for switch on button
@app.route("/switch/on")
def switch_on():
# Send "ON" message to Raspberry Pi Pico using Socket.IO
socketio.send("ON")
# Redirect to home page
return index()
# Define route for switch off button
@app.route("/switch/off")
def switch_off():
# Send "OFF" message to Raspberry Pi Pico using Socket.IO
socketio.send("OFF")
# Redirect to home page
return index()
# Run Flask app and Socket.IO server in debug mode
if __name__ == "__main__":
socketio.run(app, debug=True)
- Create an HTML template named
index.html
that will display the light level and the switch status on a web page. The template will also have buttons to manually control the switch by sending requests to the web app. The template will also use JavaScript and jQuery to handle the Socket.IO events and update the web page dynamically. The template will look something like this:
<html>
<head>
<title>Smart Power Switch</title>
<!-- Load jQuery library -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- Load Socket.IO library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.1.3/socket.io.min.js"></script>
</head>
<body>
<h1>Smart Power Switch</h1>
<p>Light level: <span id="light">0</span>%</p>
<p>Switch status: <span id="switch">OFF</span></p>
<form action="/switch/on" method="get">
<button type="submit">Switch ON</button>
</form>
<form action="/switch/off" method="get">
<button type="submit">Switch OFF</button>
</form>
<!-- Define script for Socket.IO events -->
<script>
// Create Socket.IO client object
var socket = io();
// Define function for Socket.IO light event
socket.on("light", function(data) {
// Get light level as float
var light = parseFloat(data);
// Update light span element with light level
$("#light").text(light.toFixed(2));
});
// Define function for Socket.IO switch event
socket.on("switch", function(data) {
// Get switch status as string
var switch = data;
// Update switch span element with switch status
$("#switch").text(switch);
});
</script>
</body>
</html>
- Run the MicroPython script and the web app on the Raspberry Pi Pico and open the web page on a browser to see the results.
This project demonstrates how to create a smart power switch that can turn on or off an appliance based on the ambient light level. The project uses a Raspberry Pi Pico, a photoresistor, a relay module, and an LED to sense and control the power switch. The project also uses a web app to display the light level and the switch status on a web page. The project also allows the user to manually control the switch by sending “ON” or “OFF” messages to the Raspberry Pi Pico. This project can be further improved by adding more sensors, such as motion, sound, etc., and more features, such as timers, schedules, etc., to make it more smart and convenient.